Hey, I’ve been working on a 2D game and I’ve been planning on using Java2D since I don’t know OpenGL at all and would rather keep it simple. Anyway, I’ve noticed a HUGE performance hit when using anti aliasing. I’ve compiled a small demo in which I simply create a window containing a 400x400 Canvas, to which I render using a BufferStrategy. In each frame I render 100 triangles and draw a single string. When disabling AA I get a nice ~3000 FPS, which is good enough for me. However, when enabling AA I get ~6 FPS (a 500x performance hit!!!). Below is the code I am using :
package x;
import java.awt.Canvas;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferStrategy;
import java.util.Random;
import javax.swing.JFrame;
/**
*
* @author laginimaineb
*/
public class Test2D {
public static void main(String[] args) {
JFrame frame = new JFrame("Test2D");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestCanvas canvas = new TestCanvas(400,400);
frame.getContentPane().add(canvas);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
canvas.start();
}
static class TestCanvas extends Canvas {
private int width,height;
private boolean running = true;
private int fps;
protected static final long NANOSECOND = 1000000000L;
public TestCanvas(int width, int height) {
this.width = width;
this.height = height;
setIgnoreRepaint(true);
}
public void start() {
createBufferStrategy(2);
BufferStrategy strategy = getBufferStrategy();
long now = System.nanoTime(), lastFps = 0;
int counter = 0;
while (running) {
counter++;
do {
do {
Graphics2D stratG = (Graphics2D) strategy.getDrawGraphics();
render(stratG);
stratG.dispose();
} while (strategy.contentsRestored());
strategy.show();
} while (strategy.contentsLost());
now = System.nanoTime();
if (now-lastFps >= NANOSECOND) {
lastFps = now;
fps = counter;
counter = 0;
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(width,height);
}
public void render(Graphics2D g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, width, height);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.WHITE);
g.drawString("FPS="+fps, 20, 20);
Random r = new Random();
for (int i=0; i<100; i++) {
int[] xs = {r.nextInt(width),r.nextInt(width),r.nextInt(width)};
int[] ys = {r.nextInt(height),r.nextInt(height),r.nextInt(height)};
g.drawPolygon(xs,ys,3);
}
}
public void stop() {
running = false;
}
}
}
I’m using java version 1.6.0_07 and my system specs are:
OS: Ubuntu 8.04
GPU: nVidia 8800GT
By the way, when using the -Dsun.java2d.trace=COUNT property, I get:
Without AA :
1084087 calls to X11DrawPoly
10842 calls to X11DrawGlyphs
10848 calls to X11FillRect
1 call to sun.java2d.x11.X11PMBlitLoops::Blit(“Integer RGB Pixmap”, SrcNoEa, “Integer RGB Pixmap”)
1105817 total calls to 4 different primitives
With AA:
165794 calls to sun.java2d.loops.MaskFill::MaskFill(AnyColor, SrcOver, IntRgb)
1 call to sun.java2d.x11.X11PMBlitLoops::Blit(“Integer RGB Pixmap”, SrcNoEa, “Integer RGB Pixmap”)
82 calls to X11FillRect
165889 total calls to 3 different primitives
Seems to me that without AA the rendering is accelerated but with AA there are lots of calls to java2d.loops (software rendering… :()
So… what am I doing wrong? Help much appreciated