在配备Mali-400 GPU(三星Galaxy S II,三星Galaxy S3 Mini,三星Galaxy Note II)的Android设备上,随机时间屏幕将开始显示重复帧。
以下视频https://www.youtube.com/watch?v=5-p6Oy0BZmg
中0:51至1:01的示例似乎没有渲染新帧,并且旧缓冲区中的内容再次显示。游戏继续在重复帧后面前进。
其他GPU上不会发生这种情况。
我读过关于使用glFlush或glFinish的内容,但是在onDrawFrame之后执行eglSwapBuffers时,GLSurfaceView会处理这个问题。
我读过关于Mali-400的怪癖,比如使用不同的纹理坐标或使用lowp更好,但它没有帮助。以下是着色器供参考:
顶点着色器:
// Vertex Shader
attribute vec4 position;
attribute vec4 colorModelIn;
attribute vec4 colorVertexIn;
varying lowp vec4 colorOut;
uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelMatrix;
attribute vec2 TexCoordIn;
varying lowp vec2 TexCoordOut;
uniform bool bUseVertexColor;
void main()
{
if( bUseVertexColor ){
colorOut = colorVertexIn * colorModelIn;
} else {
colorOut = colorModelIn;
}
TexCoordOut = TexCoordIn;
gl_Position = modelViewProjectionMatrix * modelMatrix * position;
}
片段着色器:
// Fragment shader
varying lowp vec4 colorOut;
varying lowp vec2 TexCoordOut;
uniform sampler2D Texture;
uniform bool bUseTexture;
void main()
{
if( bUseTexture ){
gl_FragColor = colorOut * texture2D(Texture, TexCoordOut);
} else {
gl_FragColor = colorOut;
}
}
我知道这些着色器不是最佳的,而且我正在沿着复制固定管道的道路前进。
渲染在一段时间后或触摸屏幕后恢复正常。我能够想到在触摸时恢复正常的唯一原因是我使用颜色编码来检测被触摸的物体。我将图像渲染到后台缓冲区并从中渲染glReadPixels。然后,用正常的游戏图像覆盖后台缓冲区。
我没有关于如何解决这个问题的想法。
修改
按照Muzza的建议后,我开始记录GL错误。 glGetInteger和glBindBuffer报告内存不足。
上面我说过一段时间后问题就解决了。当发生这种情况时,它们会出现在日志中:
01-23 21:57:52.956: D/WebView(9860): onSizeChanged - w:480 h:75
01-23 21:57:53.126: D/TilesManager(9860): new EGLContext from framework: 40e00bd0
01-23 21:57:53.126: D/GLWebViewState(9860): Reinit shader
01-23 21:57:53.171: D/GLWebViewState(9860): Reinit transferQueue
答案 0 :(得分:0)
如果OpenGL状态在某种程度上变得无效,就会发生这种情况。图形驱动程序可以完全跳过帧。检查Logcat以查看驱动程序是否有任何输出,并在整个代码中添加glGetError()调用以查看是否出现任何错误。