【问题标题】:Repeated frames on Android Mali-400Android Mali-400 上的重复帧
【发布时间】:2016-04-24 07:17:12
【问题描述】:

在配备 Mali-400 GPU 的 Android 设备(Samsung Galaxy S II、Samsung Galaxy S3 Mini、Samsung Galaxy Note II)上,屏幕会随机开始显示重复帧。

以下视频https://www.youtube.com/watch?v=5-p6Oy0BZmg0:51 至 1:01 的示例

似乎新帧没有被渲染,而旧缓冲区中的内容又被显示出来了。游戏在重复的帧后面继续前进。

这在其他 GPU 上不会发生。

我读过关于使用 glFlush 或 glFinish 的文章,但 GLSurfaceView 在 onDrawFrame 之后执行 eglSwapBuffers 时会处理这个问题。

我读过关于 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

【问题讨论】:

  • 除非您退出应用程序或旋转屏幕,否则丢失 EGLContext 很奇怪。请查看setPreserveEGLContextOnPause 以获得一种可能的解决方案。
  • 谢谢!我们正在处理应用退出时的上下文,我们的应用也不允许屏幕旋转。我认为问题是GPU内存不足。在显示大量模型的场景中会发生此错误。我会尝试优化这些场景:)

标签: android opengl-es opengl-es-2.0 gpu mali


【解决方案1】:

如果 OpenGL 状态以某种方式变得无效,就会发生这种情况。图形驱动程序可以完全跳过帧。检查 Logcat 以查看驱动程序是否有任何输出,并在整个代码中添加 glGetError() 调用以查看是否出现任何错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    相关资源
    最近更新 更多