July 1, 2011

GLSurfaceView problems

Filed under: Uncategorized — zet @ 16:36

I am looking into the Android Development Kit right now and went straight for OpenGL, rejoicing to see a simple-looking class to paint stuff. But … o-boy how bugged it is!

This is what I am talking about: http://android-developers.blogspot.com/2009/04/introducing-glsurfaceview.html

And here are the painful-pitfalls that I stumbled in and solved so far (not all – of course). It runs smooth and fine as long as you don’t deal with .onResume and .onPause. If you’re doing that, you’re already in the middle of threading without knowing. The GLSurfaceView class is using a thread that takes care about rendering, however, the looping is fragile and it even gives me more headaches when thinking about the potential impact on threadsafety and so on. And I only have begun to look into the ADK. Sigh.

So here are the trouble makers in detail:

Nr.1: http://code.google.com/p/android/issues/detail?id=2828 describes what can happen if you pause / resume an activity (which can happen already when just rotating the device’ screen). The device screen remains black and after some time a dialog offers you to terminate the activity. It seems to be a sort-of deadlock issue when trying to pause the state. It helps to call Thread.sleep after calling GLSurfaceVies.onPause() to give it time to settle down. I assume that the sleeptime should be at least as long as one frame needs to be rendered. This issue arises only if you’re in the RENDERMODE_CONTINUOUSLY mode.

Nr.2: After figuring that out, I decided to switch to RENDERMODE_WHEN_DIRTY because I also want to save battery powers and avoid unnecessary renderings. And guess what: More problems, similar, but yet different: http://www.mailinglistarchive.com/html/android-developers@googlegroups.com/2009-11/msg04528.html . The problem here is, that the dirty mode doesn’t cooperate with onPause cleanly either! So instead, you have to switch to the other buggy mode (RENDERMODE_CONTINUOUSLY) during onPause, WAIT to avoid the OTHER bug and when resuming, switch to the RENDERMODE_WHEN_DIRTY again!

Big fun, and it still doesn’t fit what I am experiencing now, check this out, this is what I am supposed to see:

But I am seeing this:

You could now think: Well, the background texture hasn’t yet loaded yet simply, or something failed, however: It’s one single picture – the symbols and the background share the same texture! So it hasn’t failed (completely). My first thought was that the texture is not being loaded fully when drawing the first screen (the background comes first of course). So I checked the threads and calling order and the problem doesn’t seem to be threading – in short, I have no idea what the cause of this trouble is, but right now, I can only fix it by enforcing a second rendering after the first one. This is really sort of annoying. Though I AM happy that I can use OpenGL for the drawing process.

Maybe the only reason for all this trouble is that I am developing for the G1, a fairly old device by now and so I am using an older API version, but still… couldn’t this issue be fixed and updated? Or maybe someone is afraid to touch this particular code because knowing that there’s stuff our there relying on it. Anyway, if you’re dealing with the GLSurfaceView class, be warned of strange behavior regarding initialization and deinitialization. If you’re in trouble, read the logcat output for any warnings or problems – googling for it in conjunction with the “GLSurfaceView” classname spits out most pointers to issues (except for a page that hints out all the pitfalls of that class).

No related posts.

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Copyright Eike Decker 2009