目录

  • 一、问题描述
  • 二、分析问题
    • 2.1 排查onPause和onResume方法
    • 2.2 注释掉onPause和onResume方法
    • 2.3 GLSurfaceView 关于Activity生命周期的建议
    • 2.4 查询Native层的具体Render渲染问题
    • 2.5 解决Native层的具体Render渲染问题
  • 三、总结一下

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

一、问题描述

最近在学习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] func start
2021-12-12 12:58:39.431 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][98]: [GLUtils::loadShader] func start
2021-12-12 12:58:39.435 27461-27724/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][createProgram][192]: [GLUtils::createProgram] func cost time 5ms
2021-12-12 12:58:39.435 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 12:58:39.435 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 12:58:39.435 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][53]: NativeTriangle::draw()
2021-12-12 12:58:39.442 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][53]: NativeTriangle::draw()

接着息屏,然后亮屏,看看日志

2021-12-12 13:00:06.392 27461-27461/com.oyp.openglesdemo D/NativeRenderActivity: onPause()
2021-12-12 13:00:10.294 27461-27461/com.oyp.openglesdemo D/NativeRenderActivity: onResume()
2021-12-12 13:00:10.326 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceCreated][189]: MyGLRenderContext::OnSurfaceCreated
2021-12-12 13:00:10.326 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 13:00:10.326 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 13:00:10.326 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][53]: NativeTriangle::draw()
2021-12-12 13:00:10.330 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 13:00:10.330 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 13:00:10.330 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][53]: NativeTriangle::draw()
2021-12-12 13:00:10.334 27461-27724/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][53]: NativeTriangle::draw()

我们对比正常和黑屏的日志打印,如下所示:


我们发现,MyGLRenderContext::OnSurfaceCreatedMyGLRenderContext::OnSurfaceChanged以及NativeTriangle::draw()方法,两次都调用了,

  • 在正常显示的时候,调用MyGLRenderContext::OnSurfaceCreated 去加载了顶点着色器和片段着色器并链接生成程序对象,
  • 但是息屏再亮屏这一次黑屏的异常时候,调用MyGLRenderContext::OnSurfaceCreated 时候啥都没有做就直接进入了MyGLRenderContext::OnSurfaceChanged

那我们得来看看这里有啥问题了。

我们查看一下MyGLRenderContext::OnSurfaceCreated发现最终会调用具体的Sample的create方法。

void MyGLRenderContext::OnSurfaceCreated(JNIEnv *env, jobject assetManager) {LOGD("MyGLRenderContext::OnSurfaceCreated")// 初始化设置assetManager  一定要记得初始化,否则会报空指针异常GLUtils::setEnvAndAssetManager(env, assetManager);if (m_pBeforeSample) {m_pBeforeSample->shutdown();delete m_pBeforeSample;m_pBeforeSample = nullptr;}if (m_pCurSample) {m_pCurSample->create();}
}


因此,我们来看看这个错误的Sample,即NativeTrianglecreate()方法,代码如下所示:

void NativeTriangle::create() {if(mProgram){return;}GLUtils::printGLInfo();// Main ProgramVERTEX_SHADER = GLUtils::openTextFile("vertex/vertex_shader_hello_triangle.glsl");FRAGMENT_SHADER = GLUtils::openTextFile("fragment/fragment_shader_hello_triangle.glsl");mProgram = GLUtils::createProgram(&VERTEX_SHADER, &FRAGMENT_SHADER);if (!mProgram) {LOGD("Could not create program")return;}// 设置清除颜色glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
}

看起来代码量并不多。而且从日志打印来看,下面的GLUtils::printGLInfo();打印GL相关信息的代码和加载着色器以及链接程序的代码时候没执行。
我们加一行日志验证一下,如下所示:

void NativeTriangle::create() {if(mProgram){LOGE("NativeTriangle::create() 已经初始化过 直接return")return;}GLUtils::printGLInfo();// Main ProgramVERTEX_SHADER = GLUtils::openTextFile("vertex/vertex_shader_hello_triangle.glsl");FRAGMENT_SHADER = GLUtils::openTextFile("fragment/fragment_shader_hello_triangle.glsl");mProgram = GLUtils::createProgram(&VERTEX_SHADER, &FRAGMENT_SHADER);if (!mProgram) {LOGD("Could not create program")return;}// 设置清除颜色glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
}

改好了,我们重新编译运行下程序看看。

2021-12-12 13:12:42.874 30501-30501/com.oyp.openglesdemo D/NativeRenderActivity: onPause()
2021-12-12 13:12:45.117 30501-30501/com.oyp.openglesdemo D/NativeRenderActivity: onResume()
2021-12-12 13:12:45.177 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceCreated][189]: MyGLRenderContext::OnSurfaceCreated
2021-12-12 13:12:45.177 30501-30639/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][create][31]: NativeTriangle::create() 已经初始化过 直接return
2021-12-12 13:12:45.177 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 13:12:45.177 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 13:12:45.177 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()
2021-12-12 13:12:45.184 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 13:12:45.184 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 13:12:45.184 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()
2021-12-12 13:12:45.192 30501-30639/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()

好家伙,果然问题是在这。因为 mProgram 并不为空,然后不重新初始化 mProgram,这样在draw的时候,就出现了黑屏问题。

2.5 解决Native层的具体Render渲染问题

解决这个问题,我们之间把这个判断去掉,如下所示:

void NativeTriangle::create() {//    if(mProgram){//        LOGE("NativeTriangle::create() 已经初始化过 直接return")
//        return;
//    }GLUtils::printGLInfo();// Main ProgramVERTEX_SHADER = GLUtils::openTextFile("vertex/vertex_shader_hello_triangle.glsl");FRAGMENT_SHADER = GLUtils::openTextFile("fragment/fragment_shader_hello_triangle.glsl");mProgram = GLUtils::createProgram(&VERTEX_SHADER, &FRAGMENT_SHADER);if (!mProgram) {LOGD("Could not create program")return;}// 设置清除颜色glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
}

程序编译运行程序,验证一下。
这一次,息屏再亮屏就不会出现异常了。

运行的日志如下:

2021-12-12 13:17:09.299 31251-31251/com.oyp.openglesdemo D/NativeRenderActivity: onPause()
2021-12-12 13:17:11.314 31251-31251/com.oyp.openglesdemo D/NativeRenderActivity: onResume()
2021-12-12 13:17:11.377 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceCreated][189]: MyGLRenderContext::OnSurfaceCreated
2021-12-12 13:17:11.377 31251-31302/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 13:17:11.377 31251-31302/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 13:17:11.377 31251-31302/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\GLUtils.h][printGLString][52]: GL Vendor = Qualcomm
2021-12-12 13:17:11.377 31251-31302/com.oyp.openglesdemo I/NDK_JNI_LOG_TAG: [utils\GLUtils.h][printGLString][52]: GL Renderer = Adreno (TM) 640
2021-12-12 13:17:11.377 31251-31302/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 13:17:11.377 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][309]: [GLUtils::openTextFile] func start
2021-12-12 13:17:11.378 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][325]: [GLUtils::openTextFile] func cost time 1ms
2021-12-12 13:17:11.378 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][309]: [GLUtils::openTextFile] func start
2021-12-12 13:17:11.378 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][openTextFile][325]: [GLUtils::openTextFile] func cost time 0ms
2021-12-12 13:17:11.378 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][createProgram][141]: [GLUtils::createProgram] func start
2021-12-12 13:17:11.378 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][98]: [GLUtils::loadShader] func start
2021-12-12 13:17:11.378 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][loadShader][98]: [GLUtils::loadShader] func start
2021-12-12 13:17:11.379 31251-31302/com.oyp.openglesdemo E/NDK_JNI_LOG_TAG: [GLUtils.cpp][createProgram][192]: [GLUtils::createProgram] func cost time 1ms
2021-12-12 13:17:11.379 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 13:17:11.379 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 13:17:11.379 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()
2021-12-12 13:17:11.396 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [MyGLRenderContext.cpp][OnSurfaceChanged][206]: MyGLRenderContext::OnSurfaceChanged [w, h] = [1080, 2221]
2021-12-12 13:17:11.396 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [sample\GLBaseSample.h][change][27]: change() width = 1080 , height = 2221
2021-12-12 13:17:11.397 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()
2021-12-12 13:17:11.403 31251-31302/com.oyp.openglesdemo D/NDK_JNI_LOG_TAG: [NativeTriangle.cpp][draw][52]: NativeTriangle::draw()

至此,这个bug终于算解决了。

三、总结一下

  1. Activity 处于 pausedresumed状态时,必须通知GLSurfaceViewGLSurfaceView 客户端需要在Activity 处于paused 状态时调用onPause(),在Activity 处于resumed状态时调用onResume()。这些调用允许GLSurfaceView 暂停和恢复渲染线程,还允许GLSurfaceView 释放和重新创建OpenGL显示。
   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()}
  1. 在重写了ActivityonResume()onPause()方法,并在方法内调用了GLSurfaceViewonResume()onPause()的时候,当GLSurfaceViewRenderer 回调了 onSurfaceChanged的时候, onSurfaceChanged 方法调用的Native层方法一旦要重新初始Program,否则会导致息屏再亮屏之后黑屏,没有任何画面渲染出来。

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

  1. 原创 【我的OpenGL学习进阶之旅】介绍一下OpenGL ES的 遮挡查询

    目录 一.遮挡查询 1.1 开始和结束遮挡查询 1.2 创建和删除id 1.3 检索查询对象的结果 1.4 遮挡查询的步骤 1.5 例子 1.6 扩展阅读 一.遮挡查询 在一个场景中,如果有有些物体被 ...

  2. 【我的OpenGL学习进阶之旅】C++如何加载TGA文件?

    一.TGA文件相关介绍 通过前面的博客 [我的OpenGL学习进阶之旅]什么是TGA文件以及如何打开TGA文件? 地址:https://ouyangpeng.blog.csdn.net/article ...

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

    目录 一.相关书籍 OpenGL 方面 C方面 NDK 线性代数 二.相关博客 2.0 一些比较官方的链接 2.1 OpenGL着色器语言相关 2.2 [[yfan]](https://segment ...

  4. 【我的OpenGL学习进阶之旅】着色器和程序(上)------着色器

    着色器和程序 一.前言 二.着色器和程序 2.1 创建和编译一个着色器 2.1.1 创建着色器 2.1.2 删除着色器 2.1.3 提供着色器源代码 2.1.4 编译色器 2.1.4 查询有关着色器对 ...

  5. 【我的OpenGL学习进阶之旅】介绍一下 绘制图元

    目录 一.绘制图元 1.1 `glDrawArrays` 1.1.1 `glDrawArrays`API说明 1.1.2 `glDrawArrays`API示例 1.2 `glDrawElements ...

  6. 【我的OpenGL学习进阶之旅】OpenGL ES 3.0新功能

    目录 1.1 纹理 1.2 着色器 1.3 几何形状 1.4 缓冲区对象 1.5 帧缓冲区 OpenGL ES 2.0 开创了手持设备可编程着色器的时代,在驱动大量设备的游戏.应用程序和用户接口中获得 ...

  7. 【我的OpenGL学习进阶之旅】解决OpenGL绘制带透明通道的png纹理时出现黑边问题,并彻底了解其原理

    文章目录 一.问题描述 二.解决问题 2.1 解决效果 2.2 如何解决 三.知其然知其所以然 3.1 像素.抗锯齿的基本概念 3.2 alpha的两种类型,直通和预乘 3.3 直通和预乘的计算方式 ...

  8. 【我的OpenGL学习进阶之旅】关于OpenGL ES 开启深度测试,直接黑屏的问题的解决方法

    目录 一.问题描述 二.排查问题 2.1 怀疑createProgram链接着色器出了问题 2.2 怀疑是不是没有draw()? 2.3 对比以前写的可以正常显示的其他Demo代码 三.解决问题 3. ...

  9. 【我的OpenGL学习进阶之旅】解决使用VAO的时候误用glDisableVertexAttribArray导致无法渲染出现白屏或者黑屏的问题

    一.问题描述 今天将OpenGL项目运行到android真机的时候,发现一个简单的矩形居然白屏.然而在模拟器上是可以正常渲染的,如下所示: 模拟器正常渲染 真机白屏 二.分析问题 通过对比日志来分析: ...

最新文章

  1. 打印九九口诀表(15)
  2. Uedit32安装教程附安装包资源
  3. java中的类型转换
  4. centos7安装es mysql_Centos7 安装MySQL详细步骤
  5. python bool转string_Python:可以返回boolean和string吗?
  6. Django 模板系统2
  7. derby数据库操作比较难理解的错误及解决方法大全
  8. MyEclipse 10, 2013, 2014 破解、注册码
  9. java 抽象类的匿名类_Java匿名内部类(通过继承抽象类来实现)
  10. Json学习总结(5)——阿里巴巴开源库 Fastjson详解
  11. 评价目标检测区域的准确性——IoU
  12. python读取xml文件
  13. 建设城市(city)(【CCF】NOI Online 能力测试2 入门组第三题 )
  14. 用jsp代码完成购物车并且实现添加功能
  15. Ventoy+WePE 装机教程(装PVE+ESXI等,不用单独费一个U盘)
  16. 电驴让分享继续 服务器不稳定,电驴快快跑—分流教程
  17. Mac下查看公网以及内网IP地址
  18. jeecms导入myeclipse时web-inf下html出错,jeecms myeclipse
  19. python文章抄袭检测_用Python写了个检测文章抄袭,详谈去重算法原理
  20. NV21格式图像旋转 c++,平移、缩放实现代码

热门文章

  1. char*的vector数组pushback产生错误
  2. 一次装修合同引发的思考
  3. nginx 代理 redis 端口
  4. 记一次数据库中大量html和svg组成的json字符串 如何处理为数组
  5. 8k,4k,2k视频时序参数分享
  6. 根据实体类生成持久层、控制层、服务层、实现层
  7. Roson的Qt之旅#56 QTime用法
  8. 淘宝/天猫电商API接口详情
  9. .net开发微信公众号
  10. Failure to find was cached in the local repository