Warum blockiert GlClear in OpenGLES?

8

Ich versuche, meinen Renderer zu profilieren, und ich sehe ein seltsames Profiling-Verhalten, das ich nicht erklären kann.

Ich verwende eine glSurfaceView, die ich eingestellt habe, um kontinuierlich zu rendern.

So ist meine onDrawFrame() strukturiert

%Vor%

Dies hat sich langsam unter geringer Last verhalten, also habe ich eine Timer-Klasse erstellt und angefangen, diese zu profilieren. Ich war ziemlich überrascht von dem, was ich gesehen habe.

Ich habe ein paar Sonden auf meine onDrawFrame-Methode gesetzt:

%Vor%

clearTimer misst die Zeit, die zum Aufrufen von glClear benötigt wird, drawTimer misst die Zeit, die benötigt wird, um alle meine Zeichenaufrufe auszuführen, und swapTimer misst die Zeit ab wann onDrawFrame beendet wird und wann es zurückkehrt (die Zeit bis rufe eglSwapBuffers auf.

Wenn ich eine sehr leicht geladene Szene lief, bekam ich einige wirklich seltsame Zahlen, die ich nicht erklären kann:

%Vor%

Ich habe erwartet, dass die Swap-Zeit etwas größer ist, da ich glaube, dass das Gerät vsync forced bei ~ 30 fps aktiviert hat, obwohl ich nicht weiß, warum der eigentliche "Clear" -Aufruf für 11 Millisekunden blockiert? Ich dachte, es sollte nur einen asynchronen Befehl ausgeben und zurückgeben?

Wenn ich eine viel beschäftigtere Szene zeichne, ändern sich die Zahlen ziemlich:

%Vor%

In dieser Szene nehmen meine Draw-Aufrufe so viel Zeit in Anspruch, dass es aussieht, als ob sie einen Großteil der vsync-Periode verdeckt, und die Blockierung des Clear-Calls verschwindet vollständig.

Gibt es eine Erklärung dafür, warum glClear in meiner leicht belasteten Szene blockiert?

Link zu meinem 'Timer' Klassenquellcode für den Fall, dass jemand meine Messtechnik misstraut: Ссылка

    
Tim 01.09.2012, 01:38
quelle

1 Antwort

10
  

Ich setze ein glFinish (und finishTimer.start () / end () um es herum), und es dauert die ganze Zeit weg von glClear. Stattdessen benötigt glFinish nun einige Millisekunden und glClear wird sofort.

Das erklärt es.

Wenn Ihre Szene sehr hell ist und die Zeichnungen sehr schnell gerendert werden, wird die Zeit zum Löschen und Füllen der Pixel mit der neuen Farbe einige Zeit dauern (es wird immer Zeit brauchen, da der Renderer sonst neu gezeichnet wird) Sachen). Die neueren Android-Geräte haben Füllgrenzen. Zum Beispiel hat Nexus One eine Füllstandssperre bei 30 Hz - der Bildschirm wird bei dieser Frequenz synchronisiert, egal wie schnell Ihre tatsächlichen Zeichnungen sind. Wenn die Zeichnungen unter 30 Hz enden, wird der Renderer mit dem Bildschirm synchronisiert. Aus diesem Grund bemerken Sie diese Verzögerung, die Sie bemerken sollten, auch wenn Sie den glClear() -Aufruf entfernen. Der Renderer ist vor und schneller als die Bildschirmaktualisierungen.

Wenn der Renderer viele zu zeichnende Objekte hat, wird die Synchronisierung angehalten (angesichts der Profildaten Ihrer ausgelasteten Szene), da der Renderer jetzt nach den Aktualisierungen des Bildschirms ist.

Wenn Sie glFinish() verwenden, wird die Zeit entfernt, die die glClear() -Funktion sonst verursachen würde. Durch Befolgen der Füllratenlogik bedeutet dies, dass glFinish() jetzt die Funktion ist, die die Synchronisierung mit dem Bildschirm gewährleistet.

Berechnungen :

F = 1 / T

Einfache Szene :

F = 1 / T = 1 / ((20 + 11 + 2) * 10 ^ -3) = ~ 30 Hz

Die Verzögerungszeit der Synchronisierung wird in Ihrem Profiler angezeigt. Der Renderer wird mit dem Bildschirm synchronisiert. Das heißt, wenn Sie den Aufruf glClear() oder glFinish() entfernen, erscheint die Verzögerung an anderer Stelle.

Schwere Szene :

F = 1 / T = 1 / ((2 + 0 + 44) * 10 ^ -3)) = ~ 22 Hz

Die Verzögerungszeit der Synchronisierung wird nicht in Ihrem Profiler angezeigt. Renderer ist nach der Aktualisierungsfrequenz des Bildschirms.

  

Es scheint, dass dies alles mit vsync zusammenhängt.

Das scheint richtig zu sein.

    
Wroclai 02.09.2012, 12:51
quelle