0

Mali-400 GPU を搭載した Android デバイス (Samsung Galaxy S II、Samsung Galaxy S3 Mini、Samsung Galaxy Note II) では、ランダムなタイミングで画面に繰り返しフレームが表示され始めます。

次のビデオの 0:51 から 1:01 までの例https://www.youtube.com/watch?v=5-p6Oy0BZmg

新しいフレームがレンダリングされていないようで、古いバッファにあったものが再び表示されています。ゲームは繰り返されるフレームの後ろで進行し続けます。

これは、他の 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
4

1 に答える 1

0

これは、OpenGL の状態が何らかの方法で無効になった場合に発生する可能性があります。グラフィックス ドライバーは、フレームを完全にスキップすることができます。Logcat をチェックしてドライバーからの出力があるかどうかを確認し、コード全体に glGetError() 呼び出しを追加して、エラーが発生するかどうかを確認します。

于 2016-01-19T01:13:05.913 に答える