Android: понимание OnDrawFrame, FPS и VSync (OpenGL ES 2.0)

Некоторое время назад я испытывал периодическое «заикание» спрайтов, которые находятся в движении в моей игре для Android. Это очень простая 2D игра OpenGL ES 2.0. (Это постоянная проблема, которую я неоднократно посещал).

В моем игровом цикле у меня есть 2 «таймера» - один, который будет регистрировать количество кадров в предыдущую секунду, а другой подсчитывает время (в миллисекундах) от конца текущей итерации onDrawFrame до начала следующей.

Вот что я нашел:

Когда ничего не рендерится, я получаю 60 кадров в секунду (по большей части), и каждый раз, когда вызывается onDrawFrame, он сообщает, что он занимает больше, чем 16,667 мс. Теперь, если я что-то визуализирую (неважно, если это 1 квад или 100 квадратов, результат тот же), я получаю 60 кадров в секунду (по большей части), но сейчас только около 20% вызовов onDrawFrame сообщают, что они занимают больше времени чем 16.667ms с последнего звонка.

Я не очень понимаю, почему это происходит, во-первых, почему, когда onDrawFrame ничего не делает, он вызывается так «медленно» - и, что более важно, почему любой вызов GL (один простой квад) все еще делает время между onDrawFrame вызывает больше чем 16.667ms (хотя и намного реже).

Я должен сказать, что когда отчеты onDrawFrame занимают более 16.667 мс от последней итерации, это почти всегда сопровождается падением FPS (до 58 или 59), но не всегда, иногда, FPS остается постоянным. И наоборот, иногда, когда FPS падает, onDrawFrame вызывается в течение 16.667ms после завершения последней итерации.

Так......

Я пытаюсь исправить свой игровой цикл и устранить эти «заикания» - некоторые другие вещи, на которые следует обратить внимание:

Когда я делаю метод профилирования, он показывает glSwapBuffers, иногда занимает много времениКогда я делаю трассировку GL, большинство сцен, как говорят, отрисовывается менее чем за 1 мс, но иногда нечетный кадр занимает 3,5-4 мс - та же сцена. Ничего не меняется, кроме времени, которое требуетсяПочти каждый раз, когда кадр сбрасывается или onDrawFrame сообщает о большой задержке (или обоих), визуальный сбой возникает, но не каждый раз. Большие визуальные глюки, кажется, совпадают с несколькими «задержанными» вызовами onDrawFrame и / или пропущенными кадрами.Я не думаю, что это проблема сложности сцены по двум причинам: 1) даже если я отрисовываю свою сцену дважды, это не усугубляет проблему, я все еще по большей части получаю 60FPS со случайным падением, просто как и прежде, и 2), даже если я раздену сцену, я все равно получаю проблему.

Я, очевидно, что-то неправильно понимаю, поэтому толчок в правильном направлении был бы оценен.

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();        
}

Этот игровой цикл, представленный вышестатья.

Ответы на вопрос(1)

Ваш ответ на вопрос