Temel veri yapıları ve bunların renderNG'deki rolleri

Chris Harrelson
Chris Harrelson
Daniel Cheng
Daniel Cheng
Philip Rogers
Philip Rogers
Koji Ishi
Koji Ishi
Ian Kilpatrick
Ian Kilpatrick
Kyle Charbonneau
Kyle Charbonneau

Bu serinin önceki yayınları, RenderingNG mimarisinin hedeflerine, temel özelliklerine ve üst düzey bileşen parçalarına genel bir bakış sundu. Şimdi, oluşturma ardışık düzeninin giriş ve çıkışları olan temel veri yapılarını inceleyelim.

Bu veri yapıları şunlardır:

  • Hangi web dokümanlarının hangi oluşturma işleminde ve hangi Blink oluşturucusunu temsil ettiğini gösteren yerel ve uzak düğümlerden oluşan çerçeve ağaçları.
  • Sabit parça ağacı, düzen sınırlama algoritmasının çıktısını (ve girişini) temsil eder.
  • Bir web dokümanının dönüşüm, kırpma, efekt ve kaydırma hiyerarşilerini temsil eden ve ardışık düzen genelinde kullanılan mülk ağaçları.
  • Görüntüleme listeleri ve boyama parçaları, kafes ve katmanlaştırma algoritmalarına yapılan girişlerdir.
  • Bileşik çerçeveler GPU kullanarak çizim yapmak için kullanılan yüzeyleri, oluşturma yüzeylerini ve GPU doku karolarını içerir.

Bu veri yapılarına göz atmadan önce, bir önceki gönderide yer alan aşağıdaki basit örneği göstermek istiyorum. Bu gönderide bu örneği birkaç kez kullanıp veri yapılarının üzerine nasıl uygulandığını göstereceğim.

<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>

Ağaç çerçeveleri

Chrome bazen çapraz kaynak çerçevesini üst çerçevesinden farklı bir oluşturma işleminde oluşturmayı tercih edebilir.

Giriş bölümündeki örnekte, toplamda üç çerçeve vardır:

İki iframe içeren bir üst çerçeve foo.com.

Chromium, site izolasyonu ile bu web sayfasını oluşturmak için iki oluşturma işlemi kullanır. Her oluşturma işleminin, söz konusu web sayfasının çerçeve ağacının kendi temsili vardır:

İki oluşturma işlemini temsil eden iki çerçeve ağacı.

Farklı bir işlemde oluşturulan bir kare, uzak kare olarak temsil edilir. Uzak kare, oluşturma sırasında bir yer tutucu olarak hareket etmesi için gereken minimum bilgileri (ör. boyutları) içerir. Aksi takdirde, uzak kare asıl içeriğini oluşturmak için gereken bilgileri içermez.

Buna karşılık yerel bir çerçeve, önceki yayınlarda açıklanan standart oluşturma ardışık düzeninden geçecek bir kareyi temsil eder. Yerel çerçeve, söz konusu çerçeveye ait verileri (DOM ağacı ve stil verileri gibi) oluşturulabilecek ve görüntülenebilecek bir şeye dönüştürmek için gereken tüm bilgileri içerir.

Oluşturma ardışık düzeni, yerel çerçeve ağacı parçasının ayrıntı düzeyine göre çalışır. Ana çerçeve olarak foo.com kullanılan daha karmaşık bir örnek düşünün:

<iframe src="bar.com"></iframe>

Şu bar.com alt çerçeve ise:

<iframe src="foo.com/etc"></iframe>

Hâlâ yalnızca iki oluşturucu olsa da artık ikisi foo.com için oluşturma işleminde ve biri bar.com için oluşturma işleminde olmak üzere üç yerel çerçeve ağacı parçası vardır:

İki oluşturma işleminin ve üç çerçeve ağaç parçasının gösterimi.

Web sayfası için bir birleştirme çerçevesi oluşturmak için Viz, aynı anda üç yerel çerçeve ağacının her birinin kök çerçevesinden bir birleştirici çerçevesi isteğinde bulunur ve daha sonra, bunları birleştirir. (Bu yazının ilerleyen kısımlarındaki birleştirici çerçeveleri bölümüne de bakın.)

foo.com ana çerçevesi ve foo.com/other-page alt çerçeve, aynı çerçeve ağacının parçasıdır ve aynı süreçte oluşturulur. Ancak iki çerçeve, farklı yerel çerçeve ağacı parçalarının parçası oldukları için hâlâ bağımsız belge yaşam döngülerine sahiptir. Bu nedenle, tek güncellemede her ikisi için bir birleştirici çerçevesi oluşturulamaz. Oluşturma işleminde, foo.com/other-page için oluşturulan birleştirici çerçevesini doğrudan foo.com ana çerçevesinin birleştirici çerçevesiyle birleştirmek için yeterli bilgi yoktur. Örneğin, işlem dışı bar.com üst çerçevesi, iframe'i CSS ile dönüştürerek veya iframe'in bölümlerini DOM'deki diğer öğelerle kapatarak foo.com/other-url iframe'in görüntülenmesini etkileyebilir.

Görsel özellik güncelleme şelalesi

Cihaz ölçek faktörü ve görüntü alanı boyutu gibi görsel özellikler, oluşturulan çıktıyı etkiler ve yerel çerçeve ağacı parçaları arasında senkronize edilmelidir. Her bir yerel çerçeve ağaç parçasının kökü, kendisiyle ilişkilendirilmiş bir widget nesnesine sahiptir. Görsel özellik güncellemeleri, üstten alta doğru kalan widget'lara uygulanmadan önce ana çerçevenin widget'ına gider. Örneğin, görüntü alanı boyutu değiştiğinde:

Önceki metinde açıklanan işlemin şeması.

Bu işlem anlık olmadığından çoğaltılan görsel özellikler bir senkronizasyon jetonu da içerir. Viz oluşturucu, tüm yerel çerçeve ağacı parçalarının geçerli senkronizasyon jetonuyla bir birleştirici çerçevesi göndermesini beklemek için bu senkronizasyon jetonunu kullanır. Bu işlem, farklı görsel özelliklere sahip birleştirici çerçevelerinin karıştırılmasını önler.

Sabit parça ağacı

Sabit parça ağacı, oluşturma ardışık düzeninin düzen aşamasının çıktısıdır. Sayfadaki tüm öğelerin konumunu ve boyutunu temsil eder (dönüşüm uygulanmadan).

Her bir ağaçtaki parçaların, bir parçanın gerekli düzen olarak işaretlendiği şekilde gösterilmesi.

Her parça, bir DOM öğesinin bir bölümünü temsil eder. Öğe başına genellikle yalnızca bir parça bulunur ancak yazdırma sırasında farklı sayfalara veya çok sütunlu bağlamda sütunlara bölünürse daha fazla parça olabilir.

Düzenden sonra her parça sabit hale gelir ve bir daha asla değişmez. Ayrıca birkaç ek kısıtlama da uygularız. Yapmadıklarımız:

  • Ağaçta "yukarı" referanslarına izin verin. (Alt öğe, üst öğe işaretçisine sahip olamaz.)
  • veri "baloncuk" olarak ayarlanır (bir alt öğeden gelen bilgileri değil, yalnızca alt öğelerindeki bilgileri okur).

Bu kısıtlamalar, bir parçayı sonraki düzen için yeniden kullanmamıza olanak tanır. Bu kısıtlamalar olmasaydı ağacın tamamını yeniden üretmemiz gerekirdi ve bu da çok pahalı olurdu.

Çoğu düzen genellikle artımlı güncellemelerdir. Örneğin, kullanıcının bir öğeyi tıklamasına yanıt olarak kullanıcı arayüzünün küçük bir bölümünü güncelleyen bir web uygulaması. İdeal olarak düzen sadece ekranda gerçekte değiştirilen şeyle orantılı olarak çalışmalıdır. Bunu, önceki ağacın mümkün olduğunca çok bölümünü yeniden kullanarak yapabiliriz. Bu, (tipik) yalnızca ağacın omurgasını yeniden inşa etmemiz gerektiği anlamına gelir.

Gelecekte, bu değişmez tasarım, gerektiğinde sabit parça ağacını iş parçacığı sınırlarından geçirmek (farklı bir iş parçacığında sonraki aşamaları gerçekleştirmek), düzgün bir düzen animasyonu için birden çok ağaç oluşturmak veya paralel kurgusal düzenler gerçekleştirmek gibi ilginç şeyler yapabilmemize olanak tanıyacak. Bu ayrıca bize çoklu iş parçacığı düzeneği sunma potansiyeli de sağlıyor.

Satır içi parça öğeleri

Satır içi içerik (Ağırlıklı olarak stilize edilmiş metin) biraz farklı bir temsil kullanır. Satır içi içeriği, kutular ve işaretçiler içeren bir ağaç yapısı yerine, ağacı temsil eden düz bir liste halinde sunarız. Başlıca avantajı satır içi veriler için düz liste gösteriminin hızlı, satır içi veri yapılarını incelemek veya sorgulamak için kullanışlı olmasıdır. Ayrıca bellek açısından verimlidir. Metin oluşturma işlemi çok karmaşık olduğundan ve yüksek düzeyde optimize edilmediği sürece ardışık düzenin en yavaş parçası olabileceğinden bu işlem, web oluşturma performansı için son derece önemlidir.

İlginç bir tarih olarak belirtmek gerekirse bu durum, başlangıçta metin düzenleyiciye benzer bir şekilde oluşturulduğu için Internet Explorer'ın önceden DOM'unu temsil etmesine çok benzer.

Düz liste, her satır içi biçimlendirme bağlamı için, satır içi düzen alt ağacında derinliğe öncelik veren arama sırasına göre oluşturulur. Listedeki her giriş bir unsurdur (nesne, alt öğe sayısı). Örneğin, şu DOM'yi ele alalım:

<div style="width: 0;">
  <span style="color: blue; position: relative;">Hi</span> <b>there</b>.
</div>

(Satırın "Yüksek" ve "orada" arasında kayması için width özelliğinin 0 olarak ayarlandığını unutmayın.) Bu durumun satır içi biçimlendirme bağlamı ağaç olarak sunulduğunda şöyle görünür:

{
  "Line box": {
    "Box <span>": {
      "Text": "Hi"
    }
  },
  "Line box": {
    "Box <b>": {
      "Text": "There"
    }
  },
  {
    "Text": "."
  }
}

Düz liste aşağıdaki gibi görünür:

  • (Satır kutusu, 2)
  • (Kutu <span>, 1)
  • ("Merhaba" kısa mesajı, 0)
  • (Satır kutusu, 3)
  • (Kutu <b>, 1)
  • ("orada" metni, 0)
  • (Metin ".", 0)

Bu veri yapısının birçok tüketicisi vardır: Accessibility API'ler, getClientRects ve contenteditable gibi geometri API'leri. Her biri farklı şartlara tabidir. Bu bileşenler, düz veri yapısına bir kolaylık imleciyle erişir.

İmleç MoveToNext, MoveToNextLine, CursorForChildren gibi API'lere sahiptir. Bu imleç gösterimi, çeşitli nedenlerden dolayı metin içeriği için çok güçlüdür:

  • Derinlik öncelikli arama sırasında yineleme çok hızlıdır. Bu imleç hareketine benzer olduğu için çok sık kullanılır. Derinlik öncelikli arama düz bir liste olduğundan sadece dizi ofsetini artırarak hızlı yinelemeler ve bellek konumu sağlar.
  • Örneğin, satır ve satır içi kutuların arka planını boyarken gereken öncelikli arama özelliğini sağlar.
  • Alt alt öğe sayısını bilmek, sonraki eşdüzey öğeye hızla geçilmesini sağlar (dizi ofsetini bu sayıya göre artırmanız yeterlidir).

Mülk ağaçları

Bildiğiniz gibi DOM bir öğe ağacıdır (ayrıca metin düğümleri) ve CSS öğelere çeşitli stiller uygulayabilir.

Bunlar çoğunlukla dört etki şeklinde gelir:

  • Düzen: Düzen kısıtlama algoritmasına yapılan girişler.
  • Boya: Öğenin nasıl boyanacağı ve kafesleneceği (alt öğelerinin değil) nasıl yapılacağı.
  • Görsel: DOM alt ağacına uygulanan dönüştürme, filtreler ve kırpma gibi kafes/çizim efektleri.
  • Kaydırma: Eksene hizalı ve yuvarlatılmış köşenin içerdiği alt ağacın kırpılması ve kaydırılması.

Mülk ağaçları, görsel efektlerin ve kaydırma efektlerinin DOM öğelerine nasıl uygulandığını açıklayan veri yapılarıdır. "Düzen boyutu ve konumu dikkate alındığında, belirli bir DOM öğesi ekrana göre nerededir?" gibi soruları yanıtlamaya yönelik araçlar sağlarlar. Görsel ve kaydırma efektleri uygulamak için GPU işlemleri dizisi nedir?

Web'deki görsel ve kaydırma efektleri tüm ihtişamıyla çok karmaşıktır. Bu yüzden mülk ağaçlarının yaptığı en önemli şey, bu karmaşıklığı, yapısını ve anlamını kesin olarak temsil eden tek bir veri yapısına dönüştürmek, aynı zamanda DOM ve CSS'nin karmaşıklığını da ortadan kaldırmaktır. Bu, birleştirme ve kaydırma algoritmalarını çok daha güvenli bir şekilde uygulamamıza olanak tanır. Özellikle:

  • Hataya açık olabilecek geometri ve diğer hesaplamalar tek bir yerde toplanabilir.
  • Mülk ağaçlarını oluşturmanın ve güncellemenin karmaşıklığı tek bir oluşturma ardışık düzeni aşamasında gerçekleşir.
  • Özellik ağaçlarını farklı iş parçacığı ve süreçlere tam DOM durumuna kıyasla çok daha kolay ve hızlı bir şekilde gönderebilir, bu sayede bunları birçok kullanım alanında kullanmak mümkün hale gelir.
  • Kullanım alanları ne kadar fazla olursa, birbirlerinin önbelleklerini yeniden kullanabileceklerinden, geometrik şekil önbelleğe almanın üst köşeye yerleştirildiğinde sağladığı kazanç da o kadar fazla olur.

RenderingNG, mülk ağaçlarını aşağıdakiler gibi birçok amaç için kullanır:

  • Kompozisyon boyadan ve ana iş parçacığından birleştiriliyor
  • En uygun birleştirme / çizim stratejisini belirleme.
  • IntersectionObserver geometrisinin ölçümüdür.
  • Ekran dışı öğeler ve GPU doku karoları için çalışma yapılması önlenir.
  • Boya ve kafesi verimli ve doğru şekilde geçersiz kılma.
  • Core Web Vitals'da düzen kaymasını ve Largest Contentful Paint ölçümü.

Her web dokümanının dört ayrı özellik ağacı vardır: dönüştürme, kırpma, efekt ve kaydırma.(*) Dönüşüm ağacı, CSS dönüşümlerini ve kaydırmayı temsil eder. (Kaydırma dönüşümü, 2D dönüşüm matrisi olarak temsil edilir.) Klip ağacı, taşma klipleri'ni temsil eder. Efekt ağacı diğer tüm görsel efektleri temsil eder: opaklık, filtreler, maskeler, harmanlama modları ve klip yolu gibi diğer klip türleri. Kaydırma ağacı, zincirlemenin birlikte nasıl kaydırıldığı gibi kaydırmayla ilgili bilgileri temsil eder; birleştirici iş parçacığında kaydırma yapmak için gereklidir. Bir özellik ağacındaki her düğüm, bir DOM öğesi tarafından uygulanan bir kaydırmayı veya görsel efekti temsil eder. Birden çok etkisi olursa aynı öğe için her ağaçta birden fazla özellik ağacı düğümü olabilir.

Her ağacın topolojisi, DOM'nin seyrek bir temsili gibidir. Örneğin, taşma kliplerine sahip üç DOM öğesi varsa üç klip ağacı düğümü olur ve klip ağacının yapısı, taşma klipleri arasındaki kapsayıcı blok ilişkisini izler. Ağaçlar arasında bağlantılar da vardır. Bu bağlantılar, düğümlerin göreli DOM hiyerarşisini ve dolayısıyla uygulama sırasını gösterir. Örneğin, bir DOM öğesindeki dönüşüm, filtreli başka bir DOM öğesinin altındaysa elbette dönüşüm işlemi filtreden önce uygulanır.

Her DOM öğesinin özellik ağacı durumu, söz konusu öğe üzerinde geçerli olan en yakın üst öğe klibini, dönüşümünü ve etki ağacı düğümlerini belirten 4 unsurdan (dönüştürme, klip, efekt, kaydırma) oluşur. Bu yöntem çok kullanışlıdır, çünkü bu bilgi sayesinde o öğeye uygulanan kliplerin, dönüşümlerin ve efektlerin listesini ve bunların sıralamasını tam olarak biliyoruz. Bu şekilde resmin ekranda nerede olduğunu ve nasıl çizileceğini öğrenebilirsiniz.

Örnek

(kaynak)

<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>

Önceki örnek için (giriştekinden biraz farklıdır) mülk ağaçlarının oluşturduğu temel öğeleri burada bulabilirsiniz:

Mülk ağacındaki çeşitli öğelere örnek.

Listeleri ve boya parçalarını görüntüle

Bir ekran öğesi, Skia ile pikselleştirilebilecek düşük düzeyli çizim komutları içerir (buraya bakın). Görüntüleme öğeleri, kenarlık veya arka plan çizme gibi yalnızca birkaç çizim komutuyla genellikle basittir. Boyama ağacı yürüyüşü, bir görüntüleme öğesi listesi oluşturmak için düzen ağacında ve ilişkili parçalarda CSS boyama sırasını takip eder.

Örneğin:

Yeşil bir dikdörtgenin içinde &quot;Merhaba dünya&quot; yazan mavi bir kutu.

<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>

Bu HTML ve CSS, her hücrenin bir görüntüleme öğesi olduğu aşağıdaki görüntüleme listesini oluşturur:

Görünümün arka planı #blue arka planı #green arka planı #green satır içi metin
800x600 boyutunda ve beyaz renkli drawRect. 0,0 konumunda 100x100 boyutlu ve mavi renkli drawRect. 8,8 konumunda 80x18 boyutlu ve yeşil renkli drawRect. drawTextBlob: 8,8. konumu ve "Merhaba dünya" metni.

Gösterilen öğe listesi arkadan öne gelecek şekilde sıralanır. Yukarıdaki örnekte, yeşil div, DOM sırasındaki mavi div'den öncedir ancak CSS boyama sırası, negatif z-endeksi mavi div'in yeşil div'den (3. adım) önce boyanmasını gerektirir (4.1 adımı). Görüntülü öğeler kabaca CSS boya siparişi spesifikasyonunun atomik adımlarına karşılık gelir. Tek bir DOM öğesi, #green'in arka plan için bir görüntüleme öğesine ve satır içi metin için başka bir görüntüleme öğesine sahip olması gibi çeşitli görüntüleme öğelerine neden olabilir. Bu ayrıntı düzeyi, CSS boyama siparişi spesifikasyonunun tüm karmaşıklığını (ör. negatif marj tarafından oluşturulan araya ekleme) temsil etmek açısından önemlidir:

Kısmen üzerinde gri bir kutu görünen yeşil bir dikdörtgen ve &quot;Merhaba dünya&quot; yazısı.

<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>

Bu, her hücrenin bir görüntüleme öğesi olduğu aşağıdaki görüntüleme listesini oluşturur:

Görünümün arka planı #green arka planı #gray arka planı #green satır içi metin
800x600 boyutunda ve beyaz renkli drawRect. 8,8 konumunda 80x18 boyutlu ve yeşil renkli drawRect. 8,16 konumunda 35x20 boyutlu ve gri renkli drawRect. drawTextBlob: 8,8. konumu ve "Merhaba dünya" metni.

Görünen öğe listesi depolanır ve sonraki güncellemeler tarafından yeniden kullanılır. Boyama ağacı yürüyüşü sırasında bir düzen nesnesi değişmediyse düzenin görüntüleme öğeleri önceki listeden kopyalanır. Ek optimizasyon, CSS boyama siparişi spesifikasyonunun bir özelliğine bağlıdır: bağlamları yığınlamak atomik olarak boyanır. Yığma bağlamında herhangi bir düzen nesnesi değişmediyse boyama ağacı yürüyüşü, yığın bağlamı atlar ve önceki listedeki görüntülü reklam öğelerinin sırasının tamamını kopyalar.

Boyama ağacı yürüyüşü sırasında geçerli mülk ağacı durumu korunur ve görüntüleme öğesi listesi, aynı mülk ağacı durumunu paylaşan görüntülü reklam öğeleri "parçaları" halinde gruplandırılır. Bu, aşağıdaki örnekte gösterilmiştir:

Eğik turuncu bir kutu bulunan pembe kutu.

<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>

Bu, her hücrenin bir görüntüleme öğesi olduğu aşağıdaki görüntüleme listesini oluşturur:

Görünümün arka planı #scroll arka planı #scroll satır içi metin #orange arka planı #orange satır içi metin
800x600 boyutunda ve beyaz renkli drawRect. 0,0 konumunda 100x100 boyutlu ve pembe renkli drawRect. drawTextBlob 0,0 konumuyla ve "Merhaba dünya" metniyle. 0,0 konumunda 75x200 boyutlu ve turuncu renkli drawRect. drawTextBlob: 0,0 konumuyla ve "Düşüyorum" metniyle.

Bu durumda dönüşüm özelliği ağacı ve boya parçaları şu şekilde olur (kısa olması için basitleştirilmiştir):

Önceki tablonun resmi; parça 1&#39;deki ilk iki hücre, üçüncü parça 2&#39;deki üçüncü hücre, yığın 3&#39;teki son iki hücre.

Görüntüleme öğesi grupları ve bir mülk ağacı durumu olan boya parçalarının sıralı listesi, oluşturma ardışık düzeninin katmanlandırma adımına yapılan girişlerdir. Boyama parçaları listesinin tamamı, birleştirilmiş tek bir katmanda birleştirilebilir ve birlikte piksellendirilebilir ancak bu işlem, kullanıcının ekranı her kaydırdığında pahalı pikselleştirme gerektirir. Her boya parçası için birleştirilmiş bir katman oluşturulabilir ve tüm yeniden tarama işlemlerini önlemek için ayrı ayrı pikseller uygulanabilir ancak bu, GPU belleğinin hızla tüketilmesine neden olur. Katmanlaştırma adımında, GPU belleği arasında denge kurması ve işler değiştiğinde maliyetlerin azaltılması gerekir. Varsayılan olarak parçaları birleştirmek ve birleştirici iş parçacığında değişmesi beklenen özellik ağacı durumlarını (ör. birleştirici iş parçacığı kaydırması veya birleştirici iş parçacığı dönüştürme animasyonları) içeren boya parçalarını birleştirmemek iyi bir genel yaklaşımdır.

Yukarıdaki örnek ideal olarak iki birleştirilmiş katman üretmelidir:

  • Çizim komutlarını içeren 800x600 boyutunda birleştirilmiş katman:
    1. 800x600 boyutlu ve beyaz renkli drawRect
    2. 0,0 konumunda 100x100 boyutlu ve pembe renkli drawRect
  • Çizim komutlarını içeren, 144x224 boyutlarında birleştirilmiş bir katman:
    1. drawTextBlob konumu 0,0 ve "Merhaba dünya" metniyle
    2. 0,18'i çevir
    3. rotateZ(25deg)
    4. 0,0 konumunda 75x200 boyutlu ve turuncu renkli drawRect
    5. drawTextBlob konumu 0,0 ve "Düşüyorum" metni

Kullanıcı #scroll öğesini kaydırırsa ikinci birleştirilmiş katman taşınır ancak pikselleştirme gerekmez.

Buradaki örnekte, mülk ağaçlarıyla ilgili bir önceki bölümde yer alan altı boya parçası vardır. (dönüştürme, klip oluştur, Efekt, Kaydırma) özellik ağacı durumlarıyla birlikte:

  • Doküman arka planı: doküman kaydırma, doküman klibi, kök, doküman kaydırma.
  • Div için yatay, dikey ve kaydırma köşesi (üç ayrı boya parçası): doküman kaydırma, doküman klibi, #one bulanıklaştırma, doküman kaydırma.
  • iFrame #one: #one döndürme, taşma kaydırma klibi, #one bulanıklaştırma, div kaydırma.
  • iFrame #two: #two ölçeği, doküman klibi, kök, doküman kaydırma.

Birleştirici çerçeveler: yüzeyler, oluşturma yüzeyleri ve GPU doku karoları

Önceki yayında açıklandığı gibi (çalışan bir örneği burada bulabilirsiniz), tarayıcı ve oluşturma süreçleri içeriğin pikselleştirilmesini yönetir, ardından birleştirici çerçevelerini ekranda göstermek üzere Viz işlemine gönderir. Bileşik çerçeveler, RenderingNG'nin pikselleştirilmiş içeriğin nasıl birleştirileceğini ve GPU kullanılarak verimli bir şekilde nasıl çizileceğini temsil etmesidir.

Kartlar

Teoride, bir oluşturma işlemi veya tarayıcı işlemi birleştiricisi, pikselleri oluşturucu görüntü alanının tam boyutunda tek bir doku halinde pikselleştirir ve bu dokuyu Viz'e gönderebilir. Görüntüyü görüntülemek için görüntü birleştiricinin, sadece bu tek dokudaki pikselleri, kare arabelleğinde uygun konuma (örneğin, ekran) kopyalaması yeterlidir. Ancak, bu birleştirici tek bir pikseli bile güncellemek isterse, tam görüntü alanını yeniden kandırması ve Viz'e yeni bir doku göndermesi gerekir.

Bunun yerine, görüntü alanı karolara bölünür. Ayrı bir GPU doku parçası, her bir karoyu, görüntü alanının bir bölümü için pikselleştirilmiş piksellerle destekler. Oluşturucu daha sonra tek tek karoları güncelleyebilir veya hatta mevcut karolar için ekrandaki konumu değiştirebilir. Örneğin, bir web sitesi kaydırılırken mevcut parçaların konumu yukarı kayacak ve sayfanın alt kısmındaki içerik için yalnızca ara sıra yeni bir döşemenin pikselleştirilmesi gerekecektir.

Dört karo.

Yukarıdaki resimde dört karo içeren güneşli bir gün resmi gösterilmektedir. Kaydırma gerçekleştiğinde beşinci bir karo görünmeye başlar. Kutulardan birinin yalnızca tek bir rengi (gök mavisi) vardır ve üstte bir video ile bir iframe bulunur. Bu da bir sonraki konuya geçiyor.

Dörtlü ve yüzeyler

GPU doku blokları, bir doku kategorisi veya başka bir doku kategorisi için yalnızca süslü bir ad olan özel bir dörtlü türüdür. Dört, giriş dokusunu tanımlayarak nasıl dönüştürüleceğini ve görsel efektlerin nasıl uygulanacağını ifade eder. Örneğin, normal içerik karolarında, karo ızgarasında x ve y konumlarını gösteren bir dönüşüm vardır.

GPU doku karoları.

Bu pikselleştirilmiş bloklar, dörtlülerden oluşan bir oluşturma kartı içinde sarmalanır. Oluşturma geçişi herhangi bir piksel bilgisi içermez. Bunun yerine, istenen piksel çıkışını elde etmek için her dört dörtlün nereye ve nasıl çizileceğine ilişkin talimatlar içerir. Her GPU doku bloğu için bir çizim dörtlüsü vardır. Görüntü oluşturucunun, oluşturma geçişi için istenen piksel çıkışını üretmek üzere dörtlüler listesini yinelemesi ve her birini belirtilen görsel efektlerle çizmesi gerekir. İzin verilen görsel efektler doğrudan GPU özellikleriyle eşlenenler olarak dikkatle seçildiğinden, oluşturma geçişi için dörtlü karelerin oluşturulması GPU'da verimli bir şekilde yapılabilir.

Pikselleştirilmiş karoların ötesinde ek dörtlü kare türleri de vardır. Örneğin, hiçbir dokuyla desteklenmeyen düz renk çizim dörtlüleri veya video ya da tuval gibi karo olmayan dokular için doku çizim dörtlüleri vardır.

Bir birleştirme çerçevesinin başka bir birleştirici çerçevesi yerleştirmesi de mümkündür. Örneğin, tarayıcı oluşturucu, tarayıcı kullanıcı arayüzüyle bir birleştirme çerçevesi ve oluşturma birleştirici içeriğinin yerleştirileceği boş bir dikdörtgen oluşturur. Diğer bir örnek de site izole iframe'lerdir. Bu yerleştirme işlemi, yüzeyler aracılığıyla gerçekleştirilir.

Bir besteci, bir birleştirme çerçevesi gönderdiğinde, bu çerçeveye yüzey kimliği adı verilen bir tanımlayıcı eşlik eder. Bu tanımlayıcı, diğer birleştirici çerçevelerinin bunu referans olarak yerleştirmesine olanak tanır. Belirli bir yüzey kimliğiyle gönderilen en yeni birleştirici çerçevesi Viz tarafından depolanır. Başka bir oluşturucu çerçeve, daha sonra yüzey çizim dörtlüsü aracılığıyla ona referans verebilir ve bu şekilde Viz ne çizileceğini bilir. (Yüzey çizim dörtlülerinin dokular değil, yalnızca yüzey kimlikleri içerdiğini unutmayın.)

Ara oluşturma kartları

Birçok filtre veya gelişmiş harmanlama modu gibi bazı görsel efektler, iki veya daha fazla dörtgenin ara dokuya çekilmesini gerektirir. Daha sonra ara doku, görsel efekt aynı anda uygulanarak GPU'daki bir hedef arabelleğe (veya başka bir ara dokuya) çizilir. Buna olanak tanımak için bir birleştirici çerçevesi aslında oluşturma geçişlerinin bir listesini içerir. Her zaman bir kök oluşturma geçişi vardır. Bu aktarım, en son çizilen, hedefi ise çerçeve arabelleğine karşılık gelen verilere karşılık gelir. Daha fazla olabilir.

Birden fazla oluşturma geçişi olasılığı, "oluşturma kartı" adını açıklar. Her geçişin GPU üzerinde sırayla birden fazla "pasta" yürütülmesi gerekirken tek bir geçiş, tek bir çok büyük paralel GPU hesaplamasında tamamlanabilir.

Toplama

Birden fazla birleştirme çerçevesi Viz'e gönderilir ve bunların ekrana birlikte çizilmesi gerekir. Bu işlem, bunları tek bir birleştirilmiş birleştirici çerçevesine dönüştüren bir toplama aşamasında gerçekleşir. Toplama, yüzey çizim dörtlülerini belirttikleri birleştirici kareleriyle değiştirir. Gereksiz ara dokuları veya ekran dışındaki içerikleri optimize etmek için de bir fırsattır. Örneğin, çoğu durumda, site izole edilmiş iframe'e ilişkin birleştirici çerçevesinin kendi ara dokusuna ihtiyacı yoktur ve uygun çizim dörtlüleri aracılığıyla doğrudan çerçeve arabelleğine çizilebilir. Toplama aşamasında bu tür optimizasyonlar tespit edilir ve her bir oluşturma birleştiricilerinin erişemeyeceği genel bilgilere göre uygulanır.

Örnek

Burada, bu gönderinin başlangıcından itibaren verilen örneği temsil eden gerçek birleştirme çerçeveleri verilmiştir.

  • foo.com/index.html yüzeyi: id=0
    • Render Pass 0: Çıkışa çizim yapın.
      • Oluşturma geçişi çizim dörtlü: 3 piksel bulanıklık ile çizin ve oluşturma geçişi 0'a kırpın.
        • İşlem pasosu 1:
          • Her biri için x ve y konumları olacak şekilde #one iframe'in parça içeriklerinde dörtlüler çizin.
      • Yüzey çizim dörtlü: 2 kimlikle, ölçek ve çevirme dönüşümüyle çizilir.
  • Tarayıcı kullanıcı arayüzü yüzeyi: ID=1
    • Render Pass 0: Çıkışa çizim yapın.
      • Tarayıcı kullanıcı arayüzü için dörtlüler çizin (ayrıca parçalara ayrılmış)
  • bar.com/index.html yüzeyi: ID=2
    • Render Pass 0: Çıkışa çizim yapın.
      • Her biri için x ve y konumları olacak şekilde #two iframe içerikleri için dörtlüler çizin.

Sonuç

Okuduğunuz için teşekkür ederiz! Önceki iki gönderiyle birlikte RenderingNG'e genel bakışı sonlandırıyoruz. Sırada, görüntü oluşturma ardışık düzeninin birçok alt bileşenindeki zorluklar ve teknoloji hakkında baştan sona ayrıntılı incelemelere değineceğiz. Bu özellikler çok yakında kullanıma sunulacak.

Çizimler: Una Kravets.