Airing

Airing

哲学系学生 / 小学教师 / 程序员,个人网站: ursb.me
github
email
zhihu
medium
tg_channel
twitter_id

WJ.14: 鉻渲染管道 - 介紹

本文檔系個人研究 Chromium 渲染管線的筆記記錄,本文介紹 Chromium 的一些基礎知識與渲染管線的主要流程。

本文分析的源碼基於當前最新版本 107,每個版本類名 / 函數名和對應的具體實現或許有所差異,但主邏輯目前來看不會有所變動。

推薦閱讀本系列後續文章:

推薦前往 Airing Notes 閱讀本文,適配了特殊的筆記排版,閱讀體驗會更優。

Blink 是 Web 的渲染引擎,Chromium 和 Android Webview 都是用 Blink 作為渲染引擎。

Blink in Web platform

Blink 包括以下特性:

  • 實現了 Web 平台的規範(也就是 HTML 標準),包括 DOM,CSS 和 WebIDL;
  • 內嵌 V8 運行 JavaScript;
  • 通過底層的網絡棧請求資源;
  • 構建 DOM 樹;
  • 計算樣式和排版;
  • 內嵌 Chrome Compositor 用於繪圖;

你可以閱讀 How Blink works 獲取更多關於 Blink 的知識。

從代碼結構的角度來看,"Blink" 指的是 //third_party/blink/ 目錄下的代碼。

從項目的角度來看,"Blink" 指的是實現 Web 平台特性的項目,實現這些 Web 特性的代碼分布在 //third_party/blink///content/renderer///content/browser/ 及其他相關依賴。

Renderer architecture overview#

本文中我們重點介紹渲染管線,它的代碼在 //third_party/blink/renderer下,目錄結構如下所示:

  • controller/: 一些使用 core/ 和 modules/ 的高級庫。比如,devtools 的前端。
  • core/and bindings/core: core/ 實現了跟 DOM 緊密相關的特性。bindings/core 屬於 core/ 的一部分,bindings 目錄獨立是因為它和 V8 強相關。
  • modules/and bindings/modules: modules/ 實現一些與 DOM 無關的特性,如 WebAudio,IndexDB 等。bindings/modules/ 屬於 modules/ 的一部分,bindings 目錄獨立是因為它和 V8 強相關。
  • platform/: Blink 的低階功能集合,從龐大的 core/ 中分解出來,包括 geometry 和 graphics 等相關的功能。
  • extensions/
  • public/web
  • public/platform
  • public/common
  • //base: chromium 基礎庫,基礎庫的源碼解讀可見 Chromium //base
  • //cc: chromium composite
  • V8: JavaScript 解釋器

Dependencies in //third_party/blink/renderer

Renderer processes#

Chromium 擁有一個 browser processes 和 N 個沙盒 renderer processes,其中 Blink 運行在 renderer processes。browser 與 renderer 進程間通訊是由 Mojo來實現的。

過去進程間通信使用 Chromium IPC,現在還有很多代碼仍舊在使用 IPC

Blink renderer processes 模型如下圖所示:

Renderer processes

Renderer process 擁有一個 main thread, 多個 worker threads, 一個 compositor thread, 以及一個 raster thread。

而 Blink 幾乎所有的主要活動都發生在 main thread,如 JavaScript 調用,DOM 解析、CSS 樣式和排版計算,因此 Blink 的架構被認為主要是單線程的。

Rendering Pipeline#

Goals#

渲染管線的目的是將 WebContent 渲染到螢幕上,它會將 HTML 的內容經過層層處理,最後通過 Open GL 操作顯卡硬體驅動,將 HTML 內容光柵化輸出到螢幕上。

需要注意的是 WebContent 指的是下圖區域,即 HTML 的內容,不包括瀏覽器外殼:

WebContent

除此之外,渲染管線還設計了優良的數據結構,目的是高效處理渲染內容的更新。

Pipeline#

Blink 渲染管線如下圖所示:

Chromium Rendering Pipeline (by Life of a pixel)

"impl" = compositor thread.

這張圖來自於 Life of a pixel,雖然描述了管線的關鍵流程,但不是很完整。此外也不是很準確,比如 Raster 階段是運行在專門的 Raster thread 而不是 Compositor thread 中。

因此,結合 cc 與 viz 的工作流,重新繪製了下圖:

Chromium Rendering Pipeline

完整的渲染管線經歷以下幾個階段:

  1. Parsing
  2. Style
  3. Layout
  4. Composting
  5. Paint
  6. Commit
  7. Tiling
  8. Raster
  9. Activate
  10. Submit
  11. Draw
  12. Display

渲染管線的前半程是在 Renderer process 中進行的,其中渲染管線的 1-5 階段運行在 Main thread 中,這也是 Blink 負責的內容;而 6-10 階段,除了 Raster 是運行在專門的 Raster thread 中,其它流程均是在 Compositor thread 中進行的,這也是 cc 的主要內容,其中 cc 的數據源由 Paint 產生。渲染管線的尾程則是在 GPU process 中進行的,跨進程的環節交給了 viz 負責。

在後續的文章,我們將逐個解析渲染管線的各個流程中 Chromium 是如何工作的。

Resources#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。