Disappointing performance with OS X

I have recently got a new Mac and have been disappointed to find that a game I have been working on is much slower than it was on my PC. I have downloaded a few games from these forums a Mortal Kombat clone, a tile based scrolling map example and the following sample app
http://www.pkl.net/~rsc/Balls.jar
and while all behave beautifully on my PC they are shockingly slow under OS X.

It seems that it may be related to fullscreen exclusive mode as my game maps scroll at a similar speed to my PC in the map editor but not in fullscreen mode and the sample app Balls.jar runs fine in windowed mode as well.

Has anyone else experienced this when trying a fullscreen game on OS X?

Is fullscreen exclusive mode fully supported on OS X?

Thanks in advance.

What type of graphics images are being displayed? This is often system/video dependent. Try running this performance test on both platforms:

// Program : TestGraphics.java
// Description: Test performance of graphics types.
// Notes : Use ‘java -Xcomp’ to run this app. This option will
// force JIT-compilation at startup, instead of letting
// HotSpot decide when and what to compile. Without it,
// HotSpot may trigger compilation at an unknown or
// unexpected point, invalidating the elapsed times due
// to a flurry of JITC-ing. It may also be useful to run
// with -Xint and -Xmixed to show how much is interpreter
// cost and how much is graphics rendering cost.

import java.awt.;
import java.awt.image.
;

public class TestGraphics
{
static final int WIDTH = 700,
HEIGHT = 700;

  static final int COUNT = Math.min(WIDTH,HEIGHT)/2;

  static final String[] sImageNames =
  {
        "TYPE_INT_RGB (HotSpot warm-up, throw away)",
        "TYPE_INT_RGB",
        "TYPE_INT_ARGB",
        "TYPE_INT_ARGB_PRE",
        "TYPE_INT_BGR",
        "TYPE_3BYTE_BGR",
        "TYPE_4BYTE_ABGR",
        "TYPE_4BYTE_ABGR_PRE",
        "TYPE_USHORT_565_RGB",
        "TYPE_USHORT_555_RGB",
        "TYPE_BYTE_GRAY",
        "TYPE_USHORT_GRAY",
        "TYPE_BYTE_BINARY",
        "TYPE_BYTE_INDEXED",
        "native CompatibleImage"
  };

  static final int[] sImageConstants =
  {
        BufferedImage.TYPE_INT_RGB,
        BufferedImage.TYPE_INT_RGB,
        BufferedImage.TYPE_INT_ARGB,
        BufferedImage.TYPE_INT_ARGB_PRE,
        BufferedImage.TYPE_INT_BGR,
        BufferedImage.TYPE_3BYTE_BGR,
        BufferedImage.TYPE_4BYTE_ABGR,
        BufferedImage.TYPE_4BYTE_ABGR_PRE,
        BufferedImage.TYPE_USHORT_565_RGB,
        BufferedImage.TYPE_USHORT_555_RGB,
        BufferedImage.TYPE_BYTE_GRAY,
        BufferedImage.TYPE_USHORT_GRAY,
        BufferedImage.TYPE_BYTE_BINARY,
        BufferedImage.TYPE_BYTE_INDEXED
   };

  // This is a simple test that does setColors and fillRects
  static void recTest(BufferedImage bi)
  {
        Graphics g2D = (Graphics2D) bi.getGraphics();
        for (int i=0; i<COUNT; i++)
        {
              if (i%2 == 0 )
              {
                    g2D.setColor(Color.black);
              }
              else
              {
                    g2D.setColor(Color.red);
              }      
              g2D.fillRect(i,i, WIDTH-i,HEIGHT-i);
        }
  }

  public static void main(String[] args)
  {
      long startTime;
      long[] elapsedTime = new long[sImageConstants.length + 1];

        // Allocate 14 different buffered images to cross-compare
        BufferedImage[] bis = new BufferedImage[sImageConstants.length + 1];
        for (int i=0; i<sImageConstants.length; i++)
              bis[i] = new BufferedImage(WIDTH, HEIGHT, sImageConstants[i]);

        // Include native type:
        bis[sImageConstants.length] = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(WIDTH, HEIGHT);

        // Compute and print performance
        System.out.println("Simple Graphics Performance Example");
        System.out.println("Time\tImage Type\n----\t----------");
        for (int i=0; i<=sImageConstants.length; i++)
        {
              startTime = System.currentTimeMillis();
                    recTest(bis[i]);
              elapsedTime[i] = System.currentTimeMillis() - startTime;
              System.out.println(elapsedTime[i] + "\t" + sImageNames[i]);
        }

        // Doing graphics may start the AWT event-thread, thereby preventing
        // a return from main() from causing an exit.  So, always force an exit.
        System.exit(0);
  }

}

Thanks I have run the TestGraphics app on both systems and here are the results.

—PC—
Simple Graphics Performance Example
Time Image Type


859 TYPE_INT_RGB (HotSpot warm-up, throw away)
828 TYPE_INT_RGB
813 TYPE_INT_ARGB
828 TYPE_INT_ARGB_PRE
828 TYPE_INT_BGR
609 TYPE_3BYTE_BGR
813 TYPE_4BYTE_ABGR
828 TYPE_4BYTE_ABGR_PRE
375 TYPE_USHORT_565_RGB
375 TYPE_USHORT_555_RGB
109 TYPE_BYTE_GRAY
360 TYPE_USHORT_GRAY
468 TYPE_BYTE_BINARY
110 TYPE_BYTE_INDEXED
828 native CompatibleImage

—Mac—
Simple Graphics Performance Example
Time Image Type


1220 TYPE_INT_RGB (HotSpot warm-up, throw away)
459 TYPE_INT_RGB
519 TYPE_INT_ARGB
478 TYPE_INT_ARGB_PRE
467 TYPE_INT_BGR
498 TYPE_3BYTE_BGR
465 TYPE_4BYTE_ABGR
463 TYPE_4BYTE_ABGR_PRE
196 TYPE_USHORT_565_RGB
163 TYPE_USHORT_555_RGB
121 TYPE_BYTE_GRAY
90 TYPE_USHORT_GRAY
106 TYPE_BYTE_BINARY
480 TYPE_BYTE_INDEXED
463 native CompatibleImage

The PC is running a GForce2 mx and the Mac has an ATI Radeon 9000.

I have tested a quick example whith no images and just an animated filled rectangle and the performance is still bad with OS X in fullscreen.

That test program doesn’t measure the time required to copy the image to the graphics device.

yeah, the test program is just measuring the speed at which the different image types can be altered.
(The results are still interesting, though not relevant to the issue of hardware acceleration or fullscreen)

Surprised by that. I haven’t got OS X yet, but the fact that the problem is in seems to be in fullscreen only is a bit worrying. Have you tried the mailing list archives on apples developers site?

http://lists.apple.com/mailman/listinfo/java-dev

From what I understand it should just be the standard cocoa classes to achieve fullscreen, so maybe it’s a miss configuration when setting up fullscreen. Do the apps you have tried just use the existing resolution/bitdepth or try and impose new ones?

There are definately some speed issues with image blitting in Java on OS X. File a bug report with Apple.

For me Balls.jar doens’t do so hot in windowed mode either… how many balls did you have going? For me it degrades much faster than on the PC as more balls are added.

Also from the timings above byte indexed images (GIFs) are going to be much slower for somethings than other image types. It would probably be best (for PC and Mac) to make sure the images are copied to the native image format when they are loaded.

[quote]For me Balls.jar doens’t do so hot in windowed mode either… how many balls did you have going?
[/quote]
I actually tried Balls.jar on a friends Powerbook and it ran at about 8 to 12 fps straight off from the first ball animated as opposed to 25 to 30 fps when in windowed mode.

[quote]Do the apps you have tried just use the existing resolution/bitdepth or try and impose new ones?
[/quote]
Both, some changed the resolution and bit depth but I have tried using the current display mode and get the same behaviour.

To me this really seems to be related to fullscreen exclusive mode and not just image types.

I have looked at the apple java-dev mailing list but I can barely find any mention of fullscreen exclusive mode at all except someone asking when 1.4 will be available for OS X so he could try it out.

Im really hoping this means that other people arent getting this problem and that there is something I can do about it. :’(

Is DisplayMode switching supported in fullscreen on OSX?
(In Balls.jar I think I assumed it would always be supported, so it might fall over on a platform that doesn’t support it ::))

Either way, it sounds to me like there is no hardware acceleration going on at all - without a mac, its kinda hard to be sure though :frowning:

Is their a setProperty flag that disables all hardware features? (Acceleration, fullscreen etc etc)
It’d be the eziest way for me to check what Balls.jar does on machines that don’t support fullscreen :smiley:

:edit:

btw, that was a shoking old version of Balls.jar - I’ve just updated it now :smiley:
This version has tonnes of new features, as well as working windowed mode<->fullscreen switching!!
(Its a massive hack, just have a look at GameFrame.java to see how its done :P)

Just tried the latest Balls.jar on my PowerBook 1GHz, ATI Radeon…

It does not exit when you press Esc… the full screen display is simply ‘stuck’ - I had to kill the process.

All tests were triple buffered 32 bit…

At max res 1280x854 fullscreen I got between 6 and 7 frames per second WITH 0 BALLS

1024 x 768 WINDOWED mode got 15 FPS with 0 balls
1024 x 768 FULLSCREEN mode was 8-9 FPS with 0 balls

Yep, fullscreen seems to be sucking more than windowed mode… but let’s not forget that the windowed mode SUCKS BIGTIME too.

Switching the fullscreen display resolution from fullscreen mode locked up the app.

800 x 600 windowed mode kept cycling the # of balls and would not stabilize??

[quote]Just tried the latest Balls.jar on my PowerBook 1GHz, ATI Radeon…

It does not exit when you press Esc… the full screen display is simply ‘stuck’ - I had to kill the process.
[/quote]
ye gads, the OSX JVM sucks big time ;D

The ‘esc’ not quitting is abit disturbing - sounds to me like a bug in the APIs somewhere, cos the code definitly adds a key listener to both frames
(As a work around for frame.setUndecorated() breaking bufferStrategy, i’ve used 2 frames, 1 for windowed, 1 for fullscreen)

[quote]All tests were triple buffered 32 bit…

At max res 1280x854 fullscreen I got between 6 and 7 frames per second WITH 0 BALLS

1024 x 768 WINDOWED mode got 15 FPS with 0 balls
1024 x 768 FULLSCREEN mode was 8-9 FPS with 0 balls
[/quote]
low fps at high resolutions sounds to me like the back buffers arn’t being created in vram at all.

So there realy isn’t any HW acceleration in OSX ???

changing display mode while in fullscreen crashes it, huh?

but, u can start it up in different display modes fine?

sounds like its not releasing the old frame buffer, before creating the next 1.
That sometimes happens in the Win JVM as well, its shitty coding by Sun IMO.

damn it Sun, get your act together :confused:

@low fps, it will never stablise properly…
Gonna change the way balls are added to fix that.

In my defence, when it all works properly, (and you get a decent fps) the ball adding code works fine :smiley:

I get 7000ish bitmasked balls at 30fps on a 1.33gig athlon with gf2 (under win98)

AFAIK, hardware acceleration isn’t fully implemented yet.

Longshot – have you tried passing the runtime flag:

-Dcom.apple.awt.hwaccel=true

?

Here are the details on Apple’s JVM hardware accel support:
http://developer.apple.com/techpubs/macosx/Java/JavaWhatsNew/hardwareaccel/index.html

I just wanna say that I have the same problem with the thing I’m doing. (Show and scroll a map from .png)

Mac OSX: Fast compiling, real slow running (PB G4 867, 768 MB, Radeon 9000 mobility)
Win ME: Slow compiling fast running (Athlon 1 GHz, 512 MB RAM, Geforce 2mx)

It’s a shame…

Actually, as I understand it, on OS X ‘managed’ (formerly ‘automatic’) images are definately not supported… and I suspect that volatile images are not in VRAM either…
What freaks me out is how the performance can still be so bad… 7 FPS to draw a few lines of text on the screen really blows even if the back buffer isn’t in VRAM… we are talking about a system that can playback fullscreen MPEGs faster… decoding MPEG takes a tad more CPU processing than drawing a few balls or lines of text… forget hardware blits…

Better get that bloody port workin’ then eh? ;D
Then we’ll make the bugger’s eyes water.

Cas :slight_smile:

Funny really considering one of the things that looked cool about MacOS X Java was that Swing was hardware accelerated. If they are accelerating Swing, how come “automatic” images aren’t there/accelerated?

I wonder whether this is a similar problem to the AWT-Thread bug? Anyone tried profiling to see what the apps are really doing?

Also for the Esc key thing, could it be a focus problem? That’s usually the first thing I look for when my keys don’t work in an app.

John

I just thought I would point out an interesting observation that I hadn’t noticed before.

BufferCapabilities methods isPageFlipping and isMultiBufferAvailable both return FALSE on Mac OS X.

:’(

If I understand this, it means that there can only be at most one back buffer and that the contents of the back buffer are copied to the primary surface with a blitting operation.

What i don’t get is this comment from the Fullscreen tutorial, “For best results, create your buffer strategy on a full-screen exclusive window. Make sure you check the isFullScreenRequired and isPageFlipping capabilities before using page-flipping.”

Doesn’t the buffer strategy do page flipping or blitting when you call show() and you have no direct control of which will be happening anyway? What are you supposed to do with the result of isPageFlipping() ???

According to http://java.sun.com/docs/books/tutorial/extra/fullscreen/example-1dot4/CapabilitiesTest.java the backbuffer is accelerated(?), but nothing else is checked… No Accelerated images, or front buffer, not volatile capabilities, full screen is not required etc…

Seems that the Mac 1.4 implementation kind of stinks for this tuff… which is a shame.

This isn’t related to the fact the everything in OS X is double buffered for free is it?
Haven’t really used fullscreen stuff much yet, but does that mean that you could make a BufferStategy with one buffer (e.g. createBufferStrategy( 1 )) and it would be double buffered on OS X? The only trouble is I’m not sure how you’d detect you were on OS X (short of System.getProperty( “os” )).

Found this for making “fake fullscreen mode” on OS X:

http://developer.apple.com/techpubs/macosx/Java/Java141Development/System_Properties/chapter_10_section_4.html#//apple_ref/doc/uid/TP30000299/TPXREF111

Seeing as windowed mode seems faster this might help until we can figure out what’s going on/a bug fix is realised.