Android圖形繪製


Android圖形繪製涉及的概念較多:

Window、View、Surface、SurfaceFlinger、Layer、Canvas、FrontBuffer/BackBuffer、Bitmap、Compose、FrameBuffer等等。

To draw something, you need 4 basic components: 
(1)A Bitmap to hold the pixels
(2)a Canvas to host the draw calls (writing into the bitmap)
(3)a drawing primitive (e.g. Rect, Path, text, Bitmap)
(4)a paint (to describe the colors and styles for the drawing).

創建Window/View:
應用程序啓動時,實際是通過ActivityThread的main函數啓動消息循環,在LAUNCH_ACTIVITY消息處理中調用performLaunchActivity,此方法中創建Activity對象並調用其attach方法,在此方法中創建Window對象(PhoneWindow),而後建立Decro View(ViewRoot)加入到WindowManager中。
在將Window(主View)加入到WindowManager中後,會建立一個WindowManager的代理對象,並維護一個Activity和WindowManager之間的對話(Session)。
之後加入的View或ViewGroup都會被維護在Decro View之下。

畫圖操作:
應用程序在建立窗口時,就申請創建一個Surface;一個ViewRoot對應一個Surface,其中所有的View共用同一個Surface。
在申請創建surface的過程中,會在surfaceflinger中創建一個對應的layer。
在創建layer的時候,surfaceflinger爲其創建了兩個圖形緩衝區,front buffer / back buffer,在surface中也是使用這兩個緩衝區,由於SurfaceFlinger和應用程序並不是運行在同一個進程中,所以應用客戶端(Surface)和服務端(SurfaceFlinger - Layer)之間要通過SharedBufferStack傳遞和同步顯示緩衝區。
android中的作圖全是在canvas上進行繪製,兩個圖形緩衝區中的back buffer也就是我們通常所說的canvas,要想在canvas上進行繪製,其前提就是必須已經將它和對應的圖形緩衝區綁定完畢,所謂的綁定只是獲得back buffer的首地址,這樣我們在canvas上進行繪製便有了內存空間。可以研究android_view_Surface.cpp::lockCanvas。

圖形顯示:
在所有的View進行繪製完畢後,會將canvas/back buffer中已經畫好的圖像,全部swap成front buffer,然後由surfaceflinger進行compose工作,最後繪製到framebuffer中,並顯示出來。這樣就完成了圖形的繪製工作。

具體的接口調用:
View組件的繪製會層層上傳直到ViewRoot,然後由ViewRoot調用performTraversals()繪製,而後調用下一層的draw(Canvas canvas)方法,其中依次調用background.draw(),onDraw(Canvas canvas),dispatchDraw(Canvas canvas)方法。dispatchDraw()主要是分發給子View進行繪製,我們通常定製組件的時候重寫的是onDraw()方法。
值得注意的是ViewGroup容器組件的繪製,當它沒有背景時直接調用的是dispatchDraw()方法, 而繞過了draw()方法,當它有背景的時候就調用draw()方法,而draw()方法裏包含了dispatchDraw()方法的調用。因此要在ViewGroup上繪製東西的時候往往重寫的是dispatchDraw()方法。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章