摘要:書接上文瀏覽器內(nèi)核之渲染基礎(chǔ)硬件加速基礎(chǔ)概念硬件加速技術(shù)是指使用的硬件能力為幫助渲染網(wǎng)頁,在為的作用主要是用來繪制圖形并且性能特別好。包含的節(jié)點表示的是使用硬件加速的元素或者技術(shù)。
微信公眾號:愛寫bugger的阿拉斯加前言
如有問題或建議,請后臺留言,我會盡力解決你的問題。
此文章是我最近在看的【W(wǎng)ebKit 技術(shù)內(nèi)幕】一書的一些理解和做的筆記。
而【W(wǎng)ebKit 技術(shù)內(nèi)幕】是基于 WebKit 的 Chromium 項目的講解。
書接上文 瀏覽器內(nèi)核之渲染基礎(chǔ)
1. 硬件加速基礎(chǔ) 1.1 概念硬件加速技術(shù)是指:使用 GPU 的硬件能力為幫助渲染網(wǎng)頁,在為 GPU 的作用主要是用來繪制 3D 圖形并且性能特別好。
對于 GPU 繪圖而言,當(dāng)網(wǎng)頁分層之后,部分區(qū)域的更新可能只在網(wǎng)頁的一層或者幾層,而不需要將整個網(wǎng)頁都重新繪制。 通過重新繪制網(wǎng)頁的一個或者幾個層,并將它們和其他之前繪制完的層合成起來,既能使用 GPU 的能力,又能減少重繪的開銷。
每個 RenderLayer 對象都有一個后端存儲與其對應(yīng),好處是:當(dāng)每一層更新的時候,WebKit 只需要更新 RenderLayer 對象包含的節(jié)點即可。所以當(dāng)某一層有作保更新的時候,WebKit 重繪該層的所在內(nèi)容, 這是理想的情況?,F(xiàn)實中,由于硬件能力和資源有限。為了節(jié)省 GPU 的內(nèi)存資源,硬件加速機(jī)制在 RenderLayer 樹建立之后需要做三件事情來完成網(wǎng)頁的渲染。
WebKit 決定將哪些 RenderLayer 對象組合在一起,形成一個有后端存儲的新層,這一新層不久后會用于之后的合成(Compositing),這里面稱之為合成層(Compositing Layer)。每個新層都有一個或者多個后端存儲,這里的后端存儲可能是 GPU 的內(nèi)存。對于一個 RenderLayer 對象,如果它沒有后端存儲的新層,那么就使用它的父親所使用的合成層。
將每個合成層包含的這些 RenderLayer 內(nèi)容繪制在合成層的后端存儲中,這里的繪制可以是軟件繪制也可以是硬件繪制。
由合成層(Compositor)將多個合成層合成起來,形成網(wǎng)頁的最終可視化結(jié)果,實際就是一張圖片。 合成器是一種能夠?qū)⒍鄠€合成層按照這些層的前后順序、合成層的 3D 變形等設(shè)置而合成一個圖像結(jié)果的設(shè)施。
在 WebKit 中,只有把編譯的 C 代碼宏(macro)“ACCELERATED_COMPOSITING” 打開之后,硬件加速機(jī)制才會被開啟,有關(guān)硬件加速的基礎(chǔ)設(shè)施才會被編譯進(jìn)去。
1.2 WebKit 硬件加速設(shè)施一個 RenderLayer 對象如果需要后端存儲,它會創(chuàng)建一個 RenderLayerBacking 對象,該對象負(fù)責(zé) RenderLayer 對象所需要的各種存儲。理想情況下,每個 RenderLayer 都可以創(chuàng)建自己的后端存儲,但事實上不是所有 RenderLayer 都有自己的 RenderLayerBacking 對象。如果一個 RenderLayer 對象被 WebKit 按照一定的規(guī)則創(chuàng)建了后端存儲,那么該 RenderLayer 被稱為合成層。
每個合成層都有一個 RenderLayerBacking, RenderLayerBacking 負(fù)責(zé)管理 RenderLayer 所需要的所有后端存儲,因為后端存儲可能需要多個存儲空間。在 WebKit 中,存儲空間使用 GraphicsLayer 類來表示。
其中圖中的 GraphicsLayer 表示 RenderLayer 中前景層、背景層所需要的一個后端存儲。每一個 GraphicsLayer 都使用一個 GraphicsLayerClient 對象,該對象能夠收到 GraphicsLayer 的一些狀態(tài)更新信息,并且包含一個繪制該 GraphicsLayer 對象的方法,RenderLayerBacking 繼承于該類。GraphicsLayer 是 WebKit 中的基礎(chǔ)類,主要定義一套標(biāo)準(zhǔn)接口。
如果一個 RenderLayer 對象具有以下特征之一,那么它就是合成層。
RenderLayer 具有 CSS 3D 屬性或者 CSS 透視效果。
RenderLayer 包含的 RenderObject 節(jié)點表示的是使用硬件加速的視頻解碼技術(shù)的 HTML5 “video” 元素。
RenderLayer 包含的 RenderObject 節(jié)點表示的是使用硬件加速的 Canvas 2D 元素或者 WebGL 技術(shù)。
RenderLayer 使用了 CSS 透明效果的動畫或者 CSS 變換的動畫。
RenderLayer 使用了硬件加速的 CSS Filters 技術(shù)。
RenderLayer 使用了剪裁(Clip)或者反射(Reflection)屬性,并且它的后代中包括一個合成層。
RenderLayer 有一個 Z 坐標(biāo)比自己小的兄弟節(jié)點,且該節(jié)點是一個合成層。
這么做的原因有三個:
首先當(dāng)然是合并一些 RenderLayer 層,這樣可以減少內(nèi)存的使用量;
其二是在合并之后,盡量減少合并帶來的重繪性能和處理上的困難;
其三對于那些使用多帶帶層能夠顯著提升性能的 RenderLayer 對象,可以繼續(xù)使用這些好處。
為什么一個 RenderLayerBacking 對象需要這么多層?原因有很多,例如,WebKit 需要將滾動條獨立開來稱為一個層,需要兩個容器層來表示 RenderLayer 對應(yīng)的 Z坐標(biāo)為正數(shù)的子女和 Z 坐標(biāo)為負(fù)數(shù)的子女,需要滾動的內(nèi)容建立新層,還可能需要剪裁層和反射層。
圖 8-4 中的樹狀結(jié)構(gòu)描述了所有層的繪制順序,按照先根順序遍歷的結(jié)果即是繪制順序,圖中每個層就是一個 GraphicsLayer 對象。
管理這些合成層等工作的是 RenderLayerCompositor 類,可以說是個 “大管家”。
1.3 硬件渲染過程首先,WebKit 決定哪些些是合成層并為它們分配后端存儲。
其次,WebKit 需要遍歷和繪制每一個合成層,也就是每個合成層可能有一個或者多個 RenderLayer 對象。
最后,渲染引擎將所有繪制完的合成層合成起來,這個是由 WebKit 的移植來完成的。
1.4 3D 圖形上下文WebKit 中的 3D 圖形上下文主要是提供一組抽象接口,這組接口能夠提供類似 OpenGLES(使用 GPU 硬件能力的 3D 圖形應(yīng)用編程接口)的功能,其主要目的當(dāng)然是使用 OpenGL 繪制 3D 圖形的能力。這一層抽象能夠?qū)?WebKit 各個移植的不同部分隱藏起來,WebCore 只是使用統(tǒng)一的抽象接口。在 WebKit 中,3D 圖形上下文的主要用途是 WebGL,當(dāng)然啟用硬件加速的 Canvas2D 等 HTML5 技術(shù)也會使用 3D 圖形技術(shù),不過情況有些不同。
1.2 Chromium 的硬件加速機(jī)制 1.2.1 GraphicsLayer 的支持GraphicsLayer 對象是對一個渲染后端存儲中某一層的抽象,同眾多其他 WebKit 所定義的抽象類一樣,在 WebKit 移植中,它還需要具體的實現(xiàn)類來支持該類所要提供的功能。
1.2.2 框架在 Chromium 中,所以使用 GPu 硬件加速(也就是調(diào)用 OpenGL編程接口)的操作都是由一個進(jìn)程(稱為 GPU 進(jìn)程)負(fù)責(zé)來完成的,這其中包括使用 GPU 硬件來進(jìn)行繪圖和合成。
Chromium 是多進(jìn)程架構(gòu),每個網(wǎng)頁的 Renderer 進(jìn)程都是將之前介紹的 3D 繪圖和合成操作通過 IPC 傳遞給 GPU 進(jìn)程,由它來統(tǒng)一調(diào)度并執(zhí)行。
在 Chromium 的 Android 版本中,GPU 進(jìn)程并不存在, Chromium 是將 GPU 的所有工作放在 Browser 進(jìn)程中的一個線程來完成,這得益于結(jié)構(gòu)設(shè)計的靈活性。但是本質(zhì)上,GPU 進(jìn)程和 GPU 線程并無太大區(qū)別。
上圖 描述了 Chromium 的多進(jìn)程架構(gòu)中 GPU 進(jìn)程同其他進(jìn)程之間的聯(lián)系,事實上每個 Renderer 進(jìn)程都依賴 GPU 進(jìn)程來渲染網(wǎng)頁,當(dāng)然 Browser 進(jìn)程也會同 GPU 進(jìn)程進(jìn)行通信,其作用是創(chuàng)建該進(jìn)程并提供網(wǎng)頁渲染過程最后繪制的目標(biāo)存儲。
那么 GPU 進(jìn)程和 Render 進(jìn)程是如何同步這些命令的呢?答案是,GPU 進(jìn)程處理一些命令后,會向 Renderer 進(jìn)程報告自己當(dāng)前的狀態(tài), Renderer 進(jìn)程通過檢查狀態(tài)信息和自己的期望結(jié)果來確定是否滿足自己的條件。
GPU 進(jìn)程最終繪制的結(jié)果不再像軟件渲染那樣通過共享內(nèi)存?zhèn)鬟f給 Browser 進(jìn)程,而是直接將頁面的內(nèi)容繪制在瀏覽器的標(biāo)簽窗口內(nèi)。
1.2.3 命令緩沖區(qū)命令緩沖區(qū)(Command Buffer)主要用于 GPU 進(jìn)程和 GPU 的調(diào)用都進(jìn)程傳遞 GL 操作命令。從接口上來講,這一設(shè)計只提供一些基本的接口來管理緩沖區(qū),寬并沒有對緩沖區(qū)的具體方式和命令的類型進(jìn)行任何限制,不過目前 Chromium 只有 GLES 一種實現(xiàn)方式。
1.2.4 Chromium 合成器(Chromium Compositor)合成器的作用就是將多個合成層合成并輸出一個最終的結(jié)果,所以它的輸入是多個待合成的合成層,每個層都有一些屬性(如 3D 變形等),它的輸出就是一個后端存儲,例如一個 GPU 的紋理緩沖區(qū)。
Chromium 合成器是一個獨立并且復(fù)雜的模塊,它的作用是合成網(wǎng)頁劃分后的合成層。
總結(jié)硬件加速是指用GPU的硬件能力來渲染網(wǎng)頁,GPU的主要作用是用來繪制3D圖形并且有很好的性能,對于GPU繪圖而言,通常不像軟件渲染那樣只是計算其中更新的區(qū)域,一旦有新的更新請求,如果沒有分層,引擎可能會重新繪制所有的區(qū)域,因為計算更新部分對GPU來說可能耗費更多的時間,當(dāng)網(wǎng)頁分層之后,部分區(qū)域的更新可能只在一層或幾層,而不需要更新整個網(wǎng)頁,通過重新繪制網(wǎng)頁的一個或幾個層,并將它們和其他之前繪制完的層合成起來,既能使用GPU的能力,又能夠減少重繪的開銷。
最后希望本文對你有點幫助。
下期分享 【第九章 JavaScript 引擎】 敬請期待。
送上 資源分享——Python、Java、Linux、Go、vue、react、javaScript
對 全棧開發(fā) 有興趣的朋友可以掃下方二維碼關(guān)注我的公眾號 —— 愛寫bugger的阿拉斯加
分享 web 開發(fā)相關(guān)的技術(shù)文章,熱點資源,全棧程序員的成長之路。
大家一起交流成長。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/97651.html
摘要:多線程的主要目的就是為了保持用戶界面的高響應(yīng)度,保證線程進(jìn)程中的主線程不會被任何其他費用時的操作阻礙從而影響了對用戶操作的響應(yīng)。 showImg(https://segmentfault.com/img/remote/1460000016113034); 微信公眾號:愛寫bugger的阿拉斯加如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 此文章是我最近在看的【W(wǎng)ebKit ...
摘要:而瀏覽器渲染與密切相關(guān),因此只有了解其中工作原理才能讓更好地工作。瀏覽器也稱為布局渲染方式瓦片渲染流暢動畫總結(jié)參考文章瀏覽器用戶界面包括地址欄前進(jìn)后退按鈕書簽菜單等。瀏覽器引擎在用戶界面和渲染引擎之間傳送指令。渲染引擎負(fù)責(zé)顯示請求的內(nèi)容。 singsong: 文本是自己看了一些不錯資料整理出來的,對該知識點感興趣的同學(xué)可以查看參考文章小節(jié)。 ??最新內(nèi)容請以github上的為準(zhǔn)?? 為...
閱讀 2274·2023-04-25 19:06
閱讀 1517·2021-11-17 09:33
閱讀 1876·2019-08-30 15:53
閱讀 2681·2019-08-30 14:20
閱讀 3626·2019-08-29 12:58
閱讀 3640·2019-08-26 13:27
閱讀 604·2019-08-26 12:23
閱讀 576·2019-08-26 12:22