android opengl-es egl

android - Opengls eglCreateWindowSurface Error GL EGL_BAD_ALLOC



opengl-es (1)

Solucioné el error GL Error EGL_BAD_ALLOC. Este error ocurre debido a que no manejo adecuadamente el Renderer con el ciclo de vida de la actividad.

Estoy recibiendo eglCreateWindowSurface GL Error EGL_BAD_ALLOC cuando abre la aplicación por primera vez después de la instalación en Samsung Galaxy S6 y el mismo código funciona bien en otro dispositivo.

Traté de limpiar la memoria y destruir la textura y deinicializar todos los objetos opengl en destruir, pero eso no puede ayudarme.

03-30 09:21:32.983 21942-26083/com.example E/TextureSurfaceRenderer: createContext: EGL10.EGL_YES_CONTEXT com.google.android.gles_jni.GLImpl@24406d0 03-30 09:21:32.983 21942-26083/com.example E/libEGL: eglCreateWindowSurface: native_window_api_connect (win=0x7f7b100e10) failed (0xffffffea) (already connected to another API?) 03-30 09:21:32.983 21942-26083/com.example E/libEGL: eglCreateWindowSurface:485 error 3003 (EGL_BAD_ALLOC) 03-30 09:21:32.993 21942-26083/com.example E/GL Error:: EGL_BAD_ALLOC

Aquí está mi código.

import android.graphics.SurfaceTexture; import android.opengl.GLUtils; import android.os.Handler; import android.util.Log; import javax.microedition.khronos.egl.*; /** * Renderer which initializes OpenGL 2.0 context on a passed surface and starts * a rendering thread * * This class has to be subclassed to be used properly */ public abstract class TextureSurfaceRenderer implements Runnable { private static final int EGL_OPENGL_ES2_BIT = 4; private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; private static final String TAG = TextureSurfaceRenderer.class.getSimpleName(); protected final SurfaceTexture texture; protected Handler myHandler; private EGL10 egl; private EGLDisplay eglDisplay; private EGLContext eglContext; private EGLSurface eglSurface; protected int width; protected int height; private boolean running; /** * @param texture * Surface texture on which to render. This has to be called * AFTER the texture became available * @param width * Width of the passed surface * @param height * Height of the passed surface */ public TextureSurfaceRenderer(SurfaceTexture texture, int width, int height,Handler myHandler) { this.myHandler = myHandler; this.texture = texture; this.width = width; this.height = height; this.running = true; Thread thrd = new Thread(this); thrd.start(); } @Override public void run() { initGL(); if(eglSurface != null){ initGLComponents(); Log.d(TAG, "OpenGL init OK."); while (running) { long loopStart = System.currentTimeMillis(); pingFps(); boolean isDraw = draw(); // Log.e(TAG, "eglSwapBuffers Before Draw " + isDraw); if (isDraw) { if(!egl.eglSwapBuffers(eglDisplay, eglSurface)){ int error = egl.eglGetError(); Log.e(TAG, "eglSwapBuffers Error " + GLUtils.getEGLErrorString(error)); } } // Targeting 60 fps, no need for faster long waitDelta = 16 - (System.currentTimeMillis() - loopStart); if (waitDelta > 0) { try { Thread.sleep(waitDelta); } catch (InterruptedException e) { MyApplication.getInstance().trackException(e); continue; } } } deInitGLComponents(); deinitGL(); } else { Log.e(TAG, "Egl Surface is null " + GLUtils.getEGLErrorString(egl.eglGetError())); } } /** * Main draw function, subclass this and add custom drawing code here. The * rendering thread will attempt to limit FPS to 60 to keep CPU usage low. */ protected abstract boolean draw(); /** * OpenGL component initialization funcion. This is called after OpenGL * context has been initialized on the rendering thread. Subclass this and * initialize shaders / textures / other GL related components here. */ public abstract void initGLComponents(); public abstract void deInitGLComponents(); private long lastFpsOutput = 0; private int frames; private void pingFps() { if (lastFpsOutput == 0) lastFpsOutput = System.currentTimeMillis(); frames++; if (System.currentTimeMillis() - lastFpsOutput > 1000) { Log.d(TAG, "FPS: " + frames); lastFpsOutput = System.currentTimeMillis(); frames = 0; } } /** * Call when activity pauses. This stops the rendering thread and * deinitializes OpenGL. */ public void onPause() { running = false; } private void initGL() { egl = (EGL10) EGLContext.getEGL(); eglDisplay = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] version = new int[2]; egl.eglInitialize(eglDisplay, version); EGLConfig eglConfig = chooseEglConfig(); eglContext = createContext(egl, eglDisplay, eglConfig); eglSurface = egl.eglCreateWindowSurface(eglDisplay, eglConfig, texture, null); // Here I am getting null eglSurface first Time. if (eglSurface == null || eglSurface == EGL10.EGL_NO_SURFACE) { myHandler.sendEmptyMessage(0); Log.e("GL Error: " ,""+ GLUtils.getEGLErrorString(egl.eglGetError())); return; } if (!egl.eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)) { myHandler.sendEmptyMessage(0); Log.e("GL Make current error: " , "" + GLUtils.getEGLErrorString(egl.eglGetError())); return; } } private void deinitGL() { egl.eglMakeCurrent(eglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(eglDisplay, eglSurface); egl.eglDestroyContext(eglDisplay, eglContext); egl.eglTerminate(eglDisplay); Log.d(TAG, "OpenGL deinit OK."); } private EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { int[] attribList = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; EGLContext eglContext = egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attribList); if(eglContext.getGL().equals(EGL10.EGL_NO_CONTEXT)){ Log.e(TAG, "createContext: EGL10.EGL_NO_CONTEXT"); } else { Log.e(TAG, "createContext: EGL10.EGL_YES_CONTEXT " + eglContext.getGL().toString()); } return eglContext; } private EGLConfig chooseEglConfig() { int[] configsCount = new int[1]; EGLConfig[] configs = new EGLConfig[1]; int[] configSpec = getConfig(); if (!egl.eglChooseConfig(eglDisplay, configSpec, configs, 1, configsCount)) { Log.e(TAG , "Failed to choose config: " + GLUtils.getEGLErrorString(egl.eglGetError())); } else if (configsCount[0] > 0) { return configs[0]; } return null; } private int[] getConfig() { return new int[] { EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_BLUE_SIZE, 8, EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_STENCIL_SIZE, 0, EGL10.EGL_NONE }; } @Override protected void finalize() throws Throwable { super.finalize(); running = false; } }