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

    Question Drawing to large BufferedImage, Direct3D pipeline slower then software pipeline?

    Hi,

    I've recently run into a problem where I'm rendering graphics too a large BufferedImage. Strangely what I've discovered is that using the Direct3D pipeline, which to my understanding is hardware accelerated, is very slow compared to disabling the Direct3D pipeline and other hardware acceleration.

    The problem is disabling hardware acceleration slows every other aspect of my application down such as animations that use scaling, translation and alpha.

    I use the VM option:
    Java Code:
    -Dsun.java2d.trace=count
    To see what the problem might be in regards to hardware acceleration:

    Java Code:
    -Dsun.java2d.d3d=false
    With Direct3D (hardware acceleration) disabled: (Fast)
    Java Code:
    205 calls to sun.java2d.loops.Blit$GeneralMaskBlit::Blit(IntArgb, SrcOverNoEa, IntRgb)
    208 calls to sun.java2d.loops.FillRect::FillRect(AnyColor, SrcNoEa, AnyInt)
    204 calls to sun.java2d.loops.DrawLine::DrawLine(AnyColor, SrcNoEa, AnyInt)
    205 calls to sun.java2d.loops.MaskBlit::MaskBlit(IntArgb, SrcOver, IntRgb)
    205 calls to sun.java2d.windows.GDIBlitLoops::Blit(IntRgb, SrcNoEa, "GDI")
    1027 total calls to 5 different primitives
    Java Code:
    -Dsun.java2d.d3d=true
    With Direct3D enabled: (Slow)
    Java Code:
    46 calls to sun.java2d.loops.DrawLine::DrawLine(AnyColor, SrcNoEa, AnyInt)
    1 call to sun.java2d.d3d.D3DTextureToSurfaceBlit::Blit("D3D Texture", AnyAlpha, "D3D Surface")
    44 calls to sun.java2d.d3d.D3DSwToSurfaceBlit::Blit(IntArgbPre, AnyAlpha, "D3D Surface")
    50 calls to D3DFillRect
    45 calls to sun.java2d.d3d.D3DRTTSurfaceToSurfaceBlit::Blit("D3D Surface (render-to-texture)", AnyAlpha, "D3D Surface")
    1 call to sun.java2d.d3d.D3DSwToTextureBlit::Blit(IntArgbPre, SrcNoEa, "D3D Texture")
    187 total calls to 6 different primitives
    So given my SSCCE below, what might cause poor performance when using Direct3D while rendering to a large BufferedImage? I would if anything expect performance to be faster with hardware acceleration opposed to without it.

    Thank you for you're help , this is really confusing to me and I need to have Direct3D enabled... Also strangely it looks like half my code is commented out but that's just a coloring error.

    Try passing the VM option "-Dsun.java2d.d3d=true" and "-Dsun.java2d.d3d=false" at the command line to see the difference in performance.

    SSCCE:
    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() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                    } catch(Exception err) {
                        err.printStackTrace();
                    }
                    new HardwareAcceleration();
                }
            });
        }
    
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsConfiguration gc = env.getDefaultScreenDevice().getDefaultConfiguration();
    
        BufferedImage drawSurface;
        Graphics2D drawGraphics;
    
        Point mouse = new Point(0,0);
        PaintSurface canvas = new PaintSurface();
    
        public HardwareAcceleration() {
    
            /*
           The BufferedImage to which graphics will be drawn too. The size is large
           to demonstrate the sluggish drawing I experience curiously only when
           not using the line "createBufferStrategy(2) or the command line argument "-Dsun.java2d.d3d=true".
            */
            drawSurface = gc.createCompatibleImage(4000, 4000, Transparency.TRANSLUCENT);
            drawGraphics = drawSurface.createGraphics();
    
            setSize(600, 400);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            canvas.addMouseListener(new MouseListener());
            canvas.addMouseMotionListener(new MouseListener());
    
            add(canvas);
    
            setVisible(true);
    
            /*
            The line below also solves the problem by indirectly disabling Direct3D.
             */
            //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) {
                Graphics2D g2 = (Graphics2D)g;
                
                g2.setColor(Color.black);
                g2.fillRect(0, 0, getWidth(), getHeight());
                
                g2.drawImage(drawSurface, 0, 0, this);
            }
        }
    }
    Last edited by neptune296; 03-23-2012 at 11:24 PM.

Similar Threads

  1. intercept a c++ IO pipeline??
    By blackfox in forum Threads and Synchronization
    Replies: 7
    Last Post: 01-07-2012, 10:51 AM
  2. Problem Drawing Grid with BufferedImage.
    By Shikatsu in forum Java 2D
    Replies: 10
    Last Post: 11-26-2011, 01:01 AM
  3. creating a BufferedImage from a drawing
    By chappa in forum Java 2D
    Replies: 2
    Last Post: 01-10-2010, 07:04 PM
  4. Replies: 0
    Last Post: 10-31-2008, 03:13 PM
  5. Data Pipeline Released
    By dele in forum Java Software
    Replies: 0
    Last Post: 06-28-2007, 04:29 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
  •