Повторные кадры на Android Mali-400

На устройствах Android с графическим процессором Mali-400 (Samsung Galaxy S II, Samsung Galaxy S3 Mini, Samsung Galaxy Note II) в случайное время на экране будут появляться повторяющиеся кадры.

Пример с 0:51 до 1:01 на следующем видео https://www.youtube.com/watch?v=5-p6Oy0BZmg

Кажется, что новые кадры не отображаются, и то, что было в старом буфере, показывается снова. Игра продолжает продвигаться за повторяющимися кадрами.

Это не происходит на других графических процессорах.

Я читал об использовании glFlush или glFinish, но GLSurfaceView заботится об этом при выполнении eglSwapBuffers после onDrawFrame.

Я читал о причудах 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 из него. Затем перезаписать задний буфер обычным игровым образом.

У меня нет идей о том, как атаковать эту проблему.

РЕДАКТИРОВАТЬ

Следуя совету Муззы, я начал регистрировать ошибки 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

1 ответ

Решение

Это может произойти, если состояние OpenGL каким-то образом станет недействительным. Графические драйверы могут просто пропустить кадры полностью. Проверьте Logcat, чтобы увидеть, есть ли какие-либо выходные данные от драйверов, и добавьте вызовы glGetError() по всему коду, чтобы увидеть, появляется ли какая-либо ошибка там.

Другие вопросы по тегам