eglMakeCurrent EGL_BAD_ALLOC失败

时间:2015-05-22 09:40:54

标签: android renderer android-hardware

我继续收到此错误报告

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)

2 个答案:

答案 0 :(得分:3)

如果查看EGL specification,可能会导致此错误。您的应用程序中的某些内容似乎会导致资源耗尽。规范说明如下:

  

3.7.3绑定上下文和Drawables

     

...   eglMakeCurrent将ctx绑定到当前渲染线程以及绘图和   阅读表面...

     

<强>错误

     

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

要解决此问题,您可以检查应用程序的内存使用情况。有许多不同的技术可用于调查应用程序的ram使用情况,some techniques are documented quite well in this guide.

This post还描述了如果在调用EGL_WIDTH时未设置像素缓冲区的EGL_HEIGHTeglCreatePbufferSurface参数,则在调用eglMakeCurrent时会触发错误。这是一个创建像素缓冲区(full source located here)的最小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);
}

如果不了解有关应用程序实现的更多详细信息,很难查明确切原因。这应该是识别和解决问题的良好起点。

答案 1 :(得分:0)

此EGL错误通常是由特定于设备的硬件加速问题引起的。 Webview可能特别容易受到此错误的影响。尝试为有问题的视图禁用硬件加速。如果错误仍然存​​在,请确保您正确连接到Activity生命周期,因为这也可能导致EGL分配崩溃。具体来说,请检查在封闭的Activity上调用时是否在您的GLSurfaceView上调用了onPause和onResume。

资源:

  1. CreateWindowSurface failed EGL_BAD_ALLOC
  2. GLSurfaceView EGL_BAD_ALLOC
  3. GLSurfaceView in Android 2.3.x consistently produces EGL_BAD_ALLOC