Anti aliased drawPolygon

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 :slight_smile:

update to 1.6.0_10.

A lot more of the J2D rendering pipeline is hardware accelerated in update 10 - I can’t be sure, but I would expect AA to be one of the aspects to have been improved.
For older releases you can try enabling the opengl pipeline; though it brakes horribly on a lot of hardware configurations - so don’t expect too much.

Unfortunately even 6u10 won’t help on linux for AA primitives.
If your application does a lot of antialiasing you might want to disable the use
of pixmaps (-Dsun.java2d.pmoffscreen=false).

Hopefully we’ll get the xrender-accelerated pipeline for 7 (http://linuxhippy.blogspot.com/)…

Thanks,
Dmitri

I see… Thanks for your help. Unfortunately this means I’ll have to go OpenGL, I guess. Do you know of any good libraries using OpenGL which are syntactically similar to Java2D?

EDIT: After some googling I’ve found Slick to be exactly what I need.

Have you tried -Dsun.java2d.pmoffscreen=false ?
It should help a lot in your case.

  • Clemens

I have - to no effect. :-\

Disclaimer: This was after reverting back to 6u7, if it makes any difference.

well, there’s still -Dsun.java2d.opengl=True :wink:

Also to no effect :o

Anyway, the switch to Slick2D was quite easy and performance is no longer an issue.
(Thanks for all the help, nontheless :P).