Foreword: This severe bug can cause Android devices to lock up (unable to press Home/Back buttons, needs hard reset). It is associated with OpenGL surfaces and audio playback. Logcat repeats something to the effect of
W/SharedBufferStack( 398): waitForCondition(LockCondition) timed out (identity=9, status=0). CPU may be pegged. trying again.
once every second, hence the name of this bug. The fundamental cause of this is likely due to a deadlock when buffering data, be it sound or graphics.
I occasionally get this bug when testing my app on the Asus EEE Transformer tablet. The crash occurs when the sound thread populates MediaPlayer
objects using MediaPlayer.create(context, R.raw.someid);
and the GLSurface
thread loads textures from bitmaps using
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.textureMap,opts);
gl.glGenTextures(1, texAtlas, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, texAtlas[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
I don't think the cause is the audio, as the audio does in fact still play (the thread which loads the audio then plays it after x amount of time). If so, the cause lies in the OpenGL ES buffering using the above code.
Related Material
AudioTrack
object. However, I do not use that in my app.Common Elements
My question is pretty simple. Is there a workaround for this issue? If you can't prevent it, is there a way to fail elegantly and prevent the whole device being bricked?
In the case of my game the "waitForCondition" problem has been noticed on Samsung Galaxy S (Android 2.3.3). Of course I don't know if the issue has been noticed on different devices, but probably the problem exists there too. Fortunately I was able to reproduce it as one of my friends has got the device and he was kind enough to lent me one for a week.
In my case the game is practically all written in Java (few calls through NDK to OpenGL functions), so I'm not really sure if this will apply to your problem too.
Anyway it seems that the problem is somehow related to OpenGL internal buffers. In the code presented below the line which has been commented out (1) has been changed to (2) - manual config selection. I didn't test it thoroughly yet, but since that change I haven't noticed any freezes, so there is a hope..
UPDATE 1: As an additional info, I think I read somewhere that somebody had the same problem with his CPU gets pegged and his solution was to set up all the OpenGL Surface components to 8 bits (alpha component too) rather than 565 or 4 bits (I don't remember exactly what was the faulty configuration)
UPDATE 2: Also one may consider to use the following implementation of the EGLConfigChooser: GdxEglConfigChooser.java. If this doesn't help eventually use the approach presented in GLSurfaceView20.java.
UPDATE 3: Additionally simplifying the program shaders as much as it's possible helped a bit too.
// in Activity...
glView = new GLSurfaceView(this);
glView.setEGLContextClientVersion(2); // OpenGL ES 2.0
// glView.setEGLConfigChooser(false); // (1) false - no depth buffer
glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
glView.setEGLConfigChooser(8,8,8,8,0,0); // (2) TODO: crashes on devices which doesn't support this particular configuration
glView.setRenderer(new MyRenderer(this));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With