10

Ich versuche, ein besseres Verständnis der Android-Display-Subsystem zu bekommen, aber ein Element, das immer noch verwirrend für mich ist, wie VSYNC-Signale behandelt werden, und warum so viele existieren an erster Stelle.Verständnis der Notwendigkeit von Android VSYNC Signalen

Android wurde entwickelt, um VSYNC im Kern zu verwenden, aber es gibt mehrere VSYNC-Signale, die es verwendet. Über https://source.android.com/devices/graphics/implement.html im Abschnitt "VSYNC Offset" gibt es ein Flussdiagramm, das drei VSYNC-Signale darstellt: HW_VSYNC_0, VSYNC und SF-VSYNC. Ich verstehe, dass HW_VSYNC verwendet wird, um das Timing in DispSync zu aktualisieren, und dass VSYNC und SF-VSYNC von den Apps und SurfaceFlinger verwendet werden, aber warum sind diese individuellen Signale überhaupt notwendig? Wie wirken sich die Offsets auf diese Signale aus? Gibt es irgendwo ein Timing-Diagramm, das das besser erklärt?

Danke für jede Hilfe, die Sie anbieten können.

Antwort

21

dieses Zeug zu verstehen, es ist am besten mit dem System-Level Graphics Architecture Dokument zu starten, insbesondere zur Kenntnis Die Notwendigkeit für Triple-Buffering Abschnitt und dem zugehörigen Diagramm (die idealerweise ein animiertes GIF wäre) nehmen. Der Satz, der beginnt, "Wenn die App beginnt, auf halbem Wege zwischen VSYNC-Signalen zu rendern", spricht speziell über DispSync. Sobald Sie das gelesen haben, macht der DispSync-Abschnitt des Gerätegrafik-Dokuments hoffentlich mehr Sinn.

Bei den meisten Geräten sind keine DispSync-Offsets konfiguriert, es gibt also nur ein VSYNC-Signal. Im Folgenden gehe ich davon aus, dass DispSync aktiviert ist.

Die Hardware stellt nur ein VSYNC-Signal zur Verfügung, das der primären Anzeigeaktualisierung entspricht. Die anderen werden in Software durch den SurfaceFlinger DispSync-Code generiert und mit festen Offsets vom tatsächlichen VSYNC ausgelöst. Mit etwas cleverer Software wird verhindert, dass die Zeiten aus der Phase geraten.

Die Signale werden zum Auslösen der SurfaceFlinger-Komposition und des App-Renderings verwendet. Wenn Sie dem Abschnitt im Architekturdokument folgen, können Sie feststellen, dass zwischen dem Zeitpunkt, zu dem die App ihren Inhalt rendert, und dem Zeitpunkt, zu dem der Inhalt auf dem Bildschirm angezeigt wird, zwei Latenzzeiten festgelegt werden. Stellen Sie sich das so vor: Bei drei Vorkommen von VSYNC zeichnet die App bei V0, das System erstellt die Komposition bei V1, und der zusammengesetzte Rahmen wird zur Anzeige bei V2 gesendet.

Wenn Sie versuchen, die Berührungseingabe zu verfolgen, indem Sie möglicherweise eine Karte unter dem Finger des Benutzers bewegen, wird die Latenz vom Benutzer als träge Touch-Reaktion wahrgenommen. Ziel ist es, die Latenz zu minimieren, um die Benutzererfahrung zu verbessern. Angenommen, wir haben die Ereignisse etwas verzögert, so dass die App bei V0.5 zeichnet, wir bei V1.2 zusammensetzen und dann zur Anzeige bei V2 wechseln. Durch die Verrechnung der App- und SF-Aktivität reduzieren wir die Gesamtlatenz von 2 Frames auf 1,5, wie unten gezeigt.

enter image description here

Das ist, was DispSync für ist. Im Feedback-Diagramm der verlinkten Seite ist HW_VSYNC_0 die Hardware-Aktualisierung für die physische Anzeige, VSYNC bewirkt, dass die App gerendert wird, und SF_VSYNC bewirkt, dass SurfaceFlinger die Komposition ausführt. Wenn man sie als "VSYNC" bezeichnet, ist das ein bisschen irreführend, aber auf einem LCD-Panel, das sich auf etwas wie "VSYNC" bezieht, ist wahrscheinlich eine falsche Bezeichnung.

Die im Feedback-Loop-Diagramm vermerkten "Retire Fence Timestamps" beziehen sich auf eine clevere Optimierung. Da wir an der eigentlichen Hardware VSYNC nicht arbeiten, können wir etwas effizienter sein, wenn wir das Refresh-Signal ausschalten. Der DispSync-Code verwendet stattdessen die Zeitstempel von Retentionszäunen (was eine ganze andere Diskussion ist), um zu sehen, ob er nicht mehr synchron ist, und aktiviert das Hardwaresignal vorübergehend wieder, bis es wieder in der Spur ist.

Edit: Sie können sehen, wie die Werte in der Nexus 5 boardconfig konfiguriert sind. Notieren Sie sich die Einstellungen für VSYNC_EVENT_PHASE_OFFSET_NS und SF_VSYNC_EVENT_PHASE_OFFSET_NS.

+1

fadden, danke für deine Hilfe noch einmal. Nur zwei Fragen: 1) Macht dieses Timing-Diagramm Sinn? Original (2 Frames der Latenz): i.imgur.com/4E2cD9l.png DispSync: i.imgur.com/p7LdmXF.png 2) Ist es möglich, in einem einzigen Frame zu zeichnen und zu komponieren, wenn Sie die Offsets ausreichend reduzieren (gefährdet) der Renderzeit reduzieren)? – Shookit

+0

Die Diagramme sehen gut aus. Es ist möglich, in einem VSYNC-Intervall (typischerweise 16,7 ms) zu zeichnen und zu komponieren, aber in der Praxis ist es schwierig, diese Deadlines regelmäßig zu treffen, was oft zu Janky-Ergebnissen führt. Beachten Sie, dass die SurfaceFlinger-Komposition sehr schnell ist, wenn alles in Overlays passt, aber wenn es auf die GLES-Komposition zurückgreift, wird es länger dauern, besonders wenn SF und die App um GPU-Ressourcen konkurrieren. Die genaueste Visualisierung von DispSync ist die Systrace-Ausgabe von einem Gerät, auf dem sie aktiviert ist, z. das Nexus 5. – fadden

+0

Gibt es einen Hardware-Grund, dass ein Board DispSync nicht unterstützt? Oder testet der Hersteller einfach nur, was er tun muss? Ich teste auf dem N4, und ich bemerkte, dass keiner der VSYNC_EVENT_PHASE_OFFSET_NS Flags für das N4 definiert ist (noch ist RUNNING_WITHOUT_SYNC_FRAMEWORK). Diese sind in diesem Fall standardmäßig auf 0 gesetzt und deaktivieren DispSync? – Shookit