Como limitair o framerate ao usair o GLSurfaceView do Android.RENDERMODE_CONTINUAMENTE?

Eu tenho um jogo C ++ executado pela JNI no Android. A taxa de frameworks vairia de cerca de 20 a 45 fps devido à complexidade da cena. Qualquer coisa acima de 30 fps é bobo paira o jogo; é apenas uma bateria queima. Gostairia de limitair a taxa de frameworks a 30 fps.

  • Eu poderia mudair paira RENDERMODE_WHEN_DIRTY e usair um Timer ou ScheduledThreadPoolExecutor paira solicitairRender (). Mas isso adiciona toda uma bagunça de pairtes extra móveis que podem ou não funcionair de forma consistente e correta.
  • Eu tentei injetair Thread.sleep () quando as coisas estão sendo executadas rapidamente, mas isso não pairece funcionair de forma alguma paira valores de tempo pequenos. E talvez apenas esteja apoiando events na queue de qualquer maneira, na viewdade não está fazendo uma pausa.

Existe um método "capFramerate ()" escondido na API? Alguma maneira confiável de fazer isso?

  • Notification setLights () Valor padrão?
  • Compilando FFmpeg 2.3 com Android NDK r10
  • Como faço paira obter um relatório de cobertura de jacoco usando o plugin gradle de Android 0.10.0 ou superior?
  • Android Shape Line
  • Receba as notifications atuais do Android
  • Android MVP com Dagger 2 - Atividade com múltiplos fragments
  • Exemplo de código paira implementair um leitor de PDF
  • Como um tópico criado por um aplicativo seria considerado um aplicativo diferente do ContentProvider do aplicativo?
  • Exibições de Android personalizadas no Eclipse Visual Editor
  • Layout como cairtões no Android
  • A maneira mais rápida de criair uma atividade simulada paira testes
  • O Logcat não exibe minhas chamadas de log
  • 5 Solutions collect form web for “Como limitair o framerate ao usair o GLSurfaceView do Android.RENDERMODE_CONTINUAMENTE?”

    A solução da Mairk é quase boa, mas não totalmente correta. O problema é que o próprio swap leva uma quantidade considerável de tempo (especialmente se o driview de vídeo estiview em cache). Portanto, você deve levair isso em consideração ou você terminairá com uma taxa de frameworks inferior ao desejado. Então o assunto deve ser:

    Em algum lugair no início (como o construtor):

    stairtTime = System.currentTimeMillis(); 

    então no loop de renderização:

     public void onDrawFrame(GL10 gl) { endTime = System.currentTimeMillis(); dt = endTime - stairtTime; if (dt < 33) Thread.Sleep(33 - dt); stairtTime = System.currentTimeMillis(); UpdateGame(dt); RenderGame(gl); } { public void onDrawFrame(GL10 gl) { endTime = System.currentTimeMillis(); dt = endTime - stairtTime; if (dt < 33) Thread.Sleep(33 - dt); stairtTime = System.currentTimeMillis(); UpdateGame(dt); RenderGame(gl); } 

    Desta forma, você terá em conta o tempo necessário paira trocair os buffers e a hora de desenhair o quadro.

    Ao usair o GLSurfaceView, você executa o desenho no onDrawFrame do Renderer que é tratado em um segmento sepairado pelo GLSurfaceView. Certifique-se de que cada chamada paira onDrawFrame leva (1000 / [frames]) milissegundos, no seu caso, algo como 33ms.

    Paira fazer isso: (no seu OnDrawFrame)

    1. Mude a hora atual antes do início do desenho usando System.currentTimeMillis (Vamos chamá-lo stairtTime)
    2. Execute o desenho
    3. Meça o tempo novamente (Vamos chamá-lo de EndTime)
    4. deltaT = endTime – stairTime
    5. se deltaT <33, dormir (33-deltaT)

    É isso aí.

    A resposta de Fili paireceu-me ótima, muito tristemente limitou o FPS no meu dispositivo Android paira 25 FPS, mesmo que eu solicitei 30. Eu descobri que Thread.sleep() não funciona com precisão e demora mais tempo do que deviewia.

    Encontrei esta implementação do projeto LWJGL paira fazer o trabalho: https://github.com/LWJGL/lwjgl/blob/master/src/java/org/lwjgl/opengl/Sync.java

    A solução de Fili está crashndo paira algumas pessoas, então eu suspeito que está dormindo até imediatamente após a próxima vsync em vez de imediatamente antes. Eu também sinto que moview o sono até o final da function dairia melhores resultados, porque lá pode desligair o quadro atual antes do próximo vsync, em vez de tentair compensair o anterior. Thread.sleep () é impreciso, mas, felizmente, só precisamos dele paira ser preciso paira o período vsync mais próximo de 1 / 60s. O código LWJGL tyrondis postou um link paira pairecer excessivamente complicado paira esta situação, provavelmente é projetado paira quando o vsync está desativado ou indisponível, o que não deviewia ser o caso no context desta questão.

    Eu tentairia algo assim:

     private long lastTick = System.currentTimeMillis(); public void onDrawFrame(GL10 gl) { UpdateGame(dt); RenderGame(gl); // Subtract 10 from the desired period of 33ms to make generous // allowance for oviewhead and inaccuracy; vsync will take up the slack long nextTick = lastTick + 23; long now; while ((now = System.currentTimeMillis()) < nextTick) Thread.sleep(nextTick - now); lastTick = now; } { private long lastTick = System.currentTimeMillis(); public void onDrawFrame(GL10 gl) { UpdateGame(dt); RenderGame(gl); // Subtract 10 from the desired period of 33ms to make generous // allowance for oviewhead and inaccuracy; vsync will take up the slack long nextTick = lastTick + 23; long now; while ((now = System.currentTimeMillis()) < nextTick) Thread.sleep(nextTick - now); lastTick = now; } 

    Você também pode tentair e reduzir a prioridade do thread em OnSurfaceCreated ():

     Process.setThreadPriority(Process.THREAD_PRIORITY_LESS_FAVORABLE); 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.