Android Port – Second Look

I have looked into some of the performance aspects of the Android port, and I’ve come to some conclusions. Firstly, after looking at the disassembly, there did not seem to be any additional code associated with exception handling, so there was no optimizing to be done there. Secondly, the compile flags meant that software floating point operations were used, rather than the built-in hardware FPU.

So I added compile flags to force hardware floats, and added armv6 instructions while I was at it. You can get the installer here.

This gives my phone a nice 50% boost in frame-rate to about 15fps. However, on some devices this app may fail to run. This change brings the performance in line with iPhone performance for the simulation side of the program. However the OpenGL seemed slower. I guess the Qualcomm MSM 7227 does not have strong 3D acceleration \- or perhaps I am still missing something?

For comparison, you can test the flash version of the code in this directory. I get about 6\-7 fps, which is not too far from my initial software-float based results and is quite impressive. I’m not sure if the flash renderer is using software or hardware rendering \- maybe it’s worth a closer look to find out what it’s doing.

23 Replies to “Android Port – Second Look”

    1. Hi,
      I think the magic runs a MSM7200A, which does not have hardware floating-point options. I don’t explicitly test for this, so the result is an epic fail. You will have to try the installer from the first post – hopefully I can work out a way of supporting both int the one installer – probably with 2 shared object files.

  1. Hi,

    I apologize for cross-posting! I’m compiling a haxecpp “hello world” application for an ARM GNU/Linux device. It supports SDL and OpenGL 1.1 and 2.0, and I hear that most iPhone applications port with almost no changes.

    I modified BuildCommon.xml to add a “palmpre” build target, so the files get compiled into *.o files, then linked together. However, once I try and run the app on the phone, I get this error:

    Error: could not load module nme@nme_filter_image__2

    I saw in an earlier thread that forcing 32-bit addressed this error, but I’m on a 32-bit machine, so I figure I must be missing something obvious?

    I would be VERY thankful if you would be willing to give me any ideas you have as to what could cause this error. If you need to see the exact input that’s going to the compiler, I’ve added it all to this thread:

    http://developer.palm.com/distribution/viewtopic.php?f=70&t=8004

    THANK YOU!

  2. I think I need to figure out three things:

    1.) That I have all the right files
    2.) That I’m linking all the right files
    3.) That I’m using the correct compiler flags

    Could you please take a look at this paste (build output from FlashDevelop) and let me know if this like it has the right files? If so, I can try and determine if I’m using the compiler wrong. Otherwise, if I am missing files, I don’t know anyone else but you would know.

    http://pastie.org/1036869

  3. Hi Joshua,
    The first thing I need to determine is if you are using static or dynamic linking for external libraries (nme).
    iPhone is unusual in that it uses static linking – this is because of apples terms-of-service. All the other targets (including linux/sdl) use dynamic linking.

    From the looks of it, you are using dynamic linking, since your executable linked correctly without error. The application runs, and in the startup code the nme library is dynamically loaded and the function symbols are extracted. By the looks of it, it is this process that is failing.

    So there are several reasons for this.
    1. It can’t find the nme.ndll file on your system – this could be because it is not there, or it is not in the right places. You will need to understand a bit about the LD_LIBRARY_PATH to set a particular location the this file.
    2. It is there, but the wrong format. It will need to be compiled for your hardware. If it is on an x86 system, then the libraries may just work. But usually you would need to compile nme using a similar compiler and options as used by the exe.
    3. It can find the ndll, but it can’t find symbols inside it. This could be because a compiler flag has “hidden” the symbols. You can use “nm filename” to list the symbols in a file, and then pipe it to something like “|grep nme_filter_image” to see if the symbols is there and exposed. If it’s not there, then it could be that the .hx files and the .ndll are out of sync.

    So first thing is to find out which of these cases it is. If you can set environment variables, then you can “setenv HXCPP_LOAD_DEBUG=1” to get a log. If you can’t do this, then you can edit the hxcpp/src/hx/Lib.cpp and set “bool debug = true;”, or use a debugger to step into this file and get a better idea of what’s going on.

    Once I have this extra info, I should be able to help you more.

    Hugh

  4. Hi Huge,

    Thanks so much for the help! It’s tough because I’m so unfamiliar with C++ and Linux. Starting out with a framework like yours has been a crash course in command lines and compiling 🙂

    It probably is using dynamic linking. After my *.o files are linked into one file, I’m copying it to /media/internal on the phone, and executing it directly, using Putty to access a command line through SSH. I believe that when it is run as an actual application on the phone, it is “jailed”, and thereby given it’s own mini file system, but skipping that has been quicker to test, and easier to debug.

    I ran strace on the application, which yielded a lot of information that probably is useful. I tried forcing debug to true, and it didn’t seem to make a difference, but perhaps it already was set to true? I’m using FlashDevelop, with a modified BuildCommon.xml for that accepts palmpre as a compile target.

    Here’s a paste of everything strace yielded. Particularly towards the end, I can see that it definitely is looking for files and can’t find them. I tried copying files to /usr/lib, but access was denied. I’m concerned that if I change the library path of the executable, it will have trouble finding the system libraries which are already installed on the device. In that case, do you think I should try to statically link it instead?

    I found a comment somewhere, where I believe you had recommended to someone to compile BuildLibs.xml in the hxcpp runtime directory in order to rebuild nme.ndll. I tried that, but unfortunately it gave me an error on init.cpp. I also tried to link to libnme.so, out of the version2 Android ndll directory off the SVN repository, hoping it might work, but it seemed to throw the same error. Here’s what happens when I try to compile on my own:

    c:/program files/codesourcery/sourcery g++ lite/bin/../arm-none-linux-gnueabi/li
    bc/usr/lib/crt1.o: In function `_start’:
    init.c:(.text+0x34): undefined reference to `main’
    collect2: ld returned 1 exit status
    Called from line 1
    Called from BuildTool.hx line 840
    Called from BuildTool.hx line 433
    Called from BuildTool.hx line 456
    Called from BuildTool.hx line 529
    Called from BuildTool.hx line 610
    Called from BuildTool.hx line 238
    Uncaught exception – Error : 1 – build cancelled

    Linking the Android .so file is less verbose. It just says “collect2: ld returned 1 exit status”

    Just to see what would happen, I also tried to rename the “libnme.iphoneos.a” file (or whatever it’s called) to nme.ndll and linked it into my executable, which didn’t cause errors, but didn’t fix my problem, either. I tried it again with an .so extension, just in case, but still no dice. Everyone I’ve asked so far about my problem, who had C++ experience seemed to ask if I was missing a file called “nme.dso”. I’m guessing the “nme.ndll” accomplishes the same thing, just with a different extension

    I apologize if I’ve commented too many times. I’m REALLY excited by the idea of running haXe on my phone, then sharing the code so others can do the same. I’ve been a Flash developer for a long time … I love FlashDevelop, and I want to make games but learning C++ from the ground up or trying to use JS or canvas just hasn’t felt right. I had been hoping that Flash would be available, but so far Adobe keeps stalling. Who knows? hxcpp might be even faster than the official Flash plugin, plus it would mean I can retool all my existing libraries I’ve written in Actionscript 3, and deploy to the web and to mobile. That’s exciting to me!

    Even novelty games, I feel, will take on different meaning on a mobile device. For example, this soccer game I made is fun on a desktop, but it could be entirely more interesting using touch controls, or even if it could tie into an accelerometer.

    http://www.eclecticdesignstudio.com/clients/flyingrhino/upward/soccer/juggling/01

  5. This stuff is tricky!

    When I set LD_LIBRARY_PATH, and rename libnme.so (for Android) to nme.ndll (just to try it), it loads it, but still throws the same error.

    I’ve been trying to build nme from the source, and its going alright. Actually, using the version 1 source, I was able to get all the way to the point where I was linking. The trouble is that it was trying to link a lot of SDL libraries regarding fonts and sound, and I don’t have those libraries … which makes me guess that I would have to go and try and compile those libraries as well?

    I tried it also on the version 2 source, but it threw errors when it hit ExternalInterface. I had errors with the version 1 source, but nothing a couple headers couldn’t fix. Although, maybe I also got that “undefined reference to main” error? I don’t remember. The errors with version2 seem more severe, although it almost seems like it could be caused by a misplaced comma or something

    http://pastie.org/1037844

    It’s no wonder why you guys distribute nme as a pre-compiled file! This stuff isn’t simple 🙂

  6. I successfully compiled and linked the version 1 source, almost. It threw some errors, expecting GL functions which are not available in OpenGL ES. Palm has both OpenGL ES 1.1 and 2.0 available, but it appears that the version 1 source is expecting a desktop library?

    That suggests to me that I’ll need to use the version 2 source, but I can’t move forward until I’m able to get around those compiler errors. Probably something slight

  7. Hi Huge,

    That’s some amazing work! The apk from this post (v2) runs between 12-14fps whereas the first one was more around 7-9fps on my Galaxy Spica (Samsung GT-i5700).

  8. I found my problem:

    I cannot compile version 2 of NME because the class “AutoGCRoot” is unavailable. This is because haxelib has an older version of hxcpp installed.

    Once I figure out how to get haxelib to use the latest release of NME and hxcpp, I’ll try everything again and let you know if I run into anything that might require updates to the source code. Chances are, I’ll just be tuning the code base to work with a “Palm” compiler flag.

    I just realized that the errors were caused because the class “AutoGCRoot” was unavailable.

  9. i have try the installer from the first post,still crash on G2(magic),and second apk crash on milestone too.

  10. Couldn’t get it to run on the G1 with Froyo2.2/CyanogenMod6-RC1. It would briefly flicker, with a mouse cursor strangely enough, then FC.

    Just picked up a Samsung Galaxy S/Vibrant tonight and i’m pleased to see yr demo running at a smooth 54-59 fps with 4-5ms physics.

    Would you be able to do a write up of the toolchain being used?

Leave a Reply

Your email address will not be published. Required fields are marked *