LWJGL Forum

Programming => Lightweight Java Gaming Library => Topic started by: directedchaos on August 31, 2007, 02:35:27

Title: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on August 31, 2007, 02:35:27
I recently restarted development on a lwjgl game and noticed it seemed to be very slow on my macbook pro: around 15-20fps (with dips in the low teens).  I restarted in Windows XP (same machine, dual boot), and it's a steady ~60fps (seems capped even).  Exact same builds of my game.

This doesn't seem right.  Anyone ever had a similar experience?

Some more quirks: XP detects 60hz refresh rates, while OS X does the 0hz filler (all available modes are 0hz).  Is this ok?

I realize this is very little to go on, but I didn't want to drown you with details about the game -- particularly since it looks like I'll have to comb back over the engine and find the bottlenecks for comparison (of course, if that does sound exciting, I could update this with more speed tests with various rendering/engine sections cut out :P).  I just wanted to test the waters and see if anyone had come across this and/or had any suggestions.  15fps vs 60fps... :S

Thank you for your time!
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 02, 2007, 21:22:18
I gather this isn't a common phenomenon.  A few profiling experiments later and I'm still at a loss; it just seems to be slower, at everything.  Over half of the time is spent purely in openGL calls (nearly 70% -- glBegin is about 30%!); everything I turn off gives steady speed boosts.  I'm not an expert at profiling (just used a Netbeans profiler, mainly looking at functions' self times, which excludes other method calls), but I'm pretty sure there is no game logic bottleneck (the game engine -- physics, ai, etc. -- takes about 4%).

The final scene averages maybe 100 small (~64x64) textured quads.  Surely I'm not hitting my GeForce 8600M GT's fill rate. 

Do you know a way I can verify that it's using the gpu and not software rendering?

15-20fps seems awfully low for such a simple 2d engine :-/ (especially, again, considering the 60fps on XP).

Thank you for reading this!

Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias4444 on September 04, 2007, 15:38:41
I'm personally at a loss for what to tell you. I develop all my games on a Mac, and they seem to run the same whether I'm on a Mac or in Windows. Are you sure you're using the same displaymode for both systems in your initialization?

Also, how are you handling the screen vsync?
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 04, 2007, 22:07:24
Quote from: elias4444 on September 04, 2007, 15:38:41
I'm personally at a loss for what to tell you. I develop all my games on a Mac, and they seem to run the same whether I'm on a Mac or in Windows. Are you sure you're using the same displaymode for both systems in your initialization?

Also, how are you handling the screen vsync?


Hey, thank you for responding!  The only display difference between the two systems is that XP finds 60hz refresh rates, while OS X does the 0 hz thing (it's a laptop, I gather that's the norm as a filler for whatever its actual rate is, maybe only the OS knows).  Normally vsync  is enabled (standard for games, right?) but I tried disabling it and nothing seemed to change.

Should gl calls be taking up that much time?

Also, everything is done in one thread.  I experimented with multiple threads but the overhead of splitting up the work then recombining it in 1/60th of a second seemed too much (particularly with the engine hovering in such a small % of the worktime).  I may also have been doing inefficient object creation, so I could revisit it as another means to speed up the game.

Finally, if it isn't obvious, I'm not a professional -- this is a hobby project (albeit long in the making).

I was planning to wait until I got some final features hammered down, but perhaps I should compile a speed test demo.  I'll try to spruce one up for tonight, and would appreciate specs and fps.  Should I post it here or a new thread?

Let me know if you have any other ideas!
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias4444 on September 05, 2007, 19:31:25
I'd say go ahead and post it here for some bug catching, and then, once it's spruced up, post it in a new thread for everyone to try.

Just my opinion though.  ;)
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 05, 2007, 22:39:51
Alright, here's a rough-and-dirty demo:
http://www.directedchaos.net/files/games/ff/FF_latest_build.zip (2.6mb)

It's a simple overhead 2d engine, aimed mainly for medieval fantasy.  I called it Futile Fantasy, though that name is probably taken by some other cooler game, and you can read more details about it here:
http://www.directedchaos.net/pages/ff/index.php

You should be able to double-click Futile_Fantasy.jar to run it, wherever you dl it to.  You can change some display settings in "settings.txt" and game settings (such as keybindings and scenario directory) in "prefs.txt".  You shouldn't have to change anything.  If you're just doing this to be nice to me and give me an FPS number, here's the basics:
a,w,s,d: left, forward, backward, right
p: "quick" save
o: "quick" load (latest save)
v: open/close door ("activate terrain")
c: loot ("activate object")
return: toggle fps display

If you decide you actual want to play it, but find it too slow, you can try turning off the map (bottom right of the screen) by clicking the x button in its bottom-left corner.  Also, you can zoom in/out using +/- keys or middle mouse scroll (fewer tiles/creatures=faster).  Staring at the 3 tiles around me I can get like 50fps...
Hopefully, though, there's some fun in the little scenario.  Despite the very very very crude graphics.

There are bound to be bugs, and while I welcome any reports, don't feel obligated to hunt them down!  This is above all a simple speed test; I need the engine to be playable.

Oh, one serious known bug: you cannot save if you're using 1.6. 1.5, which I test on as the OS X standard, runs fine.  I had to fiddle with it on Windows to revert back to 1.5 so I could do saving/loading.  The problem deals with object serialization, and I'm a total noob at that.  But 1.5 should work fine.  Let me know if it doesn't!

Some, probably not comprehensive, acknowledgements:
-GLApp.java base, from napier@potatoland.org
-TextureLoader by Kevin Glass and Brian Matzon, from spaceinvaders

Thank you for reading this!
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: princec on September 07, 2007, 15:58:11
Got this:

(WinXP)

org.lwjgl.openal.OpenALException: Invalid Value
        at org.lwjgl.openal.Util.checkALCError(Util.java:55)
        at org.lwjgl.openal.ALC10.alcGetInteger(ALC10.java:184)
        at org.lwjgl.openal.ALC11.initialize(ALC11.java:172)
        at org.lwjgl.openal.AL.init(AL.java:180)
        at org.lwjgl.openal.AL.create(AL.java:140)
        at org.lwjgl.openal.AL.create(AL.java:104)
        at org.lwjgl.openal.AL.create(AL.java:191)
        at futilefantasy.MainGameWindow.init(MainGameWindow.java:103)
        at futilefantasy.MainGameWindow.start(MainGameWindow.java:120)
        at futilefantasy.Main.main(Main.java:74)


Cas :)
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 08, 2007, 01:43:48
Hey, thank you for the feedback!  Sorry it didn't work -- it didn't even start, how embarrassing!  I'll put some musings here, don't feel obligated to help me track down the bug.

It looks like a toughy.  It's crashing on AL.create(), but works on my machine (OS X and Windows, macbook pro).  I suppose I should post in the openAL forum?  I have no idea how to interpret that :(

Things that happened before it crashed (the log should verify this):
-created display
-created input
-created opengl

The exact line it failed on:
AL.create();

My best guess is that it's not finding the natives properly, even though they are in the same folder as the jar.  If you or anyone else gets this problem again, try running it command-line adding:
-Djava.library.path="C:\absolute\path\to\FF_game_dir"

Again, no worries if you don't, and thank you for your time!
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: princec on September 08, 2007, 12:19:59
Everything worked up to that point - got a display and everything - you just passed an invalid value into AL.create() somehow. Are you using the default initialization, or doing some other monkeying?

Cas :)
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 08, 2007, 22:05:50
Hah, I don't know enough to monkey; it's the default (empty) create method.  Here's the code:


//other initialization: display, input, opengl
try {
    AL.create(); //dies here!
} catch (LWJGLException ex) {
    ex.printStackTrace();
}
AL10.alGetError();


I don't get it.  Works on mine :( Thank you for trying!  I'm open to any ideas -- in what cases will AL.create() fail?  This is the first line (in execution) that even mentions AL.
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias on September 11, 2007, 10:01:53
My guess is that it is using the system supplied openal32.dll. Try bundling the openal32.dll from lwjgl instead, and make sure lwjgl can find it.

- elias
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 14, 2007, 06:20:24
I really don't know what to say about the sound crash.  I do include all the lwjgl natives in the same directory as the executable JAR.  I've tried experimenting with putting them in a separate folder and editing the manifest, but it wouldn't find them.  Just in case, I still include them in the manifest file classpath, alongside the lwjgl JARs.

Manifest file:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-87 ("Apple Computer, Inc.")
Main-Class: futilefantasy.Main
Class-Path: ./lwjgl/lwjgl.jar ./lwjgl/jinput.jar ./lwjgl/lwjgl_test.ja
r ./lwjgl/lwjgl_util_applet.jar ./lwjgl/lwjgl_util.jar ./jinput-dx8.d
ll ./jinput-raw.dll ./libjinput-linux.so ./libjinput-osx.jnilib ./lib
lwjgl.jnilib ./liblwjgl.so ./liblwjgl64.so ./libopenal.so ./lwjgl.dll
  ./openal.dylib ./OpenAL32.dll
X-COMMENT: Main-Class will be added automatically by build


I do have some good news though!  I've been digging deep into the cause of the slowdown on the OS X side, and rewrote the drawing routines to include a simple scenegraph which shoots up the fps to near that of XP.  Basically, I was very naive about the capabilities of openGL and was switching textures and starting quads willy-nilly.  I gather now that you're supposed to group them to minimize texture switches and glBegins, among other things (strangely enough, quad strips didn't seem all that effective, probably because of the higher glBegins required to create distinct strip ranges).  Anywho, it's much more playable.  Here's a recent snap:

(http://www.directedchaos.net/resources/pictures/ff/surrounded_poorquality.jpg) (http://www.directedchaos.net/resources/pictures/ff/)

Don't mind the 30fps, it was generally 55-60 (probably messing around with other stuff + screenshot).  However, there is some weird hiccup that drops it ~5fps every couple seconds, sometimes, then bounces back up.  Very elusive.  Replaced FF_latest_build.zip (http://www.directedchaos.net/files/games/ff/FF_latest_build.zip) (~2.6mb)

One caveat: it does slow down significantly when moving with the map on auto-follow.  The map is automatically rendered to a texture if left alone for a second.
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias on September 14, 2007, 07:01:21
You can check which openal library is loaded by enabling lwjgl debugging (java -Dorg.lwjgl.util.Debug=true ...) and looking at the lwjgl debug output.

- elias
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 14, 2007, 22:52:20
Thank you!  It looks like the exact opposite of what I thought.  XP is finding OpenAL32.dll in the game directory, while OS X is not finding openal.dylib in the game directory.  However, XP does search the system32 directory first.  Does anybody know a way to force it to search the current directory first, preferably via something in the manifest file?  Writing custom scripts for each OS seems a little counterproductive (and I don't know how to do that).

The biggest problem atm is not finding openal.dylib.  :-/  It just mysteriously says "Found openAL bundle."

Here's some output, if you're feeling overly generous:
([...] = snipped absolute path to game directory)
OS X: java -Dorg.lwjgl.util.Debug=true -jar Futile_Fantasy.jar
getPathFromClassLoader: searching for: openal
Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
getPathFromClassLoader: searching for: lwjgl
Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.Launcher$AppClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.URLClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.security.SecureClassLoader.findLibrary(java.lang.String)
Found 6 OpenAL paths
Testing './openal.dylib'
Failed to load ./openal.dylib: Could not load OpenAL library
Testing '/Library/Java/Extensions/openal.dylib'
Failed to load /Library/Java/Extensions/openal.dylib: Could not load OpenAL library
Testing '/System/Library/Java/Extensions/openal.dylib'
Failed to load /System/Library/Java/Extensions/openal.dylib: Could not load OpenAL library
Testing '/usr/lib/java/openal.dylib'
Failed to load /usr/lib/java/openal.dylib: Could not load OpenAL library
Testing '/[...]/FF_latest_build/openal.dylib'
Failed to load /[...]/FF_latest_build/openal.dylib: Could not load OpenAL library
Testing 'openal.dylib'
Failed to load openal.dylib: Could not load OpenAL library
Found OpenAL Bundle

At this point it proceeds to create sources and make all sorts of silly sounds (that I recorded).

OS X: java -Djava.library.path=/[...]/FF_latest_build -Dorg.lwjgl.util.Debug=true -jar Futile_Fantasy.jar
Same as above, but only found 3 paths:
Found 3 OpenAL paths
Testing '/[...]/FF_latest_build/openal.dylib'
Failed to load /[...]/FF_latest_build/openal.dylib: Could not load OpenAL library
Testing '/[...]/FF_latest_build/openal.dylib'
Failed to load /[...]/FF_latest_build/openal.dylib: Could not load OpenAL library
Testing 'openal.dylib'
Failed to load openal.dylib: Could not load OpenAL library
Found OpenAL Bundle


XP: java -Dorg.lwjgl.util.Debug=true -jar Futile_Fantasy.jar
Similar, but sucessful:
getPathFromClassLoader: searching for: OpenAL32
Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.L
auncher$AppClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.U
RLClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.secur
ity.SecureClassLoader.findLibrary(java.lang.String)
getPathFromClassLoader: searching for: lwjgl
Failed to locate findLibrary method: java.lang.NoSuchMethodException: sun.misc.L
auncher$AppClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.net.U
RLClassLoader.findLibrary(java.lang.String)
Failed to locate findLibrary method: java.lang.NoSuchMethodException: java.secur
ity.SecureClassLoader.findLibrary(java.lang.String)
Found 10 OpenAL paths
Testing 'C:\WINDOWS\system32\OpenAL32.dll'
Failed to load C:\WINDOWS\system32\OpenAL32.dll: Could not load OpenAL library
Testing '.\OpenAL32.dll'
Found OpenAL at '.\OpenAL32.dll'


XP: java -Dorg.lwjgl.util.Debug=true -Djava.library.path="C:\[...]\FF_latest_build" -jar Futile_Fantasy.jar
(again, same as above but only 3 openAL paths, but this time it finds it first go)
Found 3 OpenAL paths
Testing 'C:\[...]\FF_latest_b
uild\OpenAL32.dll'
Found OpenAL at 'C:\[...]\OpenAL32.dll'


Again, thank you for your time!
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias on September 15, 2007, 05:30:43
LWJGL first looks at what the current ClassLoader.findLibrary returns, which is important for web start where the location of native libraries are not given by java.library.path. Then it looks at java.library.path and finally it lets the OS do the search.

The "Found OpenAL bundle" is printed when lwjgl falls back to the built in mac os x library (which is in a so-called bundle).

If you're hearing weird noises instead of proper sound and you're using a PPC mac, make sure you give OpenAL sound samples with the correct endianness (PPC is big-endian, intel is little-endian), which usually means you create a ShortBuffer ordered with ByteOrder.nativeOrder() and copy from samples from another ShortBuffer ordered in the file order (for wav, this means little-endian). Finally, the first buffer is used to upload sound with alBufferData.

- elias
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 17, 2007, 09:09:20
Thank you for the explanation!  I gather I'm facing two problems:
In the first case, should I mess with a custom class loader to override findLibrary, immediately returning the local path?  If I could do this, it would mean I could also move the natives to a more discreet location instead of floating in the main folder.  I've been doing some experimenting and can't seem to get it to use my custom class loader.  I've tried both setting the thread and system classloader.

Here's the simple classloader, just for testing:
public class FF_lwjgl_ClassLoader extends ClassLoader{
    public FF_lwjgl_ClassLoader(ClassLoader parent){
        super(parent);
    }
    public FF_lwjgl_ClassLoader(){ ; }
    public String findLibrary(String libName){
        String s = super.findLibrary(libName);

        System.out.println("findLibrary("+libName+") called value: '"+s+"'");
        return s;
    }
}


Here's how I set the thread:
FF_lwjgl_ClassLoader loader = new FF_lwjgl_ClassLoader(Thread.currentThread().getContextClassLoader());
Thread.currentThread().setContextClassLoader(loader);

And for the system I added -Djava.system.class.loader=futilefantasy.FF_lwjgl_ClassLoader to the command-line arguments (futilefantasy is the package name; the class is found just fine, no errors)

The output was unchanged, implying that I'm not actually accessing AL's classloader.  I gather this section from AL.java is where the action happens:
String[] oalPaths = LWJGLUtil.getLibraryPaths(libname, library_names, AL.class.getClassLoader())
Somehow, I have to make sure AL.class.getClassLoader() returns my custom class loader.

As a side note, the "failed to locate findLibrary method" errors are no biggy, as it searches up the inheritance chain until findLibrary is defined?

Somehow, I think this isn't what most people do when they bundle lwjgl with their game desktop-side.  Ideas, anyone?


The second problem might be more daunting though.  Again, it tries the exact absolute path to openal.dylib:
Testing '/Projects/Java/Futile Fantasy/FF_latest_build/openal.dylib'
Failed to load /Projects/Java/Futile Fantasy/FF_latest_build/openal.dylib: Could not load OpenAL library

and fails.  I'm clueless.  :(
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias on September 17, 2007, 12:09:08
Putting the library beside the lwjgl library should work, since lwjgl also tries to locate openal by locating the main lwjgl native library (liblwjgl.jnilib), then cutting out the liblwjgl.jnilib part and replacing it with openal.dylib.

The failure to find method errors are not a problem.

Failing to load openal.dylib is probably caused by us using a ppc-compiled openal.dylib and you running an intel mac. The bundled openal.dylib won't work on intel macs. The reason behind this is that all intel macs have at least mac os x 10.4 where openal is built in, thus only requiring the bundled openal library for ppc macs. liblwjgl.jnilib is special, since it is compiled to work on both 10.3 ppc and 10.4 intel machines. Theortically, the same could be done to openal.dylib, but I haven't yet bothered to fiddle with the openal build scripts (it involves compiling the entire library with two different compilers, then using a special tool to glue the parts together).

- elias
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 18, 2007, 00:16:49
Thanks again!  I understand this is all done in donated free time, and I appreciate the library -- I wouldn't be able to make this game without openGL bindings (I tried, too many rotations -- needed hardware acceleration).  You've been very helpful!

I do have an intel mac, and the sounds are fine (in fact, my entire game works wonderfully on my machine -- minus my poor artistic abilities).  The potentially dangerous scenario I'm trying to avoid is where lwjgl checks the system's openal library (say, under 'C:\WINDOWS\system32\OpenAL32.dll') first, finds it, and uses it without ever checking the local bundled lwjgl openal. It seems like this is something the default classloader does.
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias on September 18, 2007, 05:34:45
Right, so does it work when you put the bundled openal library in the same directory as the lwjgl native library? That should always be tried first by AL, and only the system library path last.
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: directedchaos on September 18, 2007, 21:43:53
Yes, all the native files are in the same folder -- the folder that the game itself is in.  If I don't set -Djava.library.path, lwjgl checks the system openal first:

Found 10 OpenAL paths
Testing 'C:\WINDOWS\system32\OpenAL32.dll'
Failed to load C:\WINDOWS\system32\OpenAL32.dll: Could not load OpenAL library
Testing '.\OpenAL32.dll'
Found OpenAL at '.\OpenAL32.dll'


(I just happen to not have a system openal, so it works fine on mine)

If I do set -Djava.library.path (to the absolute path to the game directory), it finds it on the first go as the absolute path to the bundled openal:
Found 3 OpenAL paths
Testing 'C:\[...]\FF_latest_build\OpenAL32.dll'
Found OpenAL at 'C:\[...]\FF_latest_build\OpenAL32.dll'


So, is the prevailing solution just to write custom OS-specific launch scripts?  I was trying to avoid that with the JAR.
Title: Re: Speed: Windows >>> OS X? Am I missing something?
Post by: elias on September 19, 2007, 08:07:41
Scripts or a custom classloader will solve it. If you use a custom classloader, you can't use the one you posted earlier in this thread. To make it work, you have to make sure your custom classloader actually loads the LWJGL classes, not the parent class loader. FF_lwjgl_ClassLoader always delegates to its parent (because that's the default implementation of ClassLoader.loadClass), and thus AL.class.getClassLoader() will be the parent class loader. You can probably make it work, but it requires some fiddling (for example, let FF_lwjgl_ClassLoader inherit from URLClassLoader with your jar as the classpath). You can always test if it works by querying AL.class.getClassLoader() and see if it is your classloader or something else.

- elias