Architektur und Komponenten
Hinweis
Für Apps auf Windows 10 wird die Verwendung von Windows.UI.Composition-APIs anstelle von DirectComposition empfohlen. Weitere Informationen finden Sie unter Modernisieren Ihrer Desktop-App mithilfe der visuellen Ebene.
In diesem Thema werden die Komponenten beschrieben, aus denen Microsoft DirectComposition besteht. Sie besteht aus den folgenden Abschnitten.
Softwarekomponenten
DirectComposition besteht aus den folgenden Standard Softwarekomponenten.
- Eine Anwendungsbibliothek im Benutzermodus (dcomp.dll), die die com-basierte API (Component Object Model) implementiert.
- Eine Kompositions-Engine für den Benutzermodus (dwmcore.dll), die im DWM-Prozess (Desktop Window Manager) (dwm.exe) gehostet wird und die eigentliche Desktopkomposition ausführt.
- Eine Objektdatenbank im Kernelmodus (Teil von win32k.sys), die Befehle aus der Anwendung an die Kompositions-Engine marshallt.
Ein einzelner instance der Kompositions-Engine verarbeitet die DirectComposition-Kompositionsbaumstrukturen für alle Anwendungen und die DWM-Kompositionsstruktur, die den gesamten Desktop darstellt. Sowohl die Kernelmodusobjektdatenbank als auch die Kompositions-Engine für den Benutzermodus werden einmal pro Sitzung instanziiert, sodass ein Terminalservercomputer mit mehreren Benutzern über mehrere Instanzen dieser beiden Komponenten verfügt.
Das folgende Diagramm zeigt die Standard DirectComposition-Komponenten und deren Beziehung zueinander.
Anwendungsbibliothek
Die DirectComposition-Anwendungsbibliothek ist eine öffentliche COM-basierte API mit einem einzelnen flachen Einstiegspunkt, der aus dcomp.dll exportiert wird und einen Schnittstellenzeiger auf ein Geräteobjekt zurückgibt. Das Geräteobjekt verfügt wiederum über Methoden zum Erstellen aller anderen Objekte, die jeweils durch einen Schnittstellenzeiger dargestellt werden. Alle DirectComposition-Schnittstellen erben von der IUnknown-Schnittstelle und implementieren sie vollständig. Alle Methoden, die DirectComposition-Schnittstellen akzeptieren, überprüfen, ob die Schnittstelle innerhalb von dcomp.dll implementiert ist oder ob sie von einer anderen Komponente implementiert wird. Da DirectComposition nicht erweiterbar ist, geben Methoden, die Schnittstellen als Parameter verwenden, E_INVALIDARG zurück, wenn die Schnittstellen nicht in dcomp.dll implementiert sind. Die API erfordert keine speziellen Berechtigungen. Sie kann von Prozessen aufgerufen werden, die auf der niedrigsten Zugriffsebene ausgeführt werden. Da die API jedoch nicht in Sitzung 0 ausgeführt wird, ist sie für Dienste nicht geeignet. In dieser Hinsicht ähnelt die DirectComposition-API anderen Microsoft DirectX-APIs, insbesondere Direct2D, Microsoft Direct3D und Microsoft DirectWrite.
Da die Kompositions-Engine ausschließlich für die asynchrone Ausführung entwickelt wurde, sind Objekteigenschaften in der DirectComposition-API schreibgeschützt. Alle Eigenschaften verfügen über Settermethoden, aber keine Gettermethoden. Das Lesen von Eigenschaften ist nicht nur ressourcenintensiv, sondern kann auch ungenau sein, da jeder Wert, den die Kompositions-Engine zurückgibt, sofort ungültig werden kann. Dies kann beispielsweise der Fall sein, wenn eine unabhängige Animation an die zu lesende Eigenschaft gebunden ist.
Die API ist threadsicher. Eine Anwendung kann jederzeit jede Methode aus einem beliebigen Thread aufrufen. Da jedoch viele API-Methoden in einer bestimmten Sequenz aufgerufen werden müssen, kann eine Anwendung ohne Synchronisierung unvorhersehbares Verhalten erleben, je nachdem, wie sich die Threads verschachteln. Wenn beispielsweise zwei Threads die gleiche Eigenschaft desselben Objekts gleichzeitig in unterschiedliche Werte ändern, kann die Anwendung nicht vorhersagen, welcher der beiden Werte der endgültige Wert der Eigenschaft sein wird. Wenn zwei Threads Commit auf demselben Gerät aufrufen, erhält keiner der Threads ein wirkliches Transaktionsverhalten, da ein Aufruf von Commit für einen Thread den Batch aller Befehle übermittelt, die von beiden Threads ausgegeben werden, nicht nur der, der Commit aufgerufen hat.
Das System verwaltet den gesamten internen Zustand pro Geräteobjekt. Wenn eine Anwendung zwei oder mehr DirectComposition-Geräteobjekte erstellt, kann die Anwendung unabhängige Batches und einen anderen Zustand zwischen den beiden beibehalten.
Alle DirectComposition-Objekte verfügen über Geräteobjektaffinität; Von einem bestimmten Geräteobjekt erstellte Objekte können nur mit diesem Geräteobjekt verwendet werden und können nur anderen Objekten zugeordnet werden, die von demselben Geräteobjekt erstellt wurden. Mit anderen Worten, jedes Geräteobjekt ist eine separate, getrennte Insel der Funktionalität. Die einzige Ausnahme ist die visuelle Klasse, die das Erstellen visueller Strukturen ermöglicht, in denen ein Visual zu einem anderen Geräteobjekt als seinem übergeordneten Objekt gehören kann. Dies ermöglicht Szenarien, in denen eine Anwendung und ein Steuerelement eine einzelne Kompositionsstruktur verwalten können, ohne auch ein einzelnes DirectComposition-Geräteobjekt freigeben zu müssen.
Kompositions-Engine
Die DirectComposition-Kompositions-Engine wird in einem dedizierten Prozess unabhängig von jedem Anwendungsprozess ausgeführt. Ein einzelner Kompositionsprozess dwm.exe unterstützt jede Anwendung in einer Sitzung. Jede Anwendung kann zwei visuelle Strukturen für jedes Fenster erstellen, das sie besitzt. Alle Strukturen werden tatsächlich als Teilstrukturen einer größeren visuellen Struktur implementiert, die auch die Kompositionsstrukturen von DWM umfasst. Der DWM erstellt eine große visuelle Struktur für jeden Desktop in einer Sitzung. Hier sind die wichtigsten Vorteile dieser Architektur:
- Die Kompositions-Engine hat Zugriff auf alle Anwendungsbitbits und visuellen Strukturen, wodurch prozessübergreifende Interoperabilität und Komposition von Fenstern ermöglicht werden.
- Die Kompositions-Engine wird in einem vertrauenswürdigen Systemprozess ausgeführt, der von jedem Anwendungsprozess getrennt ist, sodass Anwendungen mit geringen Zugriffsrechten geschützte Inhalte sicher verfassen können.
- Die Kompositions-Engine kann erkennen, wenn ein bestimmtes Fenster vollständig verdeckt ist, und vermeiden, dass CPU- und GPU-Ressourcen (Graphics Processing Unit) für das Fenster erstellt werden.
- Die Kompositions-Engine kann direkt im Bildschirmrückpuffer verfassen, sodass keine zusätzliche Kopie erforderlich ist, die für kompositionsbasierte Engines pro Prozess erforderlich ist.
- Alle Anwendungen teilen sich ein einzelnes Direct3D-Gerät für die Komposition, was erhebliche Speichereinsparungen bietet.
Die visuelle Struktur ist eine beibehaltene Struktur. Die DirectComposition-API macht Methoden zum Bearbeiten der Struktur in Batches von Änderungen verfügbar, die atomar verarbeitet werden. Das Stammobjekt in der DirectComposition-API ist das Geräteobjekt, das als Factory für alle anderen DirectComposition-Objekte dient und eine Methode namens Commit enthält. Die Kompositions-Engine spiegelt keine Änderungen wider, die die Anwendung an der visuellen Struktur vornimmt, bis die Anwendung Commit aufruft. An diesem Punkt werden alle Änderungen seit dem letzten Commit als einzelne Transaktion verarbeitet.
Die Anforderung, Commit aufzurufen, ähnelt dem Konzept eines "Frames", mit der Ausnahme, dass die Kompositions-Engine, da sie asynchron ausgeführt wird, mehrere verschiedene Frames zwischen Aufrufen von Commit darstellen kann. In DirectComposition ist ein Frame eine einzelne Iteration der Kompositions-Engine, und das Intervall, das eine Anwendung zwischen zwei Commitaufrufen aufwendet, wird als Batch bezeichnet.
DirectComposition batchiert alle Anwendungsaufrufe an die DirectComposition-API. Die Kernelobjektdatenbank, die im win32k.sys Sitzungstreiber implementiert ist, speichert alle Zustandsinformationen, die den API-Aufrufen zugeordnet sind.
Die Kompositions-Engine erzeugt einen Rahmen für jede vertikale Leere in der Anzeige. Der Frame wird an einem vertikalen Leerzeichen gestartet und zielt auf den nachfolgenden vertikalen Leerzeichen ab. Wenn der Frame gestartet wird, übernimmt die Kompositions-Engine alle ausstehenden Batches und schließt deren Befehle in diesen Frame ein. Batches werden in einer ausstehenden Warteschlange platziert, wenn die Anwendung Commit aufruft, und die ausstehende Warteschlange wird am Anfang des Frames atomar geleert. Daher gibt es einen einzelnen Zeitpunkt, der den Anfang eines Frames markiert. Alle Batches, die vor diesem Punkt übermittelt werden, sind im Frame enthalten, während alle nach übermittelten Batches warten müssen, bis der nächste Frame verarbeitet wird. Die vollständige Kompositionsschleife lautet wie folgt:
- Schätzen Sie die Zeit des nächsten vertikalen Leerzeichens.
- Ruft alle ausstehenden Batches ab.
- Verarbeiten Sie die abgerufenen Batches.
- Aktualisieren Sie alle Animationen mithilfe der in Schritt 1 geschätzten Zeit.
- Bestimmen Sie die Bereiche des Bildschirms, die neu zusammengesetzt werden müssen.
- Erstellen Sie die modifiziert Regionen neu.
- Präsentieren Sie den Frame, indem Sie die Puffer hinten und vorne für jeden Bildschirm umdrehen.
- Wenn in den Schritten 6 und 7 nichts erstellt und angezeigt wurde, warten Sie, bis ein Batch committet wurde.
- Warten Sie auf den nächsten vertikalen Leerzeichen.
Wenn mehrere Monitore an eine einzelne Grafikkarte angefügt sind, verwendet die Kompositions-Engine den vertikalen Leerzeichen des primären Monitors, um die Kompositionsschleife zu steuern und die Animationsamplingzeiten festzulegen. Jeder Monitor wird durch eine separate Vollbild-Flip-Kette dargestellt; Die Kompositions-Engine wiederholt die Schritte 6 und 7 für jeden Monitor auf Roundrobin-Weise mit einem einzelnen Direct3D-Gerät. Wenn auch mehrere Grafikkarten vorhanden sind, verwendet die Kompositions-Engine in den Schritten 6 und 7 ein separates Direct3D-Gerät für jeden Grafikkarten.
Kompositionsrahmen werden so geplant, dass sie immer bei einem vertikalen Leerzeichen beginnen, wie in der folgenden Abbildung gezeigt.
Wenn die Kompositions-Engine keine Arbeit hat, weil sich die Kompositionsstruktur nicht geändert hat, wird der Kompositionsthread in den Ruhezustand versetzt, während auf einen neuen Batch gewartet wird. Wenn ein neuer Batch übermittelt wird, wird der Kompositionsthread reaktiviert, wechselt aber sofort wieder in den Standbymodus, bis der nächste vertikale Leerzustand angezeigt wird. Dieses Verhalten gewährleistet vorhersagbare Framestart- und -endzeiten für Anwendungen und für die Kompositions-Engine.
Die Kompositions-Engine veröffentlicht die Framepräsentationszeiten und die aktuelle Bildfrequenz. Durch die Veröffentlichung dieser Informationen können Anwendungen die Präsentationszeit für ihre eigenen Batches schätzen, wodurch wiederum Animationen synchronisiert werden können. Insbesondere kann eine Anwendung eine Kombination aus Framestatistiken der Kompositions-Engine und einem historischen Modell verwenden, wie lange der UI-Thread zum Erstellen eines Batches benötigt, um die Samplingzeit für eigene Animationen zu bestimmen.
Beispielsweise kann die Anwendung am Anfang des in der vorherigen Abbildung gezeigten Anwendungsbatches die Kompositions-Engine abfragen, um die genaue Präsentationszeit des nächsten Frames zu bestimmen. Die Anwendung kann dann die aktuelle Zeit zusammen mit Informationen zu vorherigen Batches, die sie erstellt hat, verwenden, um zu bestimmen, ob die Anwendung den aktuellen Batch vor dem nächsten vertikalen Leeren abschließen kann. Daher verwendet die Anwendung die Framepräsentationszeit als Samplingzeit für ihre eigenen Animationen. Wenn die Anwendung feststellt, dass es unwahrscheinlich ist, dass die Arbeit im aktuellen vertikalen Leerzeichen abgeschlossen wird, kann die Anwendung stattdessen die nachfolgende Framezeit als Samplingzeit verwenden, indem sie die von der Kompositions-Engine zurückgegebenen Bildfrequenzinformationen verwendet, um diese Zeit zu berechnen.
Zugehörige Themen