Android: comprensión de OnDrawFrame, FPS y VSync (OpenGL ES 2.0)

Durante un tiempo, he experimentado un "tartamudeo" intermitente de los sprites que están en movimiento dentro de mi juego de Android. Es un juego 2D OpenGL ES 2.0 muy simple. (Este es un problema continuo que he visitado muchas veces).

En mi ciclo de juego, tengo 2 'temporizadores', uno que registrará el número de fotogramas en el segundo anterior y otro que cuenta el tiempo (en milisegundos) desde el final de la iteración actual de onDrawFrame hasta el comienzo del siguiente.

Esto es lo que he encontrado:

Cuando no renderizo nada, obtengo 60 fps (en su mayor parte), y cada vez que se llama onDrawFrame, se informa que tarda más de 16.667 ms. Ahora, si renderizo algo (no importa si es 1 quad o 100 quads, el resultado es el mismo), obtengo 60 fps (en su mayor parte) pero ahora, solo alrededor del 20% de las llamadas de onDrawFrame se reportan a sí mismas como que demoran más de 16.667 ms desde la última llamada.

Realmente no entiendo por qué sucede esto, en primer lugar, por qué, cuando onDrawFrame no está haciendo nada, se llama tan 'lentamente', y lo que es más importante, ¿por qué una llamada GL (un quad simple), todavía hace el tiempo entre onDrawFrame llama a más de 16.667 ms (aunque con mucha menos frecuencia).

Debo decir que cuando onDrawFrame informa que tarda más de 16.667 ms desde la última iteración, casi siempre va acompañado de una caída en FPS (a 58 o 59), pero no todo el tiempo, a veces, el FPS se mantiene constante. Y a la inversa, a veces, cuando cae el FPS, se llama a onDrawFrame dentro de los 16.667 ms de la última iteración completada.

Entonces......

Estoy tratando de arreglar mi ciclo de juego y erradicar estos 'tartamudeos', algunas otras cosas a tener en cuenta:

Cuando hago perfiles de métodos, muestra glSwapBuffers, a veces toma mucho tiempoCuando hago un seguimiento de GL, la mayoría de las escenas dicen que se procesan en menos de 1 ms, pero a veces el fotograma extraño tarda 3,5-4 ms, la misma escena. Nada cambia aparte del tiempo que llevaCasi cada vez que se cae un cuadro, o enDrawFrame informa un retraso prolongado (o ambos), hay una falla visual, pero no siempre. Las grandes fallas visuales parecen coincidir con múltiples llamadas 'retrasadas' en llamadas DraftFrame y / o cuadros descartados.No creo que este sea un problema de complejidad de la escena por 2 razones: 1) incluso si renderizo mi escena dos veces, no empeora el problema, todavía en su mayor parte, obtengo 60 FPS con la caída ocasional, solo como antes y 2), incluso si desnudo la escena, sigo teniendo el problema.

Obviamente estoy malinterpretando algo, por lo que agradecería un impulso en la dirección correcta.

OnDrawFrame

@Override
public void onDrawFrame(GL10 gl) {

    startTime = System.nanoTime();        
    fps++;                        
    totalTime = System.nanoTime() - timeSinceLastCalled;    

    if (totalTime > 16667000) {     
        Log.v("Logging","Time between onDrawFrame calls: " + (totalTime /(double)1000000));
    }

    //Grab time
    newTime = System.currentTimeMillis() * 0.001;
    frameTime = newTime - currentTime; //Time the last frame took

    if (frameTime > 0.25)
        frameTime = 0.25;

    currentTime = newTime;
    accumulator += frameTime;

    while (accumulator >= dt){              
      saveGameState();
      updateLogic();
      accumulator -= dt;
    }

    interpolation = (float) (accumulator / dt);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

    render(interpolation);

    if (startTime > lastSecond + 1000000000) {          
        lastSecond = startTime;
        Log.v("Logging","fps: "+fps);
        fps=0;          
    }

    endTime = startTime;
    timeSinceLastCalled = System.nanoTime();        
}

Este bucle de juego anterior es el que aparece en este excelenteartículo.

Respuestas a la pregunta(1)

Su respuesta a la pregunta