Chrome中的GPU加速合成
原文鏈接:https://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome
簡介:為什么要進行硬件合成?
? ? ? ? 傳統上,Web瀏覽器完全依靠CPU來呈現網頁內容。如今,即使是最小的設備,功能強大的GPU也已成為不可或缺的一部分,人們的注意力已轉移到尋找更有效地使用此基礎硬件以實現更好的性能和節能的方法。使用GPU合成網頁內容可以大大提高速度。
硬件合成的好處有以下三種:
- 在涉及大量像素的繪圖和合成操作中,在GPU上合成頁面層可以獲得比CPU更高的效率(在速度和功耗方面)。硬件專門針對這些類型的工作負載而設計。
- 對于GPU中已經存在的內容(例如加速視頻,Canvas2D或WebGL),無需進行昂貴的回讀。
- CPU和GPU之間的并行性可以同時運行以創建有效的圖形管線
第1部分:Blink渲染基礎知識
? ? ? ? Blink渲染引擎的源代碼龐大,復雜,幾乎沒有文檔記錄。為了了解GPU加速在Chrome中的工作原理,首先必須了解Blink呈現頁面的基本結構。
節點和DOM樹
? ? ? ? 在Blink中,網頁的內容在內部存儲為稱為DOM樹的Node對象樹。頁面上的每個HTML元素以及元素之間出現的文本都與一個節點相關聯。 DOM樹的頂級節點始終是文檔節點。
從節點到RenderObjects
? ? ? ? DOM樹中產生可視輸出的每個節點都有一個對應的RenderObject。 RenderObject存儲在稱為Render Tree的并行樹結構中。 RenderObject知道如何在顯示表面上繪制Node的內容。通過向GraphicsContext發出必要的繪制調用來實現。 GraphicsContext負責將像素寫入位圖,最終將其顯示在屏幕上。在Chrome中,GraphicsContext包裝了我們的2D圖形庫Skia。
? ? ? ? 傳統上,大多數GraphicsContext調用都變成了對SkCanvas或SkPlatformCanvas的調用,即立即繪制到軟件位圖中。但是為了將繪畫從主線程上移開,現在將這些命令記錄到SkPicture中。 SkPicture是可序列化的數據結構,可以捕獲和隨后重播命令,類似于顯示列表。
從RenderObjects到RenderLayers
? ? ? ? 每個RenderObject都直接或通過祖先RenderObject間接與RenderLayer關聯。
? ? ? ?共享相同坐標空間(例如,受相同CSS轉換影響)的RenderObject通常屬于同一RenderLayer。存在RenderLayers以便按正確的順序組合頁面的元素以正確顯示重疊的內容,半透明的元素等。有許多條件會觸發為特定的RenderObject創建新的RenderLayer,如RenderBoxModelObject :: requiresLayer()并為某些派生類覆蓋。保證創建RenderLayer的RenderObject的常見情況:
- 它是頁面的根對象
- 它具有明確的CSS位置屬性(相對,絕對或轉換)
- 它是透明的
- 有溢出,alpha蒙版或反射
- 有一個CSS過濾器
- 對應具有3D(WebGL)上下文或加速2D上下文的<canvas>元素
- 對應于<video>元素
? ? ? ? 注意,RenderObjects和RenderLayers之間沒有一一對應的關系。特定的RenderObject與為其創建的RenderLayer(如果有)關聯,或者與具有一個的第一個祖先的RenderLayer關聯。
? ? ? ? RenderLayers也形成樹層次結構。根節點是與頁面中根元素相對應的RenderLayer,并且每個節點的后代都是可見地包含在父層中的層。
Layer Squashing
? ? ? ? 就內存和其他資源而言,GraphicsLayers可能會很昂貴(例如,某些關鍵操作的CPU時間復雜度與GraphicsLayer樹的大小成正比)。可以為RenderLayers創建許多其他圖層,這些圖層將RenderLayer與它自己的底面重疊,這可能會很昂貴。
? ? ? ? 我們將固有的合成原因(例如,具有3D轉換的圖層)稱為“直接”合成原因。為了防止由于直接合成原因而在圖層上放置許多元素時發生“圖層爆炸”,Blink會將多個RenderLayers與直接合成原因RenderLayer重疊,然后將它們“擠壓”到單個后備存儲中。這樣可以防止重疊引起的層爆炸。可以在此演示文稿中找到更詳細的激勵層壓縮,以及在此演示文稿中可以找到有關RenderLayers和合成層之間的代碼的更多詳細信息;兩者都是截至2014年1月的最新版本,盡管該法規在2014年發生了重大變化。
從GraphicsLayers到WebLayers再到CC層
? ? ? ? 在我們開始使用Chrome的合成器實現之前,只需要再進行幾層抽象即可! GraphicsLayers可以通過一個或多個Web * Layers表示其內容。這些是WebKit端口需要實現的接口。有關諸如WebContentsLayer.h或WebScrollbarLayer.h之類的界面,請參見Blink的public / platform目錄。 Chrome的實現位于src / webkit / renderer / compositor_bindings中,這些實現使用Chrome合成器層類型實現抽象的Web * Layer接口。
Putting it Together: The Compositing Forest
總而言之,概念上存在四個并行的樹結構,它們的呈現目的略有不同:
- DOM樹,這是我們的基本保留模型
- RenderObject樹,其中1:1映射到DOM樹的可見節點。 RenderObjects知道如何繪制其相應的DOM節點。
- RenderLayer樹,由映射到RenderObject樹上的RenderObject的RenderLayers組成。映射是多對一的,因為每個RenderObject要么與其自己的RenderLayer關聯,要么與其第一祖先的RenderLayer關聯。 RenderLayer樹保留層之間的z順序。
- GraphicsLayer樹,映射GraphicsLayers一對多的RenderLayers。
? ? ? ? 每個GraphicsLayer都有在Chrome中使用Chrome合成器層實現的Web * Layers。合成器知道如何操作這些最終“ cc層”(cc = Chrome合成器)。
? ? ? ? 從本文開始,“層”將指代通用cc層,因為對于硬件合成而言,這些是最有趣的-但不要上當,在其他人說“層”時,它們可能是指任何以上構造.
現在,我們已經簡要地介紹了將DOM鏈接到合成器的Blink數據結構,我們已經準備好認真研究合成器本身。
第2部分:The Compositor 合成器
? ? ? ? Chrome的合成器是一個軟件庫,用于管理GraphicsLayer樹和協調框架生命周期。它的代碼位于Blink之外的src / cc目錄中。
介紹合成器
? ? ? ? 回想一下,渲染分為兩個階段:首先進行繪制,然后進行合成。這允許合成器在每個合成層的基礎上執行其他工作。例如,合成器負責在合成之前對每個合成層的位圖應用必要的轉換(由圖層的CSS轉換屬性指定)。此外,由于層的繪畫與合成是分離的,因此使這些層之一無效只會導致僅重新繪畫該層的內容并進行合成。每當瀏覽器需要制作新框架時,合成器都會繪制。注意這個(令人困惑的)術語區別:繪圖是將圖層組合成最終屏幕圖像的合成器;而繪畫則是層的支持(具有軟件光柵化的位圖;具有硬件光柵化的紋理)。
還有GPU嗎?
? ? ? ? 那么GPU如何發揮作用呢?合成器可以使用GPU來執行其繪制步驟。這與舊的軟件渲染模型有很大的不同,在舊的軟件渲染模型中,Renderer進程(通過IPC和共享內存)將帶有頁面內容的位圖傳遞到Browser進程進行顯示(有關更多信息,請參見“舊版軟件渲染路徑”附錄)。如何運作)。
? ? ? ? 在硬件加速架構中,合成是通過調用特定于平臺的3D API(Windows上為D3D;其他任何地方為GL)在GPU上進行的。渲染器的合成器實質上是使用GPU將頁面的矩形區域(即根據圖層樹的轉換層次結構相對于視口定位的所有那些合成層)繪制為單個位圖,即最終頁面圖像。
建筑插曲:GPU進程
? ? ? ? 在進一步研究合成器生成的GPU命令之前,了解renderer進程如何將所有命令發布給GPU至關重要。在Chrome的多進程模型中,我們有專門的流程來執行此任務:GPU進程。 GPU進程的存在主要是出于安全原因。請注意,Android是一個例外,其中Chrome使用進程內GPU實現,該實現在瀏覽器進程中作為線程運行。否則,Android上的GPU線程的行為與其他平臺上的GPU進程相同。受其沙箱限制,Renderer進程(包含Blink和cc的實例)無法直接向操作系統(GL / D3D)提供的3D API發出調用。因此,我們使用單獨的進程來訪問設備。我們稱此過程為GPU進程。 GPU進程經過專門設計,可從Renderer沙箱或更為嚴格的Native Client“ jail”中訪問系統的3D API。它通過客戶端-服務器模型工作,如下所示:客戶端(在Renderer或NaCl模塊中運行的代碼)不是直接向系統API發出調用,而是對其進行序列化,然后將其放入位于自身和服務器進程之間共享的內存中的環形緩沖區(命令緩沖區)中。服務器(運行在限制較少的沙箱中的GPU進程,允許訪問平臺的3D API)從共享內存中提取序列化的命令,解析它們并執行適當的圖形調用。
命令緩沖區
? ? ? ? GPU進程接受的命令在GL ES 2.0 API之后進行了緊密模式化(例如,有一個命令與glClear相對應,一個與glDrawArrays相對應,等等)。由于大多數GL調用都沒有返回值,因此客戶端和服務器幾乎可以異步工作,從而使性能開銷相當低。客戶端和服務器之間的任何必要同步(例如客戶端通知服務器還有其他工作要做)都通過IPC機制處理。
? ? ? ? 從客戶端的角度來看,應用程序可以選擇將命令直接寫入命令緩沖區,也可以通過我們提供的客戶端庫使用GL ES 2.0 API,該庫可以處理后臺的序列化。為了方便起見,合成器和WebGL當前都使用GL ES客戶端庫。在服務器端,通過命令緩沖區接收的命令將通過ANGLE轉換為對桌面OpenGL或Direct3D的調用。
資源共享與同步
? ? ? ? 除了為命令緩沖區提供存儲外,Chrome還使用共享內存在客戶端和服務器之間傳遞較大的資源,例如紋理位圖,頂點數組等。有關命令格式和數據傳輸的更多信息,請參見命令緩沖區文檔。
? ? ? ? 另一種稱為郵箱的構造提供了一種在命令緩沖區之間共享紋理并管理其生存期的方法。郵箱是一個簡單的字符串標識符,可以將其附加(使用)到任何命令緩沖區的本地紋理ID,然后通過該紋理ID別名進行訪問。以這種方式附加的每個紋理id都在基礎真實紋理上保留了一個引用,并且通過刪除本地紋理id釋放了所有引用之后,真實紋理也會被破壞。
? ? ? ? 同步點用于在要通過郵箱共享紋理的命令緩沖區之間提供非阻塞同步。在命令緩沖區A上插入一個同步點,然后在命令緩沖區B上的同步點上“等待”可確保您隨后在B上插入的命令不會在同步點之前在A上插入的命令之前運行。
命令緩沖區多路復用
? ? ? ? 目前,Chrome中 瀏覽器實例使用一個GPU進程處理來自所有渲染器進程和任何插件進程的請求。 GPU進程可以在多個命令緩沖區之間進行多路復用,每個命令緩沖區都與其自己的呈現上下文相關聯。
? ? ? ? 每個渲染器可以具有多個GL來源,例如WebGL Canvas元素直接創建GL命令流。直接在GPU上創建其內容的圖層的組成如下:代替直接渲染到后緩沖區中,它們渲染成紋理(使用幀緩沖區對象),該紋理由合成器上下文在渲染??該GraphicsLayer時捕獲并使用。重要的是要注意,為了使合成器的GL上下文能夠訪問由屏幕外GL上下文(即,用于其他GraphicsLayers的FBO的GL上下文)生成的紋理,GPU過程使用的所有GL上下文都必須創建為他們共享資源。
產生的架構如下所示:
總結:
GPU流程體系結構具有以下優點:
?
- 安全性:大部分渲染邏輯仍保留在沙盒renderer進程中,并且對平臺3D API的訪問僅限于GPU進程。
- 穩健性:GPU進程崩潰(例如,由于錯誤的驅動程序導致)不會導致瀏覽器崩潰。
- 統一性:無論平臺如何,都可以將OpenGL ES 2.0標準化為瀏覽器的呈現API,從而可以跨Chrome的所有OS端口輕松維護單個代碼庫。
- 并行性:渲染器可以快速將命令發布到命令緩沖區中,并返回到CPU密集型渲染活動,而由GPU進程處理。借助此管道,我們可以充分利用多核計算機上的兩個進程以及GPU和CPU。
順便說一句,我們可以回到解釋渲染器的合成器如何生成GL命令和資源的方式。
第3部分:線程合成器
? ? ? ? 合成器在GL ES 2.0客戶端庫的頂部實現,該客戶端庫代理對GPU進程的圖形調用(使用上述方法)。當頁面通過合成器渲染時,其所有像素均通過GPU進程直接繪制(記住,繪制!=繪畫)到窗口的后緩沖區中。
? ? ? ? 合成器的體系結構隨著時間的推移不斷發展:最初它位于Renderer的主線程中,然后移至其自己的線程(所謂的合成器線程),然后在繪制顏料時承擔了其他責任(編排)(所謂的“側面繪畫”) )。本文檔將重點關注最新版本。有關可能仍在使用較舊版本的信息,請參閱GPU架構路線圖。
? ? ? ? 從理論上講,線程合成器的基本任務是從主線程中獲取足夠的信息,以響應將來的用戶輸入而獨立生成幀,即使主線程很忙并且無法請求其他數據。實際上,這實際上意味著它會為視口當前位置周圍區域中的圖層區域復制cc圖層樹和SkPicture記錄。
錄制:從Blink的角度繪畫
? ? ? ? 興趣區域是視口周圍記錄SkPictures的區域。當DOM更改時,例如因為某些元素的樣式現在與之前的主線程框架不同,并且已經失效,所以Blink將感興趣區域內無效層的區域繪制到SkPicture支持的GraphicsContext中。實際上并不會產生新像素,而是會產生產生這些新像素所需的Skia命令的顯示列表。該顯示列表將在以后由合成者酌情使用,以生成新的像素。
提交:移交給合成線程
? ? ? ? 線程合成器的key屬性是對主線程狀態副本的操作,因此它可以生成幀而無需向主線程詢問任何內容。因此,線程化合成器有兩個方面:主線程側和(俗稱的)“ impl”側,即合成器線程的一半。主線程有一個LayerTreeHost,它是它的層樹副本,而impl線程有一個LayerTreeHostImpl,它是它的層樹副本。始終遵循類似的命名約定。
? ? ? ? ?從概念上講,這兩層樹是完全分開的,并且可以使用合成器(impl)線程的副本來生成幀,而無需與主線程進行任何交互。這意味著主線程可能正在忙于運行JavaScript,并且合成器仍可以在GPU上重新繪制以前提交的內容而不會中斷。
? ? ? ? 為了產生有趣的新幀,合成器線程需要知道如何修改其狀態(例如,響應于滾動之類的事件來更新圖層變換)。因此,一些輸入事件(如滾動)首先從瀏覽器進程轉發到合成器,再從那里轉發到渲染器主線程。通過在其控制下的輸入和輸出,線程合成器可以保證對用戶輸入的視覺響應。除了滾動之外,該合成器還可以執行其他任何頁面更新,而無需要求Blink重新繪制任何內容。到目前為止,CSS動畫和CSS過濾器是其他主要的由合成器驅動的頁面更新。
? ? ? ? 兩層樹通過一系列消息(稱為提交)保持同步,這些消息由合成器的調度程序(在cc / trees / thread_proxy.cc中)介導。提交將主線程的世界狀態轉移到合成器線程(包括更新的圖層樹,任何新的SkPicture記錄等),從而阻塞了主線程,因此可以進行此同步。這是主線程參與特定框架生產的最后一步。
? ? ? ? 在自己的線程中運行合成器可以使合成器的層樹副本在不涉及主線程的情況下更新層變換層次結構,但是最終主線程最終需要例如以及滾動偏移信息(例如,JavaScript可以知道視口滾動到的位置)。因此,提交還負責將任何復合線程層樹更新應用于主線程樹和其他一些任務。
? ? ? ? ?除了有趣的是,此體系結構是JavaScript觸摸事件處理程序阻止合成滾動的原因,而滾動事件處理程序則不能。 JavaScript可以在觸摸事件上調用preventDefault(),但不能在滾動事件上調用。因此,合成器必須先詢問JavaScript(在主線程上運行)是否要取消傳入的觸摸事件,才能滾動頁面。另一方面,滾動事件是無法避免的,而是異步傳遞給JavaScript的;因此,無論主線程是否立即處理滾動事件,合成器線程都可以立即開始滾動。
樹激活
? ? ? ? 當合成器線程從主線程獲取新的圖層樹時,它將檢查該新樹以查看哪些區域無效并重新柵格化這些圖層。在此期間,活動樹仍然是合成器線程先前擁有的舊層樹,而掛起的樹是其內容正在柵格化的新層樹。
? ? ? ? 為了保持所顯示內容的一致性,僅當待處理樹的可見(即,在視口內)高分辨率內容被完全光柵化時才激活。從當前活動樹交換到現在就緒的掛起樹稱為激活。等待柵格內容準備就緒的最終效果是,用戶通常可以看到至少一些內容,但是該內容可能是陳舊的。如果沒有可用的內容,Chrome將顯示帶有GL著色器的空白或棋盤圖案。
? ? ? ? 請務必注意,由于Chrome僅記錄感興趣區域內圖層區域的SkPictures,因此甚至可以滾動到活動樹的柵格區域。如果用戶向著未記錄區域滾動,則合成器將要求主線程記錄并提交其他內容,但是如果該新內容無法被記錄,提交和柵格化以及時激活,則用戶將滾動到棋盤格區域。
? ? ? ? 為了減輕棋盤格,Chrome還可以在高分辨率之前快速光柵化待處理樹的低分辨率內容。如果視口中只有低分辨率內容的待處理樹比當前屏幕上顯示的要好(例如,待處理的活動樹根本沒有為當前視口柵格化的內容),則待激活的樹將被激活。切片管理器(在下一節中說明)決定何時柵格化什么內容。
? ? ? ? 這種架構將光柵化與其余幀制作流程隔離開來。它啟用了多種可改善圖形系統響應能力的技術。圖像解碼和調整大小操作是異步執行的,這些操作以前是在繪制過程中執行的昂貴的主線程操作。本文檔前面提到的異步紋理上載系統也已在impl-side繪畫中引入。
平鋪
? ? ? ? 光柵化頁面上每一層的全部都是浪費CPU時間(用于繪畫操作)和內存(用于該層所需的任何軟件位圖的RAM;用于紋理存儲的VRAM)。合成器沒有光柵化整個頁面,而是將大多數Web內容層分解為圖塊,并逐個瓦片化層。
? ? ? ? Web內容層圖塊會根據許多因素進行啟發式優先排序,這些因素包括圖塊與視口的接近程度以及其到達屏幕的估計時間。然后,將GPU內存根據其優先級分配給圖塊,并從SkPicture記錄中柵格化圖塊,以按優先級順序填充可用的內存預算。當前(2014年5月)正在重新設計切片優先級的具體方法;有關更多信息,請參見圖塊優先級設計文檔。
? ? ? ? 請注意,對于內容已經駐留在GPU上的圖層類型(例如加速視頻或WebGL),平鋪不是必需的(出于好奇,圖層類型在cc / layers目錄中實現)。
柵格化:從cc / Skia的角度繪畫
? ? ? ? 合成器線程上的SkPicture記錄通過以下兩種方式之一轉換為GPU上的位圖:由Skia的軟件光柵化器繪制為位圖,然后作為紋理上傳到GPU,或由Skia的OpenGL后端(Ganesh)直接繪制為紋理GPU。
? ? ? ?對于經過Ganesh柵格化的圖層,將使用Ganesh回放SkPicture,并將生成的GL命令流通過命令緩沖區傳遞給GPU進程。當合成器決定柵格化任何圖塊時,就會立即生成GL命令,并且將圖塊捆綁在一起以避免GPU上的圖塊化柵格化產生過多開銷。有關此方法的更多信息,請參見GPU加速柵格化設計文檔。
? ? ? ? 對于軟件柵格化的圖層,繪畫將目標指定為渲染器進程和GPU進程之間共享的內存中的位圖。位圖通過上述資源傳輸機制傳遞給GPU處理。由于軟件光柵化可能非常昂貴,因此這種光柵化不會在合成器線程本身中發生(它可能會阻止為活動樹繪制新框架),而是在合成器光柵工作線程中發生。可以使用多個柵格工作線程來加速軟件柵格化;每個工作人員從優先的圖塊隊列的最前面拉。完成的圖塊作為紋理上傳到GPU。
? ? ? ? 在內存帶寬受限的平臺上,位圖的紋理上載是一個不小的瓶頸。這阻礙了軟件光柵化的層的性能,并且繼續阻礙了硬件光柵化器(例如,對于圖像數據或CPU渲染的掩模)所必需的位圖的上傳。 Chrome過去有多種不同的紋理上載機制,但是最成功的是異步上載器,該上載器在GPU進程的工作線程中執行上載(對于Android,則在Browser進程中的其他線程中上載)。防止其他操作必須阻止可能冗長的紋理上載。
? ? ? ? ?完全消除紋理上傳問題的一種方法是在暴露此類原語的統一內存體系結構設備上,在CPU和GPU之間共享零拷貝緩沖區。 Chrome當前不使用此構造,但將來會使用。有關更多信息,請參見GpuMemoryBuffer設計文檔。
? ? ? ? ?另請注意,在使用GPU進行柵格化時,可能會采用第三種方法來繪制內容:在繪制時將每一層的內容直接柵格化到后緩沖區中,而不是預先柵格化。這具有節省內存(無中間紋理)和一些性能改進(在繪制時將紋理的副本保存到后緩沖區)的優點,但是當紋理有效地緩存圖層內容時(由于現在需要,所以它會降低性能)每幀重新繪制一次)。截至2014年5月,尚未實現這種“直接到后緩沖”或“直接Ganesh”模式,但有關其他注意事項,請參閱GPU柵格化設計文檔。
在GPU,平鋪和四邊形上繪圖
? ? ? ? 一旦填充了所有紋理,渲染頁面內容就簡單地完成了對圖層層次結構的深度優先遍歷并發出GL命令以將每個圖層的紋理繪制到幀緩沖區中。
? ? ? ?在屏幕上繪制圖層實際上是繪制每個圖塊的問題。瓷磚以四邊形(簡單的4邊形,即矩形;請參見cc / quads)表示,并填充了給定圖層內容的子區域。合成器生成四邊形和一組渲染通道(渲染通道是保存四邊形列表的簡單數據結構)。用于繪制的實際GL命令與四邊形分開生成(請參見cc / output / gl_renderer.cc)。這是從Quad實現中抽象出來的,因此可以為合成器編寫非GL后端(唯一重要的非GL實現是軟件合成器,稍后介紹)。或多或少地繪制四邊形,相當于為每個渲染過程設置視口,然后為該渲染過程設置變換并在渲染過程的四邊形列表中繪制每個四邊形。
? ? ? ?請注意,進行深度優先遍歷可確保cc層正確進行z排序,并且當某個層的RenderObjects遍歷時,可通過順序遍歷RenderObject樹來保證與該cc層關聯的潛在多個RenderLayers的z排序被繪。
各種比例因子
? ? ? ? impl-side繪畫的一個顯著優點是,合成器可以以任意比例因子重新渲染現有的SkPictures。這在兩個主要情況下很有用:捏縮放并在快速掃射期間生成低分辨率的圖塊。
? ? ? ? 合成器將攔截輸入事件以進行捏合/縮放,并在GPU上適當縮放已柵格化的圖塊,但是在發生這種情況時,它也會以更合適的目標分辨率進行柵格化。每當新的圖塊準備就緒(柵格化和上載)時,都可以通過激活掛起的樹來交換它們,從而提高縮放/縮放屏幕的分辨率(即使縮放尚未完成)。
? ? ? ? 在使用軟件進行柵格化時,合成器還會嘗試快速生成低分辨率的圖塊(通常更便宜地繪制),如果尚未準備好高分辨率圖塊,則在滾動期間顯示它們。這就是為什么某些頁面在快速滾動過程中看起來模糊的原因-合成器在屏幕上顯示低分辨率圖塊,而高分辨率圖塊柵格化。
附錄
附錄A:瀏覽器合成
? ? ? ? 本文檔主要介紹Renderer進程中用于顯示Web內容的活動。 Chrome的用戶界面也使用了相同的基礎合成基礎架構,值得注意的是brower的參與程度。
瀏覽器與Aura / Ash合成
? ? ? ? Chrome&ChromeOS具有由Ash和Aura組合而成的復合窗口管理器(Ash是窗口管理器本身,而Aura提供了諸如窗口和輸入事件之類的基本原語)。窗口管理器Ash僅在ChromeOS和Win8的Metro模式下使用;在Linux和非Metro Windows上,Aura窗口包裝了本機OS窗口。 Aura使用cc來制作Aura窗口,而Views使用cc到Aura來合成窗口的瀏覽器UI中的不同元素。盡管有些視圖也可以彈出到自己的層中,但大多數“光環”窗口只有一層。這些反映了Blink使用cc來組合Web內容層的方式。有關Aura的更多信息,請參見Aura設計文檔索引。
übercompositor
? ? ? ? 最初,Blink會將Renderer的所有圖層(即Web內容區域的圖層)合成為紋理,然后在瀏覽器進程中通過cc的第二個副本將該紋理與瀏覽器UI的其余層進行合成。這很簡單,但主要缺點是每幀都會產生視口大小的額外副本(因為內容層首先被合成為紋理,然后在瀏覽器合成器繪制時會復制該紋理)。
? ? ? ? ?übercompositor可以在一次繪圖過程中完成瀏覽器UI和渲染器層的所有合成。渲染器沒有將其四邊形本身繪制,而是將所有四角形交給了瀏覽器,然后在瀏覽器合成器的層樹中DelegatedRendererLayer的位置繪制了它們。有關此主題的更多詳細信息,請參見übercompositor設計文檔。
附錄B:軟件合成器
? ? ? ? 在某些情況下,硬件合成是不可行的,例如如果設備的圖形驅動程序被列入黑名單,或者設備完全缺少GPU。對于這些情況,是GL渲染器的另一種實現,稱為SoftwareRenderer(請參見src / cc / output / software_renderer)。當OutputSurface(請參見src / cc / output / output_surface)ContextProvider不可用時,許多其他地方(RasterWorkerPool,ResourceProvider等)也需要它們自己的軟件后備。總之,在不使用GPU的情況下運行時,Chrome在軟件上具有大致相同的功能,但在實現方面存在一些關鍵差異:
- 與其將四邊形作為紋理上傳到GPU,不如將它們留在系統內存中并作為共享內存穿梭在周圍
- 該軟件渲染器沒有使用GL將內容紋理圖塊復制到后緩沖中,而是使用Skia的軟件光柵化器來執行復制(以及執行任何必要的矩陣數學和剪切操作)
? ? ? ? 這意味著3D轉換和復合CSS過濾器之類的操作可以與軟件渲染器“一起使用”,而本質上依賴于GL(例如WebGL)的Web內容則不需要。對于WebGL的軟件渲染,Chrome使用了SwiftGLder(一種軟件GL光柵化器)。
附錄C:Grafix 4 N00bs詞匯表
?
- bitmap: a buffer of pixel values in memory (main memory or the GPU’s video RAM)
- texture: a bitmap meant to be applied to a 3D model on the GPU
- texture quad: a texture applied to a very simple model: a four-pointed polygon, e.g. a rectangle. Useful when all you want is to display the texture as a flat rectangular surface, potentially translated (either in 2D or 3D), which is exactly what we do when compositing.
- invalidation: region of the document marked dirty, usually meaning it requires repainting. The style system has a similar notion of invalidation, so style can be dirtied too, but most commonly this refers to a region needing repainting.
- painting: in our terms, the phase of rendering where RenderObjects make calls into the GraphicsContext API to make a visual representation of themselves
- rasterization: in our terms, the phase of rendering where the bitmaps backing up RenderLayers are filled. This can occur immediately as GraphicsContext calls are by the RenderObjects, or it can occur later if we’re using SkPicture record for painting and SkPicture playback for rasterization.
- compositing: in our terms, the phase of rendering that combines RenderLayer’s textures into a final screen image
- drawing: in our terms, the phase of rendering that actually puts pixels onto the screen (i.e. puts the final screen image onto the screen).
- backbuffer: when double-buffering, the screen buffer that’s rendered into, not the one that’s currently being displayed
- frontbuffer: when double-buffering, the screen buffer that’s currently being displayed, not the one that’s currently being rendered into
- swapbuffers: switching the front and back buffers
- Frame Buffer Object: OpenGL term for a texture that can be rendered to off-screen as if it were a normal screen buffer (e.g. the backbuffer). Useful for us because we want to be able to render to textures and then composite these textures; with FBOs we can pretend to give e.g. WebGL its own frame and it need not worry about anything else going on on the page.
- damage: the area of the screen that has been “dirtied” by user interaction or programmatic changes (e.g. JavaScript changing styles). This is the area of the screen that needs to be re-painted when updating.
- retained mode: a rendering method where the graphics system maintains a complete model of the objects to be rendered. The web platform is retained in that the DOM is the model, and the platform (i.e. the browser) keeps track of the state of the DOM and its API (i.e. JavaScript’s access to the DOM) can be used to modify it or query the current state of it, but the browser can render from the model at any time without any instruction from JavaScript.
- immediate mode: a rendering method where the graphics system doesn’t keep track of the overall scene state but rather immediately executes any commands given to it and forgets about them. To redraw the whole scene all commands need to be re-issued. Direct3D is immediate mode, as is Canvas2D.
- context virtualization: The GPU process does not necessarily create an actual driver-level GL context for a given command buffer client. It can also have a shared real context for multiple clients and restore the GL state to the expected state for a given client when it parses its GL commands -- we refer to this shadowed state as a “virtual context”. This is used on Android to work around bugs and performance problems with certain drivers (slow GL context switches, synchronization issues with FBO rendering across multiple contexts, and crashes when using share groups). ?Chrome enables context virtualization on a subset of drivers via the GPU blacklist file.
?
?
總結
以上是生活随笔為你收集整理的Chrome中的GPU加速合成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 牛客网【每日一题】4月14日题目精讲 X
- 下一篇: ChatGPT 中文调教指南