eglMakeCurrent() 失败,EGL_BAD_ALLOC。

28

我一直收到这个错误报告:

Fatal Exception: java.lang.IllegalStateException
eglMakeCurrent failed EGL_BAD_ALLOC
android.view.HardwareRenderer$GlRenderer.createSurface

我在Play商店上的应用程序中遇到了崩溃的问题。

是什么导致了这个崩溃,如何修复?

以下是完整的错误日志:

java.lang.IllegalStateException: eglMakeCurrent failed EGL_BAD_ALLOC
   at android.view.HardwareRenderer$GlRenderer.createSurface(HardwareRenderer.java:1354)
   at android.view.HardwareRenderer$GlRenderer.createEglSurface(HardwareRenderer.java:1241)
   at android.view.HardwareRenderer$GlRenderer.initialize(HardwareRenderer.java:1058)
   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1811)
   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1235)
   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6472)
   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
   at android.view.Choreographer.doCallbacks(Choreographer.java:603)
   at android.view.Choreographer.doFrame(Choreographer.java:573)
   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
   at android.os.Handler.handleCallback(Handler.java:733)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:157)
   at android.app.ActivityThread.main(ActivityThread.java:5356)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:515)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
   at dalvik.system.NativeStart.main(NativeStart.java)

@AlexKombo,您能告诉我们哪些设备出现了这个错误吗?看起来这个错误是特定于设备的,知道设备将有助于缩小范围。 - Milk
另外,您能否发布您的着陆活动的onPause和onResume方法。这可能是由于在某些版本的Android上的某些设备上发生的竞争条件引起的。 - Milk
2个回答

4
如果您查看EGL规范,则此错误可能有几种可能的原因。似乎您的应用程序中的某些内容导致其资源耗尽。规范指出如下内容:

3.7.3 绑定上下文和绘图表面

... eglMakeCurrent将ctx绑定到当前渲染线程以及draw和read表面。

错误

...如果无法分配绘制和读取辅助缓冲区,则会生成EGL_BAD_ALLOC错误...

要解决问题,您可以检查应用程序的内存使用情况。有许多不同的技术可用于调查应用程序的RAM使用情况,一些技术在本指南中记录得非常好。

这篇文章还描述了在调用eglCreatePbufferSurface时,如果像素缓冲区的EGL_WIDTHEGL_HEIGHT参数未设置,则会触发错误。这里是创建像素缓冲区的最小Java示例(完整源代码位于此处),请确保输入的宽度和高度大于零:

private void eglSetup(int width, int height) {
    mEGL = (EGL10)EGLContext.getEGL();
    mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    if (!mEGL.eglInitialize(mEGLDisplay, null)) {
        throw new RuntimeException("unable to initialize EGL10");
    }

    // Configure EGL for pbuffer and OpenGL ES 2.0.  We want enough RGB bits
    // to be able to tell if the frame is reasonable.
    int[] attribList = {
            EGL10.EGL_RED_SIZE, 8,
            EGL10.EGL_GREEN_SIZE, 8,
            EGL10.EGL_BLUE_SIZE, 8,
            EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL10.EGL_NONE
    };
    EGLConfig[] configs = new EGLConfig[1];
    int[] numConfigs = new int[1];
    if (!mEGL.eglChooseConfig(mEGLDisplay, attribList, configs, 1, numConfigs)) {
        throw new RuntimeException("unable to find RGB888+pbuffer EGL config");
    }

    // Configure context for OpenGL ES 2.0.
    int[] attrib_list = {
            EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL10.EGL_NONE
    };
    mEGLContext = mEGL.eglCreateContext(mEGLDisplay, configs[0], EGL10.EGL_NO_CONTEXT,
        attrib_list);
    checkEglError("eglCreateContext");
    if (mEGLContext == null) {
        throw new RuntimeException("null context");
    }

    // Create a pbuffer surface.  By using this for output, we can use glReadPixels
    // to test values in the output.
    int[] surfaceAttribs = {
            EGL10.EGL_WIDTH, width,
            EGL10.EGL_HEIGHT, height,
            EGL10.EGL_NONE
    };
    mEGLSurface = mEGL.eglCreatePbufferSurface(mEGLDisplay, configs[0], surfaceAttribs);
    checkEglError("eglCreatePbufferSurface");
    if (mEGLSurface == null) {
        throw new RuntimeException("surface was null");
    }

    mEGL.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext);
}

如果不知道您的应用程序实现的更多细节,很难确定确切的原因。这应该是一个很好的起点来识别和解决问题。


0

这个EGL错误通常是由于设备特定的硬件加速问题引起的。Webview可能尤其容易出现这种错误。尝试禁用有问题视图的硬件加速。如果错误仍然存在,请确保您正确地连接到Activity生命周期,因为这也可能导致EGL分配崩溃。具体而言,请检查当调用包含的Activity时,GLSurfaceView是否调用了onPause和onResume。

资源:

  1. CreateWindowSurface failed EGL_BAD_ALLOC
  2. GLSurfaceView EGL_BAD_ALLOC
  3. 在Android 2.3.x中,GLSurfaceView始终产生EGL_BAD_ALLOC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接