Android "cpu may be pegged"漏洞

标签 android opengl-es

前言:这个严重的错误会导致 Android 设备锁定(无法按 Home/Back 按钮,需要硬重置)。它与 OpenGL 表面和音频播放相关联。 Logcat 重复了一些内容,效果如下:

W/SharedBufferStack( 398): waitForCondition(LockCondition) timed out (identity=9, status=0). CPU may be pegged. trying again.

每秒一次,因此是此错误的名称。造成这种情况的根本原因可能是缓冲数据(无论是声音还是图形)时出现死锁。

在 Asus EEE Transformer 平板电脑上测试我的应用程序时,我偶尔会遇到此错误。当声音线程填充时发生崩溃 MediaPlayer使用 MediaPlayer.create(context, R.raw.someid); 的对象和 GLSurface线程使用

从位图中加载纹理
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();

我认为原因不是音频,因为音频实际上仍在播放(加载音频的线程然后在 x 时间后播放)。如果是,则原因在于使用上述代码的 OpenGL ES 缓冲。

相关资料

  • This SO post指的是这个错误。他们使用 OpenGL ES 2.0 和 NDK。我使用 OpenGL ES 1.1(尽管大多数设备模拟 1.1 到 2.0,所以从技术上讲它们使用的是 2.0)并且我不使用 NDK。此外,他们使用 Android 2.1,而我的崩溃发生在 Android 3.2.1 上。
  • This site将错误链接到 AudioTrack目的。但是,我不会在我的应用程序中使用它。
  • The Android Bug Tracker将其列为已知错误,但目前尚无解决方案(并且未在 Honeycomb+ 中修复)。

通用元素

  • 缓冲时发生卡住。缓冲的内容通常非常大,因此图像(图像越大,错误发生的频率越高)或音频通常会受到影响。
  • 卡住只发生在某些设备上。
  • 卡住与特定的 Android 版本无关 - 已记录在 2.1 和 3.2.1 等。
  • 卡住与 NDK 的使用无关。
  • 卡住与单一编程实践(缓冲顺序、文件类型等)无关

我的问题很简单。这个问题有解决方法吗?如果不能阻止,有没有办法优雅地失败,防止整个设备变砖?

最佳答案

就我的游戏而言,“waitForCondition”问题已在 Samsung Galaxy S (Android 2.3.3) 上被发现。当然我不知道这个问题是否已经在不同的设备上被注意到,但可能那里也存在问题。幸运的是,我能够重现它,因为我的一个 friend 得到了这个设备,他很友好地借给我一个一周。 在我的例子中,游戏几乎都是用 Java 编写的(很少通过 NDK 调用 OpenGL 函数),所以我不确定这是否也适用于您的问题。

无论如何,问题似乎与 OpenGL 内部缓冲区有关。在下面显示的代码中,被注释掉的行 (1) 已更改为 (2) - 手动配置选择。我还没有对它进行彻底的测试,但是自从那个变化我没有注意到任何卡住,所以有希望..

更新 1: 作为附加信息,我想我在某处读到有人在他的 CPU 上遇到了同样的问题,他的解决方案是将所有 OpenGL Surface 组件设置为 8 位(alpha 组件也是如此) ) 而不是 565 或 4 位(我不记得到底是什么错误配置)

更新 2: 也可以考虑使用 EGLConfigChooser 的以下实现:GdxEglConfigChooser.java .如果这最终没有帮助,请使用 GLSurfaceView20.java 中介绍的方法.

更新 3:此外,尽可能简化程序着色器也有一点帮助。

// 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));

关于Android "cpu may be pegged"漏洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8458404/

相关文章:

安卓开发 : Find/get recently used Apps

android - 错误 : Cause: compileSdkVersion is not specified

java - 与导航主机 fragment 大小不同的 fragment

c - 如何靠近前剪裁平面?

opengl-es - GLSurfaceView.Renderer 在恢复时崩溃,因为 "bitmap is recycled"

android - AndEngine渲染纹理异常: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

java - 无法在真实设备上安装 apk

android - 搜索 ListView ?

android - onPause()/onResume() 中的 GLSurface 问题

iphone - 优化 iPhone OpenGL ES 填充率