Understanding slowdowns on Android.

Started by monkey0506, Tue 01/10/2013 00:19:44

Previous topic - Next topic

monkey0506

Hey, as some of you have noticed, I'm working on the whole "publishing" issue for AGS games on Android, and I've hit somewhat of a snag in that the engine seems to run quite slowly in graphic-intensive games. Even on higher end devices which have very successfully published 3D games available, the engine is slowing to a crawl. I'm not really sure where to look, so what would be the best way of finding the root causes? I know the engine isn't highly optimized ATM, but I'm looking to see what could be done to just make these games run a bit smoother.

Any leads would be appreciated. Also, I'm quite new to Java, Eclipse, and Android development in general, so feel free to "dumb it down" a bit if you're referencing anything specific to those areas. I imagine the biggest issue will lay in the native C++ code, but again, I'm not really sure how to go about determining that.


Thanks!

Crimson Wizard

JJS should know better about this, but I think OpenGL graphics driver should be enabled for Android port. Are you running games with Software renderer or OpenGL?

monkey0506

It seems silly now, but I'll have to make sure I was using OpenGL. I'd sort of overlooked that the "PreferencesActivity" was being utilized by the launcher app, not the engine library, and subsequently forgotten about "android.cfg". 8-) Which actually brings up other issues, but that's another story entirely!

Aside from the renderer, any other thoughts? I tried to email JJS but he hasn't gotten back to me.

Ryan Timothy B

#3
Quote from: monkey_05_06 on Tue 01/10/2013 00:19:44Even on higher end devices which have very successfully published 3D games available, the engine is slowing to a crawl.
Are the games experiencing slowdown full 3D games or a series of hires animated sprites (like AGS)?

The only other thing I can warn you about is the garbage collector. It's a beast and can kill almost any simple game on the phone. Avoid any looping occurrences of creating and disposing of objects; aka: temporary objects.

Edit (better link): https://code.google.com/p/libgdx-users/wiki/ForceGarbageCollection

Crimson Wizard

Quote from: Ryan Timothy on Tue 01/10/2013 06:25:52
The only other thing I can warn you about is the garbage collector. It's a beast and can kill almost any simple game on the phone. Avoid any looping occurrences of creating and disposing of objects; aka: temporary objects.
Does this refer to C++ objects as well? To my shame I have no idea how the Java wrapper (?) works with underlying C++ program. Does it put everything engine creates on managed memory too?
Because, actually, engine does create (and re-create) number of objects (e.g. temporary bitmaps) during running/drawing routines.

tzachs

To add to what Ryan said, I developed a small game (not using AGS) for Android, and was experiencing a slowdown due to the garbage collection and the fact that I was allocating memory in the main loop.

Basically the garbage collection runs repeatedly in a separate thread, which is good, but, if it sees it's low on memory it will do an "emergency" garbage collection on the UI thread which causes slowdowns.
Every garbage collection logs to logcat and you can see which kind of garbage collection is running (the good kind or the bad kind). You can also profile your memory to see if there are things there that shouldn't be.
A really good video on this.

Edit: CW, watch the video, it might give you some answers...

Crimson Wizard

Quote from: tzachs on Tue 01/10/2013 08:27:56
Basically the garbage collection runs repeatedly in a separate thread, which is good, but, if it sees it's low on memory it will do an "emergency" garbage collection on the UI thread which causes slowdowns.
The only reason I do not like automatic garbage collectors: you never know when they decide to start working hard :P.

PS. Can't watch the youtube video right now, maybe later this day.

monkey0506

Quote from: Ryan Timothy on Tue 01/10/2013 06:25:52
Quote from: monkey_05_06 on Tue 01/10/2013 00:19:44Even on higher end devices which have very successfully published 3D games available, the engine is slowing to a crawl.
Are the games experiencing slowdown full 3D games or a series of hires animated sprites (like AGS)?

No, not 3D games. Yes, very much like AGS games, considering it's the AGS engine slowing down. :P

Quote from: Crimson Wizard on Tue 01/10/2013 08:25:15
Quote from: Ryan Timothy on Tue 01/10/2013 06:25:52The only other thing I can warn you about is the garbage collector. It's a beast and can kill almost any simple game on the phone. Avoid any looping occurrences of creating and disposing of objects; aka: temporary objects.

Does this refer to C++ objects as well? To my shame I have no idea how the Java wrapper (?) works with underlying C++ program. Does it put everything engine creates on managed memory too?
Because, actually, engine does create (and re-create) number of objects (e.g. temporary bitmaps) during running/drawing routines.

A quick Google search turned up this answer on StackOverflow:

QuoteThere is no relationship between C++ objects and Dalvik's garbage collection.

Still, I suppose it's probably worth profiling to check for any GC issues. I'll need to do more testing, but it looks like I probably wasn't running the OpenGL renderer, which was probably the root of my issues... I'll continue looking into it, and I'm checking in with the developer who initially notified me of it.

Ryan Timothy B

Quote from: Crimson Wizard on Tue 01/10/2013 08:25:15
Because, actually, engine does create (and re-create) number of objects (e.g. temporary bitmaps) during running/drawing routines.
Mainly you should try to allocate any memory for your objects at load time. In the case of AGS and these temporary bitmaps, if they're being created every gameloop instead of doing this (complete pseudo code):

Code: ags

void MainGameLoop() {
  Bitmap temporaryBitmap = new Bitmap(etc etc);
}

This would create that bitmap every single game loop (40 times a second), where you'd be better off doing this:
Code: ags

Bitmap temporaryBitmap;
void MainGameLoop() {
  temporaryBitmap = new Bitmap(etc etc);
  
  // OR - IF POSSIBLE
  temporaryBitmap.New(etc etc);  // where you're still using the same size bitmap, just editing over it (I don't know much about bitmap editing in C++, so this may not be practical)
}


Of course with a PC this isn't something that can severely hamper the CPU as it could with a phone. A year ago when I was creating a tower defense game for Android I was experiencing massive slowdown because of all the temporary objects I was creating each and every game loop, or sometimes even within numerous loops (30fps x 100 loops). I later rescripted it all to not constantly create an object pointer within each loop and game loop, the FPS doubled (and that was all I changed with my rescripting).

Crimson Wizard

Quote from: Ryan Timothy on Tue 01/10/2013 08:52:15
Mainly you should try to allocate any memory for your objects at load time.
Yes, I know. :tongue:

I was planning to revise those parts of code for a long time, but can't get to that yet.
There were other things that raise questions, like is it really necessary to redraw things so often as AGS does (about every time you move mouse around); this may be related to how software renderer works though...

monkey0506

It seems that some of the biggest existing slowdowns are during screen fades and playback of OGG Theora videos. Is there any way the Theora playback could be optimized? I read somewhat about it, but I have no knowledge of video codecs or optimizing code for particular architectures... :-\

DazJ

The OGG Theora playback issues are what's really slowing down Calm Waters being released on Android. I'd really love this issue to be resolved. The game features a large amount of video cutscenes so this is a vital requirement for me.

SMF spam blocked by CleanTalk