Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

eglMakeCurrent failed EGL_BAD_ALLOC

I keep on getting this error report:

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

...on my app that is on Play Store.

What causes this crash and how can it be fixed?

Below is the full error log:

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)
like image 247
Alex Kombo Avatar asked May 22 '15 09:05

Alex Kombo


1 Answers

If you look at the EGL specification, there are several possible causes for this error. It seems like something in your application is causing it to run out of resources. The spec states the following:

3.7.3 Binding Contexts and Drawables

... eglMakeCurrent binds ctx to the current rendering thread and to the draw and read surfaces...

Errors

... If the ancillary buffers for draw and read cannot be allocated, an EGL_BAD_ALLOC error is generated...

To troubleshoot the issue, you could inspect the memory usage of your application. There are many different techniques to investigate ram usage of your application, some techniques are documented quite well in this guide.

This post also describes that the error is triggered when calling eglMakeCurrent if the EGL_WIDTH and EGL_HEIGHT parameters of the pixel buffer are not set when calling eglCreatePbufferSurface. Here is a minimal java sample to create a pixel buffer (full source located here), ensure that the input width and height are greater than zero:

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

It is difficult to pinpoint the exact cause without knowing more details on the implementation of your application. This should be a good starting point to identify and fix the issue.

like image 164
sparkplug Avatar answered Oct 21 '22 07:10

sparkplug