天天看點

Skia深入分析1——skia上下文

前言:

        斷斷續續跟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——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上下文

skia相關子產品

1、調用skia的庫

libandroid_runtime:framework.jar的jni實作,連結framework和lib庫的橋梁

hwui:2d硬體加速庫,使用skia的資料格式

libchromeview:浏覽器引擎,webview相關

2、skia使用的庫

(1)圖檔編解碼庫

libjpeg

libpng

libgif

webp

(2)字型解析

freetype

具體内容會在後續章節中講述。

繼續閱讀