Latest git version of Cocos2d-x unusable on Android :(

Finally got the Android SDK up and running again, so I decided to give Cocos2d-x a try on Android :slight_smile:

My first experience was with the cocos2dx-test.apk from the performance tests page. Here’s a bunch of notes to go along with it:

  • As you can see, the Adreno 200 GPU really hates blending - this is a known “feature”, so that’s okay
  • Adreno 200 is very slow at rendering large polygons - also known as a “feature”
  • The tilemap demo contains flickering sprites on the Desire. Tiles are wobbly when moving around.
  • Effect Advanced Test contains artifacts along the edges of the screen
  • Render Texture Test outputs garbage, no healthy results visible here, only odd colored rectangles
  • Not completely fluid, everything stutters every half a second
  • When device locks while running the Cocos2d-x app, the app won’t be running again after unlocking (no good, but not important for now)

Unit tests on device: HTC Desire, Android: 2.2, cocos2dx-test.apk (0.7.1?)

Main menu 59
Actions 59
Transitions 59
Process action 59
Effect 32-59
Click and move 59
Rotate world 59
Particle 29-59
Ease action 59
Motion streak 59
Draw primitives 59
Cocosnode 59
Touches 60
Menu 60
Action manager 59
Layer 59
Scene 59
Parallax 22-59
Tilemap 30 (iso) - 45 (ortho)
Interval 59
Box2d 59 (50 boxes: 54, 100 boxes: 30)
Box2d Testbed 3-59 (pyramid test was slowest)
EffectAdv 24-35
HiRes 59
Accelerometer 60

Atlas Test:

CCTexture atlas 52-58
Label atlas 59
CCBitmapFontAtlas1 59
CCBitmapFontAtlas2 59
CCBitmapFontAtlas3 59
CCBitmapFontAtlas4 59
CCBitmapFontAtlas5 59
CCBitmapFontAtlas6 59

Sprite Test:

Sprite 59 (50 sprites: 42 fps)
Spritesheet 59 (50 sprites: 45 fps)
Sprite vs. Spritesheet animation 59
Sprite anchor point 59
Spritesheet offset + anchor + scale 59

(you may republish these results @ the performance test page if you wish, even though they may be a bit boring to look at with all the high frame counts =)

After running those tests, I was about to try a fresh build of Cosos2d-x_git (latest, built using Crystax NDK r4 + MingW patch). It ran all right on the emulator (using the ARMv5 library because it doesn’t support ARMv7), so I was being all excited about trying the ARMv7 version instead (should be faster). But the enthusiasm got tempered quickly when I discovered that even the main menu would only show up with a max of 33 frames per second. And everything looked… well, really weird.

That’s a bit odd, but hey… perhaps there was some weird agressive optimization going on, right? So, I took out the ARMv7 library and started using the ARMv5 instruction set again, like the test apk from the performance page. Should be better, right?

Wrong.

Each and every demo shows as if there’s a black screen between every frame update, like it’s rendering twice per frame with one good and one bad frame. Also, all sprites show up with a trail behind them. It’s quite horrible to look at. And what about smoothness? Err… let’s not go there :wink:

So now I’ve got a nice build of Cocos2d-x for Android which can only display about 30 frames per second, clears the screen with every frame and stutters while showing trails of all the sprites on screen.

My question is: is this normal behavior? :slight_smile:

I noticed you were working on “fps control” for Android the other day, all these issues seem to have been introduced since those changes were made. Could that have anything to do with it?

Cool. I’ve taken out the modifications for fps throttling and now I’ve got:

no more weird flickering

  • tiny bit of a hickup whenever the system is doing something in the background (annoying indeed)
  • 61 fps in most tests
    And best of all:
  • the parallax test runs with about 55-61 frames per second (instead of 22-59 like before), awesome!
  • the difference in speed between ARMv7 and ARMv5 is HUGE for the Box2D library - the pyramid test won’t get any slower than 24 frames per second!
  • the other Box2D test doesn’t stick at 30 fps when adding 100 cubes, it stays at 60 :slight_smile:
    So, for all of you reading this and thinking about developing for Android: please do use the ARMv7 instruction set if it’s available. It’s going to make your app speedy. You can enable it by adding the following line to your Application.mk:
    <pre>
    APP_ABI
    armeabi armeabi-v7a
    </pre>

That will build you two versions of your libraries; one for phones with an older instruction set (Legend, Hero) and one for phones with the fast instruction set (Desire, Galaxy S). The Android installer will pick the right version for the device.

Anyway, back on topic again :slight_smile: I guess the fps throttling for Android has got to be reworked a bit, sorry :frowning:

Wow, awesome optimization here! Thanks Strawberry!
My guys will discuss the fps throttling on android in the next week. I knew its behavior is odd, but don’t know how to improve it. It must take a better solution.

In the other hand, cocos2dx-test.apk in the performance page is out of day. The current version is 0.7.2 now, but the apk is still on version 0.7.1. The reason I leave it there is that, cocos2d-iphone 0.99.5 has some performance test cases. We haven’t translate the performance tests into c++, but it’ll be done soon. After the translation, we can get the performance data just like http://www.cocos2d-iphone.org/wiki/doku.php/perf_test:0_99_5 Fewer work and more professional.

Awesomeness, sounds great indeed :slight_smile:

I read something about a different CCDirector (at the moment only available for Cocos2d-iphone?) which would be using NSTime to update the loop. Would it be a viable option to think about implementing that? As far as I can see, sounds like that would be ideal for this situation here. I’m still a Cocos-newbie though, so I certainly might be missing something. Don’t let my n00bnessness take influence on your choices please :slight_smile:

Thanks (again) for discussing this stuff with your guys!

I added the:

APP_ABI := armeabi armeabi-v7a

and commented

        if (interval < animationInterval){ 
            try {
                // because we render it before, so we should sleep twice time interval
                Thread.sleep((animationInterval - interval) * 2 / NANOSECONDSPERMINISECOND);
            } catch (Exception e){}
        }

I am running the test from the master version and I don’t feel any difference :frowning:

Try to remove everything inside Cocos2dxRenderer::onDrawFrame(…) and keep the call to nativeRender. That’s the part where things went really bad on my Desire :slight_smile:

For the instruction set, make sure your device actually supports ARMv7. Otherwise, it will fall back to ARMv5. If your device does have support for it, check your logcat to see if Android actually loads the correct version of the libraries (it will mention if it’s loaded from armeabi or armeabi-v7a). Some implementations are known to have a bug and load the wrong version (thus also falling back to ARMv5).

Yep I check and my nexus one loads armeabi-v7a without issues. Thanks.

issue #344 is created for this case.
I hope it do improve the performance on some android devices.