Spójrzmy na kluczowe struktury danych, czyli dane wejściowe i wyjściowe funkcji potoku renderowania.
Takie struktury danych to:
- Drzewa ramek składają się z węzłów lokalnych i zdalnych, które reprezentują zasoby sieci które obejmują proces renderowania i mechanizm renderowania Blink.
- Drzewo fragmentów stałych reprezentuje dane wyjściowe funkcji (i dane wejściowe) algorytm ograniczenia układu.
- Drzewa właściwości reprezentują hierarchie przekształceń, klipów, efektów i przewijania. dokumentu internetowego. Są one używane w całym potoku.
- Listy wyświetlania i fragmenty renderowania to dane wejściowe dla algorytmów rastrowania i warstwowania.
- Ramki kompozycji otaczają powierzchnie, powierzchnie renderowania i teksturę GPU kafelki używane do rysowania przy użyciu GPU.
Przed opisaniem tych struktur danych poniższy przykład opiera się na jeden ze przeglądu architektury. Ten został zastosowany w tym dokumencie, pokazując, w jaki sposób dane w odniesieniu do niego.
<!-- Example code -->
<html>
<div style="overflow: hidden; width: 100px; height: 100px;">
<iframe style="filter: blur(3px);
transform: rotateZ(1deg);
width: 100px; height: 300px"
id="one" src="foo.com/etc"></iframe>
</div>
<iframe style="top:200px;
transform: scale(1.1) translateX(200px)"
id="two" src="bar.com"></iframe>
</html>
Oprawianie drzew
Chrome może czasami renderować ramkę z innej domeny w innym procesie renderowania niż ramka nadrzędna.
W przykładowym kodzie widać łącznie 3 klatki:
W przypadku izolacji witryn Chromium używa 2 procesów renderowania do renderowania tej strony internetowej. Każdy proces renderowania przedstawia własną reprezentację drzewa ramek dla danej strony internetowej:
Ramka wyrenderowana w innym procesie jest reprezentowana jako ramka zdalna. Ramka zdalna zawiera minimalną ilość informacji potrzebnych do działania jako obiekt zastępczy podczas renderowania. np. jej wymiary. W przeciwnym razie ramka zdalna nie zawiera żadnych informacji potrzebnych do renderowania jej rzeczywistej zawartości.
Z kolei ramka lokalna reprezentuje klatkę, która przechodzi przez standardową i potoku renderowania. Ramka lokalna zawiera wszystkie informacje potrzebne do dane tej ramki (np. drzewo DOM i dane stylu) w określony element które można renderować i wyświetlić.
Potok renderowania działa na szczegółowości
fragment lokalnego drzewa ramek.
Rozważ bardziej skomplikowany przykład z klatką foo.com
w głównej ramce:
<iframe src="bar.com"></iframe>
Oraz ta ramka podrzędna bar.com
:
<iframe src="foo.com/etc"></iframe>
Chociaż nadal istnieją tylko dwa mechanizmy renderowania, są teraz dostępne trzy lokalne ramki
fragmenty drzewa, z 2 w procesie renderowania dla interfejsu foo.com
, a drugi w
renderowanie dla bar.com
:
Aby utworzyć jedną ramkę kompozytora dla strony internetowej, Viz jednocześnie żąda ramki kompozytora z ramki głównej każdej z tych trzech lokalnych drzew konstrukcyjnych. łączy je. Zapoznaj się też z sekcją dotyczącą ramek kompozytora.
Ramka główna foo.com
i ramka podrzędna foo.com/other-page
są częścią tego samego drzewa ramek i renderowane w ramach tego samego procesu.
Te dwie klatki nadal są niezależne od siebie
cykle życia dokumentów
ponieważ są częścią różnych lokalnych fragmentów drzewa ramek.
Z tego powodu nie można wygenerować jednej ramki kompozytora dla obu w ramach jednej aktualizacji.
Proces renderowania zawiera niewystarczające informacje
aby skomponować ramkę kompozytora wygenerowaną dla interfejsu foo.com/other-page
bezpośrednio do ramki kompozytora dla ramki głównej foo.com
.
Na przykład ramka nadrzędna bar.com
poza procesem może mieć wpływ na wyświetlanie elementu iframe foo.com/other-url
,
Przekształcając element iframe za pomocą CSS lub umieszczając jego część w elemencie DOM, umieszczając w niej inne elementy.
Kaskada aktualizacji właściwości wizualnych
Na renderowane dane wyjściowe mają wpływ właściwości wizualne, takie jak współczynnik skali urządzenia i rozmiar widocznego obszaru i musi być zsynchronizowany między fragmentami lokalnego drzewa ramek. Z rdzeniem każdego lokalnego fragmentu drzewa ramki powiązany jest obiekt widżetu. Wizualne aktualizacje właściwości trafiają do widżetu ramki głównej przed rozpowszechnieniem lub w pozostałych widżetach, od góry do dołu.
Na przykład gdy rozmiar widocznego obszaru się zmieni:
Ten proces nie jest natychmiastowy, aby replikowane właściwości wizualne również zawierały token synchronizacji. Kompozytor Viz używa tego tokena synchronizacji do oczekiwania na wszystkie lokalne fragmenty drzewa ramek aby przesłać ramkę kompozytora z bieżącym tokenem synchronizacji. Ten proces pozwala uniknąć mieszania ramek kompozytora o różnych właściwościach wizualnych.
Drzewo stałych fragmentów
Drzewo z niezmiennymi fragmentami to dane wyjściowe etapu układu renderowania. potoku. Reprezentuje położenie i rozmiar wszystkich elementów na stronie (bez przekształceń).
Każdy fragment reprezentuje część elementu DOM. Zwykle dla każdego elementu jest tylko jeden fragment, ale może być ich więcej, jeśli jest podzielony na różne strony podczas drukowania. lub kolumn w kontekście wielokolumnowym.
Po układzie każdy fragment staje się niezmienny i nigdy nie jest zmieniany. Co ważne, nakładamy też kilka dodatkowych ograniczeń. Czego nie robimy:
- Zezwalaj na dowolne wyświetlanie odwołania w drzewie. (Element podrzędny nie może mieć wskaźnika do elementu nadrzędnego).
- „dymek” dane z pierwszej ręki (element podrzędny odczytuje informacje tylko od swoich elementów podrzędnych, a nie od wydawców podrzędnych).
Te ograniczenia pozwalają na ponowne użycie fragmentu w kolejnym układzie. Bez tych ograniczeń musielibyśmy często odnawiać całe drzewo, co jest bardzo kosztowne.
Większość układów to zazwyczaj aktualizacje stopniowe. Na przykład: aplikacja internetowa aktualizująca niewielką część interfejsu w odpowiedzi na kliknięcie elementu przez użytkownika. Najlepiej, gdyby układ działał proporcjonalnie do tego, co rzeczywiście zmieniło się na ekranie. Możemy to osiągnąć, ponownie wykorzystując jak najwięcej części poprzedniego drzewa. Oznacza to, że (zwykle) musimy odbudować tylko grzbiet drzewa.
W przyszłości taka stała konstrukcja pozwoli nam robić interesujące rzeczy np. przez przeniesienie w razie potrzeby stałego drzewa fragmentów przez granice wątków. (aby wykonać kolejne etapy w innym wątku), i generuj wiele drzew, aby tworzyć płynne animacje układu. ani wykonywać równoległych układów spekulacyjnych. Rozwiązanie to również łączy się z potencjałem wielowątkowości w układzie.
Wbudowane elementy z fragmentami
Treść w tekście (głównie stylizowany tekst) wygląda trochę inaczej. Zamiast drzewa z ramkami i wskaźnikami przedstawiamy treść w treści na płaskiej liście reprezentującej drzewo. Główną zaletą jest to, że płaska lista dla elementów w tekście jest szybka, przydatny przy badaniu wbudowanych struktur danych i wykonywaniu dotyczących ich zapytań, i oszczędna pamięć. Jest to niezwykle ważne z punktu widzenia wydajności renderowania stron internetowych, ponieważ renderowanie tekstu jest bardzo złożone, i może stać się najwolniejszym elementem procesu, chyba że zostanie zoptymalizowana pod kątem skuteczności.
Dla każdego elementu tworzona jest płaska lista Kontekst formatowania w kolejności od najbardziej szczegółowego wyszukiwania w drzewie układu wbudowanego. Każdy wpis na liście jest krotką (obiektu, liczby elementów podrzędnych). Weźmy na przykład taki DOM:
<div style="width: 0;">
<span style="color: blue; position: relative;">Hi</span> <b>there</b>.
</div>
Właściwość width
ma wartość 0, więc wiersz zaczyna się między słowami „Hi”. i „tam”.
Jeśli kontekst formatowania wbudowanego w danej sytuacji jest przedstawiony jako drzewo, wygląda tak:
{
"Line box": {
"Box <span>": {
"Text": "Hi"
}
},
"Line box": {
"Box <b>": {
"Text": "There"
}
},
{
"Text": "."
}
}
Lista kartotekowa wygląda tak:
- (Pole wiersza, 2)
- (Pole <span>, 1)
- (Wyślij SMS-a „Cześć”, 0)
- (Pole wiersza, 3)
- (Pole <b>, 1)
- (Tekst „tam”, 0)
- (Tekst „.", 0)
Taka struktura danych ma wielu użytkowników: interfejsy API ułatwień dostępu,
i geometrii, np.
getClientRects
i contenteditable
.
Każdy z nich ma inne wymagania.
Komponenty te uzyskują dostęp do płaskiej struktury danych za pomocą podręcznego kursora.
Kursor
ma interfejsy API, takie jak MoveToNext
, MoveToNextLine
, CursorForChildren
.
Ta reprezentacja kursora sprawdza się bardzo dobrze w przypadku treści tekstowych z wielu powodów:
- Kolejne iteracje w kolejności wyszukiwania z najwyższym poziomem szczegółowości są bardzo szybkie. Jest on używany bardzo często, ponieważ przypomina ruchy kursora. Jest to płaska lista, więc wyszukiwanie oparte na głębokości zwiększa tylko przesunięcie tablicy, szybkie iteracje i lokalizację pamięci.
- Zapewnia wyszukiwanie szerokokątne, co jest konieczne, gdy na przykład na malowanie tła w polach z liniami i w tekście.
- Znajomość liczby elementów podrzędnych sprawia, że szybko przechodzimy do kolejnego rodzeństwa (po prostu zwiększ przesunięcie tablicy o tę liczbę).
Drzewa nieruchomości
DOM to drzewo elementów (plus węzły tekstowe), a CSS może stosować różne stylem do elementów.
Są one wyświetlane na 4 sposoby:
- Układ: dane wejściowe algorytmu ograniczenia układu.
- Farowanie: sposób malowania i rastrowania elementu. (ale nie jego elementów potomnych).
- Wizualne: efekty rastrowe/rysowania zastosowane w drzewie podrzędnym DOM, takich jak przekształcenia, filtry i przycinanie.
- Przewijanie: wyrównany do osi i zaokrąglony róg. i przewijania należącego do niego poddrzewa.
Drzewa właściwości to struktury danych, które wyjaśniają, jak efekty wizualne i przewijane są stosowane do elementów DOM. Zapewniają odpowiedzi na pytania takie jak: gdzie, względem ekranu, jest danym elementem DOM, biorąc pod uwagę rozmiar i położenie układu? Oraz: jakiej sekwencji operacji GPU należy użyć, aby zastosować efekty wizualne i przewijane?
Wizualne i przewijane efekty w internecie są w pełni skomplikowane. Dlatego najważniejszą rzeczą, jaką robią drzewa właściwości, jest przekształcanie złożoności w jedną strukturę danych, która dokładnie odzwierciedla ich strukturę i znaczenie, a jednocześnie reszta złożoności DOM i CSS. Dzięki temu możemy wdrożyć algorytmy, które skuteczniej komponują i przewijają. W szczególności:
- Geometria potencjalnie podatna na błędy i inne obliczenia które można scentralizować w jednym miejscu.
- Złożoność budowy i aktualizowania drzew nieruchomości izolowana do jednego etapu potoku renderowania.
- Drzewa właściwości można dużo łatwiej i szybciej wysyłać do innych wątków i procesów niż w stanie pełnego DOM, dzięki czemu można ich używać w wielu zastosowaniach.
- Im więcej jest zastosowań, tym więcej korzyści uzyskamy dzięki zapisanemu buforowaniu geometrii ponieważ mogą korzystać ze swoich danych pamięci podręcznej.
RenderingNG wykorzystuje drzewa właściwości do różnych celów, m.in. do:
- Oddzielenie komponowania od farby i komponowanie od wątku głównego.
- Określenie optymalnej strategii komponowania / rysowania.
- Pomiary IntersectionObserver geometrii.
- Unikanie pracy z elementami poza ekranem i kafelkami tekstur GPU.
- Efektywnie i dokładnie unieważnia renderowanie i rastrowanie.
- Pomiary layout shift i największe wyrenderowanie treści w Podstawowych wskaźnikach internetowych.
Każdy dokument internetowy ma 4 osobne drzewa właściwości: przekształcanie, klipy, efekty i przewijanie(*). Drzewo przekształceń przedstawia przekształcenia i przewijanie CSS. (Przekształcenie przewijane jest reprezentowane jako macierz przekształceń 2D). Drzewo klipów reprezentuje dodatkowe klipy. Drzewo efektów prezentuje wszystkie pozostałe efekty wizualne: przezroczystość, filtry, maski, tryby mieszania oraz inne rodzaje klipów, np. ścieżkę do klipu. Drzewo przewijania przedstawia informacje o przewijaniu, np. sposób przewijania łańcuch, jest potrzebny do przewijania wątku kompozytora. Każdy węzeł w drzewie właściwości odpowiada przewijaniu lub efektowi wizualnemu zastosowanemu przez element DOM. Jeśli wywołuje wiele skutków, w każdym drzewie może być więcej niż jeden węzeł drzewa właściwości dla tego samego elementu.
Topologia każdego drzewa jest jak rozproszona reprezentacja DOM. Jeśli np. mamy 3 elementy DOM z rozszerzonymi klipami, pojawią się 3 węzły drzewa klipsa, a struktura drzewa klipu będzie podążać za relacji blokowej między nadmiarowymi klipami. Występują też połączenia między drzewami. Linki te wskazują względną hierarchię DOM, a co za tym idzie, kolejność ich zastosowań. Jeśli na przykład przekształcenie elementu DOM znajduje się pod innym elementem DOM z filtrem, to oczywiście przekształcenie będzie stosowane przed filtrem.
Każdy element DOM ma stan drzewa właściwości, czyli 4-krotkę (przekształcanie, przycinanie, efekt, przewijanie) wskazujący najbliższy klip nadrzędny, przekształcania i tworzenia węzłów drzewa, które działają na danym elemencie. To bardzo wygodne rozwiązanie, ponieważ dzięki tym informacjom znamy dokładną listę klipów, przekształcenia i efekty, które można do nich zastosować, i w jakiej kolejności. Dzięki temu wiemy, gdzie znajduje się go na ekranie i jak go narysować.
Przykład
(źródło).
<html>
<div style="overflow: scroll; width: 100px; height: 100px;">
<iframe style="filter: blur(3px);
transform: rotateZ(1deg);
width: 100px; height: 300px"
id="one" srcdoc="iframe one"></iframe>
</div>
<iframe style="top:200px;
transform: scale(1.1) translateX(200px)" id=two
srcdoc="iframe two"></iframe>
</html>
W poprzednim przykładzie (nieco innym niż we wprowadzeniu) Oto najważniejsze elementy wygenerowanych drzew właściwości:
Wyświetl listy i fragmenty renderowania
Wyświetlany element zawiera polecenia rysowania niskiego poziomu (zobacz tutaj) które mogą być zrastrowane Skia. Elementy wyświetlane zazwyczaj są proste, wykonując jedynie kilka poleceń rysowania, takich jak obrysowanie obramowania lub tła. Spacer drzewa farby powtarza się nad drzewem układu i powiązanymi fragmentami zgodnie z kolejnością renderowania CSS. aby utworzyć listę wyświetlanych elementów.
Na przykład:
<div id="green" style="background:green; width:80px;">
Hello world
</div>
<div id="blue" style="width:100px;
height:100px; background:blue;
position:absolute;
top:0; left:0; z-index:-1;">
</div>
Kod HTML i CSS utworzy następującą listę wyświetlania: gdzie każda komórka to wyświetlany element:
Tło widoku | #blue (tło) |
#green (tło) |
#green tekst wbudowany |
---|---|---|---|
drawRect w rozmiarze 800 x 600 i w kolorze białym. |
drawRect w rozmiarze 100 x 100 w pozycji 0,0 i w kolorze niebieskim. |
drawRect w rozmiarze 80 x 18 w pozycji 8,8 i w kolorze zielonym. |
drawTextBlob z pozycją 8 i 8 i tekstem „Hello world”. |
Lista produktów jest uporządkowana od początku do końca. W powyższym przykładzie zielony element div znajduje się przed niebieskim elementem div w kolejności DOM, ale kolejność renderowania CSS wymaga, by element div z ujemnym z-indeksem został pomalowany przed (krok 3) zielonym elementem div (krok 4.1). Elementy displayowe odpowiadają poszczególnym etapom specyfikacji kolejności renderowania CSS. Pojedynczy element DOM może skutkować pojawieniem się kilku elementów wyświetlanych, . Ta szczegółowość jest ważna, ponieważ pozwala przedstawić pełną złożoność specyfikacji zamówienia renderowania CSS: np. przeplatania utworzonego z ujemną marżą:
<div id="green" style="background:green; width:80px;">
Hello world
</div>
<div id="gray" style="width:35px; height:20px;
background:gray;margin-top:-10px;"></div>
Powoduje to utworzenie poniższej listy wyświetlanej, z której każda komórka reprezentuje wyświetlany element:
Tło widoku | #green (tło) |
#gray (tło) |
#green tekst wbudowany |
---|---|---|---|
drawRect w rozmiarze 800 x 600 i w kolorze białym. |
drawRect w rozmiarze 80 x 18 w pozycji 8,8 i w kolorze zielonym. |
drawRect w rozmiarze 35 x 20 w pozycji 8,16 i w kolorze szarym. |
drawTextBlob z pozycją 8 i 8 i tekstem „Hello world”. |
Wyświetlana lista elementów jest przechowywana i może być ponownie wykorzystywana w późniejszych aktualizacjach. Jeśli obiekt szablonu nie zmienił się podczas malowania po drzewie, jego wyświetlane elementy zostaną skopiowane z poprzedniej listy. Dodatkowa optymalizacja zależy od właściwości specyfikacji zamówienia renderowania CSS: konteksty stosów są atomowe. Jeśli w kontekście stosu nie zmienił się żaden obiekt szablonu, spacer po drzewie pomija kontekst i skopiuje całą sekwencję wyświetlanych elementów z poprzedniej listy.
Podczas spaceru po malowaniu drzewa obecny stan drzewa właściwości zostanie zachowany a lista wyświetlanych elementów jest podzielona na „fragmenty”, elementów wyświetlanych, które mają ten sam stan drzewa właściwości. Zostało to pokazane w tym przykładzie:
<div id="scroll" style="background:pink; width:100px;
height:100px; overflow:scroll;
position:absolute; top:0; left:0;">
Hello world
<div id="orange" style="width:75px; height:200px;
background:orange; transform:rotateZ(25deg);">
I'm falling
</div>
</div>
Powoduje to utworzenie poniższej listy wyświetlanej, z której każda komórka reprezentuje wyświetlany element:
Tło widoku | #scroll (tło) |
#scroll tekst wbudowany |
#orange (tło) |
#orange tekst wbudowany |
---|---|---|---|---|
drawRect w rozmiarze 800 x 600 i w kolorze białym. |
drawRect w rozmiarze 100 x 100 w pozycji 0,0 i w kolorze różowym. |
drawTextBlob z pozycją 0,0 i tekstem „Hello world”. |
drawRect w rozmiarze 75 x 200 w pozycji 0,0 i w kolorze pomarańczowym. |
drawTextBlob z pozycją 0,0 i tekstem „Upadam”. |
Drzewo właściwości przekształcenia i fragmenty farby będą wyglądać tak (uproszczone w celu zachowania zwięzłości):
Uporządkowana lista fragmentów farby które są grupami wyświetlanych elementów i stanem drzewa właściwości, to dane wejściowe na etapie nakładania warstw w potoku renderowania. Całą listę fragmentów renderowania można połączyć w jedną skomponowaną warstwę i zrastrować ale wymagałoby to kosztownej rasteryzacji przy każdym przewijaniu przez użytkownika. Dla każdego fragmentu malowania można utworzyć skomponowaną warstwę i zrastrowane osobno, by uniknąć ponownej rasteryzacji, ale może to szybko wyczerpać pamięć GPU. Na etapie tworzenia warstw musisz znaleźć kompromis między pamięcią GPU i obniżeniem kosztów, gdy sytuacja się zmieni. Dobrym ogólnym podejściem jest domyślne scalanie fragmentów, a nie scalać fragmentów farby ze stanami drzewa właściwości, które powinny się zmienić w wątku kompozytora, takich jak przewijanie wątku przez kompozytor lub animację przekształcania wątku.
W poprzednim przykładzie najlepiej byłoby utworzyć dwie skomponowane warstwy:
- Skomponowana warstwa o wymiarach 800 x 600 zawierająca polecenia rysowania:
drawRect
w rozmiarze 800 x 600 i w kolorze białymdrawRect
w rozmiarze 100 x 100 w pozycji 0,0 i w kolorze różowym
- Warstwa skomponowana 144 x 224 zawierająca polecenia rysowania:
drawTextBlob
z pozycją 0,0 i tekstem „Hello world”- przetłumacz 0,18
rotateZ(25deg)
drawRect
w rozmiarze 75 x 200 w pozycji 0,0 i kolor pomarańczowydrawTextBlob
z pozycją 0,0 i tekstem „Upadam”
Jeśli użytkownik przewinie stronę #scroll
,
druga skomponowana warstwa jest przenoszona, ale rasteryzacja nie jest wymagana.
Na przykład: z poprzedniej sekcji o drzewach nieruchomości, jest 6 fragmentów farby. Wraz z ich stanami drzewa właściwości (transform, klip, efekt, przewijanie) są to:
- Tło dokumentu: przewijanie dokumentu, klip z dokumentu, katalog główny, przewijanie dokumentu.
- Poziomy, pionowy i przewijany narożnik elementu div (trzy osobne fragmenty farby):
przewijanie dokumentu, klip z dokumentu, rozmycie
#one
, przewijanie dokumentu. - Element iframe
#one
: obrót#one
, nadmiarowy klip przewijany, rozmycie#one
, przewijanie div. - Element iframe
#two
: skala#two
, klip z dokumentu, katalog główny, przewijanie dokumentu.
Ramki kompozytora: powierzchnie, powierzchnie renderowane i płytki tekstur GPU
Przeglądarka i procesy renderowania zarządzają rasteryzacją treści, a następnie prześlij ramki kompozytora do procesu Viz, aby wyświetlić je na ekranie. Ramki kompozytora ilustrują sposób łączenia zrastrowanych treści i sprawnie rysować, używając GPU.
Karty
Teoretycznie proces renderowania lub kompozytor procesów przeglądarki może rasteryzować piksele. do pojedynczej tekstury o pełnym rozmiarze widocznego obszaru mechanizmu renderowania, a następnie prześlij ją do programu Viz. Aby ją wyświetlić, kompozytor displayowych musiałby po prostu skopiować piksele z tej pojedynczej tekstury na odpowiednie miejsce w buforze ramki (np. ekran). Gdyby jednak ten kompozytor chciał zaktualizować nawet jednego piksela, wymagałby ponownej rasteryzacji całego widocznego obszaru i przesłania nowej tekstury do Viz.
Zamiast tego widoczny obszar jest podzielony na kafelki. W przypadku każdego kafelka znajduje się osobny kafelek z teksturą GPU, w którym znajdują się zrasteryzowane piksele odpowiadające części widocznego obszaru. Mechanizm renderowania może wtedy aktualizować poszczególne kafelki, a nawet wystarczy zmienić położenie istniejących kafelków na ekranie. Na przykład podczas przewijania strony internetowej położenie istniejących kafelków zmienia się tylko sporadycznie w górę w przypadku treści niżej na stronie nowy kafelek musiałby być zrastrowany.
![Cztery kafelki.](https://developer.chrome.com/static/docs/chromium/renderingng-data-structures/image/four-tiles-b115857a2f73.jpg?authuser=9&hl=pl)
Quady i powierzchnie
Kafelki tekstur GPU to specjalny rodzaj quadów, To tylko wymyślna nazwa dla jednej lub innej kategorii tekstury. Czwórka wskazuje teksturę wejściową i wskazuje, jak ją przekształcić i zastosować do niej efekty wizualne. Na przykład zwykłe kafelki treści mają przekształcenie, które wskazuje ich pozycję na osi x i y w siatce kafelków.
Te zrasteryzowane kafelki są zapakowane w zgodności z renderowaniem, która jest listą czworokątów. Przebieg renderowania nie zawiera żadnych informacji o pikselach. znajdziesz w nim instrukcje, gdzie i jak narysować poszczególne czworokąty, aby uzyskać oczekiwany efekt. Każdy kafelek tekstury GPU obejmuje obszar rysowania. Kompozytor wyświetlania musi przeprowadzać iterację przez listę czworokątów, rysując każdy z nich z określonymi efektami wizualnymi, w celu wygenerowania oczekiwanego parametru wyjściowego piksela w ramach przebiegu renderowania. Komponowanie czworokątów rysowania dla procesu renderowania można wydajnie wykonywać w GPU, bo dozwolone efekty wizualne są starannie dobierane tak, aby odzwierciedlały bezpośrednio funkcje GPU.
Oprócz kafelków zrastrowanych dostępne są dodatkowe typy czworokątów rysowania. Są na przykład czworokąty w jednolitym kolorze, które nie są w ogóle poparte teksturą. lub tekstury rysowane czworokąty w przypadku tekstur niepołożonych (np. filmów lub obiektów canvas).
Inna ramka kompozytora może być też osadzona w ramce kompozytora. Na przykład kompozytor przeglądarki tworzy ramkę kompozytora z interfejsem przeglądarki, i pusty prostokąt, w którym zostanie umieszczona treść kompozytora renderowania. Innym przykładem są elementy iframe izolowane od witryny. Osadzanie się w ten sposób odbywa się za pomocą przestrzeni.
Gdy kompozytor przesyła ramkę kompozytora, towarzyszy mu identyfikator nazywamy identyfikatorem surfaces, co pozwala innym ramkom kompozytora umieszczać go przez odwołanie. Najnowsza ramka kompozytora przesłana z określonym identyfikatorem powierzchni jest przechowywana przez Viz. Inna klatka kompozytora może odwoływać się do niej później za pomocą czworokąta rysowania powierzchni, więc Viz wie, co narysować. (Pamiętaj, że czworokąty do rysowania powierzchni zawierają tylko identyfikatory powierzchni, a nie tekstury).
Pośrednie karty renderowania
Niektóre efekty wizualne, takie jak wiele filtrów lub zaawansowane tryby mieszania, wymagają narysowania co najmniej dwóch czworokątów do tekstury pośredniej. Następnie tekstura pośrednia jest rysowana w buforze miejsca docelowego w GPU (lub innej tekstury pośredniej), z wykorzystaniem efektu wizualnego. Aby to umożliwić, ramka kompozytora zawiera listę procesów renderowania. Zawsze istnieje główny kod renderowania, która jest rysowana jako ostatnia i której miejsce docelowe odpowiada buforowi ramki, i może być ich więcej.
Nazwa może wynikać z możliwości wielu kart renderowania „render Pass”. Każda karta musi być wykonywana sekwencyjnie w GPU, w wielu „kartach” a pojedynczy przebieg można wykonać w ramach pojedynczego, niezwykle równoległego przetwarzania GPU.
Agregacja
Do Viz przesyłanych jest wiele ramek kompozytora, i muszą być rysowane razem na ekranie. Jest to możliwe dzięki fazie agregacji, która przekształca je w jeden, ramki agregowanego kompozytora. Agregacja zastępuje czworokąty rysowania powierzchni przez określone ramki kompozytora. Można też zoptymalizować wyświetlanie zbędnych tekstur pośrednich i treści spoza ekranu. Na przykład w wielu przypadkach ramka kompozytora dla elementu iframe izolowanego z witryny nie wymaga własnej tekstury pośredniej, i można go narysować bezpośrednio w buforze ramki za pomocą odpowiednich czworokątów rysowania. Etap agregacji określa takie optymalizacje. i stosuje je na podstawie globalnej wiedzy, która nie jest dostępna dla poszczególnych kompozytorów renderowania.
Przykład
Oto ramki kompozytora reprezentujące przykład od początku argumentu tego posta.
- Powierzchnia
foo.com/index.html
: id=0- Renderowanie z przebiegiem 0: rysowanie na ekranie wyjściowym.
- Renderowanie z płytką rysunkową: rysowanie z rozmyciem 3 pikseli i przypinanie do przebiegu 0 renderowania.
- Renderowanie – przebieg 1:
- Narysuj czworokąty dla zawartości kafelków elementu iframe
#one
, podając pozycje x i y dla każdego z nich.
- Narysuj czworokąty dla zawartości kafelków elementu iframe
- Renderowanie – przebieg 1:
- Powierzchnia, rysowanie prostokąta o identyfikatorze 2, ze skalą i przekształceniem.
- Renderowanie z płytką rysunkową: rysowanie z rozmyciem 3 pikseli i przypinanie do przebiegu 0 renderowania.
- Renderowanie z przebiegiem 0: rysowanie na ekranie wyjściowym.
- Interfejs użytkownika przeglądarki: ID=1
- Renderowanie z przebiegiem 0: rysowanie na ekranie wyjściowym.
- Rysuj kwadraty dla interfejsu przeglądarki (również na kafelkach)
- Renderowanie z przebiegiem 0: rysowanie na ekranie wyjściowym.
- Platforma
bar.com/index.html
: ID=2- Renderowanie z przebiegiem 0: rysowanie na ekranie wyjściowym.
- Narysuj czworokąty treści elementu iframe
#two
, podając pozycje x i y dla każdego z nich.
- Narysuj czworokąty treści elementu iframe
- Renderowanie z przebiegiem 0: rysowanie na ekranie wyjściowym.
Ilustracje Uny Kravets.