Was sind die Ursachen schwank mal die Ausführung, wenn die Renderbuffer zu präsentieren? (OpenGL)

StackOverflow https://stackoverflow.com/questions/677211

  •  21-08-2019
  •  | 
  •  

Frage

Dies ist, was passiert:

  • Die drawGL Funktion wird genau an dem Ende des Rahmens dank eine usleep genannt, wie vorgeschlagen. Dies hält bereits eine stetige Framerate.

  • Die eigentliche Präsentation des renderbuffer erfolgt mit drawGL(). Messen der Zeit, dies zu tun nimmt, gibt mir schwankAusführungsZeiten, was zu einem Stottern in meiner Animation. Dieser Timer verwendet mach_absolute_time so es ist extrem genau .

  • Am Ende meines Rahmens, ich messe timeDifference. Ja, es ist durchschnittlich 1 Millisekunde, aber weicht viel , im Bereich von 0,8 Millisekunden bis 1,2 mit Spitzenwerten von bis zu mehr als 2 Millisekunden.

Beispiel:

// Every something of a second I call tick
-(void)tick
{
  drawGL(); 
}

- (void)drawGL
{   
  // startTime using mach_absolute_time;

  glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
  [context presentRenderbuffer:GL_RENDERBUFFER_OES];

 // endTime using mach_absolute_time;
 // timeDifference = endTime - startTime;
}
immer den gleichen Aufwand, unabhängig von der Komplexität des Rahmens

Mein Verständnis ist, dass, sobald der Framebuffer erstellt wurde, sollte die renderbuffer zu präsentieren? Ist das wahr? Und wenn nicht, wie kann ich das verhindern?

By the way, ist dies ein Beispiel für ein iPhone App. So sprechen wir OpenGL ES hier, obwohl ich nicht glaube, es ist eine Plattform-spezifisches Problem. Wenn es ist, als das, was ist hier los? Und sollte dies nicht sein nicht passiert? Und wieder, wenn ja, wie kann ich das verhindern?

War es hilfreich?

Lösung

Die Abweichungen Sie vielleicht durch viele Faktoren verursacht werden begegnen, einschließlich OS Scheduler, der anspringt und gibt CPU an einen anderen Prozess oder ähnliche Probleme. In der Tat wird die normale Mensch sagt kein Unterschied zwischen 1 und 2 ms mal machen. Bewegen Bilder laufen bei 25 fps, die jeden Rahmen Mittel für etwa 40 ms gezeigt und es sieht Flüssigkeit für menschliches Auge.

Wie für die Animation Stottern Sie sollten prüfen, wie Sie ständig Animationsgeschwindigkeit beizubehalten. Die häufigsten Ansatz, den ich gesehen habe etwa wie folgt aussieht:

while(loop)
{
  lastFrameTime; // time it took for last frame to render
  timeSinceLastUpdate+= lastFrameTime;

  if(timeSinceLastUpdate > (1 second / DESIRED_UPDATES_PER_SECOND))
  {
     updateAnimation(timeSinceLastUpdate);
     timeSinceLastUpdate = 0;
  }

  // do the drawing

  presentScene();
}

Oder Sie könnten nur lastFrameTime passieren jeden Rahmen und interpolieren zwischen Animation Staaten updateAnimation. Das Ergebnis wird noch mehr Flüssigkeit.

Wenn Sie bereits so etwas wie die oben verwenden, sollten Sie vielleicht nach Schuldigen suchen in anderen Teilen der Schleife machen. In Direct3D waren die Kostbarkeiten Anrufe für Primitive zeichnen und Zustände zu ändern machen, so dass Sie möglicherweise um OpenGL-Analoga von denen überprüft werden soll.

Andere Tipps

Meine Lieblinge OpenGL Ausdruck aller Zeiten: "Implementierung spezifische" . Ich denke, es ist hier sehr gut gilt.

Eine schnelle Suche nach mach_absolute_time Ergebnissen in diesem Artikel: Link-

Sieht aus wie Genauigkeit dieser Timer auf einem iPhone ist nur 166,67 ns (und vielleicht noch schlimmer). Während das den großen Unterschied erklären kann, ist es nicht erklären, dass es ein Unterschied überhaupt.

Die drei wichtigsten Gründe dafür sind wahrscheinlich:

  • verschiedene Ausführungspfade während renderbuffer Präsentation. Vieles kann in 1ms passieren und nur weil man die gleichen Funktionen mit den gleichen Parametern aufrufen bedeutet nicht exakt die gleichen Befehle ausgeführt werden. Dies gilt insbesondere, wenn andere Hardware beteiligt ist.
  • Interrupts / andere Prozesse, gibt es immer etwas anderes los, dass die CPU ablenkt. Soweit ich das iPhone O weiß, ist kein Echtzeitbetriebssystem und so gibt es keine Garantie, dass jede Operation innerhalb einer bestimmten Frist (und sogar ein Echtzeitbetriebssystem Zeitvariationen hat) abgeschlossen wird.
  • Wenn es andere OpenGL-Anrufe noch von der GPU verarbeitet werden, die presentRenderbuffer verzögern könnte. Das ist am einfachsten zu testen, rufen Sie einfach glFinish () vor der Startzeit zu bekommen.

Am besten ist es nicht für eine Reihe von Gründen auf einer hohe konstanten Framerate zu verlassen, das wichtigste ist, dass das Betriebssystem etwas im Hintergrund tun kann, die Dinge verlangsamt. Besser einen Timer zu probieren und herausfinden, wie viel Zeit jeder Frame bestanden hat, sollte dies glatte Animation gewährleisten.

Ist es möglich, dass der Timer auf die Unter ms nicht genau gerade ist und obwohl es Dezimalzahlen 0,8-> 2.0?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top