例:實(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)算跛蛋,通常所說的“顯卡”的核心部件就是GPU
4.硬件加速原理:就是通過底層軟件代碼熬的,將CPU不擅長(zhǎng)的圖形運(yùn)算轉(zhuǎn)換成GPU專用指令,由GPU完成
Android中的硬件加速
大多數(shù)界面都是利用常規(guī)的View來構(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樹的固定流程锈麸。首先根據(jù)標(biāo)志位判斷是否需要重新布局并執(zhí)行布局镀脂。然后進(jìn)行Canvas的創(chuàng)建等操作開始繪制
①如果硬件加速不支持或者被關(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)過用于在遍歷VIew樹繪制的過程中更新DisplayList屬性但荤,并快速跳過不需要重建DisplayList的View罗岖。
4.在硬件加速情況下,draw流程執(zhí)行結(jié)束后DisplayList的構(gòu)建完成腹躁,然后通過ThreadedRender.nSyAndDrawFrame()利用GPU繪制DisplayList到屏幕上呀闻。
####歡迎關(guān)注公共號(hào)
