部分设备调用glDrawTexiOES抛出INVALID_OPERATION异常问题排查
问题描述
在动态壁纸开发中使用glDrawTexiOES接口,每秒通过纹理绘制一张位图,99.9%的设备运行正常,但部分设备会抛出INVALID_OPERATION异常:
- 无法复现该异常,仅在宽高为负数或零值时能触发
INVALID_VALUE异常 - 尝试过禁用纹理、将活动纹理设置为1等操作,甚至注释所有代码后,该接口仍能正常运行无异常
异常日志
Exception android.opengl.GLException: invalid operation at android.opengl.GLErrorWrapper.checkError (GLErrorWrapper.java:62) at android.opengl.GLErrorWrapper.glDrawTexiOES (GLErrorWrapper.java:894) at com.example.WallpaperServiceGL$EngineGl$RendererMy.onDrawFrame (WallpaperServiceGL.java:270) at android.opengl.GLSurfaceView$GLThread.guardedRun (GLSurfaceView.java:1581) at android.opengl.GLSurfaceView$GLThread.run (GLSurfaceView.java:1280) backtrace: #00 pc 0x00000000007080f4 /vendor/lib64/egl/mt6789/libGLES_mali.so #01 pc 0x000000000076a924 /vendor/lib64/egl/mt6789/libGLES_mali.so #02 pc 0x0000000000707be0 /vendor/lib64/egl/mt6789/libGLES_mali.so #03 pc 0x000000000076bbb4 /vendor/lib64/egl/mt6789/libGLES_mali.so #04 pc 0x000000000038c3c0 /data/misc/apexdata/com.android.art/dalvik-cache/arm64/boot.oat (art_jni_trampoline+112) #05 pc 0x00000000007815f4 /apex/com.android.art/lib64/libart.so (nterp_helper+11140) #06 pc 0x000000000045e8ac /system/framework/framework.jar (android.opengl.GLErrorWrapper.glDrawTexiOES+20) #07 pc 0x00000000020059f8 /memfd:jit-cache (t1.e0.onDrawFrame+1640) #08 pc 0x0000000000780890 /apex/com.android.art/lib64/libart.so (nterp_helper+7712) #09 pc 0x000000000046955e /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.guardedRun+2034) #10 pc 0x000000000077f9c4 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) #11 pc 0x000000000046a00a /system/framework/framework.jar (android.opengl.GLSurfaceView$GLThread.run+122) #12 pc 0x000000000036db74 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) #13 pc 0x0000000000359324 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+132) #14 pc 0x0000000000944438 /apex/com.android.art/lib64/libart.so (art::detail::ShortyTraits<(char)86>::Type art::ArtMethod::InvokeInstance<(char)86>(art::Thread*, art::ObjPtr<art::mirror::Object>, art::detail::ShortyTraits<>::Type...)+60) #15 pc 0x00000000006209f4 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1344) #16 pc 0x00000000006204a4 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallbackWithUffdGc(void*)+8) #17 pc 0x00000000000fbacc /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+204) #18 pc 0x000000000008e670 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
排查思路
- 针对MTK Mali GPU特性排查:从堆栈看异常出现在联发科Mali GPU的驱动库中,这类GPU对GL状态要求更严格:
- 调用
glDrawTexiOES前,确认当前绑定的纹理ID有效,且glTexImage2D已执行完成,纹理加载无遗漏 - 验证位图尺寸和格式:确保尺寸是2的幂次,或开启
GL_TEXTURE_NPOT扩展;检查像素格式是否为GPU支持的标准格式(如RGBA8888)
- 调用
- 检查GL上下文与状态:
- 确认调用
glDrawTexiOES时,GL上下文处于激活状态,避免在上下文销毁/重建的间隙执行绘制 - 检查默认纹理环境设置:
glDrawTexiOES依赖默认纹理环境,确认glTexEnvf配置正确,无冲突的着色器程序干扰
- 确认调用
- 添加详细错误日志:
- 在
glDrawTexiOES前后调用glGetError(),记录所有GL错误码,排查是否是之前操作遗留的错误导致后续异常 - 收集异常设备的系统版本、GPU型号、屏幕分辨率等信息,对比正常设备找出差异点
- 在
- 替代方案验证:
- 用
glDrawArrays绘制纹理四边形替代glDrawTexiOES,排除该接口本身的兼容性问题 - 降低纹理更新频率(比如每2秒更新一次),测试是否是高频更新导致的资源阻塞
- 用
- 检查动态壁纸生命周期:
- 动态壁纸在后台、锁屏状态下,GLSurfaceView的上下文可能被暂停或重建,确保
onSurfaceCreated、onSurfaceChanged中正确重新初始化纹理和GL状态
- 动态壁纸在后台、锁屏状态下,GLSurfaceView的上下文可能被暂停或重建,确保
内容的提问来源于stack exchange,提问作者Style-7
相关产品推荐
相关产品推荐

