Подтвердить что ты не робот

EglMakeCurrent не удалось EGL_BAD_ALLOC

Я продолжаю получать этот отчет об ошибке

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)
4b9b3361

Ответ 1

Если вы посмотрите на спецификацию EGL, существует несколько возможных причин этой ошибки. Кажется, что что-то в вашем приложении приводит к тому, что у него заканчиваются ресурсы. В спецификации указано следующее:

3.7.3 Связывание контекстов и чертежей

... eglMakeCurrent привязывает ctx к текущему потоку рендеринга и к ничьей и читать поверхности...

Ошибки

... Если вспомогательные буферы для рисования и чтения не могут быть выделены, EGL_BAD_ALLOC генерируется ошибка...

Чтобы устранить эту проблему, вы можете проверить использование памяти в своем приложении. Существует множество различных методов исследования использования вашего приложения, некоторые методы хорошо описаны в этом руководстве.

В этом сообщении также описывается, что ошибка запускается при вызове eglMakeCurrent, если параметры EGL_WIDTH и EGL_HEIGHT пиксельного буфера не установлены при вызове eglCreatePbufferSurface. Вот минимальный образец 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);
}

Трудно точно определить точную причину, не зная подробностей о реализации вашего приложения. Это должно стать хорошей отправной точкой для выявления и устранения проблемы.

Ответ 2

Эта ошибка EGL обычно вызвана проблемами аппаратного ускорения для конкретного устройства. Веб-просмотры могут быть особенно подвержены этой ошибке. Попробуйте отключить аппаратное ускорение для проблемных представлений. Если ошибка не устранена, убедитесь, что вы правильно подключили жизненный цикл Activity, поскольку это также может привести к сбою выделения EGL. В частности, проверьте, вызваны ли onPause & onResume в GLSurfaceView при вызове в вмещающем действии.

Ресурсы:

  1. Ошибка CreateWindowSurface EGL_BAD_ALLOC
  2. GLSurfaceView EGL_BAD_ALLOC
  3. GLSurfaceView в Android 2.3.x последовательно выдает EGL_BAD_ALLOC