Các cấu trúc dữ liệu chính trong RenderingNG

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

Hãy xem các cấu trúc dữ liệu chính, đó là dữ liệu đầu vào và đầu ra cho quy trình hiển thị.

Các cấu trúc dữ liệu này bao gồm:

  • Cây khung bao gồm các nút cục bộ và nút từ xa đại diện cho tài liệu web có chứa quá trình kết xuất và trình kết xuất Blink nào.
  • Cây mảnh không thể thay đổi thể hiện kết quả của (và đầu vào) thuật toán ràng buộc bố cục.
  • Cây thuộc tính thể hiện hệ phân cấp biến đổi, cắt đoạn, hiệu ứng và cuộn của tài liệu web. Các thông báo này được sử dụng trong toàn bộ quy trình.
  • Danh sách hiển thị và phân đoạn tô màu là dữ liệu đầu vào cho thuật toán đường quét và thuật toán phân lớp.
  • Khung trình tổng hợp đóng gói các bề mặt, bề mặt kết xuất và thẻ thông tin kết cấu GPU dùng để vẽ bằng GPU.

Trước khi tìm hiểu các cấu trúc dữ liệu này, ví dụ sau đây được xây dựng dựa trên một ví dụ trong quá trình đánh giá cấu trúc. Ví dụ này được sử dụng trong toàn bộ tài liệu kèm theo thông tin minh hoạ cách áp dụng các cấu trúc dữ liệu.

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

Cây khung

Đôi khi, Chrome có thể chọn kết xuất khung trên nhiều nguồn gốc trong một quy trình kết xuất khác với khung gốc.

Trong mã ví dụ, có tổng cộng 3 khung hình:

Khung chính foo.com, chứa hai iframe.

Với tính năng tách biệt trang web, Chromium sử dụng hai quy trình kết xuất để kết xuất trang web này. Mỗi quá trình kết xuất có đại diện riêng cho cây khung cho trang web đó:

Hai cây khung đại diện cho hai quá trình kết xuất.

Khung hình kết xuất trong một quy trình khác được bi��u thị dưới dạng khung từ xa. Khung từ xa chứa thông tin tối thiểu cần thiết để hoạt động như một phần giữ chỗ trong quá trình kết xuất, chẳng hạn như kích thước của khung đó. Nếu không, khung từ xa không chứa bất kỳ thông tin nào cần thiết để kết xuất nội dung thực tế.

Ngược lại, khung cục bộ đại diện cho một khung đi qua quy trình kết xuất chuẩn. Khung cục bộ chứa tất cả thông tin cần thiết để biến dữ liệu cho khung đó (chẳng hạn như cây DOM và dữ liệu kiểu) thành nội dung có thể kết xuất và hiển thị.

Quy trình kết xuất hoạt động dựa trên độ chi tiết của một mảnh cây khung cục bộ. Hãy xem xét một ví dụ phức tạp hơn với foo.com là khung chính:

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

bar.com khung phụ sau:

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

Mặc dù vẫn chỉ có 2 trình kết xuất, nhưng hiện tại đã có 3 mảnh cây khung cục bộ, trong đó có 2 mảnh trong quy trình kết xuất foo.com và 1 mảnh trong quy trình kết xuất bar.com:

Hình minh hoạ 2 kết xuất và 3 mảnh cây khung.

Để tạo một khung trình tổng hợp cho trang web, Viz yêu cầu đồng thời một khung trình tổng hợp từ khung gốc của từng cây trong số 3 cây khung cục bộ, sau đó tổng hợp các khung đó. Hãy tham khảo thêm phần khung trình tổng hợp.

Khung chính foo.com và khung phụ foo.com/other-page thuộc cùng một cây khung và được kết xuất trong cùng một quy trình. Tuy nhiên, 2 khung này vẫn có vòng đời tài liệu độc lập vì chúng là một phần của nhiều mảnh cây khung cục bộ. Do đó, bạn không thể tạo một khung trình tổng hợp cho cả hai trong một lần cập nhật. Quá trình kết xuất không có đủ thông tin để kết hợp khung trình tổng hợp được tạo cho foo.com/other-page trực tiếp vào khung của trình tổng hợp cho khung chính foo.com. Ví dụ: khung mẹ bar.com ngoài quy trình có thể ảnh hưởng đến việc hiển thị iframe foo.com/other-url, bằng cách chuyển đổi iframe với CSS hoặc che khuất các phần của iframe với các phần tử khác trong DOM.

Thác nước cập nhật thuộc tính hình ảnh

Các thuộc tính hình ảnh như hệ số tỷ lệ của thiết bị và kích thước khung nhìn ảnh hưởng đến kết quả kết xuất và phải được đồng bộ hoá giữa các mảnh cây khung cục bộ. Gốc của mỗi mảnh cây khung cục bộ có một đối tượng tiện ích được liên kết với nó. Nội dung cập nhật thuộc tính hình ảnh sẽ chuyển đến tiện ích của khung chính trước khi phổ biến đến các tiện ích còn lại từ trên xuống dưới.

Ví dụ: khi kích thước khung nhìn thay đổi:

Sơ đồ về quy trình được giải thích trong văn bản trước.

Quá trình này không diễn ra ngay lập tức, vì vậy, các thuộc tính hình ảnh được sao chép cũng bao gồm mã thông báo đồng bộ hoá. Trình tổng hợp Viz sử dụng mã thông báo đồng bộ hoá này để đợi tất cả các mảnh cây khung cục bộ gửi một khung trình tổng hợp có mã thông báo đồng bộ hoá hiện tại. Quá trình này tránh kết hợp các khung trình tổng hợp có các thuộc tính hình ảnh khác nhau.

Cây mảnh bất biến

Cây mảnh bất biến là kết quả của giai đoạn bố cục của quy trình kết xuất. Thuộc tính này đại diện cho vị trí và kích thước của tất cả phần tử trên trang (không áp dụng phép biến đổi).

Giá trị đại diện của các mảnh trong mỗi cây, với một mảnh được đánh dấu là cần bố cục.

Mỗi mảnh đại diện cho một phần của phần tử DOM. Thông thường, mỗi phần tử chỉ có một mảnh, nhưng có thể có nhiều mảnh hơn nếu mảnh được chia trên nhiều trang khi in hoặc các cột khi ở trong ngữ cảnh nhiều cột.

Sau bố cục, mỗi mảnh trở thành không thể thay đổi và không bao giờ thay đổi lại. Một điều quan trọng là chúng tôi cũng đặt ra thêm một số quy định hạn chế. Chúng tôi không:

  • Cho phép mọi tệp tham chiếu "lên" trong cây. (Phần tử con không thể có con trỏ trỏ đến phần tử mẹ.)
  • dữ liệu "bong bóng" xuống cây (con chỉ đọc thông tin của phần tử con, chứ không đọc thông tin của phần tử mẹ).

Những hạn chế này cho phép chúng ta sử dụng lại một mảnh cho bố cục tiếp theo. Nếu không có những hạn chế này, chúng tôi thường phải tái tạo toàn bộ cây, việc này rất tốn kém.

Hầu hết bố cục thường là bản cập nhật gia tăng, ví dụ: một ứng dụng web cập nhật một phần nhỏ của giao diện người dùng để phản hồi khi người dùng nhấp vào một phần tử. Tốt nhất là bố cục chỉ nên hoạt động tương xứng với những gì thực sự thay đổi trên màn hình. Chúng ta có thể làm việc này bằng cách sử dụng lại nhiều phần của cây trước đó nhất có thể. Điều này có nghĩa là (thường) chúng ta chỉ cần xây dựng lại gáy của cây.

Trong tương lai, thiết kế bất biến này có thể cho phép chúng ta thực hiện những điều thú vị như truyền cây mảnh bất biến qua ranh giới luồng nếu cần (để thực hiện các giai đoạn tiếp theo trên một luồng khác), tạo nhiều cây để ảnh động bố cục mượt mà hoặc thực hiện các bố cục suy đoán song song. Điều này cũng cho chúng ta biết tiềm năng của chính bố cục đa luồng.

Mục trong mảnh cùng dòng

Nội dung cùng dòng (chủ yếu theo kiểu) sử dụng cách trình bày hơi khác. Thay vì cấu trúc cây có các hộp và con trỏ, chúng tôi biểu thị nội dung cùng dòng trong một danh sách phẳng biểu thị cây. Lợi ích chính là việc biểu diễn danh sách phẳng cho cùng dòng rất nhanh, hữu ích cho việc kiểm tra hoặc truy vấn cấu trúc dữ liệu cùng dòng, đồng thời giúp bộ nhớ hiệu quả hơn. Điều này cực kỳ quan trọng đối với hiệu suất kết xuất web, vì việc hiển thị văn bản rất phức tạp và có thể dễ dàng trở thành phần chậm nhất của quy trình trừ phi được tối ưu hoá cao.

Danh sách phẳng được tạo cho mỗi ngữ cảnh định dạng cùng dòng theo thứ tự tìm kiếm theo chiều sâu của cây con bố cục cùng dòng. Mỗi mục trong danh sách là một bộ dữ liệu (đối tượng, số lượng thành phần con). Ví dụ: hãy xem xét DOM này:

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

Thuộc tính width được đặt thành 0 để dòng bao bọc giữa "Xin chào" và "ở đó".

Khi ngữ cảnh định dạng cùng dòng cho trường hợp này được biểu thị dưới dạng cây, mã sẽ có dạng như sau:

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

Danh sách phẳng có dạng như sau:

  • (Hộp dòng, 2)
  • (Hộp <span>, 1)
  • (Văn bản "Xin chào", 0)
  • (Hộp dòng, 3)
  • (Hộp <b>, 1)
  • (Văn bản "ở đó", 0)
  • (Văn bản ".", 0)

Có nhiều đối tượng sử dụng cấu trúc dữ liệu này: API hỗ trợ tiếp cận và API hình học như getClientRectscontenteditable. Mỗi loại sẽ có những yêu cầu khác nhau. Các thành phần này truy cập vào cấu trúc dữ liệu phẳng thông qua một con trỏ tiện lợi.

Con trỏ có các API, chẳng hạn như MoveToNext, MoveToNextLine, CursorForChildren. Biểu diễn con trỏ này rất hiệu quả đối với nội dung văn bản vì nhiều lý do:

  • Việc lặp lại theo thứ tự tìm kiếm theo chiều sâu rất nhanh. Phương pháp này được sử dụng rất thường xuyên vì tương tự như cử động con nháy. Vì đây là danh sách phẳng, nên phương pháp tìm kiếm ưu tiên theo chiều sâu chỉ làm tăng độ lệch mảng, cung cấp thời gian lặp lại nhanh và vị trí của bộ nhớ.
  • Công cụ này cung cấp tính năng tìm kiếm theo chiều rộng, cần thiết khi chẳng hạn như khi tô màu nền của các dòng và hộp cùng dòng.
  • Khi biết số lượng con cháu tiếp theo, việc di chuyển sang lớp đồng cấp tiếp theo sẽ nhanh chóng (chỉ tăng độ lệch mảng theo số đó).

Cây tài sản

DOM là một cây gồm các phần tử (cùng với các nút văn bản) và CSS có thể áp dụng nhiều kiểu cho các phần tử.

Điều này xuất hiện theo 4 cách:

  • Bố cục: đầu vào cho thuật toán ràng buộc bố cục.
  • Paint: cách vẽ và tạo điểm ảnh cho phần tử (chứ không phải các thành phần con cháu của phần tử đó).
  • Hình ảnh: hiệu ứng đường quét/vẽ được áp dụng cho cây con DOM, chẳng hạn như phép biến đổi, bộ lọc và đoạn cắt (clipping).
  • Cuộn: căn chỉnh theo trục và bo tròn góc cắt và cuộn của cây con chứa trong đó.

Cây thuộc tính là các cấu trúc dữ liệu giải thích cách các hiệu ứng hình ảnh và cuộn áp dụng cho các phần tử DOM. Các ví dụ này đưa ra phương tiện để trả lời các câu hỏi như: một phần tử DOM nhất định là ở đâu, so với màn hình, dựa trên kích thước và vị trí bố cục? Và: nên sử dụng trình tự hoạt động GPU nào để áp dụng hiệu ứng hình ảnh và cuộn?

Hiệu ứng hình ảnh và hiệu ứng cuộn trên web rất phức tạp nếu xét đến tận cùng là vô cùng hiệu quả. Vì vậy, điều quan trọng nhất mà cây thuộc tính làm là chuyển tính phức tạp đó thành một cấu trúc dữ liệu duy nhất thể hiện chính xác cấu trúc và ý nghĩa của chúng, đồng thời loại bỏ phần phức tạp còn lại của DOM và CSS. Điều này cho phép chúng tôi triển khai các thuật toán để tổng hợp và cuộn một cách tự tin hơn nhiều. Cụ thể:

  • Hình học dễ xảy ra lỗi và các phép tính khác có thể được tập trung vào cùng một nơi.
  • Tính phức tạp của việc xây dựng và cập nhật cây thuộc tính được tách riêng thành một giai đoạn quy trình kết xuất.
  • Việc gửi cây thuộc tính xung quanh các luồng và quy trình khác nhau sẽ dễ dàng và nhanh chóng hơn nhiều so với trạng thái DOM đầy đủ. Do đó, bạn có thể sử dụng chúng cho nhiều trường hợp sử dụng.
  • Càng có nhiều trường hợp sử dụng, chúng ta càng đạt được nhiều thành công từ tính năng lưu vào bộ nhớ đệm hình học được xây dựng ở trên cùng, vì chúng có thể sử dụng lại bộ nhớ đệm của nhau.

Quá trình kết xuấtNG sử dụng cây thuộc tính cho nhiều mục đích, chẳng hạn như:

  • Tách hoạt động tổng hợp khỏi sự kiện vẽ và hoạt động kết hợp khỏi luồng chính.
  • Xác định chiến lược kết hợp / rút tối ưu.
  • Đo lường hình học IntersectionObserver.
  • Tránh sử dụng cho các thành phần ngoài màn hình và ô hoạ tiết GPU.
  • Làm mất hiệu lực sơn và đường quét một cách hiệu qu��� và chính xác.
  • Đo lường sự thay đổi bố cụcnội dung lớn nhất hiển thị trong Chỉ số quan trọng chính của trang web.

Mỗi tài liệu web có 4 cây thuộc tính riêng biệt: biến đổi, cắt xén, hiệu ứng và cuộn.(*) Cây biến đổi đại diện cho các biến đổi và cuộn CSS. (Một biến đổi cuộn được biểu thị dưới dạng ma trận biến đổi 2D.) Cây clip đại diện cho các đoạn video bị tràn. Cây hiệu ứng thể hiện tất cả các hiệu ứng hình ảnh khác: độ mờ, bộ lọc, mặt nạ, chế độ kết hợp và các loại đoạn video khác như đường dẫn cắt (clip-path). Cây cuộn biểu thị thông tin về thao tác cuộn, chẳng hạn như cách xâu chuỗi các thao tác cuộn với nhau; cần thiết để thực hiện việc cuộn trên luồng của trình tổng hợp. Mỗi nút trong cây thuộc tính đại diện cho một hiệu ứng cuộn hoặc hiệu ứng hình ảnh do một phần tử DOM áp dụng. Nếu có nhiều hiệu ứng, thì có thể có nhiều nút cây thuộc tính trong mỗi cây cho cùng một phần tử.

Cấu trúc liên kết của mỗi cây giống như một bản trình bày DOM thưa thớt. Ví dụ: nếu có 3 phần tử DOM có các đoạn video tràn, thì sẽ có 3 nút cây cắt và cấu trúc của cây cắt sẽ tuân theo mối quan hệ khối chứa giữa các đoạn nội dung bổ sung. Ngoài ra còn có các mối liên kết giữa các cây. Các đường liên kết này cho biết hệ phân cấp DOM tương đối và thứ tự ứng dụng của các nút. Ví dụ: nếu một phép biến đổi trên một phần tử DOM nằm dưới một phần tử DOM khác có bộ lọc, thì tất nhiên phép biến đổi đó sẽ được áp dụng trước bộ lọc.

Mỗi phần tử DOM có một trạng thái cây thuộc tính, là 4 bộ dữ liệu (biến đổi, cắt, hiệu ứng, cuộn) cho biết nút cây đối tượng cấp trên gần nhất, biến đổi và nút cây hiệu ứng có hiệu lực trên phần tử đó. Điều này rất thuận tiện vì với thông tin này, chúng ta biết chính xác danh sách các đoạn video, biến đổi và hiệu ứng áp dụng cho phần tử đó cũng như thứ tự áp dụng. Thông tin này cho chúng tôi biết vị trí của khung hiển thị trên màn hình và cách vẽ.

Ví dụ:

(nguồn)

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

Đối với ví dụ trước (hơi khác với ví dụ trong phần giới thiệu), sau đây là các phần tử chính của cây thuộc tính được tạo:

Ví dụ về các phần tử trong cây tài sản.

Hiển thị danh sách và vẽ các phần

Một mục hiển thị chứa các lệnh vẽ cấp thấp (xem tại đây) có thể được tạo điểm ảnh bằng Skia. Các mục trên màn hình thường đơn giản, chỉ cần một vài lệnh vẽ, chẳng hạn như vẽ đường viền hoặc nền. Bước đi trên cây sơn sẽ lặp lại cây bố cục và các mảnh được liên kết theo đơn đặt hàng vẽ CSS để tạo danh sách mặt hàng hiển thị.

Ví dụ:

Một hộp màu xanh dương có dòng chữ &quot;Hello world&quot; (Xin chào thế giới) bên trong một hình chữ nhật màu xanh lục.

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

HTML và CSS này sẽ tạo danh sách hiển thị sau đây, trong đó mỗi ô là một mục hiển thị:

Nền chế độ xem #blue (âm thanh trong nền) #green (âm thanh trong nền) #green văn bản cùng dòng
drawRect có kích thước 800x600 và có màu trắng. drawRect có kích thước 100x100 ở vị trí 0.0 và có màu xanh dương. drawRect có kích thước 80x18 ở vị trí 8.8 và có màu xanh lục. drawTextBlob ở vị trí 8,8 và dòng chữ "Hello world".

Danh sách mặt hàng hiển thị được sắp xếp từ sau ra trước. Trong ví dụ trên, div màu xanh lục nằm trước div màu xanh dương theo thứ tự DOM, nhưng thứ tự hiển thị CSS yêu cầu div màu xanh dương z-index âm phải vẽ trước (bước 3) div màu xanh lục (bước 4.1). Các mục hiển thị gần như tương ứng với các bước không thể phân chia trong quy cách đơn đặt hàng sơn CSS. Một phần tử DOM có thể dẫn đến một số mục hiển thị, chẳng hạn như cách #green có một mục hiển thị cho nền và một mục hiển thị khác cho văn bản cùng dòng. Mức độ chi tiết này rất quan trọng để thể hiện đầy đủ độ phức tạp của quy cách thứ tự hiển thị CSS, chẳng hạn như sự xen kẽ do lề âm tạo ra:

Một hình chữ nhật màu xanh lục có hộp màu xám phủ một phần và dòng chữ &quot;Hello world&quot;.

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

Thao tác này sẽ tạo ra danh sách hiển thị sau đây, trong đó mỗi ô là một mục hiển thị:

Nền chế độ xem #green (âm thanh trong nền) #gray (âm thanh trong nền) #green văn bản cùng dòng
drawRect có kích thước 800x600 và có màu trắng. drawRect có kích thước 80x18 ở vị trí 8.8 và có màu xanh lục. drawRect có kích thước 35x20 ở vị trí 8,16 và màu xám. drawTextBlob ở vị trí 8,8 và dòng chữ "Hello world".

Danh sách mặt hàng hiển thị được lưu trữ và sử dụng lại trong các lần cập nhật sau này. Nếu một đối tượng bố cục không thay đổi trong quá trình đi bộ vẽ cây, thì các mục hiển thị của đối tượng đó sẽ được sao chép từ danh sách trước. Việc tối ưu hoá bổ sung dựa trên một thuộc tính của thông số kỹ thuật của thứ tự hiển thị CSS: các ngữ cảnh xếp chồng hiển thị một cách chi tiết. Nếu không có đối tượng bố cục nào thay đổi trong ngữ cảnh xếp chồng, thì bước đi cây vẽ sẽ bỏ qua ngữ cảnh xếp chồng và sao chép toàn bộ trình tự các mục hiển thị từ danh sách trước.

Trạng thái cây thuộc tính hiện tại được duy trì trong quá trình đi bộ cây sơn và danh sách mục hiển thị được nhóm thành "các phần" của các mục hiển thị có cùng trạng thái cây thuộc tính. Điều này được minh hoạ trong ví dụ sau:

Một chiếc hộp màu hồng với một hộp màu cam nghiêng.

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

Thao tác này sẽ tạo ra danh sách hiển thị sau đây, trong đó mỗi ô là một mục hiển thị:

Nền chế độ xem #scroll (âm thanh trong nền) #scroll văn bản cùng dòng #orange (âm thanh trong nền) #orange văn bản cùng dòng
drawRect có kích thước 800x600 và có màu trắng. drawRect có kích thước 100x100 ở vị trí 0.0 và có màu hồng. drawTextBlob với vị trí 0.0 và dòng chữ "Hello world". drawRect có kích thước 75x200 tại vị trí 0.0 và có màu cam. drawTextBlob với vị trí 0.0 và dòng chữ "Tôi đang ngã".

Sau đó, cây thuộc tính biến đổi và các đoạn sơn sẽ được (được đơn giản hoá cho ngắn gọn):

Hình ảnh của bảng trước, hai ô đầu tiên trong phân đoạn 1, ô thứ ba trong phân đoạn 2, hai ô cuối cùng trong phân đoạn 3.

Danh sách theo thứ tự các phần sơn, là các nhóm các mục hiển thị và trạng thái cây thuộc tính, là dữ liệu đầu vào cho bước phân lớp của quy trình kết xuất. Toàn bộ danh sách các phần sơn có thể được hợp nhất thành một lớp tổng hợp duy nhất và tạo điểm ảnh lại với nhau, nhưng việc này sẽ đòi hỏi việc tạo điểm ảnh tốn kém mỗi lần người dùng cuộn. Bạn có thể tạo một lớp tổng hợp cho từng phân đoạn sơn và tạo điểm ảnh riêng lẻ để tránh tất cả quá trình tạo lại điểm ảnh, nhưng điều đó sẽ nhanh chóng làm cạn kiệt bộ nhớ GPU. Bước phân lớp phải đưa ra sự đánh đổi giữa bộ nhớ GPU và giảm chi phí khi mọi thứ thay đổi. Một phương pháp chung nên dùng là hợp nhất các đoạn theo mặc định và không hợp nhất các đoạn sơn có trạng thái cây thuộc tính dự kiến sẽ thay đổi tr��n luồng của trình tổng hợp, chẳng hạn như với ảnh động chuyển đổi luồng của trình tổng hợp hoặc chuyển đổi luồng của trình tổng hợp.

Ví dụ trước tốt nhất nên tạo ra 2 lớp tổng hợp:

  • Một lớp tổng hợp có kích thước 800x600 chứa các lệnh vẽ:
    1. drawRect có kích thước 800x600 và màu trắng
    2. drawRect có kích thước 100x100 ở vị trí 0.0 và màu hồng
  • Một lớp tổng hợp có kích thước 144x224 chứa các lệnh vẽ:
    1. drawTextBlob với vị trí là 0,0 và dòng chữ "Hello world" ("Xin chào thế giới")
    2. dịch 0,18
    3. rotateZ(25deg)
    4. drawRect có kích thước 75x200 tại vị trí 0.0 và có màu cam
    5. drawTextBlob với vị trí 0.0 và dòng chữ "Tôi sắp giảm"

Nếu người dùng cuộn #scroll, lớp tổng hợp thứ hai sẽ được di chuyển, nhưng không cần tạo điểm ảnh.

Ví dụ: từ phần trước trên cây thuộc tính, có 6 đoạn tô. Cùng với các trạng thái cây thuộc tính (biến đổi, cắt, hiệu ứng, cuộn) của chúng, chúng là:

  • Nền tài liệu: cuộn tài liệu, đoạn trích tài liệu, gốc, cuộn tài liệu.
  • Góc ngang, dọc và cuộn cho div (3 phần hiển thị riêng biệt): cuộn tài liệu, đoạn trích tài liệu, làm mờ #one, cuộn tài liệu.
  • Khung nội tuyến #one: #one xoay, đoạn video cuộn tràn, làm mờ #one, cuộn div.
  • Iframe #two: Tỷ lệ #two, đoạn trích tài liệu, thư mục gốc, cuộn tài liệu.

Khung tổng hợp: bề mặt, bề mặt kết xuất và ô hoạ tiết GPU

Trình duyệt và các quy trình kết xuất quản lý quá trình tạo điểm ảnh cho nội dung, sau đó gửi các khung hình tổng hợp đến quy trình Viz để hiển thị lên màn hình. Khung của bộ tổng hợp cho biết cách nối nội dung được tạo điểm ảnh lại với nhau và vẽ nội dung đó hiệu quả bằng GPU.

Thẻ thông tin

Theo lý thuyết, trình tổng hợp quy trình kết xuất hoặc trình duyệt có thể tạo điểm ảnh thành một kết cấu duy nhất bằng kích thước đầy đủ của khung nhìn trình kết xuất và gửi kết cấu đó đến Viz. Để hiển thị kết cấu đó, trình tổng hợp màn hình chỉ cần sao chép pixel từ hoạ tiết đó vào vị trí thích hợp trong vùng đệm khung (ví dụ: màn hình). Tuy nhiên, nếu trình tổng hợp đó muốn cập nhật dù chỉ một pixel đơn lẻ, thì trình tổng hợp đó sẽ cần phải chuyển đổi lại khung nhìn đầy đủ và gửi hoạ tiết mới cho Viz.

Thay vào đó, khung nhìn được chia thành các ô. Một ô hoạ tiết GPU riêng biệt phía sau mỗi ô có các pixel đã tạo điểm ảnh cho một phần của khung nhìn. Sau đó, trình kết xuất có thể cập nhật từng thẻ thông tin hoặc thậm chí chỉ cần thay đổi vị trí trên màn hình cho các thẻ thông tin hiện có. Ví dụ: khi cuộn một trang web, vị trí của các thẻ thông tin hiện có sẽ dịch chuyển lên trên và chỉ thỉnh thoảng một thẻ thông tin mới cần được tạo điểm ảnh cho nội dung ở phía dưới trang.

4 ô.
Hình ảnh này mô tả một ngày nắng, có 4 ô. Khi một lượt cuộn diễn ra, ô thứ năm sẽ bắt đầu xuất hiện. Một trong các thẻ thông tin chỉ có một màu (xanh da trời) và có một video và iframe ở trên cùng.

Bốn phần và nền tảng

Ô hoạ tiết GPU là một loại quad đặc biệt, chỉ là một tên gọi dành cho một danh mục hoạ tiết hoặc một danh mục hoạ tiết khác. Một góc quad xác định hoạ tiết đầu vào, đồng thời cho biết cách chuyển đổi và áp dụng hiệu ứng hình ảnh cho hoạ tiết đó. Ví dụ: ô nội dung thông thường có phép biến đổi cho biết vị trí x, y của chúng trong lưới ô.

Ô hoạ tiết GPU.

Những thẻ thông tin đã tạo điểm ảnh này được gói trong một lượt kết xuất, là một danh sách các quads. Lượt kết xuất không chứa bất kỳ thông tin pixel nào; thay vào đó, lượt hiển thị này có hướng dẫn về vị trí và cách vẽ từng quad để tạo đầu ra pixel mong muốn. Có một 4 hình vẽ cho mỗi ô kết cấu GPU. Trình tổng hợp hiển thị chỉ phải lặp lại danh sách các phần tư, vẽ từng phần tử bằng hiệu ứng hình ảnh đã chỉ định để tạo đầu ra pixel mong muốn cho lượt kết xuất. Bạn có thể thực hiện hiệu quả việc tổng hợp các góc vẽ cho một lượt kết xuất trên GPU, vì các hiệu ứng hình ảnh cho phép được chọn cẩn thận là những hiệu ứng ánh xạ trực tiếp đến các tính năng của GPU.

Ngoài các ô được tạo điểm ảnh, còn có các loại ô vẽ khác. Ví dụ: có các tứ giác vẽ màu đồng nhất không hề được hoạ tiết hỗ trợ hoặc tứ giác vẽ hoạ tiết cho các hoạ tiết không có ô xếp kề (như video hoặc canvas).

Khung của trình tổng hợp cũng có thể nhúng một khung của trình tổng hợp khác. Ví dụ: trình tổng hợp trình duyệt tạo ra một khung trình tổng hợp có giao diện người dùng trình duyệt và một hình chữ nhật trống nơi nội dung của trình tổng hợp hiển thị sẽ được nhúng. Một ví dụ khác là iframe được tách biệt trang web. Việc nhúng này được thực hiện thông qua các nền tảng.

Khi trình tổng hợp gửi một khung trình tổng hợp, khung đó sẽ đi kèm với một giá trị nhận dạng, được gọi là mã nhận dạng bề mặt, cho phép các khung của trình tổng hợp khác nhúng khung đó theo tham chiếu. Viz lưu trữ khung trình tổng hợp mới nhất được gửi bằng một mã nhận dạng nền tảng cụ thể. Sau đó, một khung trình tổng hợp khác có thể tham chiếu đến khung đó thông qua 4 chiều vẽ bề mặt và nhờ đó Viz biết cần vẽ gì. (Lưu ý rằng các góc vẽ bề mặt chỉ chứa mã nhận dạng bề mặt chứ không chứa hoạ tiết.)

Lượt kết xuất trung gian

Một số hiệu ứng hình ảnh, chẳng hạn như nhiều bộ lọc hoặc chế độ kết hợp nâng cao, yêu cầu phải có 2 hoặc nhiều quad được vẽ tr��n một hoạ tiết trung gian. Sau đó, hoạ tiết trung gian được vẽ vào vùng đệm đích trên GPU (hoặc có thể là một hoạ tiết trung gian khác), áp dụng đồng thời hiệu ứng hình ảnh. Để cho phép điều này, khung trình tổng hợp thực sự chứa danh sách các lượt kết xuất. Luôn có một lượt kết xuất gốc, được vẽ cuối cùng và có đích đến tương ứng với vùng đệm khung, ngoài ra còn có thể có nhiều lượt truyền khác.

Việc có nhiều lượt kết xuất hình ảnh giải thích tên "truyền kết xuất". Mỗi lượt truyền phải được thực thi tuần tự trên GPU, trong nhiều "lượt truyền", trong khi một lượt truyền có thể được hoàn tất trong một phép tính GPU song song ở quy mô lớn.

Tổng hợp

Nhiều khung trình tổng hợp được gửi đến Viz và các khung đó cần được vẽ lên màn hình cùng nhau. Điều này được thực hiện bằng giai đoạn tổng hợp nhằm chuyển đổi chúng thành một khung tổng hợp duy nhất. Tập hợp sẽ thay thế các góc vẽ bề mặt bằng các khung trình tổng hợp mà chúng chỉ định. Đây cũng là cơ hội để tối ưu hoá các hoạ tiết hoặc nội dung trung gian không cần thiết nằm ngoài màn hình. Ví dụ: trong nhiều trường hợp, khung trình tổng hợp cho một iframe được tách biệt trang web không cần kết cấu trung gian riêng và có thể được vẽ trực tiếp vào vùng đệm khung thông qua các góc vẽ thích hợp. Giai đoạn tổng hợp này chỉ ra các cách tối ưu hoá đó và áp dụng chúng dựa trên kiến thức toàn cầu mà từng trình tổng hợp kết xuất không thể tiếp cận.

Ví dụ:

Dưới đây là các khung trình tổng hợp đại diện cho ví dụ ở đầu bài đăng này.

  • Nền tảng foo.com/index.html: id=0
    • Kết xuất truyền 0: vẽ thành đầu ra.
      • Kết xuất đường quét quad vẽ: vẽ với hiệu ứng làm mờ 3px và cắt vào đường truyền kết xuất 0.
        • Hiển thị lượt 1:
          • Vẽ các phần tư cho nội dung ô của iframe #one, với vị trí x và y cho mỗi iframe.
      • Bề mặt vẽ quad: với mã nhận dạng 2, được vẽ theo tỷ lệ và chuyển đổi phép biến đổi.
  • Nền tảng giao diện người dùng của trình duyệt: ID=1
    • Kết xuất truyền 0: vẽ thành đầu ra.
      • Vẽ bốn góc cho giao diện người dùng của trình duyệt (cũng xếp kề)
  • Nền tảng bar.com/index.html: ID=2
    • Kết xuất truyền 0: vẽ thành đầu ra.
      • Vẽ các phần tư cho nội dung của iframe #two, với vị trí x và y cho mỗi iframe.

Ảnh minh hoạ của Una Kravets.