我的OpenGL学习进阶之旅解决关于在OpenGL ES开发中GLSurfaceView调用了onPause和onResume方法,然后息屏亮屏之后GLSurfaceView黑屏的问题

Posted 字节卷动

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的OpenGL学习进阶之旅解决关于在OpenGL ES开发中GLSurfaceView调用了onPause和onResume方法,然后息屏亮屏之后GLSurfaceView黑屏的问题相关的知识,希望对你有一定的参考价值。

扫码下方二维码,关注微信公众号【字节卷动】!

一、问题描述

最近在学习OpenGL ES技术,刚刚无意发现我写的代码有个Bug,Bug描述如下:

本篇博客为了简单描述,挑选了一个简单的例子来欢迎这个bug,如下所示:

  • 正常现象

一开始运行程序的时候是正常的绘制图形,如下绘制一个三角形。

  • 异常现象
    然后把手机息屏,然后接着把手机亮屏,则出现下面的异常画面

什么鬼,居然黑屏了,我绘制的三角形去哪里了?


一脸的黑人问号

好吧,出现问题就得排查,下面慢慢的一步一步来排查吧

二、分析问题

2.1 排查onPause和onResume方法

因为我们的操作是息屏然后亮屏,按照android的Activity的生命周期,应该是会走onPauseonResume方法。

这两个方法重写之后,如下所示:

   override fun onResume() 
        Log.d(TAG,"onResume()")
        // The activity must call the GL surface view's onResume() on activity onResume().
        super.onResume()
        mGLSurfaceView?.onResume()
    

    override fun onPause() 
        Log.d(TAG,"onPause()")
        // The activity must call the GL surface view's onPause() on activity onPause().
        super.onPause()
        mGLSurfaceView?.onPause()
    

然后我们重新操作一遍复现,查看日志如下:

我们发现代码里面调用了如下代码:mGLSurfaceView?.onResume()mGLSurfaceView?.onPause(),而我们的bug就是因为这个mGLSurfaceView感觉出问题了,导致黑屏。

2.2 注释掉onPause和onResume方法

要不,先把这两个重写的方法注释掉,看看效果。


然后我们重新运行程序看看,

这次运行,发现不会出现息屏亮屏之后,GLSurfaceView黑屏的现象。

我们看全程的Native层Render渲染具体实现的日志打印如下:

2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceCreated][189]: MyGLRenderContext::OnSurfaceCreated
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][shutdown][112]: NativeTriangle::shutdown()
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [GLUtils.cpp][DeleteProgram][198]: GLUtils::DeleteProgram
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Version = OpenGL ES 3.2 V@0502.0 (GIT@42297a4, I9e9b240040, 1616178534) (Date:03/19/21) 
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL GLSL Version = OpenGL ES GLSL ES 3.20 
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Vendor = Qualcomm 
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Renderer = Adreno (TM) 640 
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Extensions = GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_vertex_half_float GL_OES_framebuffer_object GL_OES_rgb8_rgba8 GL_OES_compressed_ETC1_RGB8_texture GL_AMD_compressed_ATC_texture GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_OES_texture_compression_astc GL_OES_texture_npot GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra GL_OES_texture_3D GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_QCOM_alpha_test GL_OES_depth24 GL_OES_packed_depth_stencil GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_EXT_sRGB GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_sRGB_decode GL_EXT_texture_format_sRGB_override GL_OES_element_index_uint GL_EXT_copy_image GL_EXT_geometry_shader GL_EXT_tessellation_shader GL_OES_texture_stencil8 GL_EXT_shader_io_blocks GL_OES_shader_
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][309]: [GLUtils::openTextFile] func start
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][325]: [GLUtils::openTextFile] func cost time 0ms
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][309]: [GLUtils::openTextFile] func start
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][325]: [GLUtils::openTextFile] func cost time 0ms
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][createProgram][141]: [GLUtils::createProgram] func start
2021-12-12 12:43:13.687 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][98]: [GLUtils::loadShader] func start
2021-12-12 12:43:13.688 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][98]: [GLUtils::loadShader] func start
2021-12-12 12:43:13.688 25395-25445/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][createProgram][192]: [GLUtils::createProgram] func cost time 1ms
2021-12-12 12:43:13.689 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 12:43:13.689 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 12:43:13.689 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()


息屏再亮屏   日志继续打印


2021-12-12 12:43:17.116 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2265]
2021-12-12 12:43:17.116 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\\GLBaseSample.h][change][27]: change() width = 1080 , height = 2265
2021-12-12 12:43:17.116 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()
2021-12-12 12:43:17.122 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 12:43:17.122 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 12:43:17.122 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()
2021-12-12 12:43:17.126 25395-25445/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()

虽然注释掉 onPause和onResume方法解决了此问题,但是不建议这么做。至于为啥,请接着看。

2.3 GLSurfaceView 关于Activity生命周期的建议

因为在GLSurfaceView 源代码中,有如下一段建议:

Activity Life-cycle
A GLSurfaceView must be notified when the activity is paused and resumed. GLSurfaceView clients are required to call onPause() when the activity pauses and onResume() when the activity resumes. These calls allow GLSurfaceView to pause and resume the rendering thread, and also allow GLSurfaceView to release and recreate the OpenGL display.


翻译成中文就是:

Activity 处于 pausedresumed状态时,必须通知GLSurfaceViewGLSurfaceView 客户端需要在Activity 处于paused 状态时调用onPause(),在Activity 处于resumed状态时调用onResume()。这些调用允许GLSurfaceView 暂停和恢复渲染线程,还允许GLSurfaceView 释放和重新创建OpenGL显示。

因此,我们上面重写的Activity的onPause()onResume()的代码保留,我们继续查询为啥会这样。

GLSurfaceViewonPause()onResume()的代码如下所示:


    /**
     * Pause the rendering thread, optionally tearing down the EGL context
     * depending upon the value of @link #setPreserveEGLContextOnPause(boolean).
     *
     * This method should be called when it is no longer desirable for the
     * GLSurfaceView to continue rendering, such as in response to
     * @link android.app.Activity#onStop Activity.onStop.
     *
     * Must not be called before a renderer has been set.
     */
    public void onPause() 
        mGLThread.onPause();
    

    /**
     * Resumes the rendering thread, re-creating the OpenGL context if necessary. It
     * is the counterpart to @link #onPause().
     *
     * This method should typically be called in
     * @link android.app.Activity#onStart Activity.onStart.
     *
     * Must not be called before a renderer has been set.
     */
    public void onResume() 
        mGLThread.onResume();
    

2.4 查询Native层的具体Render渲染问题

我们上面重写的Activity的onPause()onResume()的代码保留,重新运行程序,继续排查问题。

这一次,运行程序,然后息屏再亮屏,黑屏的问题又出现了,我们来查看一下日志。

2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceCreated][189]: MyGLRenderContext::OnSurfaceCreated
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][shutdown][113]: NativeTriangle::shutdown()
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [GLUtils.cpp][DeleteProgram][198]: GLUtils::DeleteProgram
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Version = OpenGL ES 3.2 V@0502.0 (GIT@42297a4, I9e9b240040, 1616178534) (Date:03/19/21) 
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL GLSL Version = OpenGL ES GLSL ES 3.20 
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Vendor = Qualcomm 
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Renderer = Adreno (TM) 640 
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\\GLUtils.h][printGLString][52]: GL Extensions = GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_vertex_half_float GL_OES_framebuffer_object GL_OES_rgb8_rgba8 GL_OES_compressed_ETC1_RGB8_texture GL_AMD_compressed_ATC_texture GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_OES_texture_compression_astc GL_OES_texture_npot GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_EXT_read_format_bgra GL_OES_texture_3D GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_QCOM_alpha_test GL_OES_depth24 GL_OES_packed_depth_stencil GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_EXT_sRGB GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_sRGB_decode GL_EXT_texture_format_sRGB_override GL_OES_element_index_uint GL_EXT_copy_image GL_EXT_geometry_shader GL_EXT_tessellation_shader GL_OES_texture_stencil8 GL_EXT_shader_io_blocks GL_OES_shader_
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][309]: [GLUtils::openTextFile] func start
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][325]: [GLUtils::openTextFile] func cost time 0ms
2021-12-12 12:58:39.429 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][309]: [GLUtils::openTextFile] func start
2021-12-12 12:58:39.430 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][325]: [GLUtils::openTextFile] func cost time 0ms
2021-12-12 12:58:39.430 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][createProgram][141]: [GLUtils::createProgram] func start
2021-12-12 12:58:39.430 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][98]: [GLUtils::loadShader<

以上是关于我的OpenGL学习进阶之旅解决关于在OpenGL ES开发中GLSurfaceView调用了onPause和onResume方法,然后息屏亮屏之后GLSurfaceView黑屏的问题的主要内容,如果未能解决你的问题,请参考以下文章

我的OpenGL学习进阶之旅持续更新关于学习OpenGL的一些资料

我的OpenGL学习进阶之旅持续更新关于学习OpenGL的一些资料

我的OpenGL学习进阶之旅解决关于在OpenGL ES开发中GLSurfaceView调用了onPause和onResume方法,然后息屏亮屏之后GLSurfaceView黑屏的问题

我的OpenGL学习进阶之旅解决关于在OpenGL ES开发中GLSurfaceView调用了onPause和onResume方法,然后息屏亮屏之后GLSurfaceView黑屏的问题

我的OpenGL学习进阶之旅关于OpenGL实现相机/图片滤镜的功能项目

我的OpenGL学习进阶之旅关于OpenGL实现相机/图片滤镜的功能项目