Results 1 to 2 of 2
  1. #1
    neptune296 is offline Member
    Join Date
    Mar 2012
    Posts
    5
    Rep Power
    0

    Question Does rendering to a BufferedImage get hardware accelerated? Help please?

    Hi,

    I've recently ran into a problem drawing quickly to large BufferedImages. I've read here that rendering to a BufferedImage isn't hardware accelerated.

    They state:
    Rendering to a BufferedImage almost always uses software loops.
    What's strange is I discovered calling the method
    Java Code:
    createBufferStrategy(2)
    on a JFrame makes this problem disappear. I'm familiar with how this is usually used and I don't ever use the BufferStrategy I've created as I usually would by calling getBufferStrategy().getDrawGraphics(). So i'm confused as to why this would make drawing to a very large BufferedImage extremely fast.

    I would just count my blessing and be done with this if using the line "createBufferStrategy(2)" didn't cause other performance problems specifically with transparent, scaling and translating animations.

    I've used the command line argument
    Java Code:
    -Dsun.java2d.trace=count
    to see where the rendering is being done:

    Without "createBufferStrategy(2)" (Slow)
    Java Code:
    34 calls to sun.java2d.d3d.D3DRTTSurfaceToSurfaceBlit::Blit("D3D Surface (render-to-texture)", AnyAlpha, "D3D Surface")
    33 calls to sun.java2d.d3d.D3DSwToSurfaceBlit::Blit(IntRgb, AnyAlpha, "D3D Surface")
    5 calls to D3DFillRect
    1 call to sun.java2d.d3d.D3DTextureToSurfaceBlit::Blit("D3D Texture", AnyAlpha, "D3D Surface")
    1 call to sun.java2d.d3d.D3DSwToTextureBlit::Blit(IntRgb, SrcNoEa, "D3D Texture")
    35 calls to sun.java2d.loops.DrawLine::DrawLine(AnyColor, SrcNoEa, AnyInt)
    109 total calls to 6 different primitives
    With "createBufferStrategy(2)" (Fast)
    Java Code:
    191 calls to sun.java2d.loops.DrawLine::DrawLine(AnyColor, SrcNoEa, AnyInt)
    193 calls to sun.java2d.windows.GDIBlitLoops::Blit(IntRgb, SrcNoEa, "GDI")
    7 calls to D3DFillRect
    193 calls to sun.java2d.loops.Blit::Blit(IntRgb, SrcNoEa, IntRgb)
    1 call to sun.java2d.d3d.D3DSwToSurfaceBlit::Blit(IntRgb, AnyAlpha, "D3D Surface")
    3 calls to sun.java2d.loops.FillRect::FillRect(AnyColor, SrcNoEa, AnyInt)
    1 call to sun.java2d.d3d.D3DSurfaceToGDIWindowSurfaceBlit::Blit("D3D Surface", AnyAlpha, "GDI")
    589 total calls to 7 different primitives
    It seems without "createBufferStrategy(2)" rendering is being done almost exclusively with the Direct3D pipeline. Which to my knowledge is fast, and hardware accelerated. Why would this be slower?

    With "createBufferStrategy(2)" rendering seems to be done almost exclusively with the sun's java2d. Why would this be faster? Doesn't this indicated it's not hardware accelerated?

    Thank you for you're help i'm just very confused. I've also created a short easy to compile application to demonstrate the problem, read the comments for some more info.

    Thanks again

    Hardware Acceleration Demo.
    Java Code:
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.image.BufferedImage;
    
    public class HardwareAcceleration extends JFrame {
        
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new HardwareAcceleration();
                }
            });
        }
    
        /*
        The BufferedImage graphics will be rendered too. The size is large
        to demonstrate the sluggish drawing I experience curiously only when
        not using the line "createBufferStrategy(2)".
         */
        BufferedImage drawSurface = new BufferedImage(4000, 4000, BufferedImage.TYPE_INT_RGB);
        Graphics2D drawGraphics = drawSurface.createGraphics();
    
        Point mouse = new Point(0,0);
        PaintSurface canvas = new PaintSurface();
    
        public HardwareAcceleration() {
    
            setSize(600, 400);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            canvas.addMouseListener(new MouseListener());
            canvas.addMouseMotionListener(new MouseListener());
            
            add(canvas);
            setVisible(true);
    
            /*
            COMMENT THIS LINE OUT TO EXPERIENCE POOR
            DRAWING PERFORMANCE.
             */
            createBufferStrategy(2);
        }
    
        class MouseListener extends MouseAdapter {
            @Override
            public void mousePressed(MouseEvent e) {
                mouse = e.getPoint();
            }
    
            @Override
            public void mouseDragged(MouseEvent e) {
    
                /*
                Here's where the problem occurs. Without the line
                "createBufferStrategy(2)" drawing on an image of such a large
                size is very slow. However with that line drawing is smooth and fast.
    
                The problem is (1) I haven't the slightest clue why the line "createBufferStrategy(2)"
                would solve this performance problem, maybe it enables some sort of hardware acceleration?
                But i'm used to using "createBufferStrategy()" when active rendering using "getBufferStrategy().getDrawGraphics()"
                so without drawing to the strategies draw graphics I'm not sure why this would effect anything.
    
                (2) The line createBufferStrategy(2) seems to cause some other performance issues with
                scaling and transparency animations where without it these animations are smooth.
    
                My final goal is to figure out why drawing to this large image is slow without
                the line "createBufferStrategy(2)" and how I might be able to speed it up without
                it as it causes other problems.
                 */
    
                drawGraphics.drawLine(mouse.x, mouse.y, e.getX(), e.getY());
                mouse = e.getPoint();
    
                canvas.repaint();
            }
        }
        
        class PaintSurface extends JPanel {
    
            @Override
            protected void paintComponent(Graphics g) {
                g.drawImage(drawSurface, 0, 0, this);
            }
        }
    }

  2. #2
    nicephotog is offline Member
    Join Date
    Mar 2012
    Posts
    41
    Rep Power
    0

    Default Re: Does rendering to a BufferedImage get hardware accelerated? Help please?

    createbufferStrategy must be greater than 1 ...(2)... for its buffers , secondly the API docs states explicitly in the 6API docs ...",then a blitting strategy using accelerated buffers"...
    often called offscreen buffering and offscreen drawing/painting

Similar Threads

  1. Applet with Hardware Access
    By TSW in forum Java Applets
    Replies: 8
    Last Post: 03-03-2012, 08:05 AM
  2. retrieving hardware information
    By finalight in forum Java Applets
    Replies: 8
    Last Post: 01-11-2012, 08:45 AM
  3. Create hardware diagnostic
    By limpcaca in forum JCreator
    Replies: 0
    Last Post: 04-20-2011, 08:36 PM
  4. get Hardware camera sound
    By ilyas in forum Advanced Java
    Replies: 0
    Last Post: 12-10-2010, 08:53 AM
  5. Problem in Hardware Input
    By kirly in forum New To Java
    Replies: 4
    Last Post: 01-22-2010, 09:37 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •