13

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

  • This SO post refers to this bug. They use OpenGL ES 2.0 and NDK. I use OpenGL ES 1.1 (albeit most devices emulate 1.1 through 2.0, so technically they are using 2.0) and I do not use the NDK. Further, they use Android 2.1 and my crash occurs on Android 3.2.1.
  • This site links the bug to the AudioTrack object. However, I do not use that in my app.
  • The Android Bug Tracker lists this as a known bug, but as of yet there is no solution (and it's not fixed in Honeycomb+).

Common Elements

  • Freeze occurs when buffering. The thing being buffered is usually quite large, so an image (bug occurs more frequently the larger the image) or audio is typically affected.
  • Freeze only occurs on some devices.
  • Freeze is not related to a specific Android version - has been recorded on 2.1 and 3.2.1, among others.
  • Freeze is not related to use of the NDK.
  • Freeze is not related to a single programming practice (order of buffering, file types, etc)

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?

Community
  • 1
  • 1
Dororo
  • 3,420
  • 2
  • 30
  • 46
  • 2
    "Bricked" refers to a device which cannot boot, not one which is frozen until reboot. – Chris Stratton Jul 25 '12 at 11:31
  • FWIW, I am getting this problem, very rarely. It does not cause freezing, only slowness, probably due to deadlock that's resolved by a timeout. I'm not directly using OpenGL, but I do have a PriorityBlockingQueue that runs on a worker thread, and gets interrupted frequently by the UI thread. When it is interrupted, it adds the item that it is presently processing BACK onto the queue before exiting, and that may be responsible for the deadlock. This could be my own error, but it causes the same message so perhaps something similar is happening inside OpenGL when this occurs. – Carl Nov 17 '12 at 10:39

2 Answers2

1

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));
Eric
  • 1,685
  • 1
  • 17
  • 32
0

Increasing the virtual memory of the device lowers the occurrences in which this issue happens. Of course this is not an option unless you are the manufacturer of the device.

RSai
  • 51
  • 6