Android 技術(shù)專題系列之九 -- 圖形系統(tǒng) 收藏
本文試圖講述Android圖形系統(tǒng)的底層實(shí)現(xiàn)。Android圖形系統(tǒng)底層實(shí)現(xiàn)非常復(fù)雜,文檔較少,沒有使用比較流行的圖形組建如X window, Cairo等。 Android中的圖形系統(tǒng)采用Client/Server架構(gòu)。Server (即SurfaceFlinger)主要由c++代碼編寫而成。Client端代碼分為兩部分,一部分是由Java提供的供應(yīng)用使用的api,另一部分則是由c++寫成的底層實(shí)現(xiàn)。下圖概要介紹了android圖形系統(tǒng)的架構(gòu)以及使用到的主要組件。
Android圖形系統(tǒng)中一個重要的概念和線索是surface。View及其子類(如TextView, Button)要畫在surface上。每個surface創(chuàng)建一個Canvas對象(但屬性時常改變),用來管理view在surface上的繪圖操作,如畫點(diǎn)畫線。每個canvas對象對應(yīng)一個bitmap,存儲畫在surface上的內(nèi)容。
每個Surface通常對應(yīng)兩個buffer,一個front buffer, 一個back buffer。其中,back buffer就是canvas繪圖時對應(yīng)的bitmap (研究android_view_Surface.cpp::lockCanvas) 。 因此,繪畫總是在back buffer上,需要更新時,則將back buffer和front buffer互換。
The window is tied to a Surface and the ViewRoot asks the Surface for a Canvas that is then used by the Views to draw onto. After View draw its data to canvas, ViewRoot will call surface.unlockCanvasAndPost(canvas) to schedule surfaceFlinger::composeSurfaces() which do the actually display to display panel. SurfaceFlinger handles to transfers drawn data in canvas to surface front buffer or backbuffer
Except for SurfaceViews, different views within the same ViewRoot share the same surface.
Layer的概念:
每個surface又對應(yīng)一個layer, SurfaceFlinger負(fù)責(zé)將各個layer的front
buffer合成(composite)繪制到屏幕上。 A Layer is something that can be composited by SurfaceFlinger (should have been called LayerFlinger). There are several types of Layers if you look in the code, in particular the regular ones (Layer.cpp) , they are backed by a Surface, and the LayerBuffer (very badly chosen name) which don't have a backing store, but receive one from their client. .Note that the GGLSurface type, should have been called GGLBuffer Multiple layers are just composited to the final buffer in their Z order. 有幾個對象與Surface概念緊密相關(guān): 1. Java Surface (frameworks/base/core/java/android/view/Surface.java)。該對象被應(yīng)用間接調(diào)用(通過SurfaceView, ViewRoot等), 應(yīng)用需要創(chuàng)建surface,(并同時創(chuàng)建canvas), 將圖形繪制到這個對象上并最終投遞到屏幕上。
2. C++ Surface (frameworks/base/libs/ui/Surface.cpp。 這個對象被Java Surface通過Jni 調(diào)用,實(shí)現(xiàn)Java Surface 的功能 3. ISurface (以及其派生類BnSurface)。這個對象是應(yīng)用和server之間的接口。C++ Surface創(chuàng)建這個ISurface (BnSurface)并發(fā)送命令,如更新surface內(nèi)容到屏幕上。Server端接受這個命令并執(zhí)行相應(yīng)操作。 研究一個surface如何創(chuàng)建的關(guān)鍵路徑如下:
1. frameworks/base/core/java/android/view/Surface.java -- Surface::Surface () 2. frameworks/base/core/jni/android_view_Surface.cpp -- Surface_init ()。在這個函數(shù)中SurfaceComposerClient 對象被創(chuàng)建。 3. frameworks/base/libs/ui/SurfaceComposerClient.cpp -- SurfaceComposerClient::SurfaceComposerClient (). 這個函數(shù)非常重要,在這里建立了client和server之間的橋梁。通過函數(shù)_get_surface_manager()獲得了一個指向 server的IBinder 對象(具有ISurfaceComposer接口),之后通過這個IBinder就可以跨進(jìn)程訪問Server的功能。接著調(diào)用 ISurfaceComposer::createConnection()創(chuàng)建并返回了一個ISurfaceFlingerClient的 IBinder。 4. frameworks/base/libs/ui/SurfaceComposerClient.cpp -- SurfaceComposerClient::createSurface().這個函數(shù)中,利用前面獲得的ISurfaceFlingerClient的IBinder,調(diào)用其createSurface接口。 5.frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp -- BClient::createSurface ()。BClient由ISurfaceFlingerClient派生而來。 6. frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp -- SurfaceFlinger:: createSurface()。這個函數(shù)為Surface創(chuàng)建一個對應(yīng)的Layer。 上述關(guān)鍵路徑中,1,2,3,4運(yùn)行于client進(jìn)程中,而5,6運(yùn)行與server進(jìn)程中。server作為一個service提供給client訪問。
與圖形相關(guān)的代碼主要位于下列目錄:
1、frameworks/base/graphics/java/android/graphics 2、frameworks/base/core/java/android/view 3、frameworks/base/core/java/android/widget 4、frameworks/base/opengl/ 5、frameworks/base/libs/ui 6、frameworks/base/libs/surfaceflinger 7、frameworks/base/core/jni/android/graphics 8、frameworks/base/core/jni/android/opengl 9、frameworks/base/core/jni/android/android_view_*.cpp 10、external/skia 一、下列目錄中的部分代碼: 1、frameworks/base/graphics/java/android/graphics 2、frameworks/base/core/java/android/view 3、frameworks/base/core/java/android/widget android.graphics, android.view和android.widget功能和其他類似的圖形庫如Qt/Gtk+差不多,分別提供基本的圖形原語(如畫點(diǎn)畫線,設(shè)置圖形上下文等),事件機(jī)制,以及開發(fā)圖形用戶界面的控件等。canvas 用于開發(fā)2D圖形, Surface 代表一個可供圖形系統(tǒng)繪制的surface??稍谄渖侠L制2D活3D圖形。
二. frameworks/base/opengl/ 這個目錄包含opengel的接口以及軟件實(shí)現(xiàn)。在http://developer./guide/topics/graphics/opengl.html有詳細(xì)介紹如何使用android.opengl開發(fā)3d graphics。 三.external/skia,臺灣的Jserv先生有一篇比較好的介紹,感興趣的讀者可以參考他的博文(http: //blog.linux.org.tw/~jserv/archives/002095.html)。簡而言之,skia與cairo功能相當(dāng),封裝底層的圖形硬件,為上面的圖形庫提供最基礎(chǔ)的操作圖形硬件的原語。
四. frameworks/base/libs/ui 和 frameworks/base/libs/surfaceflinger
ISurface 定義了基礎(chǔ)的Surface接口,供圖形系統(tǒng)客戶端(應(yīng)用)和server端(即surfaceflinger)交互。 BpSurface是ISurface的派生類,提供接口供server 調(diào)用客戶端功能; BnSurface是ISurface的另一個派生類,提供接口供客戶端調(diào)用server功能。當(dāng) server 收到來自客戶端(通過BnSurace)的調(diào)用請求后,如registerBuffers, postBuffer等,BnSurface::onTransact被觸發(fā)。 Surface (LayerBaseClient的私有類)是BnSurface的派生類。 SurfaceBuffer (SurfaceBuffer的私有類)是Surface的派生類。 ISurfaceComposer 定義了基礎(chǔ)的接口,供客戶端和server端交互。
BpSurfaceComposer是一個派生類,提供接口供server調(diào)用客戶端功能; BnSurfaceComposer是另一派生類,提供接口供客戶端調(diào)用server功能。類 SurfaceFlinger 由BnSurfaceComposer派生而來。 SurfaceComposerClient直接供客戶端使用,調(diào)用ISurface (BnSurface)和 ISurfaceComposer (BnSurfaceComposer)以及 ISurfaceFlingerClient 接口,與server交互。
BClient 派生自ISurfaceFlingerClient (BnSurfaceFlingerClient),調(diào)用server的createSurface,真正創(chuàng)建一個surface。每個surface對應(yīng)一個layer.
egl_native_window_t 定義了一個本地window類 。這個類提供了對本地window的所有描述以及用于egl (opengl 與本地圖形系統(tǒng)的接口)操作本地windwo的所有方法。
EGLNativeSurface是egl_native_window_t的一個派生類。 EGLDisplaySurface是EGLNativeSurface的派生類。 EGLDisplaySurface 是一個非常重要的類,在這個類里,真正打開framebuffer設(shè)備(/dev/graphics/fb0 或者/dev/fb0),并將這個設(shè)備封裝成EGLDisplaySurface的形式供server使用。函數(shù)mapFrameBuffer打開framebuffer, 創(chuàng)建兩個緩沖區(qū),(一個是on screen front 緩沖區(qū), 另一個back buffer, 可能位于offscreen framebuffer,也可能位于系統(tǒng)內(nèi)存)。 函數(shù)swapBuffers將back buffer內(nèi)容拷貝到front buffer中。 DisplayHardware 類中初始化了egl系統(tǒng),并為本地窗口對象EGLDisplaySurface 創(chuàng)建了對應(yīng)的EGLSurface 對象。surfaceflinger 使用DisplayHardware去和本地窗口打交道。
五、下列目錄中的部分代碼
7、frameworks/base/core/jni/android/graphics 8、frameworks/base/core/jni/android/opengl 9、frameworks/base/core/jni/android/android_view_*.cpp 這些目錄下的代碼在Java層的graphics 組件和native (c++)組件之間銜接,將java層的功能調(diào)用轉(zhuǎn)換到對應(yīng)的本地調(diào)用。
hardware/libhardware實(shí)現(xiàn)了HAL(Hardware Abstraction Layer)層,copybit device是其中一個模塊。
本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/shenbin1430/archive/2009/06/23/4291741.aspx |
|