Architektura a komponenty

Poznámka

U aplikací ve Windows 10 doporučujeme místo DirectComposition používat rozhraní API pro Windows.UI.Composition. Další informace najdete v tématu Modernizace desktopové aplikace pomocívrstvy vizuálu .

Toto téma popisuje komponenty, které tvoří Microsoft DirectComposition. Skládá se z následujících částí.

Softwarové komponenty

DirectComposition se skládá z následujících hlavních softwarových komponent.

  • Knihovna aplikací v uživatelském režimu (dcomp.dll), která implementuje veřejné rozhraní API založené na modelu COM (Component Object Model).
  • Modul složení v uživatelském režimu (dwmcore.dll), který je hostovaný v procesu Desktop Window Manager (DWM) (dwm.exe) a provádí skutečné složení plochy.
  • Databáze objektů v režimu jádra (součást win32k.sys), která zařazuje příkazy z aplikace do modulu složení.

Jedna instance kompozičního modulu zpracovává stromy složení DirectComposition pro všechny aplikace a strom složení DWM, který představuje celou plochu. Databáze objektů v režimu jádra i modul složení uživatelského režimu se vytváří jednou za relaci, takže terminálový server s více uživateli má několik instancí obou těchto komponent.

Následující diagram znázorňuje hlavní komponenty DirectComposition a jejich vztah mezi sebou.

přímou architekturu nejvyšší úrovně

Knihovna aplikací

Knihovna aplikací DirectComposition je veřejné rozhraní API založené na modelu COM s jedním plochým vstupním bodem, který je exportován z dcomp.dll a vrací ukazatel rozhraní na objekt zařízení. Objekt zařízení má metody pro vytváření všech ostatních objektů, z nichž každý je reprezentován ukazatelem rozhraní. Všechna rozhraní DirectComposition dědí a plně implementují IUnknown rozhraní. Všechny metody, které přijímají rozhraní DirectComposition, zkontrolují, zda je rozhraní implementováno uvnitř dcomp.dll nebo zda je implementována jinou komponentou. Protože DirectComposition není rozšiřitelný, metody, které přebírají rozhraní jako parametry vracejí E_INVALIDARG pokud rozhraní nejsou implementována v dcomp.dll. Rozhraní API nevyžaduje žádná zvláštní oprávnění; je možné volat procesy běžícími na nejnižší úrovni přístupu. Vzhledem k tomu, že rozhraní API nefunguje v relaci 0, není vhodné pro služby. V těchto ohledech se rozhraní DirectComposition API podobá jiným rozhraním API DirectX, zejména Direct2D, Microsoft Direct3D a Microsoft DirectWrite.

Vzhledem k tomu, že modul složení je určen výhradně pro asynchronní spouštění, vlastnosti objektů v rozhraní DIRECTComposition API jsou jen pro zápis. Všechny vlastnosti mají metody setter, ale nikoli metody getter. Vlastnosti čtení nejsou pouze náročné na prostředky, ale mohou být také nepřesné, protože jakákoli hodnota, kterou vrátí modul složení, může být okamžitě neplatná. K tomu může dojít například v případě, že nezávislá animace je vázána na vlastnost, která se čte.

Rozhraní API je bezpečné pro přístup z více vláken. Aplikace může kdykoli volat jakoukoli metodu z libovolného vlákna. Vzhledem k tomu, že se v určité sekvenci musí volat mnoho metod rozhraní API, bez jakékoli synchronizace může aplikace zaznamenat nepředvídatelné chování v závislosti na způsobu prokládání vláken. Pokud například dvě vlákna změní stejnou vlastnost stejného objektu na různé hodnoty současně, aplikace nemůže předpovědět, která z těchto dvou hodnot bude konečnou hodnotou vlastnosti. Podobně platí, že pokud dvě vlákna volají Commit na stejném zařízení, ani jedno vlákno nedostane skutečně transakční chování, protože volání Commit v jednom vlákně odešle dávku všech příkazů vydaných oběma vlákny, nikoli pouze ten, který se nazývá Commit.

Systém udržuje veškerý vnitřní stav na objekt zařízení. Pokud aplikace vytvoří dva nebo více objektů zařízení DirectComposition, může aplikace udržovat nezávislé dávky a jiný stav mezi těmito dvěma objekty.

Všechny objekty DirectComposition mají spřažení objektů zařízení; objekty vytvořené konkrétním objektem zařízení lze použít pouze s tímto objektem zařízení a lze je přidružit pouze k jiným objektům vytvořeným stejným objektem zařízení. Jinými slovy, každý objekt zařízení je samostatný nesouvislý ostrov funkčnosti. Jedinou výjimkou je třída vizuálu, která umožňuje vytváření stromů vizuálů, kde vizuál může patřit do jiného objektu zařízení než jeho nadřazený objekt. To umožňuje scénáře, kdy aplikace a ovládací prvek můžou spravovat jediný strom složení, aniž by bylo nutné sdílet jeden objekt zařízení DirectComposition.

Kompoziční motor

Modul pro složení DirectComposition běží na vyhrazeném procesu odděleně od jakéhokoli procesu aplikace. Jeden proces složení, dwm.exe, podporuje každou aplikaci v relaci. Každá aplikace může vytvořit dva stromy vizuálů pro každé okno, které vlastní. Všechny stromy jsou ve skutečnosti implementovány jako podstromy většího vizuálního stromu, který také zahrnuje struktury složení DWM. DWM vytvoří jeden velký vizuální strom pro každou plochu v relaci. Tady jsou hlavní výhody této architektury:

  • Modul složení má přístup ke všem rastrovým obrázkům aplikací a vizuálním stromům, které umožňují interoperabilitu a složení oken napříč procesy.
  • Modul složení běží v důvěryhodném systémovém procesu, který je oddělený od jakéhokoli procesu aplikace a umožňuje aplikacím, které mají nízká přístupová práva k bezpečnému vytváření chráněného obsahu.
  • Modul složení dokáže zjistit, kdy je určité okno zcela vyloděné, a vyhnout se plýtvání prostředky procesoru a grafického procesoru (GPU), které jsou určené pro toto okno.
  • Kompoziční modul může vytvořit přímo do vyrovnávací paměti obrazovky zpět, vyhnout se nutnosti dodatečné kopie, která je nutná pro moduly složení pro jednotlivé procesy.
  • Všechny aplikace sdílejí jedno zařízení Direct3D pro složení, které nabízí značné úspory paměti.

Vizuální strom je zachovaná struktura. Rozhraní DIRECTComposition API zveřejňuje metody pro úpravu struktury v dávkách změn, které se zpracovávají atomicky. Kořenový objekt v rozhraní DIRECTComposition API je objekt zařízení, který slouží jako továrna pro všechny ostatní objekty DirectComposition a obsahuje metodu s názvem Commit. Modul složení neodráží žádné změny, které aplikace provede ve stromu vizuálu, dokud aplikace nevolá Commit, v tomto okamžiku všechny změny od poslední Commit se zpracovávají jako jedna transakce.

Požadavek na volání Commit je podobný konceptu "frame" s tím rozdílem, že vzhledem k tomu, že kompoziční modul běží asynchronně, může prezentovat několik různých rámců mezi voláními Commit. V DirectComposition, rámec je jedna iterace kompozičního modulu a interval strávený aplikací mezi dvěma voláními Commit se nazývá dávkové.

DirectComposition dávková všechna volání aplikace do rozhraní DIRECTComposition API. Databáze objektů jádra, která je implementována v ovladači relace win32k.sys, ukládá všechny informace o stavu přidružené k volání rozhraní API.

Složený modul vytvoří jeden rámec pro každou svislou prázdnou hodnotu v displeji. Rámec se spustí ve svislém prázdném místě a cílí na následující svislou prázdnou hodnotu. Když se rámec spustí, modul složení převezme všechny nevyřízené dávky a zahrne do daného rámce jejich příkazy. Dávky se umístí do čekající fronty, když aplikace volá Commita čekající fronta se vyprázdní atomicky na začátku rámce. Proto existuje jeden bod v čase, který označuje začátek rámce. Všechny dávky odeslané před tímto bodem jsou zahrnuty do rámce, zatímco všechny dávky odeslané po musí čekat na zpracování dalšího rámce. Úplná smyčka složení je následující:

  1. Odhadněte čas další svislé prázdné hodnoty.
  2. Načtěte všechny čekající dávky.
  3. Zpracovat načtené dávky.
  4. Aktualizujte všechny animace podle času odhadovaného v kroku 1.
  5. Určete oblasti obrazovky, které je potřeba znovu skládat.
  6. Znovu vytvořte špinavé oblasti.
  7. Rámeček můžete prezentovat tak, že pro každou obrazovku překlopíte zadní a přední vyrovnávací paměť.
  8. Pokud se nic neskládalo a zobrazilo v krocích 6 a 7, počkejte na potvrzení dávky.
  9. Počkejte na další svislou prázdnou hodnotu.

Pokud je k jednomu grafickému adaptéru připojeno více monitorů, modul složení použije ke smyčce složení svislou prázdnou hodnotu primárního monitoru a nastaví časy vzorkování animace. Každý monitor je reprezentován samostatným řetězem překlopení na celé obrazovce; kompoziční modul opakuje kroky 6 a 7 pro každý monitor pomocí jednoho zařízení Direct3D. Pokud existuje také více grafických adaptérů, modul složení používá pro každý grafický adaptér samostatné zařízení Direct3D v krocích 6 a 7.

Snímky složení jsou naplánovány tak, aby vždy začínaly svislým prázdným, jak znázorňuje následující obrázek.

plánování snímků

Pokud kompoziční modul nemá žádnou práci, protože strom složení se nezměnil, vlákno složení spí při čekání na novou dávku. Po odeslání nové dávky se vlákno složení probudí, ale okamžitě se vrátí do režimu spánku až do dalšího svislého prázdného. Toto chování zajišťuje předvídatelné časy spuštění a ukončení rámce pro aplikace a modul složení.

Modul složení publikuje časy prezentace snímků a aktuální frekvenci snímků. Publikování těchto informací umožňuje aplikacím odhadnout čas prezentace pro vlastní dávky, což pak umožňuje synchronizaci animací. Konkrétně může aplikace použít kombinaci statistik snímků z kompozičního modulu a historický model, jak dlouho trvá jeho vlákno uživatelského rozhraní k vytvoření dávky, k určení času vzorkování pro vlastní animace.

Například na začátku dávky aplikace zobrazené na předchozím obrázku může aplikace dotazovat modul složení, aby určil přesný čas prezentace dalšího rámce. Aplikace pak může použít aktuální čas spolu s informacemi o předchozích dávkách, které vytvořila, a určit, jestli může aplikace dokončit aktuální dávku před další svislou prázdnou hodnotou. Aplikace proto používá čas prezentace rámce jako čas vzorkování pro vlastní animace. Pokud aplikace zjistí, že není pravděpodobné, že by dokončila svou práci v aktuální svislé prázdné oblasti, může aplikace místo toho použít následující dobu rámce jako čas vzorkování, pomocí informací o frekvenci snímků vrácených modulem složení k výpočtu této doby.

koncepty DirectComposition