OpenGL texture recovery

2,002 views
Skip to first unread message

BT

unread,
Dec 6, 2011, 3:57:53 AM12/6/11
to android-ndk
Hi, all.

Our app "freezes" for several seconds as it reloads OpenGL textures.
This is expecially annoying when using the soft keys on Honeycomb or
the new Kindle Fire, which seem to cause OpenGL context swaps when
Activities pop on top of our app.

Today I was trying out various apps on the Kindle Fire and noticed
that Angry Birds doesn't experience (or suffer from?) the context
switch and need to recover textures.

Is there some special trick to what they're doing or just something
we're doing incorrectly?

Note: The specific use/test case where I noticed the problem was on
the Kindle Fire because it forces the soft "menu" button over the
bottom of your app so you can get to the "home" button, etc.

I don't know what similar case would cause the issue on another
device, but probably anything that causes another window to overlay on
top of our app (alert messages, etc.).

Thanks in advance for the help!

-BT

Daniel Smith

unread,
Dec 8, 2011, 4:11:08 PM12/8/11
to andro...@googlegroups.com
In my experience - a pop-up window doesn't cause a new context to be created - usually switching away from the app completely is required, so i'd double check that recreating/reloading textures is really necessary. (note: i haven't used the kindle fire, so it could be peculiarity of that device)
Are you using GLSurfaceView? We rely onSurfaceChanged to indicate whether we need to re-init our opengl resources.

Assuming the re-init is necessary, some things to try:
Check whether the bottleneck is texture loading (from disk) or initialising them in opengl.
If it's disk access, then consider caching the textures in memory (rather than throwing away after sending to opengl)
Make your textures smaller!
A lot of time can be spent on mipmap generation. I think OpenGL ES requires that you supply a whole mipmap chain, but if you know you're only going to use the full size texture (ie. your view is fixed, or you disabled mipmap filtering), then you can manually specify empty buffers for other mipmap levels.
In honeycomb and above, GLSurfaceView has a setPreserveEGLContextOnPause - you may want to try this (though that won't help the kindle)

Having said all that, i'm still a little suspicious that you should have to do this because of an overlaid window/menu. So I'd double check that you're doing it in resposne to the correct event, and that you're not inadvertently recreating your view on activity resume (or something similar)


mrzerg

unread,
Dec 8, 2011, 11:18:51 PM12/8/11
to android-ndk
In my experience, If use GLSurfaceView, just ignore
GLSurfaceView.onPause() and onResume(), textures will be ok during
interrupts. this works fine on 2.2 and 2.3, but on 2.1 you have to
reload the textures.
Some games which didn't use GLSurfaceView can even avoid reloading
textures on 2.1

Christopher Van Kirk

unread,
Dec 9, 2011, 1:15:00 AM12/9/11
to andro...@googlegroups.com
Don't you get an onSurfaceChanged whenever you get a resume?

Also,, if you're able to get away without reloading textures, are you also able to get away without recompiling shaders?

Cheers,

Chris...
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/android-ndk/-/3hOeFntvyFYJ.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

a1

unread,
Dec 9, 2011, 5:57:46 AM12/9/11
to andro...@googlegroups.com
Don't you get an onSurfaceChanged whenever you get a resume?

Also,, if you're able to get away without reloading textures, are you also able to get away without recompiling shaders?

Context lost during interrupts is caused by explicit context destroy in GLSurfaceView.onPause (technically it's in GLThread but as a effect of putting GLSurfaceView in paused state). This is a legacy code from 1.5 which is basically workaround for GPUs that do not support multiple GL context and lack of GL context management on OS level. Since 3.0 you may use (mentioned above)  setPreserveEGLContextOnPause to disable this behavior.
If you do not call  GLSurfaceView.onPause/onResume you will never put surface in pause state effectively preventing it from releasing it's GL context, but I strongly advice you not to do that, first of all you will have to manage thread pause somehow (either by changing render mode or by putting some barrier in your render, also IIRC on 2.0/2.1 there were some issues when user switch to another app which uses GLSurfaceView (there was a global lock which caused deadlock in such situation). Instead of using such hacky workaround simply implement your own GLSurfaceView (or rather reuse one open source implementations eg. http://code.google.com/p/replicaisland/source/browse/trunk/src/com/replica/replicaisland/GLSurfaceView.java)

Bart


mrzerg

unread,
Dec 9, 2011, 11:53:19 AM12/9/11
to android-ndk
pretty cool explanation...
guess I should study this glsurfaceview implementation and rewrite my
code

> reuse one open source implementations eg.http://code.google.com/p/replicaisland/source/browse/trunk/src/com/re...
> )
>
> Bart

BT

unread,
Dec 12, 2011, 12:01:16 PM12/12/11
to android-ndk
Thanks for the great info!

I've noticed since the original post that on Kindle Fire I don't lose
Context when the bottom pop-up opens (the one with the back button on
it). But when that pop-up is open you can touch a button that causes
a drop-down from the top of the screen as well -- that's where you can
change volume, go to Settings, etc. THAT'S the one causing loss of
OpenGL context in my MainActivity even though my app can still be seen
behind both of those translucent pop-ups.

I've also experimented on a friend's cell phone and when an incoming
call dialog pops up in front of my app, it too causes a Context loss
and texture reload.

As a user, my expectation in both of those cases is that I should NOT
be waiting for textures to reload after dismissing the pop-ups/
dialogs.

As for implementation, I only reload textures in
GLSurface.onSurfaceCreated and that's probably being caused by the
Pause/Resume sequence (though I don't think it should be). Since my
app must be compatible with Android 2.2, I cannot use any Honeycomb
APIs to preserve Context.

Regarding a custom version of GLSurfaceView, I was unable to find one
that would compile at API Level 10. There's always some internal
Android symbols that just won't resolve (varies depending on which
version of the open source file I start with). How can I go about
retrieving one that I know will be compatible with my SDK?

Again, thanks much for the great info. The Android NDK adventure
continues...

-BT

a1

unread,
Dec 12, 2011, 7:15:47 PM12/12/11
to andro...@googlegroups.com
Thanks for the great info!

I've noticed since the original post that on Kindle Fire I don't lose
Context when the bottom pop-up opens (the one with the back button on
it).  But when that pop-up is open you can touch a button that causes
a drop-down from the top of the screen as well -- that's where you can
change volume, go to Settings, etc.  THAT'S the one causing loss of
OpenGL context in my MainActivity even though my app can still be seen
behind both of those translucent pop-ups.

If another activity is above your activity, activity is paused (and default implementation of GLSurfaceView releases context).
This only happens if new activity is pushed on top of activity stack even if top level activity is translucent. Please note that
activity is not paused when popup window (ie. dialog) is shown. 
 

Regarding a custom version of GLSurfaceView, I was unable to find one
that would compile at API Level 10.  There's always some internal
Android symbols that just won't resolve (varies depending on which
version of the open source file I start with).  How can I go about
retrieving one that I know will be compatible with my SDK?

The one I've linked (from replica island) works just fine.

--
Bart

BT

unread,
Dec 13, 2011, 1:04:00 PM12/13/11
to android-ndk
Thanks, Bart.

I was able to get the one you linked to compile but my test case on
the Kindle Fire continues to cause texture reloading.

Just to verify my understanding, is this modified GLSurfaceView
supposed to prevent unnecessary Context loss/recovery by shunting the
"normal" onPause/onResume behavior? If I'm still getting
onSurfaceCreated from the Kindle pop-up volume control dial, does that
mean I've missed a step somewhere or is that expected behavior?

Cheers,
BT

a1

unread,
Dec 13, 2011, 1:39:09 PM12/13/11
to andro...@googlegroups.com
GLSurfaceView from Replica Island keeps context alive between pause calls, just note that it extends Renderer a bit: it adds method onSurfaceLost (which should rather be called onContextLost) which notifies client about GL context disposal, so you should not reload/recreate GL related resources in onSurfaceCreate unless it's first notification or onSurfaceLost was called earlier.

BT

unread,
Dec 13, 2011, 2:13:40 PM12/13/11
to android-ndk
Ah, interesting information. I'm not sure my app is structured to do
this the way Replica's intended, but a few additional questions will
shed some light.

Where does the symbol 'DebugLog' come from?
- Symbol unfound when I load into Eclipse.
- Changed everything to Log.i, Log.e, etc. to resolve.

What's the intent of these functions?
- flushTextures(), loadTextures(), flushBuffers(), loadBuffers()
- What if I just delete them, since the symbols don't resolve?

My app is currently very simple: If it gets an
Renderer.onSurfaceCreated() call, it causes all textures to reload.
Not sure what is meant by "buffers".

As I understand it, the only change to my implementation would be
setting some sort of "TexturesLost" flag in onSurfaceLost. Then I'd
check that in onSurfaceCreated to see if it was REALLY lost, and only
then do a texture reload. Otherwise just start normal operations
again, assuming textures are all fine.

Correct?

BT

unread,
Dec 14, 2011, 12:33:16 PM12/14/11
to android-ndk
I changed my code to only recover textures if "OnSurfaceLost" is
called, but still getting the same behavior on Kindle Fire.

When the volume pop-up is displayed on the Galaxy Tab it doesn't cause
onSurfaceLost, but it does on the Kindle. Doesn't seem like it
should, since it's the same kind of pop-over/up, but that appears to
be a choice made differently by Amazon when creating their custom UI
skin.

At this point there's probably nothing I can do about it?

-BT

Christopher Van Kirk

unread,
Dec 14, 2011, 12:41:10 PM12/14/11
to andro...@googlegroups.com
Welcome to the wonderful world of fragmentation.

mingw android

unread,
Dec 14, 2011, 12:45:25 PM12/14/11
to andro...@googlegroups.com

I consider the kindle fire as not really an android device due to the forking, so I'd not call this android fragmentation either.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk+unsubscribe@googlegroups.com.

Christopher Van Kirk

unread,
Dec 14, 2011, 1:22:04 PM12/14/11
to andro...@googlegroups.com
Yeah, I'd disagree with that assessment.

They clearly wanted app compatibility, and from a compatibility perspective it's just another fracture in the glass of the Android device universe.

Here's hoping the Motorola acquisition solves all that.


On 12/15/2011 1:45 AM, mingw android wrote:

I consider the kindle fire as not really an android device due to the forking, so I'd not call this android fragmentation either.

On Dec 14, 2011 5:41 PM, "Christopher Van Kirk" <christoph...@gmail.com> wrote:
Welcome to the wonderful world of fragmentation.

On 12/15/2011 1:33 AM, BT wrote:
I changed my code to only recover textures if "OnSurfaceLost" is
called, but still getting the same behavior on Kindle Fire.

When the volume pop-up is displayed on the Galaxy Tab it doesn't cause
onSurfaceLost, but it does on the Kindle.  Doesn't seem like it
should, since it's the same kind of pop-over/up, but that appears to
be a choice made differently by Amazon when creating their custom UI
skin.

At this point there's probably nothing I can do about it?

-BT


--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.

a1

unread,
Dec 15, 2011, 4:39:27 AM12/15/11
to andro...@googlegroups.com
OpenGL implementation may always forcibly dispose context (see EGL_CONTEXT_LOST error description in eglMakeCurrent and eglSwapBuffer), in such case you are forced to fully restore GL resources. This is low level OS behavior and cannot be changed or workaround.

--
Bart
Reply all
Reply to author
Forward
0 new messages