Chromium原始碼分析二:LifeofaPixel.pdf
- LifeofaPixel
- 個人觀點
- ccLayer樹
- skia、vulkan、openGL、openCV
- Skia
- Vulkan
- OpenGL
- OpenCV
- 區別
- 聯絡
- PrePaint
LifeofaPixel.pdf畫素的一生,跟隨畫素的一生去理解Chromium的工作原理。據說是Chromium的入門培訓PPT
網址:https://docs.google.com/presentation/d/1boPxbgNrTU0ddsc144rcXayGA_WF53k96imRH8Mp34Y/edit?usp=sharing
在網上找到了比較精簡的筆記
圖片轉載自:https://blog.csdn.net/hebhljdx/article/details/139473588
LifeofaPixel
個人觀點
ccLayer樹
用過PhotoShop的人都知道圖層這個概念。做前端的人也熟悉CSS(層疊樣式表)。我們在螢幕上看到的最終影像其實是處於不同圖層的影像拼合起來的。
對應到前端層面(html+javascript+css)
就是DOM樹,DOM樹的每個節點都有自己的大小、位置、樣式,畫到一起就是影像了。
這裡有個特別要提到的就是“ShaddowDOM”,ShaddowDom透過獨立元件的方式,避免了在樣式、行為上受外層dom的影響。
對應到C++的實現層面這就是ccLayer樹,cc(Chromium Compositor)前文講過,是chromium的合成器。
ccLayer樹的節點是View類,後面的各種頁面的元件(視窗、button、text、toast之類的)都是繼承的view類。View類有如下常用的API:
//設定View的位置和大小
void SetBounds(int x, int y, int width, int height);
//新增一個子view
void AddChildView(View* view);
//刪除一個子view
void RemoveChildView(View* view);
//獲取View對應的Widget
Widget* GetWidget();
//獲取當前view孩子的數量
int child_count()
//獲取parent view
View* parent()
//設定view是否可見
void SetVisible(bool visible)
//觸發一次view樹排版
void Layout()
//標示當前view區域需要重繪並立馬重繪
void SchedulePaint()
//每次繪製,都會進入該方法收集繪製指令並繪製
void Paint()
//為當前view設定背景
void SetBackground(std::unique_ptr<Background> b);
//如果view設定這個屬性,說明該view的宣告週期自己負責,父view析構不會影響噹噹前view;若沒有設定這個屬性,並且當前view被新增為parent_view的child_view,則parent_view析構的時候,會一併析構調該child_view
void set_owned_by_client()
也就是說,每個頁面中的元件都有位置和大小,合成影像的時候,只要把各個層級的ccLayer樹遍歷一遍,每個節點呼叫一下Paint函式,影像就畫出來了。
這個遍歷是並非是根據節點關係遍歷的,是根據圖層的前後順序遍歷的,background先paint,foreground的後paint,還有一些不visible的,就不paint了。
paint的過程就是光柵化的過程,和PhotoShop裡說的光柵化差不多。就是把向量圖轉成點陣圖了。比較複雜的操作,比如把圖片放大、縮小、旋轉、糊化之類的操作還有可能被送到gpu中去做。
這裡面就涉及到了影像處理相關的知識了。簡單介紹一下skia、vulkan、openGL、openCV。
skia、vulkan、openGL、openCV
Skia
用途:Skia 是一個高效能的 2D 圖形處理庫,主要用於繪製文字、形狀、影像和向量圖形。它提供了跨平臺的圖形API,支援多種輸出格式,如點陣圖、PDF 和 SVG。
應用場景:Skia 常用於構建使用者介面,如網頁、移動應用和桌面應用的渲染引擎。它是 Google Chrome、Chromium 和 Android 作業系統的核心圖形庫。
Vulkan
用途:Vulkan 是一種低階別的圖形和計算API,允許開發者直接訪問GPU硬體,以實現高效能的3D圖形渲染和平行計算。
應用場景:Vulkan 適用於遊戲開發、虛擬現實、科學計算和圖形密集型應用,它減少了CPU的負載,提高了多執行緒效能和跨平臺相容性。
OpenGL
用途:OpenGL 是一種跨平臺的API,用於渲染2D和3D圖形,提供了一套標準的圖形繪製功能,包括紋理對映、光照和陰影效果。
應用場景:OpenGL 廣泛應用於遊戲開發、CAD/CAM、科學視覺化和教育軟體,支援從簡單的圖形到複雜的3D場景。
OpenCV
用途:OpenCV 是一個開源的計算機視覺和機器學習庫,提供了一系列函式和演算法,用於影像處理、特徵檢測、物體識別和影片分析。
應用場景:OpenCV 主要用於計算機視覺研究、安全監控、醫學影像分析、機器人視覺和自動駕駛等領域。
區別
抽象級別:OpenGL 和 Vulkan 處理圖形渲染,但Vulkan提供了更低階別的硬體訪問,而OpenGL提供了更高層次的抽象。
用途範圍:Skia 和 OpenGL/Vulkan 主要用於圖形渲染,而OpenCV專注於影像處理和計算機視覺任務。
計算能力:Vulkan 支援平行計算和GPU加速,而Skia、OpenGL 和 OpenCV 更側重於圖形和視覺處理的特定方面。
聯絡
圖形渲染:Skia 和 OpenGL/Vulkan 都涉及圖形渲染,但它們的使用場景和抽象級別不同。
GPU加速:Vulkan 和 OpenCV 都可以利用GPU加速,前者用於圖形渲染,後者用於影像處理和機器學習任務。
跨平臺性:Skia、OpenGL 和 Vulkan 都支援跨平臺應用,提供了一致的API,以適應不同的作業系統和硬體。
總的來說,Skia、Vulkan、OpenGL 和 OpenCV 在圖形和視覺處理領域各自發揮著獨特的作用,它們之間的聯絡主要體現在圖形渲染和GPU加速方面,而區別則在於它們的應用場景、抽象級別和計算能力。
之後就是上篇筆記講到的,把繪圖和渲染任務分配到render程序,最終放display到螢幕上。在此過程中,chromium也做了很多的最佳化,比如PrePaint,PrePaint在實際繪製之前預先計算和準備所有必要的渲染資訊,避免在渲染過程中進行昂貴的計算,從而減少重繪和佈局的成本。
PrePaint
PrePaint在 Chromium 中的主要作用
預計算和快取:PrePaint 階段會計算和快取各種渲染屬性,如圖層的位置、大小、可見性、變換矩陣、滾動偏移等。這些資訊在後續的繪製階段可以直接使用,避免了重複計算。
資源準備:PrePaint 還會準備渲染所需的資源,如紋理、字型、影像等,確保在實際繪製時這些資源已經載入完成並可用,減少繪製延遲。
最佳化渲染路徑:PrePaint 會分析圖層樹和檢視層次結構,決定哪些圖層需要繪製,哪些可以被裁剪或複用,從而最佳化渲染路徑,減少不必要的重繪。
滾動和動畫預測:PrePaint 能夠預測使用者可能的滾動和動畫操作,提前計算和準備相關的渲染資訊,確保動畫和滾動的流暢性。
非同步渲染準備:PrePaint 還支援非同步渲染,可以在後臺執行緒上進行預計算,減少主執行緒的負擔,提高渲染效能。
避免重繪:透過在 PrePaint 階段計算哪些部分需要更新,可以避免不必要的重繪,只更新發生了變化的部分,提高渲染效率。
效能分析:PrePaint 還提供了效能分析和除錯的手段,可以幫助開發者理解和最佳化渲染效能瓶頸。
總之,PrePaint 在 Chromium 中起到了橋樑的作用,它連線了佈局和繪製兩個階段,透過預計算和資源準備,大大提高了渲染效能和使用者體驗。透過將昂貴的計算移到實際繪製之前,PrePaint 能夠確保渲染流程的高效和平滑。