Re: [android-developers] Bug in GLSurfaceView.RENDERMODE_WHEN_DIRTY (and work-around)

2009-11-24 Thread Dianne Hackborn
Reply from one of our graphics engineers:

Thanks for the thorough bug report and analysis and suggested work-around!

For what it's worth, this portion of GLSurfaceView has been rewritten for a
post-2.0 version of Android. The new version uses a single wait() loop for
all the different reasons GLSurfaceView needs to wait, so the mPaused change
will no longer be lost.

On Sat, Nov 21, 2009 at 11:24 PM, tomei.ninge...@gmail.com 
tomei.ninge...@gmail.com wrote:

 My OpenGL app animates only every now and then, so I decided to use
 RENDERMODE_WHEN_DIRTY to save some battery life. However, I found that
 when I go to Home Screen and return to my app, I often get a black
 screen, and I see this in logcat:

 E/SurfaceComposerClient( 6055): using an invalid surface id=1,
 identity=735 should be 738

 This seems to be caused by this code in GLSurfaceView (1.6 here, but
 2.0 has same problem):


synchronized (this) {

if (mPaused) {
mEglHelper.finish();
needStart = true;
}
while (needToWait()) {
wait();
}
...
}
if (needStart) {
mEglHelper.start();
..

 If I use RENDERMODE_WHEN_DIRTY, I will be stuck inside the wait()
 call. When my app is paused/resumed,  GLSurfaceView.{onPause,onResume}
 will be called, by the change in mPaused will be lost. So when wait()
 finally finishes, the mEglHelper.finish() and mEglHelper.start() lines
 are not executed, and I end up drawing into the wrong surface.

 The work around is simple but a bit ugly:

public MyView() {
super();
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

public void onResume() {
super.onResume();
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
requestRender();
}

public void onPause() {
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
android.os.SystemClock.sleep(60);
super.onPause();
}

 The trick is to temporarily get the GLSurfaceView to run in
 RENDERMODE_CONTINUOUSLY. I found the sleep(60) to be necessary to
 avoid race conditions that somehow left me hanging inside the wait()
  but I am not sure if this is 100% scientific.

 Anyway, cheers, and save a few battery bars!

 P.S., I found this to be somewhat disconcerting ... as the longevity
 of this bug shows not too many people are trying to use OpenGL to make
 their UI faster -- and battery efficient. This probably means that
 iPhone apps will continue to look-and-feel better than Android for
 quite some time :-(


 --
 You received this message because you are subscribed to the Google
 Groups Android Developers group.
 To post to this group, send email to android-developers@googlegroups.com
 To unsubscribe from this group, send email to
 android-developers+unsubscr...@googlegroups.comandroid-developers%2bunsubscr...@googlegroups.com
 For more options, visit this group at
 http://groups.google.com/group/android-developers?hl=en




-- 
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails.  All such
questions should be posted on public forums, where I and others can see and
answer them.

-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

[android-developers] Bug in GLSurfaceView.RENDERMODE_WHEN_DIRTY (and work-around)

2009-11-21 Thread tomei.ninge...@gmail.com
My OpenGL app animates only every now and then, so I decided to use
RENDERMODE_WHEN_DIRTY to save some battery life. However, I found that
when I go to Home Screen and return to my app, I often get a black
screen, and I see this in logcat:

E/SurfaceComposerClient( 6055): using an invalid surface id=1,
identity=735 should be 738

This seems to be caused by this code in GLSurfaceView (1.6 here, but
2.0 has same problem):


synchronized (this) {

if (mPaused) {
mEglHelper.finish();
needStart = true;
}
while (needToWait()) {
wait();
}
...
}
if (needStart) {
mEglHelper.start();
..

If I use RENDERMODE_WHEN_DIRTY, I will be stuck inside the wait()
call. When my app is paused/resumed,  GLSurfaceView.{onPause,onResume}
will be called, by the change in mPaused will be lost. So when wait()
finally finishes, the mEglHelper.finish() and mEglHelper.start() lines
are not executed, and I end up drawing into the wrong surface.

The work around is simple but a bit ugly:

public MyView() {
super();
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}

public void onResume() {
super.onResume();
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
requestRender();
}

public void onPause() {
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
android.os.SystemClock.sleep(60);
super.onPause();
}

The trick is to temporarily get the GLSurfaceView to run in
RENDERMODE_CONTINUOUSLY. I found the sleep(60) to be necessary to
avoid race conditions that somehow left me hanging inside the wait()
 but I am not sure if this is 100% scientific.

Anyway, cheers, and save a few battery bars!

P.S., I found this to be somewhat disconcerting ... as the longevity
of this bug shows not too many people are trying to use OpenGL to make
their UI faster -- and battery efficient. This probably means that
iPhone apps will continue to look-and-feel better than Android for
quite some time :-(


-- 
You received this message because you are subscribed to the Google
Groups Android Developers group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en