Udostępnij przez


Architektura i składniki

Nuta

W przypadku aplikacji w systemie Windows 10 zalecamy używanie interfejsów API Windows.UI.Composition zamiast directComposition. Aby uzyskać więcej informacji, zobacz Modernizuj aplikację klasyczną przy użyciu warstwy wizualnej.

W tym temacie opisano składniki tworzące microsoft DirectComposition. Składa się z poniższych sekcji.

Składniki oprogramowania

Funkcja DirectComposition składa się z następujących głównych składników oprogramowania.

  • Biblioteka aplikacji trybu użytkownika (dcomp.dll), która implementuje publiczny interfejs API oparty na modelu obiektów składników (COM).
  • Aparat kompozycji trybu użytkownika (dwmcore.dll) hostowany w procesie Menedżera okien pulpitu (DWM) (dwm.exe) i wykonuje rzeczywistą kompozycję pulpitu.
  • Baza danych obiektów trybu jądra (część win32k.sys), która marshaluje polecenia z aplikacji do aparatu kompozycji.

Pojedyncze wystąpienie aparatu kompozycji obsługuje drzewa kompozycji DirectComposition dla wszystkich aplikacji i drzewa kompozycji DWM, który reprezentuje cały pulpit. Zarówno baza danych obiektów trybu jądra, jak i aparat kompozycji trybu użytkownika są tworzone raz na sesję, więc maszyna serwera terminali z wieloma użytkownikami ma wiele wystąpień obu tych składników.

Na poniższym diagramie przedstawiono główne składniki DirectComposition i sposób ich powiązania ze sobą.

architektura najwyższego poziomu directcompozycji

Biblioteka aplikacji

Biblioteka aplikacji DirectComposition jest publicznym interfejsem API opartym na modelu COM z pojedynczym płaskim punktem wejścia wyeksportowanym z dcomp.dll i zwraca wskaźnik interfejsu do obiektu urządzenia. Obiekt urządzenia ma z kolei metody tworzenia wszystkich innych obiektów, z których każdy jest reprezentowany przez wskaźnik interfejsu. Wszystkie interfejsy DirectComposition dziedziczą i w pełni implementują interfejs IUnknown. Wszystkie metody akceptujące interfejsy DirectComposition sprawdzają, czy interfejs jest implementowany wewnątrz dcomp.dll, czy jest implementowany przez inny składnik. Ponieważ funkcja DirectComposition nie jest rozszerzalna, metody, które przyjmują interfejsy jako parametry, zwracają E_INVALIDARG, jeśli interfejsy nie są implementowane w dcomp.dll. Interfejs API nie wymaga specjalnych uprawnień; może być wywoływany przez procesy uruchomione na najniższym poziomie dostępu. Jednak ponieważ interfejs API nie działa w sesji 0, nie jest odpowiedni dla usług. W związku z tym interfejs API directcompozycji jest podobny do innych interfejsów API DirectX firmy Microsoft, w szczególności Direct2D, Microsoft Direct3D i Microsoft DirectWrite.

Ponieważ aparat kompozycji jest przeznaczony wyłącznie do wykonywania asynchronicznego, właściwości obiektów w interfejsie API DirectComposition są tylko do zapisu. Wszystkie właściwości mają metody ustawiania, ale nie metody getter. Właściwości odczytu nie tylko intensywnie obciążają zasoby, ale mogą być również niedokładne, ponieważ każda wartość zwracana przez aparat kompozycji może natychmiast stać się nieprawidłowa. Może się tak zdarzyć, jeśli na przykład niezależna animacja jest powiązana z właściwością odczytywaną.

Interfejs API jest bezpieczny wątkowo. Aplikacja może wywołać dowolną metodę z dowolnego wątku w dowolnym momencie. Jednak ponieważ wiele metod interfejsu API musi być wywoływanych w określonej sekwencji, bez synchronizacji aplikacja może doświadczyć nieprzewidywalnego zachowania w zależności od sposobu przeplatania wątków. Jeśli na przykład dwa wątki zmieniają tę samą właściwość tego samego obiektu na różne wartości w tym samym czasie, aplikacja nie może przewidzieć, która z dwóch wartości będzie ostateczną wartością właściwości. Podobnie, jeśli dwa wątki wywołają Commit na tym samym urządzeniu, żaden wątek nie zostanie rzeczywiście transakcyjne zachowanie, ponieważ wywołanie Commit w jednym wątku będzie przesyłać partię wszystkich poleceń wydanych przez oba wątki, a nie tylko ten, który nosi nazwę Commit.

System utrzymuje cały stan wewnętrzny na obiekt urządzenia. Jeśli aplikacja tworzy co najmniej dwa obiekty urządzenia DirectComposition, aplikacja może obsługiwać niezależne partie i inne stany między nimi.

Wszystkie obiekty DirectComposition mają koligację obiektów urządzenia; obiekty utworzone przez określony obiekt urządzenia mogą być używane tylko z tym obiektem urządzenia i mogą być skojarzone tylko z innymi obiektami utworzonymi przez ten sam obiekt urządzenia. Innymi słowy, każdy obiekt urządzenia jest oddzielną rozłączną wyspą funkcjonalności. Jednym wyjątkiem jest klasa wizualizacji, która umożliwia tworzenie drzew wizualnych, w których wizualizacja może należeć do innego obiektu urządzenia niż jego element nadrzędny. Umożliwia to scenariusze, w których aplikacja i kontrolka mogą zarządzać pojedynczym drzewem kompozycji bez konieczności współużytkowania pojedynczego obiektu urządzenia DirectComposition.

Aparat kompozycji

Aparat kompozycji DirectComposition działa w dedykowanym procesie, niezależnie od dowolnego procesu aplikacji. Pojedynczy proces kompozycji, dwm.exe, obsługuje każdą aplikację w sesji. Każda aplikacja może utworzyć dwa drzewa wizualne dla każdego okna, którego jest właścicielem. Wszystkie drzewa są rzeczywiście implementowane jako poddrzewa większego drzewa wizualnego, które obejmuje również struktury kompozycji DWM. Usługa DWM tworzy jedno duże drzewo wizualne dla każdego pulpitu w sesji. Oto najważniejsze zalety tej architektury:

  • Aparat kompozycji ma dostęp do wszystkich map bitowych aplikacji i drzew wizualnych, co umożliwia współdziałanie i kompozycję okien krzyżowych.
  • Aparat kompozycji działa w zaufanym procesie systemowym, który jest oddzielony od dowolnego procesu aplikacji, umożliwiając aplikacjom, które mają prawa dostępu do bezpiecznego tworzenia chronionej zawartości.
  • Aparat kompozycji może wykryć, kiedy określone okno jest w pełni okludnione i uniknąć marnowania zasobów procesora CPU i procesora graficznego (GPU) tworzących okno.
  • Aparat kompozycji może tworzyć się bezpośrednio do buforu tylnego ekranu, unikając konieczności dodatkowej kopii, która jest wymagana dla aparatów kompozycji procesu.
  • Wszystkie aplikacje współdzielą jedno urządzenie Direct3D na potrzeby kompozycji, co zapewnia znaczne oszczędności pamięci

Drzewo wizualne jest zachowaną strukturą. Interfejs API DirectComposition uwidacznia metody edytowania struktury w partiach zmian, które są przetwarzane niepodzielnie. Obiekt główny w interfejsie API DirectComposition jest obiektem urządzenia, który służy jako fabryka dla wszystkich innych obiektów DirectComposition i zawiera metodę o nazwie Commit. Aparat kompozycji nie odzwierciedla żadnych zmian, które aplikacja wprowadza w drzewie wizualizacji, dopóki aplikacja nie wywoła Commit, w którym momencie wszystkie zmiany od ostatniego commit są przetwarzane jako pojedyncza transakcja.

Wymaganie wywołania Commit jest podobne do koncepcji "ramki", z tą różnicą, że ponieważ aparat kompozycji działa asynchronicznie, może przedstawiać kilka różnych ramek między wywołaniami Commit. W funkcji DirectComposition ramka jest pojedynczą iterację aparatu kompozycji, a interwał spędzony przez aplikację między dwoma wywołaniami commit jest nazywany batch.

Funkcja DirectComposition wsaduje wszystkie wywołania aplikacji do interfejsu API DirectComposition. Baza danych obiektów jądra zaimplementowana w sterowniku sesji win32k.sys przechowuje wszystkie informacje o stanie skojarzone z wywołaniami interfejsu API.

Aparat kompozycji tworzy jedną ramkę dla każdej pustej pionowej na wyświetlaczu. Ramka jest uruchamiana w pionie pustym i jest przeznaczona dla kolejnej wartości pustej w pionie. Po uruchomieniu ramki aparat kompozycji pobiera wszystkie oczekujące partie i zawiera ich polecenia w tej ramce. Partie są umieszczane w oczekującej kolejce, gdy aplikacja wywołuje Commit, a oczekująca kolejka jest opróżniona niepodziecznie na początku ramki. W związku z tym istnieje pojedynczy punkt w czasie, który oznacza początek ramki. Wszystkie partie przesłane przed tym punktem są uwzględnione w ramce, podczas gdy wszystkie partie przesłane po muszą poczekać na przetworzenie następnej ramki. Pętla pełnej kompozycji wygląda następująco:

  1. Szacowanie czasu następnego pustego w pionie.
  2. Pobierz wszystkie oczekujące partie.
  3. Przetwarzanie pobranych partii.
  4. Zaktualizuj wszystkie animacje przy użyciu czasu szacowany w kroku 1.
  5. Określ regiony ekranu, które muszą zostać ponownie skomponowane.
  6. Ponownie redaguj brudne regiony.
  7. Przedstawia ramkę, przerzucając tylne i przednie dla każdego ekranu.
  8. Jeśli nic nie zostało skomponowane i przedstawione w krokach 6 i 7, poczekaj, aż partia zostanie zatwierdzona.
  9. Zaczekaj na następne puste pole pionowe.

Jeśli istnieje wiele monitorów dołączonych do jednej karty wideo, aparat kompozycji używa pionowego pustego monitora podstawowego do napędzania pętli kompozycji i ustawiania czasów próbkowania animacji. Każdy monitor jest reprezentowany przez oddzielny łańcuch przerzucania pełnoekranowego; aparat kompozycji powtarza kroki 6 i 7 dla każdego monitora, w sposób okrężny, przy użyciu jednego urządzenia Direct3D. Jeśli istnieje również wiele kart wideo, aparat kompozycji używa oddzielnego urządzenia Direct3D dla każdej karty wideo w krokach 6 i 7.

Ramki kompozycji są zawsze uruchamiane w pionie pustym, jak pokazano na poniższej ilustracji.

planowania ramek kompozycji

Jeśli silnik kompozycji nie ma pracy do wykonania, ponieważ drzewo kompozycji nie uległo zmianie, wątek kompozycji śpi podczas oczekiwania na nową partię. Po przesłaniu nowej partii wątek kompozycji budzi się, ale natychmiast wraca do uśpienia aż do następnego pionowego pustego. To zachowanie zapewnia przewidywalne czasy rozpoczęcia i zakończenia ramki dla aplikacji i aparatu kompozycji.

Aparat kompozycji publikuje czasy prezentacji ramek i bieżącą szybkość klatek. Opublikowanie tych informacji umożliwia aplikacjom oszacowanie czasu prezentacji dla własnych partii, co z kolei umożliwia synchronizowanie animacji. W szczególności aplikacja może używać kombinacji statystyk ramek z aparatu kompozycji, a historyczny model tego, jak długo jego wątek interfejsu użytkownika trwa do utworzenia partii, w celu określenia czasu próbkowania dla własnych animacji.

Na przykład na początku partii aplikacji pokazanej na poprzedniej ilustracji aplikacja może wysłać zapytanie do aparatu kompozycji, aby określić dokładny czas prezentacji następnej ramki. Następnie aplikacja może używać bieżącego czasu wraz z informacjami o poprzednich partiach, które zostały utworzone, aby określić, czy aplikacja może ukończyć bieżącą partię przed następnym pustym pionowym. W związku z tym aplikacja używa czasu prezentacji ramowej jako czasu próbkowania dla własnych animacji. Jeśli aplikacja ustali, że wykonanie pracy w bieżącym pionie jest mało prawdopodobne, aplikacja może użyć zamiast tego czasu kolejnego przedziału czasu jako czasu próbkowania, używając informacji o szybkości klatek zwracanych przez aparat kompozycji do obliczenia tego czasu.

Pojęcia dotyczące funkcji DirectComposition