2

I'm hoping someone happens to have stumbled upon the following issue before.

My Java application has graphics performance issues on Mac, so I made a simple test application (code below). When I run this on Windows, the console tells me:

GraphicsConfiguration flipping? true
BufferStrategy flipping? true

When I run the exact same code on Mac OS, I get:

GraphicsConfiguration flipping? true
BufferStrategy flipping? false

Does this mean that on Mac OS, page flipping is simply not supported in a windowed application? Are there any tricks to make page flipping work on Mac OS without going full screen?

All pointers are very welcome,
Mattijs

Using JDK 1.6 on Windows XP and Mac OS 10.5.

The code:

import java.awt.image.BufferStrategy;
import javax.swing.*;
import java.awt.*;

public class Test {
 int width = 640;
 int height = 480;

 GraphicsEnvironment graphEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
 GraphicsDevice graphDevice = graphEnv.getDefaultScreenDevice();
 GraphicsConfiguration graphicConf = graphDevice.getDefaultConfiguration();

 public Test() {
  JFrame jFrame = new JFrame(graphicConf);
  jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  jFrame.setTitle("double buffer test");
  jFrame.setResizable(false);
  jFrame.setFocusTraversalKeysEnabled(false);

  Canvas canvas = new Canvas();
  canvas.setSize(width, height);
  canvas.setIgnoreRepaint(true);

  jFrame.getContentPane().add(canvas);
  jFrame.pack();
  jFrame.setVisible(true);

  System.out.println("GraphicsConfiguration flipping? " + graphicConf.getBufferCapabilities().isPageFlipping());
  canvas.createBufferStrategy(2);
  BufferStrategy bufferStrategy = canvas.getBufferStrategy();
  System.out.println("BufferStrategy flipping? " + bufferStrategy.getCapabilities().isPageFlipping());

  while(true) {
    Graphics g = bufferStrategy.getDrawGraphics();
    g.setColor(Color.BLACK);
    g.fillRect(0,0,width,height);
    g.setColor(Color.RED);
    g.drawLine((int)(Math.random()*width),(int)(Math.random()*height),
               (int)(Math.random()*width),(int)(Math.random()*height));
    bufferStrategy.show();
    g.dispose();
  }
 }

 public static void main(String[] args) {
  new Test();
 }
}
Mattijs
  • 1,909
  • 3
  • 19
  • 28
  • It was a while ago, but I have successfully used page flipping (not full-screen) in JOGL on a Mac. – finnw Jun 25 '10 at 19:36

2 Answers2

2

The bad news: I get the same result on the same Mac OS X configuration. The good news: isAccelerated() is true.

System.out.println("BufferStrategy accelerated? " + bufferStrategy
    .getCapabilities().getFrontBufferCapabilities().isAccelerated());

Instead of Canvas and BufferStrategy, I just use new JPanel(true).

Addendum: For example,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class NewTest extends JPanel implements ActionListener, Runnable {

    private Random r = new Random();
    private Timer t = new Timer(10, this);

    public static void main(String[] args) {
        EventQueue.invokeLater(new NewTest());
    }

    @Override
    public void run() {
        JFrame f = new JFrame("NewTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        t.start();
    }

    public NewTest() {
        super(true);
        this.setPreferredSize(new Dimension(640, 480));
    }

    @Override
    protected void paintComponent(Graphics g) {
        int width = this.getWidth();
        int height = this.getHeight();
        g.setColor(Color.BLACK);
        g.fillRect(0, 0, width, height);
        g.setColor(Color.RED);
        g.drawLine(r.nextInt(width), r.nextInt(height),
            r.nextInt(width), r.nextInt(height));

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        this.repaint();
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Though I don't know why, implementing my main application based on your code example does solve the cpu-hungry-ness on Mac. I still have some artifacts to solve that show up when I add TextFields on top of the rendered content, but so far this seems like a great step forward! Thanks! – Mattijs Jun 28 '10 at 12:47
  • @Mattijs: I like the convenience & reliability of `javax.swing.Timer`. If you've added components to the `JPanel`, try `super.paintComponent(g)` instead of `fillRect()` in `paintComponent()`. I usually just add other components nearby. – trashgod Jun 28 '10 at 13:28
  • Update: the artifacts (a small range of pixels around TextFields not repainting correctly) are solved by using JTextField instead. – Mattijs Jun 28 '10 at 13:49
  • as of yet I didn't use Timer but the conventional while loop with Thread.sleep(), but I might try the Timer approach to see if I notice any difference. Btw adding super.paintComponent(g) as you suggest appears to clear my rendered content. I keep some flags to indicate where repainting is necessary, which are set to false after repainting is done. Anyway, without this addition I seem to have everything running nicely. Thanks again. – Mattijs Jun 28 '10 at 14:00
  • A few more issues.. For a continued discussion on this topic, please have a look at http://stackoverflow.com/questions/3256269/jtextfields-on-top-of-active-drawing-on-jpanel-threading-problems – Mattijs Jul 15 '10 at 14:04
0

On Linux this happens when I set command line parameter -Dsun.java2d.opengl=true So it may be worth a try to do the opposite -Dsun.java2d.opengl=false

Marc Johnen
  • 379
  • 3
  • 11