前言:
斷斷續續跟android的skia庫打了兩年交道,如今交接掉了,便寫寫關于skia的一些知識,也算了結一段職業生涯。
找了找網上關于skia的文章,基本上都過時了,講得也不怎麼深入。雖然skia隻是一個2d引擎,但其深度優化的算法、完善的渲染體系和精煉的代碼架構,還是很值得借鑒的。
ps:文章所依據的代碼為目前最新的android 5.0.2。
基本章節規劃如下:
1、skia的上下文(即本章)
2、skia基本渲染流程與架構
3、skia圖像繪制分析
4、skia路徑繪制分析
5、skia文本繪制分析
6、skia編解碼架構分析
7、區域解碼分析
8、skia-gpu簡介
9、skia的性能瓶頸分析
10、延遲渲染機制
一、skia在android中的地位
1、規定2d繪制api
2、規定圖像資料結構
3、承擔編解碼排程和軟體渲染職責
二、android系統中主要使用skia的場景
skia調用關系簡圖
1、界面繪制(lockcanvas——draw——unlockcanvas流程)
(1)ui控件,未開啟硬體加速。由performtravelsals——drawsoftware調入。
android顯示系統是最複雜的android最複雜的子系統,沒有之一,這裡隻說明軟體繪制時的一個基本過程:
a、計算布局,看是否需要更新view。
b、計算所有需要更新的view的區域,計算其最小外包矩形,即dirtyrect
c、由surface去lock一個canvas,lock時指定dirtyrect,這裡涉及gui的buffer輪換機制,會去擷取一塊未在顯示的buffer,由于換了buffer,在gui子產品會去拷貝上一幀非dirtyrect的部分。
d、執行根view的draw方法,遞歸調用所有子view的ondraw方法。由于canvas對應的是軟體繪制的canvas,所有繪制操作經過canvas——skiacanvas——skcanvas的流程,由skia引擎執行。(androidl上在jni(libandroid_runtime)處作了一層skiacanvas的封裝,4.4及以前是canvas——skcanvas)
e、完成繪制,讓surface去unlockcanvas,将繪制好的buffer送顯。
(2)surfaceview,這個是由應用顯式實作lockcanvas——draw——unlockcanvas流程。
2、圖像處理
這種情況下,開發者自行基于目标bitmap建立canvas,調用canvas的api繪制圖像,一般是作圖像的縮放、旋轉處理,也可以加入漸變特效。(不是 lockcanvas 或 繼承 ondraw 方法中傳入的canvas,就别想拿去上屏了)
3、圖像編解碼
skia對各種類型的圖檔作了适配,提供統一的接口,開發者調用bitmapfactory,bitmapfactory進一步調用jni——skia。
(1)關于圖像全解,這部分調用邏輯看上去簡單,實際上對于輸入輸出流的處理還是比較複雜的,涉及java的流——skia規定的流——對應解碼庫的流兩重轉換。
(2)關于區域解碼,這部分是google為平衡記憶體——性能——顯示速度而設計的方案,一些android機器上的圖庫打開照片時有一塊一塊漸漸清晰的過程,就是區域解碼然後局部重新整理的結果。
區域解碼分成兩步:
a、建立tileindex,以便查找某個區域所對應的碼流位置。
b、解碼:輸入指定區域,按照tileindex查找對應碼流,将對應區域的圖檔解出來,這個過程一般會調用多次。
4、番外:webview軟體渲染
由于libchromeview将libskia以靜态方法內建進去,便跟系統的skia庫沒什麼關系了。對android系統而言是統一的webview顯示架構。
三、skia相關的庫簡介
skia相關子產品
1、調用skia的庫
libandroid_runtime:framework.jar的jni實作,連結framework和lib庫的橋梁
hwui:2d硬體加速庫,使用skia的資料格式
libchromeview:浏覽器引擎,webview相關
2、skia使用的庫
(1)圖檔編解碼庫
libjpeg
libpng
libgif
webp
(2)字型解析
freetype
具體内容會在後續章節中講述。