日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

chrome 硬件渲染(GPU Accelerated Compositing in Chrome)

發布時間:2023/11/27 生活经验 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 chrome 硬件渲染(GPU Accelerated Compositing in Chrome) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接

http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome

chrome 中集成了webkit,這篇文章對webkit 硬件渲染過程有詳細的介紹,很好。

簡介
這篇文檔講解chrome硬件加速合成的實現細節和背景。

介紹
通常來講,網頁瀏覽器完全依賴CPU來渲染網頁內容。
隨著高性能的GPU日益成為設備(即使是最小的設備)的一部分,以及富媒體(video,3D圖形游戲)在網絡體驗中扮演著越來越重要的角色,
人們的注意力開始轉向尋找一些方法來更充分利用底層硬件的能力,以提供更好的體驗以及更少的電量消耗。
很明顯,如果使GPU直接參與網頁內容的合成會帶來非常顯著地提速。這樣做最大的好處是可以省去不必要的大量數據拷貝過程,尤其是將內存中的video數據拷貝到系統內存的過程。
這種加速有兩個最明顯的用武之地,一個是使用硬件解碼的Video元素,一個是WebGL canvas, 這兩個元素都把它們的結果數據放在一個GPU無法快速訪問的內存區域。
將包含網頁內容的各個layer的合成交給GPU來做還有另外一些好處。
就涉及大量像素處理的繪制和合成操作而言,GPU要遠比CPU有效率(不管是速度還是繪制能力),這是因為針對這些類型的工作負載,GPU有做專門的設計。
將這些操作交給GPU完成,可以實現GPU和CPU并行運行,從而創造出一個高效率的圖形處理管線。
第一部分:webkit 渲染基礎及軟件渲染路徑
webkit 渲染引擎的源碼非常的繁雜,而且注釋和說明性文檔實在是太少了。
為了了解GPU加速在Chrome中是怎么工作的,必須先了解webkit 實現頁面渲染的基礎組件。
我們先簡要回顧一下GPU加入以前的工作流程,再分析GPU加入后的工作流程,以此來理解GPU是怎樣起作用的。
Nodes and DOM tree
網頁內容在webkit 內部以Node為節點的樹形結構存儲,稱為DOM tree。
網頁中的每一個HTML 元素,包括元素之間的text都和一個Node相關聯。
DOM tree的最頂層Node 永遠是Document Node.
Frome Nodes to RenderObjects
Dom tree中每一個可視化的Node 節點都對應著一個RenderObject.RenderObject 也存儲在一棵對應的樹結構中,稱為Render tree.
RenderObject 知道如何在一個display surface上顯示(繪制) Node 節點的內容。
它通過調用GraphicsContext提供的繪制接口來完成顯示(繪制)過程。
GraphicsContext最終負責將像素寫入一塊bitmap,這塊bitmap會被顯示在屏幕上。
在Chrome中,GraphicsContext 封裝了Skia, 2D圖形庫,對GraphicsContext的大多數調用都轉變成對SkCanvas或SkPlatformCanvas的接口調用。
在軟件渲染的情況下,整個網頁只有一個GraphicsContext,所有的RenderObjects都繪制在同一個GraphicsContext上.
From? RenderObjects to RenderLayers
每一個RenderObject 都關聯著一個RenderLayer.這種關聯是通過祖先RenderObject 節點直接或間接地建立的。
分享同一坐標系的RenderObject(比如被同一CSS transform屬性影響的元素)必然位于同一RenderLayer.
正是由于RenderLayer的存在,網頁上的元素才可以按照正確的順序合成,從而恰當的顯示有交疊的內容,和半透明元素等效果。
像在RenderBoxModelObject::requiresLayer() 及RenderBoxModelObject的子類中重實現的requiresLayer()中定義的那樣,有很多種條件可以
觸發一個特定的RenderObject創建一個RenderLayer.
通常來講,滿足下列條件之一時,RenderObject就會創建RenderLayer:
1.網頁的root節點;
2.有明確的CSS position屬性(relative,absolute,transform)
3.元素是透明的
4.overflow, alpha mask,或者reflection
5.有css filter(濾鏡) 屬性
6.有2D加速Context或者3D(webGL)context的 canvas 元素對應的RenderObject.
7.video元素對應的RenderObject
需要注意的是RenderObject和RenderLayer之間并不是一一對應的。?
RenderObject 或者與它所創建的RenderLayer相關聯(如果它創建了的話),或者與它的第一個擁有RenderLayer的祖先RenderObject創建的RenderLayer相關聯。
RenderLayer 也會形成一個樹型層次結構。這個樹結構的根節點是與網頁的根元素相對應的RenderLayer.每一個RenderLayer 節點的后代都是
包含在父親RenderLayer內的可視化的RenderLayer.
每一個RenderLayer的子節點都被存儲在兩個按升序排列的有序表中。
negZOrderList 有序表中存儲的子節點是z-index值為負的子RenderLayer,所以這些RenderLayer在當前RenderLayer的下面;
posZOrderList有序表中存儲的子節點是z-index值為正的子RenderLayer,所以這些RenderLayer在當前RenderLayer的上面;
Putting it Together: many trees
簡言之,在概念上存在著三顆平行的樹結構,分別負責渲染過程中的不同目的:
DOM Tree 是我們的基礎模型;
RenderObject Tree是由DOM Tree的可視化節點一對一映射而來的,RenderObject知道如何渲染它所對應的Dom Node.
RenderLayer Tree 由RenderObject 映射的RenderLayers組成。這種映射關系是多對一的,因為每一個RenderObject或者與它所擁有(創建)的RenderLayer相關聯,
或者與它的第一個擁有RenderLayer的祖先RenderObject的RenderLayer相關聯。
RenderLayer Tree負責維護RenderLayers 之間的Z-ordering 順序。

圖 render trees.png



the software rendering path
從根本上說,webkit 通過從根節點開始遍歷RenderLayer樹結構來渲染頁面。
Webkit 代碼庫中包含兩種完全不同的渲染路徑。軟件渲染路徑和硬件加速渲染路徑。
軟件渲染路徑是傳統的渲染方式。
在軟件渲染方式下,按照從后向前順序繪制各層RenderLayer來渲染頁面
從根節點開始遞歸遍歷RenderLayer層次結構。遍歷過程中要完成大量工作。
這些工作是在RenderLayer::paintLayer()中完成的,包括以下一些基本步驟(為了更明晰,簡要列在這里):
a.判斷當前RenderLayer是否與damage rect 有交集;
b.調用paintLayer()遞歸繪制有序表negZOrderList中的各層RenderLayer;
c.請求與當前RenderLayer相關聯的那些RenderObject 繪制它們自己;
d.這個繪制過程是通過遍歷以創建當前RenderLayer的RenderObject為開始節點的Render Tree進行的。當遇到一個RenderObject所關聯的RenderLayer與當前RenderLayer不同時,遍歷過程便結束了。
e.調用paintLayer()遞歸繪制有序表posZOrderList中的各層RenderLayer;
在軟件渲染方式下,RenderObjects 調用一個共享的GraphicsContext(Chrome中是Skia)提供的繪制接口將自己繪制到一塊目標bitmap上。
注意,GraphicsContext 本身并沒有Layers概念,但是為了正確繪制半透明的RenderLayer.
這里有一個警告:半透明的層在繪制與它自身相關聯的RenderObject之前會先調用 GraphicsContext::beginTransparencyLayer()。
在Skia的實現中,beginTransparencyLayer()這個調用會使接下來的所有的繪制命令都繪在一塊單獨的Bitmap上。
當前RenderLayer繪制完成后,這塊單獨的Bitmap會和之前的那塊Bitmap合成。當與當前的半透明的RenderLayer相關聯的RenderObject都繪制完時候,需要相應的調用GraphicsContext::endTransparencyLayer()。
From WebKit to the Screen
圖:software rendering architecture


當所有的RenderLayer都繪制到一塊共享的Bitmap上后,就需要將這塊Bitmap顯示到屏幕上。
在Chrome中,這塊Bitmap位于一塊共享內存中,對這塊Bitmap的控制通過IPC方式交給Browser進程。
Browser進程負責調用系統的窗口API將這塊Bitmap繪制到合適的窗口中。
第二部分: 硬件基礎
回憶Webkit 代碼庫中包含兩種渲染路徑,一種是軟件渲染路徑,一種是硬件加速渲染路徑。
如果你已經了解了軟件渲染方式,我們可以開始分析硬件加速渲染方式與軟件渲染方式的區別。
正如名字所提示的,硬件加速方式就是利用GPU在合成一些RenderLayer的內容時的加速功能。
硬件加速的相關代碼由編譯時的宏開關ACCELERATED_COMPOSITING 控制。
當至少有一個RenderLayer要求使用硬件加速時,或者當標志 --forced-compositing-mode打開時,?
Chrome就會使用硬件加速渲染路徑。這個標志在android和ChromeOS的Chrome中默認都是打開的。
蘋果和大多數iOS上的Safari都采用硬件加速的渲染方式,并且大量運用了蘋果的CoreAnimation API.
Introducing the compositor
在硬件加速渲染方式下,一些RenderLayer(不是所有)擁有自己的backing surface(擁有單獨的backing surface的renderlayer叫做compositing layers).
擁有Backing surface的RenderLayer在繪制時將它們自身繪制到自己的backing surface上,而不是網頁公共的那塊bitmap上。
隨后的合成過程會將所有的backing surface合成到目標Bitmap上。
我們仍然是從RenderLayer Tree開始,以一塊單獨的Bitmap結束,但是這種分成兩個階段的方式,允許合成器在per-compositing-layer的基礎上做一些額外的工作。
例如,在合成每個compositing layer之前,合成器負責對這個compositing layer所對應的bitmap做一些必要的變換(由css 的 transform 屬性值指定)。
而且,由于這些Layer的繪制和合成分開了,這些Layer中的一個如果失效,只會引起這一個Layer中內容的重繪,然后再將這個layer重新合成即可。
相反地,在軟件渲染中,如果任何一個Layer的內容失效會引起在它上面和下面的所有Layer的重繪。這些都是CPU的不必要的負擔。
More Trees: From RenderLayers to GraphicsLayers
在軟件渲染方式下,整個網頁只有一個GraphicsContext。
在硬件加速合成的方式下,每個compositing layer 都需要一個單獨的GraphicsContext,以便每個Compositing layer 都可以繪制在自己單獨的
bitmap上。
前面已經講過,有一組平行的概念上的樹結構,每一個都比前一個更稀疏,而且每一個都對前一個的一個子樹負責,這組樹結依次為:DOM Tree;RenderObject Tree,和RenderLayer Tree.
在介紹硬件合成時,我們要再加一個概念上的樹: GraphicsLayer tree。每一個RenderTree或者擁有自己的GraphicsLayer(如果這個RenderLayer是compositing Layer的話),或者是使用它的第一個擁有GraphicsLayer的祖先節點的GraphicsLayer.
RenderLayer與GraphicsLayer的關系類似于RenderObject與RenderLayer之間的關系。每個GraphicsLayer都擁有一個GraphicsContext,與這個GraphicsLayer相對應的每個RenderLayer都繪制到這個GraphicsContext.上。
理論上講,每一個RenderLayer都可以將自己繪制到一個單獨的backing surface上以避免不必要的重繪。
但是在實際中,這種做法會導致內存的大量浪費。在當前的Webkit 實現中,只有滿足以下條件之一,RenderLayer才會擁有它自己的composingLayers.(見RenderLayerCompositor::requiresCompositingLayer()):
layer 有3D或者CSS transform 屬性值;
layer是硬解碼的video 元素使用的;
layer是擁有3D context或2D加速context的Canvas標簽使用的;
layer是一個合成的插件使用的;
layer使用了動畫表示它的透明度,或者Layer使用了動畫形式的webkit 變換;
layer 使用了加速的CSS 濾鏡;
擁有compositing layer后代的layer
渲染在Compositing layer之上的layer
這意味著擁有需要合成的RenderLayer的網頁總是通過合成器來渲染。其他網頁可能需要也可能不需要合成器來渲染,這取決于標志 --forced-compositing- mode 的狀態。
the code?
與合成器相關的代碼在WebCore中。由USE(ACCELERATED_COMPOSITING)控制。一部分代碼是所有平臺共享的,一部分是Chrome平臺專用的。
webkit的代碼結構允許把chrome平臺相關的合成器的實現放在平臺相關的源文件中(platform/graphics/chromium),不需要修改webkit的核心代碼。
同樣的,依據Skia圖形庫實現的GraphicsContext我們也放在了平臺相關的源文件中。
GPU 在哪?
GPU是怎樣發揮作用的?為了節省耗時的內存傳送,加入了加速的合成器。瀏覽器的Tab區域的最終渲染都由GPU直接控制。
這種模式與當前的render進程將一塊含有網頁內容的Bitmap通過IPC和共享內存傳給瀏覽器進程去顯示的模式是很不相同的。
在含有硬件加速的架構中,硬件加速Layer(比如,需要合成的 Layer,即那些擁有backing surface的Layer)和網頁其余內容的合成過程是通過調用平臺相關的3D API在GPU上完成的。
實現這些API的最終代碼被封裝成一個庫,這個庫運行在渲染進程中,叫做合成器。
合成器庫利用GPU合成網頁上的矩形區域(例如所有的compositing layers)到一塊單獨的bitmap中。這塊bitmap中的內容就是最終要顯示的網頁內容。
架構插曲: GPU 進程
在我們進一步分析合成器生成的GPU 命令之前,有必要先了解一下Render進程是怎樣向GPU發送命令的。
在chrome平臺的多進程模型中,我們有一個專門的進程負責這項工作:GPU進程。GPU進程的存在主要是出于安全方面的考慮。
受限于沙箱性質,渲染進程(webkit 與合成器都運行在此進程)不能直接調用OS提供的3D API(windows平臺是Direct3D,其余平臺是OpenGL).
出于這個原因,我們需要一個單獨的進程做渲染工作。這個進程就是GPU.GPU進程是專門用來訪問系統的3D API.它以client-server模式工作:
客戶端(運行渲染進程的代碼),并不直接調用系統的3D API,而是將這些命令序列化后放在一個環形Buffer(命令Buffer)中,這塊環形Buffer位于client進程與server進程之間的一塊共享內存中。
服務端(GPU進程,運行在一個可以直接訪問平臺的3D API的受限較少的砂箱中)將序列化的命令從共享內存中取出,解析,然后調用合適的
圖形命令,結果數據直接輸出給窗口。

圖 GPU Process


GPU 進程接收到的命令的樣式類似于GL ES 2.0 API(比如一個命令對應于glClear,一個命令對應于glDrawArrays).由于大部分GL 命令都沒有返回值,
所以client 和server之間可以近乎異步的工作。這使性能負載可以保持在非常低的程度。
客戶端和服務端的所有同步,比如客戶端需要通知服務端有額外的工作需要做,都由IPC機制來控制。
還有一點需要注意的是,共享內存除了存儲命令外,還用來在客戶和服務器之間傳送更大的源數據,比如bitmap for textures,vertext

這里略掉一部分沒有翻譯
第三部分:硬件渲染模式下,利用合成器渲染
合成器的實現建立在GL ES 2.0的客戶端庫之上,這個庫將圖形接口調用代理給GPU 進程(用上文解釋的方式)。
當一個網頁使用合成器渲染時,它的所有像素都是通過GPU 進程直接繪制到窗口上。
合成器維護著GraphicsLayers的一個層次結構,這個層次結構是通過遍歷RenderLayer Tree以及隨著頁面變化的更新建立的。
除了WebGL和Video Layers,每一個GraphicsLayer的內容都是先繪制到一塊系統內存的Bitmap上的(與軟件渲染方式中的過程相同):
每一個RenderLayer都請求與它相關聯的RenderObject 繪制自身到與當前RenderLayer相關聯的GraphicsLayer的GraphicsContext上,即繪制在了
這個GraphicContext相關聯位于系統共享內存中的一塊Bitmap上。這塊Bitmap隨后會傳給GPU 進程(利用GPU進程一節中介紹的資源傳送機制),
接下來,GPU 進程就把這塊Bitmap作為一個textue上傳給GPU.
合成器跟蹤從最近一次被繪制后有變化的GraphicsLayer,只更新與變化的GraphicsLayer相對于的texture.
當所有的texture都上傳給GPU之后,渲染頁面內容就變成了深度優先遍歷GraphicsLayer層次結構并發送GL 命令為之前上傳以texture上傳給GPU的GraphicsLayer 繪制texture quad.
A texture quad 是屏幕上的用給定的Texture填充的四邊形(在我們的例子里,就是GraphicsLayer的內容)。
需要注意的是,深度優先遍歷需要確保GraphicsLayer的正確的z-ordering順序。與每一個GraphicsLayer相關聯的RenderLayer的Z-ordering序是在較早的時候RenderObject被光柵化到texture中時予以保證的。
圖: compositing with the gpu process

the code?
chrome 平臺的合成器代碼的實現在webcore下的目錄 platform/graphics/chromium中。
合成器的邏輯大部分在LayerRendererChromium.cpp文件中。
各種composited layer的實現分別在文件 {Content|Video|Image} LayerChromium.cpp中。
第四部分:優化!平滑渲染
現在我們已經大致知道怎樣用合成器渲染一個頁面:網頁內容被分布在各個Layerzhong ,Layer被光柵化到textures中,textures被上傳給GPU.
合成器告訴GPU將所有的textures合成為最終的屏幕圖像。
接下來理解怎么在一秒鐘內做60次這些事情,以確保動畫,滾動,以及其他的頁面交互能平滑進行。
為了解釋這些,我們需要介紹與渲染技術的優化相關的一些概念。
Damage:
目前為止,我們只介紹了如何渲染整個頁面。這只是Webkit在頁面加載完后第一次渲染頁面時做的事情。
但是,更典型的情況是,用戶與頁面交互時只有部分頁面內容發生了變化,這時就需要進入damage rect.
當網頁內容的可視化部分發生變化時(比如 js 改變了css style,css 動畫在運行,或者用戶滾動了viewport),webkit 會跟蹤網頁中需要更新
的部分。跟蹤的結果是用一個damage rectangle 記錄需要重繪的網頁區域。
當繪制時,我們遍歷RenderLayer只繪制與damage rectangle 有交集的Layer,跳過與damage rectangle完全沒有重疊的Layers.
這就避免了網頁中任何一部分變化時都需要重繪整個網頁,明顯會優化性能。


總結

以上是生活随笔為你收集整理的chrome 硬件渲染(GPU Accelerated Compositing in Chrome)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人网站在线进入爽爽爽 | 国产一级一片免费播放 | 欧美视频黄色 | 国产青青草视频 | 欧美视频在线一区二区三区 | 欧美黑人一级爽快片淫片高清 | av中亚| 精品欧美在线观看 | 亚洲av电影天堂男人的天堂 | 福利在线电影 | 无码国产精品一区二区色情男同 | 午夜精品久久 | 亚洲成人自拍 | 成人免费观看视频大全 | 亚洲自拍小视频 | 久久大奶 | 日韩毛片儿 | 九九视频国产 | 羞羞漫画在线播放 | 99久久综合| 亚洲欧美色图在线 | 色撸撸在线观看 | 亚洲久久色 | 久久精品动漫 | 亚洲在线色 | 日韩在线视频精品 | 天堂av中文在线观看 | 91久久超碰 | 日本少妇一区二区三区 | 成人免费看高清电影在线观看 | 久久久91精品 | 午夜伦伦电影理论片费看 | 男人天堂1024 | 国产一级爱 | 日韩精品一区二区电影 | 国产乱子伦一区二区 | 亚洲网站av | 黄色小视频免费网站 | 国产无| 又爽又黄视频 | 国产乱仑视频 | 奇米色综合| 久久久成人网 | 香港三日本三级少妇66 | 欧美日韩高清一区二区 国产亚洲免费看 | 国产最新视频在线 | 国产一级黄色电影 | 九色自拍视频 | jizz欧美性20| 人妻无码久久一区二区三区免费 | 欧美性生交大片免费看app麻豆 | 免费观看毛片网站 | 天天插天天狠天天透 | 伊人网在线观看 | 久久午夜网 | 国产又爽又猛又粗的视频a片 | 五月婷婷色丁香 | 国产精品久久久久久久成人午夜 | 人妻少妇偷人精品久久性色 | 亚洲黄色三级视频 | 久久久久国色av免费观看性色 | 亚洲男人皇宫 | 91玉足脚交嫩脚丫在线播放 | 黄色在线观看av | 欧美性xxxx| 亚洲一区91| 国产精品久久久久久久久晋中 | 欧美日韩综合 | 51久久 | 亚洲理论在线观看 | 麻豆网站入口 | 极品尤物在线观看 | 久久久久久久久久一级 | 色偷偷噜噜噜亚洲男人 | 久久男女视频 | 波多野吉衣一二三区乱码 | 91精品国产91久久久久久久久久久久 | 一边吃奶一边摸做爽视频 | 天天综合日日夜夜 | 欧洲av在线播放 | 欧美肥老妇视频九色 | 成人av在线一区二区 | 亚洲精品中文字幕在线 | 欧美日韩亚洲一区二区 | 国产一区二区视频在线观看 | 热久久中文 | 亚洲毛片视频 | 狠狠做| 一级片少妇 | 粉嫩欧美一区二区三区 | 欧美色精品在线 | 亚洲色图制服诱惑 | 精品一区二区电影 | 边打电话边做 | 欧美黄色免费大片 | 免费一级毛片麻豆精品 | 欧亚免费视频 | 青青操免费在线视频 | 456亚洲影视 |