高性能Web動畫渲染原理系列(4)“Compositor-Pipeline演講PPT”學習摘要

      網友投稿 760 2022-05-29

      示例代碼托管在:http://www.github.com/dashnowords/blogs

      博客園地址:《大史住在大前端》原創博文目錄

      華為云社區地址:【你要的前端打怪升級指南】

      高性能Web動畫和渲染原理系列(4)“Compositor-Pipeline演講PPT”學習摘要摘要1.合成流水線2. 預定義UI層3. paint是什么意思4. 分層的優勢和劣勢5. 視圖屬性及其處理方式6. Quads7. Compositor Frame8. 關于光柵化以及渲染方式9.【重要】軟件渲染和硬件渲染的區別

      附件PPT來自chromium官方網站開發文檔。術語里的cc指的是Chromium Compositor

      一直以來都想了解瀏覽器合成層的運作機制,但是相關的中文資料大多比較關注框架和開發技術,這方面的資料實在是太少了,后來在chromium官方網站的文檔里找到了項目組成員malaykeshav在 2019年4月的一份關于瀏覽器合成流水線的演講PPT,個人感覺里面講的非常清楚了,由于沒有找到視頻,有些部分只能自行理解,本文僅對關鍵信息做一些筆記,對此感興趣的讀者可以在文章開頭的github倉庫或附件中拿到這個PPT自行學習。

      摘要

      1.合成流水線

      合成流水線,就是指瀏覽器處理合成層的工作流程,其基本步驟如下:

      大致的流程就是說Paint環節會生成一個列表,列表里登記了頁面元素的繪制指令,接著這個列表需要經過Raster光柵化處理,并在合成幀中處理紋理,最后的Draw環節才是將這些紋理圖展示在瀏覽器內容區。

      2. 預定義UI層

      chromium中預定義了一些指定類型的UI層,大致分為:

      Not Drawn - 為了處理透明度或濾鏡效果、transform變形或者clip剪裁的非繪制層

      Solid color layer - 固有顏色層

      Painted texture layer - Texture紋理會在這個層執行paint渲染和后續的rasterized光柵化任務

      Transferable resource layer ? - 共享資源層,可能是GPU里面的Texture紋理也可能未來會發給GPU的位圖

      高性能Web動畫和渲染原理系列(4)“Compositor-Pipeline演講PPT”學習摘要

      Surface layer - 臨時占位層,因為自頂向下遍歷layer樹時子樹都還沒處理,需要先占位最后再填充

      Nine patch layer - 用于實現陰影的層

      3. paint是什么意思

      每個層layer是由若干個views組成的,所謂paint,就是每個views將自己對應圖形的繪制指令添加到層的可展示元素列表Display Item List里,這個列表會被添加到一個延遲執行的光柵化任務中,并最終生成當前層的texture紋理(可以理解為當前層的繪制結果),考慮到傳輸性能以及未來增量更新的需求,光柵化的結果會以tiles瓦片形式保存。在chrome中也可以看到頁面瓦片化拆分的結果:

      4. 分層的優勢和劣勢

      分層的優勢和劣勢也在此進行了說明,和之前我們主動思考的答案基本一致(暗爽一下)。

      5. 視圖屬性及其處理方式

      views中支持的屬性包含Clip剪裁,transform變換,effect效果(如半透明或濾鏡等),mask遮罩,通常按照后序遍歷的方式自底向上進行遍歷處理。

      clip剪裁的處理方式是在父節點和子節點之間插入一個剪裁層,用來將其子樹的渲染結果剪裁到限定的范圍內,然后再向上與父級進行合并;

      transform變換直接作用于父節點,處理到這個節點時其子樹都已經處理完畢,直接將整體應用變形即可;

      effect效果一般直接作用于當前處理的節點,有時也會產生交叉依賴的場景;

      PPT第40頁中在介紹effect效果處理時描述了兩種不同的透明度處理需求,從而引出了一個Render Surface的概念,它相當于一個臨時的層,它的子樹需要先繪制在這個層上,然后再向上與父節點進行合并,屏幕就是是根級的Render Surface。

      6. Quads

      Layer遍歷處理輸出的結果被稱為Quads(從意思上理解好像就是指輸出了很多個矩形方塊),每個quad都持有它被繪制到目標緩沖區所需要的資源,根據它持有的資源不同可以分為:

      Solid Color-固定顏色型

      Texture- 紋理型

      Tile- 瓦片型

      Surface- 臨時繪圖表面型

      Video - 視頻幀型

      Render Pass - Render Surface類型的占位區,Render Surface子樹處理完后填充到關聯的Render Pass

      7. Compositor Frame

      合成層真正的工作要開始了,主角概念Compositor Frame(合成幀)登場,它負責將quads合并繪制在一起,膠片里59-62頁非常清楚地展示了合成的過程,最終輸出的結果就是根節點的紋理。

      chromium是多進程架構,Browser Process瀏覽器進程會對菜單欄等等容器部分的畫面生成合成幀來輸出,每個網頁的Render Process渲染進程會對頁面內容生成合成幀來輸出,最終的結果都被共享給GPU ProcessGPU進程進行聚合并生成最終完整的合成表面,接著在Display Compositor環節將最后的位圖展示在屏幕上。

      8. 關于光柵化以及渲染方式

      膠片里并沒有描述具體的光柵化的處理過程,但是layer輸出的quads看起來應該是光柵化以后的結果,推測應該是處理Display Item List中的繪圖指令時也和WebGL類似,經過頂點著色器和片元著色器的遍歷式處理機制,并在過程中自動完成像素插值。

      9.【重要】軟件渲染和硬件渲染的區別

      聲明:本節內容是個人理解,僅用作技術交流,不保證對!

      軟件渲染和硬件渲染的區別對筆者而言一直非常抽象,只是知道基本概念。后來在【chromium開發者文檔】(國內可能無法訪問)中《Compositor Thread Architecture》這篇合成器線程架構的文章中找到了一些相關描述,也解開了筆者心中一直以來的疑惑,相關部分摘抄如下:

      Texture Upload

      One challenge with all these textures is that we rasterize them on the main thread of the renderer process, but need to actually get them into the GPU memory. This requires handing information about these textures (and their contents) to the impl thread, then to the GPU process, and once there, into the GL/D3D driver. Done naively, this causes us to copy a single texture over and over again, something we definitely don't want to do.

      We have two tricks that we use right now to make this a bit faster. To understand them, an aside on “painting” versus “rasterization.”

      Painting is the word we use for telling webkit to dump a part of its RenderObject tree to a GraphicsContext. We can pass the painting routine a GraphicsContext implementation that executes the commands as it receives them, or we can pass it a recording context that simply writes down the commands as it receives them.

      Rasterization is the word we use for actually executing graphics context commands. We typically execute the rasterization commands with the CPU (software rendering) but could also execute them directly with the GPU using Ganesh.

      Upload: this is us actually taking the contents of a rasterized bitmap in main memory and sending it to the GPU as a texture.With these definitions in mind, we deal with texture upload with the following tricks:

      Per-tile painting: we pass WebKit paint a recording context that simply records the GraphicsContext operations into an SkPicture data structure. We can then rasterize several texture tiles from that one picture.

      SHM upload: instead of rasterizing into a void* from the renderer heap, we allocate a shared memory buffer and upload into that instead. The GPU process then issues its glTex* operations using that shared memory, avoiding one texture copy.The holy grail of texture upload is “zero copy” upload. With such a scheme, we manage to get a raw pointer inside the renderer process’ sandbox to GPU memory, which we software-rasterize directly into. We can’t yet do this anywhere, but it is something we fantasize about.

      大概翻譯一下,方便英語水平一般的小伙伴理解,GPU處理圖片的方式是按照Texture進行貼圖的,對此不熟悉的小伙伴可以查看筆者以前發的有關Three.js相關的博文。

      紋理上傳:處理紋理的挑戰之一就是它是在渲染進程(可以理解為單個Tab網頁的進程)的主線程里進行的,但是最終需要將其放入GPU內存。這就需要將紋理數據遞交給合成器線程,然后再交給GPU進程(Chromium架構里有專門的GPU進程用來專門處理和GPU之間的協作任務),最后再傳遞給底層的Direct3D或OpenGL(也就是圖形學的底層技術),如果只是按照常規流程來處理,就會需要一次又一次來復制生成的紋理數據,這顯然不是我們想要的。我們現在使用了兩個小方法來使這個流程變得快一點。它們分別作用于painting(繪制)和rasterization(光柵化)兩個階段。

      1號知識點!!!Painting我們用來告訴webkit為RenderObject Tree的來生成對應的GraphicsContext。通過給painting routine(繪制流程)傳遞一個GraphicsContext的具體實現來執行這些已經編排好的繪制命令,也可以傳遞一個record context(記錄上下文)只是簡單地把繪圖命令都記錄下來。

      2號知識點!!!Rasterization(光柵化)是指Graphics context關聯的繪圖命令實際被執行的過程。通常我們使用CPU(也就是軟件渲染的方式)來執行光柵化任務,也可以直接使用GPU來渲染(也就是硬件渲染的方式)。

      上傳:指在主線程存儲區獲取到光柵化以后的位圖內容然后將它作為紋理上傳給GPU的過程,考慮到上述已經提及的定義,上傳過程是如下來處理的:

      瓦片繪制:我們在webkit中使用recording context來簡單地記錄Graphics Context的操作指令,將它存儲為SkPicture類型(直接使用軟件光柵化時生成的是SkBitmap類型),隨后可以從一張picture里面光柵化處理得到多個紋理瓦片。

      共享內存:在軟件渲染的方式中,光柵化的結果會被存儲在renderer進程的堆內存里,現在不這樣搞了,我們重新分配了一塊共享緩沖區,然后通過它來傳遞相關對象,GPU進程隨后在獲取紋理時直接從共享內存中獲取就行了,這樣就避免了數據的拷貝。總的來說,紋理上傳的過程幾乎是零拷貝的。利用這樣的結構,我們在renderer進程(也就是網頁的渲染進程)的沙箱環境內也可以獲取到指向GPU 內存的指針,而在軟件光柵化的過程中,是直接將位圖結果放在這里的。

      Painting: this is the process of asking Layers for their content. This is where we ask webkit to tell us what is on a layer. We might then rasterize that content into a bitmap using software, or we might do something fancier. Painting is a main thread operation.

      Drawing: this is the process of taking the layer tree and smashing it together with OpenGL onto the screen. Drawing is an impl-thread operation.

      painting:表示的過程是向Layers對象查詢層內容,也就是讓webkit告訴我們每一層上面到底有什么。接下來我們就可以使用軟件光柵化的方式將這些內容處理為位圖,也可以做一些更牛的事情,painting是一個主線程行為。

      drawing:是指將Layer中的內容用OpenGL繪制在屏幕上的過程,它是另一個線程中的操作。

      概念比較多沒有基礎的讀者可能理解起來有難度,我嘗試用自己的話復述一下:

      【軟件渲染】的模式下,在paint時會直接利用Graphics Context繪圖上下文將結果繪制出來,在一個SkBitmap實例中保存為位圖信息;【硬件渲染】的模式下,在paint時傳入一個SkPicture實例,將需要執行的繪圖命令保存在里面先不執行,然后通過共享內存將它傳給GPU進程,借助GPU來最終去執行繪圖命令,生成多個瓦片化的位圖紋理結果(OpenGL中頂點著色器向片元著色器傳遞數據時可以自動進行數據插值,完成光柵化的任務)。 純軟件渲染里嚴格說是沒有合成層概念的,因為最終輸出的只有一張位圖,按照順序從下往上畫,和畫到一個新層上再把新層貼到已有結果上其實是一樣的。

      不管使用哪種途徑,paint動作都是得到位圖數據,而最終的draw這個動作是借助OpenGL和位圖數據最終把圖形顯示在顯示器上。

      所以【硬件渲染】就是渲染進程把要做的事情和需要的數據都寫好,然后打包遞給GPU讓它去干活。

      完整的PPT可以在附件或開頭的github倉庫中獲取。

      附件: Chromium OS - Compositor Pipeline.rar 9.01M 下載次數:0次

      web前端 渲染

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:圖文詳解應用登錄驗證碼的多種實現方案
      下一篇:【產品】小白進階之產品經理的職責和挑戰
      相關文章
      日韩亚洲Av人人夜夜澡人人爽| 久久亚洲国产成人精品无码区| 国产成人人综合亚洲欧美丁香花| 亚洲人成伊人成综合网久久| 久久久亚洲AV波多野结衣| 亚洲av无码成h人动漫无遮挡 | 亚洲午夜久久久精品电影院| 亚洲视频在线观看地址| 精品亚洲成a人片在线观看| 亚洲狠狠综合久久| 亚洲av永久无码精品古装片| 亚洲人成人无码网www电影首页| 国产综合亚洲专区在线| 国产亚洲自拍一区| 亚洲日韩v无码中文字幕| 亚洲精品亚洲人成在线观看| 亚洲线精品一区二区三区| 亚洲午夜久久久影院伊人| 亚洲精品二区国产综合野狼 | 亚洲欧洲日韩综合| 亚洲婷婷在线视频| 亚洲天堂2016| 亚洲欧洲日产国码久在线| 亚洲av永久无码天堂网| 国内成人精品亚洲日本语音 | 亚洲男人天堂av| 精品亚洲国产成AV人片传媒| 亚洲欧洲中文日产| tom影院亚洲国产一区二区| 亚洲砖码砖专无区2023| 亚洲成AV人片高潮喷水| 国产亚洲男人的天堂在线观看| 亚洲av无码专区在线观看素人| 亚洲第一福利网站在线观看| 亚洲午夜爱爱香蕉片| 亚洲人成网7777777国产| 亚洲国产人成网站在线电影动漫| 亚洲色图.com| 亚洲中文字幕无码中文字| 欧美亚洲精品一区二区| 亚洲男人在线无码视频|