android - largeheap - eglMakeCurrent falló EGL_BAD_ALLOC
hardware acceleration chrome (1)
Sigo recibiendo este informe de error
Fatal Exception: java.lang.IllegalStateException
eglMakeCurrent failed EGL_BAD_ALLOC
android.view.HardwareRenderer$GlRenderer.createSurface
en mi aplicación que está en Play Store. ¿Qué causa este choque y cómo puede ser arreglado? A continuación se muestra el registro de errores completo.
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)
Si observa la especificación EGL , existen varias causas posibles para este error. Parece que algo en tu aplicación está causando que se quede sin recursos. La especificación establece lo siguiente:
3.7.3 Contextos de unión y dibujables
...
eglMakeCurrent
une ctx al hilo de renderización actual y a las superficies de dibujo y lectura ...Los errores
... Si los búferes auxiliares para dibujo y lectura no se pueden asignar, se genera un error
EGL_BAD_ALLOC
...
Para solucionar el problema, puede inspeccionar el uso de memoria de su aplicación. Existen muchas técnicas diferentes para investigar el uso de ram de su aplicación, algunas técnicas están bien documentadas en esta guía.
Esta publicación también describe que el error se desencadena al llamar a eglMakeCurrent si los parámetros EGL_WIDTH
y EGL_HEIGHT
del buffer de píxeles no están establecidos al llamar a eglCreatePbufferSurface
. Aquí hay una muestra java mínima para crear un búfer de píxeles (la fuente completa se encuentra aquí) , asegúrese de que el ancho y la altura de entrada sean mayores que cero:
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);
}
Es difícil identificar la causa exacta sin conocer más detalles sobre la implementación de su aplicación. Este debe ser un buen punto de partida para identificar y solucionar el problema.