Android 前后台切换与OpenGL(EGL)创建销毁的周期
来源:互联网 发布:软件培训班 编辑:程序博客网 时间:2024/06/05 05:41
EGL的创建是这样的。
/** * Creates an EGL rendering context and all associated elements */void CreateEGL(EGLNativeWindowType window, EGLDisplay* outDisplay, EGLContext* outContext, EGLSurface* outSurface, EGLConfig* outConfig){*outDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);if (*outDisplay == EGL_NO_DISPLAY){ALog_A(0, "CreateEGL failed EGL unable to eglGetDisplay");}if (!eglInitialize(*outDisplay, NULL/*major*/, NULL/*minor*/)){ALog_A(0, "CreateEGL failed EGL unable to eglInitialize");}EGLint numConfigs;// Here specify the attributes of the desired configuration.// Below, we select an EGLConfig with at least 8 bits per color// component compatible with on-screen windowsconst EGLint configAttribs[] ={ EGL_DEPTH_SIZE, 16, EGL_RED_SIZE, 8, // 5, EGL_GREEN_SIZE, 8, // 6, EGL_BLUE_SIZE, 8, // 5, EGL_ALPHA_SIZE, 8, // 0, EGL_STENCIL_SIZE, 8, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE};/* Here, the application chooses the configuration it desires. In this * sample, we have a very simplified selection process, where we pick * the first EGLConfig that matches our criteria */eglChooseConfig(*outDisplay, configAttribs, outConfig, 1, &numConfigs);if (numConfigs < 1){ALog_A(0, "CreateEGL failed no config match eglChooseConfig");}const EGLint surfaceAttrs[] ={EGL_RENDER_BUFFER,EGL_BACK_BUFFER,EGL_NONE};*outSurface = eglCreateWindowSurface(*outDisplay, *outConfig, window, surfaceAttrs);if (*outSurface == EGL_NO_SURFACE){ALog_A(0, "CreateEGL failed EGL unable to eglCreateWindowSurface");}const EGLint contextAttribs[] ={EGL_CONTEXT_CLIENT_VERSION, 2,EGL_NONE};*outContext = eglCreateContext(*outDisplay, *outConfig, EGL_NO_CONTEXT, contextAttribs);if (*outContext == EGL_NO_CONTEXT){ALog_A(0, "CreateEGL failed EGL unable to eglCreateContext");}if (!eglMakeCurrent(*outDisplay, *outSurface, *outSurface, *outContext)){ALog_A(0, "CreateEGL failed EGL unable to eglMakeCurrent");}//eglSwapInterval(*display, 1);}
我们可以看到,我们需要一个EGLNativeWindowType window,然后我们会创建display,context,config,surface。其中,display是和显示器相关的。context和config相关,surface是和window相关的。最为关键的是最后一句eglMakeCurrent就整合了这一切。以后的OpenGL指令才能正确生效。
当android应用被切换到后台的时候,会执行一系列的回调函数,onWindowDestroyed,onPause,onStop,恢复的时候又会执行onResume,onWindowCreated,onResized等等。期间在后台的时候,EGLNativeWindowType window会被销毁掉,也就会导致eglMakeCurrent失效,OpenGL不可用状态。恢复的时候我们需要重建EGL这个初始化的过程。
通过阅读源码,我们会看到NDK提供的native-activity中,会在onWindowDestroyed销毁整个EGL也就是包括了display,context,config,surface。然后在onWindowCreated时候再次创建EGL相关的所有元素。还可以阅读GLSurfaceView.java为我们封装EGL生命周期的view层。会发现同样的处理流程,就是系统的window发生变化的时候,选择了销毁EGL相关的一切。然后甚至在resized时候,对,window又发生变化了都会销毁EGL。然后在重建。
从EGL相关的几个元素display,context,config,surface,我们会发现似乎之后surface是和系统的window密切相关的。也就是eglCreateWindowSurface和ANativeWindow_setBuffersGeometry函数使用了window变量。其它的display,context,config都是不相关的。尤其是context,存放了OpenGL当前的状态。如果销毁,那么我们就丢失了OpenGL所有的状态,在恢复的时候我们需要重新恢复这些状态。否则就会造成绘制错误各种问题。
所以,我们确定去实现2点。第一,在resized之后也就是当window稳定之后再去初始化EGL,防止window的变化导致需要修正EGL。我们看到resized回调总是在windowCreated之后调用的。第二,就是当window变化的时候,我们选择只销毁surface,其他的都保持不变,在恢复的时候重建surface,然后EGL使用新的surface即可。经过测试,这个思路是可以的。并且程序切换前后台速度要快了很多。因为context没有被销毁,OpenGL的绘制状态全部都被保存了。我们需要增加一个ResetSurface函数,在恢复的时候调用。用来删除旧的surface并设置新的surface。如下:
static void ResetSurface(EGLNativeWindowType window, EGLDisplay display, EGLContext context, EGLConfig config, EGLSurface* surface){ if (*surface != EGL_NO_SURFACE) { eglDestroySurface(display, *surface); }const EGLint surfaceAttrs[] ={EGL_RENDER_BUFFER,EGL_BACK_BUFFER,EGL_NONE};*surface = eglCreateWindowSurface(display, config, window, surfaceAttrs);if (!eglMakeCurrent(display, *surface, *surface, context)){ALog_A(0, "ResetSurface failed EGL unable to eglMakeCurrent");}}
- Android 前后台切换与OpenGL(EGL)创建销毁的周期
- iOS前后台切换运行周期
- Android前后台切换
- Android 的OpenGL ES与EGL
- Android 的OpenGL ES与EGL
- Android 的OpenGL ES与EGL
- Android 的OpenGL ES与EGL
- Android 的OpenGL ES与EGL
- Android 的OpenGL ES与EGL
- Android App前后台切换的监听
- Android应用前后台切换的判断
- android应用前后台切换的监听
- Android应用前后台切换的判断
- Android应用前后台切换的判断
- Android OpenGL ES与EGL
- Android OpenGL ES与EGL
- Android OpenGL ES与EGL
- Android OpenGL ES与EGL
- Induction, Deduction and Reduction
- 【URAL 刷题记】URAL 1317 ~ URAL 1326
- pat1017
- Android逆向分析(一) - 反编译看看手Q口令红包的实现原理
- String to Integer(atoi) LeetCode
- Android 前后台切换与OpenGL(EGL)创建销毁的周期
- cvCalcBackProject() 直方图反向投影匹配
- uva 489刽子手游戏
- 大数减法
- HDU 3081 Marriage Match II(二分+并查集+最大流)
- C++继承的简单例程
- 蓝桥杯 BASIC-12 十六进制转八进制
- zookeeper使用和原理探究
- 搭建github 博客