Search code examples
javalinuxswinggraphicsawt

Swing/AWT Double Buffering very slow on Linux


I have an AWT Canvas within a JFrame (I know that Swing and AWT shouldn't be used simultaneously but it works well on Windows so I don't think the problem is caused by this) and using a BufferStrategy from the Canvas to draw on screen. It runs pretty smooth on Windows but when I tried to run it on Ubuntu 12.04 it became unbearably slow. Not just the rendering but JFrame is also unresponsive. When I comment out the double buffering and rendering part it's smooth again. I have an ATI graphics card which is no longer supported so I'm using the open source video drivers, but when I run another program which uses OpenGL it's not slow like Swing/AWT one. Why could this be happening?

Main render:

...

private void render()
{
    bs = gamePanel.getBufferStrategy();

    Graphics g = bs.getDrawGraphics();

    currentState.render(g);

    g.dispose();
    bs.show();
}

...

I don't draw anything in currentstate.render() method except a black rectangle that fills the screen.

edit: OK so I tracked down the real problem, it's my game loop. I'm using a while loop within a new Thread to update and render(render code provided above). If I use paint() method of Canvas it runs smoothly but then I don't have any control over my frame rate. Why is a while loop slowing down my program?

Game Loop looks like this:

    while(running)
    {
        update();
        render();
    }

Solution

  • I put Toolkit.getDefaultToolkit().sync(); in my render method which appears to fix it. However you should put only if it's Linux
    I used the code bellow to do that

    public static String getOsName() {
        String OS = null;
        if(OS == null) { OS = System.getProperty("os.name"); }
        return OS;
    }
    
    public static boolean isUnix() { return getOsName().startsWith("Linux"); }