例:實(shí)現(xiàn)一個(gè)圓角矩形通常有兩個(gè)方案:
1.使用PNG圖片
原理:使用PNG圖片(BitmaoDrable)解碼PNG圖片生成Bitmap,傳到底層,有GPU渲染圖片解碼,消耗CPU運(yùn)算資源,Bitmap占內(nèi)存大,繪制慢。
2.使用代碼(XML或者Java)實(shí)現(xiàn)
繪制使用XMl或者Java代碼實(shí)現(xiàn)(ShapeDrawable)直接將shape信息傳到底層,由GPU渲染消耗CPU資源少,占內(nèi)存少,繪制快。
3.CPU和GPU結(jié)構(gòu)對(duì)比
CPU:中央處理器,是計(jì)算機(jī)設(shè)備核心器件,用于執(zhí)行程序代碼
GPU:圖形處理器,主要用于處理圖形運(yùn)算,通常所說(shuō)的“顯卡”的核心部件就是GPU
4.硬件加速原理:就是通過(guò)底層軟件代碼,將CPU不擅長(zhǎng)的圖形運(yùn)算轉(zhuǎn)換成GPU專用指令,由GPU完成
Android中的硬件加速
大多數(shù)界面都是利用常規(guī)的View來(lái)構(gòu)建的。
DisplayList
DisplayList是一個(gè)基本繪制元素,包含元素原始的屬性(位置、尺寸、角度、透明度等)對(duì)應(yīng)的Canvas的draw xxx()方法。
信息的傳遞流程:
Canvas(Java API)——》OpenGL(C/C++)——》驅(qū)動(dòng)程序——》GPU
在Android4.1及以上版本,DisplayList支持屬性,如果View的屬性發(fā)生變化(比如Scala,Apla,Tranlate)只需把屬性更新給GPU,不需要生成新的DisplayList。
RenderNode
一個(gè)RenderNode包含若干個(gè)DisPlayList通常一個(gè)RenderNode對(duì)應(yīng)一個(gè)View,包含View自身及其子View的所有DisPlayList。
Android的繪制流程:

繪制步驟:
1.從ViewRootImpl.perform Traversals到phoneWindow DecraView.drawchild 是每次遍歷,VIew樹(shù)的固定流程。首先根據(jù)標(biāo)志位判斷是否需要重新布局并執(zhí)行布局。然后進(jìn)行Canvas的創(chuàng)建等操作開(kāi)始繪制
①如果硬件加速不支持或者被關(guān)閉,則使用軟件繪制,生成的Canvas即Canvas.class的對(duì)象
②如果支持硬件加速,則生成的是DisplayList Canvas.class 對(duì)象
③兩者的isHardwarve Accelerated()的方法返回的值分別是false,true,View根據(jù)這個(gè)值判斷硬件是否加速
2.VIew中的draw (cavas,parent,drawingTime)——draw——onDraw——dispatchDraw——drawchild這條遞歸路徑(簡(jiǎn)稱Draw路徑)調(diào)用了Canvas.draw xxx()方法,在軟件渲染時(shí)用于實(shí)際繪制,在硬件加速時(shí),用于構(gòu)建Displaylist。
3.View中的updateDisplayListIfDirty——dispatchGet——playList——recreatechildDisplayList這條遞歸路基(簡(jiǎn)稱DisplayList路徑)僅在硬件加速時(shí)會(huì)經(jīng)過(guò)用于在遍歷VIew樹(shù)繪制的過(guò)程中更新DisplayList屬性,并快速跳過(guò)不需要重建DisplayList的View。
4.在硬件加速情況下,draw流程執(zhí)行結(jié)束后DisplayList的構(gòu)建完成,然后通過(guò)ThreadedRender.nSyAndDrawFrame()利用GPU繪制DisplayList到屏幕上。
####歡迎關(guān)注公共號(hào)
