葉炳發(fā),孟小華
(暨南大學(xué)計(jì)算機(jī)系 廣州 510632)
Android作為第一個(gè)完整、開放、免費(fèi)的手機(jī)平臺,自推出以來就是業(yè)界的熱門話題,由于擁有良好的可移植性和強(qiáng)大的功能,在嵌入式設(shè)備方面的應(yīng)用表現(xiàn)出良好的勢頭。在圖形顯示方面,Android建立在Linux上,但并沒有像一些桌面 Linux使用GTK(GIMP Toolkit)組建XWindows(一個(gè)多平臺的圖形用戶接口),也沒有使用Cairo向量圖形鏈接庫實(shí)現(xiàn)圖形顯示,而是使用了專為Android而改良的一種2D向量圖形處理函數(shù)庫Skia。在3D圖形方面是基于嵌入式3D圖形算法標(biāo)準(zhǔn)OpenGL/ES實(shí)現(xiàn)的,該庫可以使用硬件加速。然而,雖然Google開放了Android的源代碼,但相關(guān)技術(shù)文檔很少,而且圖形系統(tǒng)的實(shí)現(xiàn)原理比較復(fù)雜,所以本文集中對Android圖形系統(tǒng)的底層原理進(jìn)行研究。
Android SDK的圖形包主要包括android.graphics、android.view、android.widget和 android.opengl,前 3 個(gè)是用于 2D的圖形開發(fā),基于 SGL(Skia graphics library)。android.opengl是用于3D的圖形開發(fā),基于OpenGL/ES。
Skia是一個(gè)開放源碼的2D向量圖形處理函數(shù)庫,包含字型、坐標(biāo)轉(zhuǎn)換以及點(diǎn)陣圖,有著高效能且簡潔的表現(xiàn),在Android平臺中搭配OpenGL/ES與特定的硬件特征強(qiáng)化了顯示效果。OpenGL/ES是OpenGL的一個(gè)子集,是一個(gè)跨平臺圖形庫,是專門為嵌入式系統(tǒng)而設(shè)計(jì)的。
Android圖形系統(tǒng)的組成如圖1所示。上層應(yīng)用調(diào)用2D和3D圖形庫對Surface Manager提供的Surface進(jìn)行繪制,通過Surface Manager的合成器SurfaceFlinger對各個(gè)Surface進(jìn)行合成,并由EGL接口實(shí)現(xiàn)在Framebuffer設(shè)備上的顯示。
在Android的圖形系統(tǒng)中,Surface Manager是一個(gè)重要組成,Surface Manager對上層提供Surface給應(yīng)用進(jìn)行繪制,管理對顯示子系統(tǒng)的訪問,對來自多個(gè)應(yīng)用的2D和3D圖像進(jìn)行無縫的合成后傳給底層的EGL進(jìn)行處理,Surface Manager的工作原理如圖2所示。
Surface Manager為Application準(zhǔn)備一個(gè)或多個(gè)Surface后,把Surface傳給 Application,讓 Application可以在上面作圖形處理。應(yīng)用程序先通過調(diào)用圖形庫提供基礎(chǔ)的繪制圖形原語和JNI函數(shù),然后又通過Native Method的繪制圖形原語調(diào)用2D和3D的圖形庫對Surface進(jìn)行繪制。
在Android平臺下,每個(gè)Surface都有一個(gè)Front Buffer和一個(gè)Back Buffer,每個(gè)窗口都以一個(gè)Surface對象作為基礎(chǔ)。每個(gè)Surface又對應(yīng)一個(gè)Layer,SurfaceFlinger將各個(gè)Layer的Front Buffer合成后繪制到Frame Buffer上。
關(guān)于SurfaceFlinger,在Surface Manager中用于管理邏輯上眾多的Surface,其功能特點(diǎn)如下:
·SurfaceFlinger在一個(gè)系統(tǒng)范圍內(nèi)合成Surface的功能,并把合成后的顯示內(nèi)容傳給幀緩沖設(shè)備;
·SurfaceFlinger能一起合成來自多個(gè)程序的2D或3D顯示的Surface;
·Surface通過Android的IPC機(jī)制Binder以緩沖的形式進(jìn)行遞交。
從Surface Manager工作原理分析,可以理解Application與Surface Manager是以C/S的模式進(jìn)行交互的,Application處理Surface的部分是客戶端,而Surface Manager提供服務(wù),它們之間通過Android的IPC機(jī)制Binder來協(xié)助完成,如圖3所示。
在Binder中,主要包括兩個(gè)方面:本地(native),如BnSurfaceFlingerClient,這是一個(gè)需要被繼承和實(shí)現(xiàn)的類;代理(proxy),如 BpSurfaceFlingerClient,這是一個(gè)在接口框架中被實(shí)現(xiàn),但是在接口中沒有體現(xiàn)的類。在客戶端中,BpSurfaceFlingerClient被調(diào)用,通過與BnSurfaceFlinger-Client通信,而 BpSurfaceFlingerClient和 BnSurfaceFlinger-Client派生自 ISurfaceFlingerClient,BClient派生自 BnSurface-FlingerClient。
在客戶端中通過類SurfaceComposerClient,調(diào)用BnSurfaceComposer和BnSurface來響應(yīng)服務(wù)端BpSurface-Composer和BpSurface,并通過調(diào)用 BpSurfaceFlingerClient來調(diào)用服務(wù)端的BnSurfaceFlingerClient,由此完成了客戶端和服務(wù)端的交互。在交互中的3個(gè)接口分別介紹如下。
ISurfaceFlingerClient:派生出BpSurfaceFlingerClient和BnSurfaceFlingerClient,由 BClient實(shí)現(xiàn),通過調(diào)用createSurface函數(shù)創(chuàng)建一個(gè)Surface供Application應(yīng)用。
ISurface:派生出BpSurface和BnSurface,主要完成對Surface的處理,在 Surface(派生自 BnSurface)的函數(shù) lock、unlockAndPost等,實(shí)現(xiàn)了Surface在雙緩沖的處理,SurfaceBuffer(派生自Surface)實(shí)現(xiàn)了Layer上的處理。
IS urfaceComposer:派生出BpSurfaceComposer和BnSurfaceComposer,SurfaceFlinger(派生自BnSurface Composer)主要為合成器SurfaceFlinger(Surface Manager的組成部分)對Surface合成的相關(guān)處理提供實(shí)現(xiàn)方法。
在Android平臺中,雙緩沖技術(shù)分別在Surface的處理和底層Framebuffer的處理中使用到,在對Framebuffer處理的雙緩沖技術(shù)根據(jù)OpenGL的標(biāo)準(zhǔn)實(shí)現(xiàn),而對Surface處理的雙緩沖技術(shù)則有所不同,下面將對兩種雙緩沖技術(shù)進(jìn)行比較。
在OpenGL中利用雙緩沖技術(shù),分配兩個(gè)幀緩沖區(qū),在連續(xù)顯示三維曲面時(shí),一個(gè)幀緩沖區(qū)中的數(shù)據(jù)執(zhí)行繪制曲面命令的同時(shí),另一個(gè)幀緩沖區(qū)中的數(shù)據(jù)進(jìn)行圖形顯示。當(dāng)前可見視頻緩沖稱為前臺視頻緩沖,不可見的、正在繪圖的視頻緩沖稱為后臺視頻緩沖。當(dāng)后臺視頻幀緩沖中的數(shù)據(jù)要求顯示時(shí),OpenGL就將它拷貝到前臺視頻幀緩沖,顯示硬件不斷地讀可見視頻緩沖中的內(nèi)容,并把結(jié)果顯示在屏幕上。應(yīng)用雙緩沖,每一幀三維曲面只在繪制完成后才顯示出來,所以觀察者可以看到每一幀完整三維曲面,而不是曲面的繪制過程。
每個(gè)Surface中都帶有兩個(gè)幀緩沖區(qū),分別稱為Front Buffer和Back Buffer,與OpenGL中雙緩沖技術(shù)有所不同,當(dāng)繪制Back Buffer后需要顯示時(shí),并沒有將Back Buffer中的數(shù)據(jù)拷貝到Front Buffer中,而是直接顯示Back Buffer中的數(shù)據(jù)到屏幕中,從而最大限度地減少了數(shù)據(jù)的復(fù)制。
圖4是使用Canvas繪制Surface的原理,具體過程如下:
·創(chuàng)建一個(gè)bitmap與Canvas關(guān)聯(lián)起來;
·把準(zhǔn)備顯示的圖形提交到Canvas上;
· lockCanvas,鎖定 Canvas;
·drawCanvas,把bitmap中的數(shù)據(jù)寫入到Back Buffer中;
· unlockCanvasAndPost,解鎖 Canvas,Back Buffer替換Front Buffer,替換后Back Buffer作為前臺緩沖,F(xiàn)ront Buffer作為后臺緩沖。
OpenGL/ES為附加功能和可能的平臺特性開發(fā)了擴(kuò)展機(jī)制,但仍然需要一個(gè)可以讓OpenGL/ES和本地視窗系統(tǒng)交互且平臺無關(guān)的層。EGL是OpenGL/ES和底層Native平臺視窗系統(tǒng)之間的接口,是為OpenGL/ES提供平臺獨(dú)立性而設(shè)計(jì)。OpenGL/ES本質(zhì)上是一個(gè)圖形渲染管線的狀態(tài)機(jī),而EGL則是用于監(jiān)控這些狀態(tài)以及維護(hù)Frame Buffer和其他渲染Surface的外部層。
在Android的底層源代碼中,egl_native_window_t是一個(gè)提供了對本地窗口的所有定義以及用于EGL操作本地窗口的所有方法的類。EGLNativeSurface派生自egl_native_window_t,EGLDisplaySurface派生自 EGLNativeSurface。EGLDisplay-Surface通過函數(shù) mapFrameBuffer打開 Framebuffer設(shè)備,并創(chuàng)建兩個(gè)緩沖區(qū),函數(shù)swapBuffer把后臺視頻緩沖區(qū)復(fù)制到前臺視頻緩沖區(qū)。DisplayHardware類中初始化了EGL,SurfaceFlinger使用了DisplayHardware去和本地窗口打交道。
Android是基于Linux的,但在Linux的幀緩沖驅(qū)動(dòng)中并沒有直接支持雙緩沖,修改驅(qū)動(dòng)包括兩個(gè)方面:一是劃分兩個(gè)緩沖區(qū);二是添加緩沖區(qū)的切換功能。本文是在PXA270上進(jìn)行研究的,對應(yīng)的驅(qū)動(dòng)文件是/drivers/video/pxafb.c。
在Android中,double buffer設(shè)計(jì)成上下兩個(gè)buffer的模式,在函數(shù) pxafb_setmode()“var->yres_virtual=var->yres”修改為“var->yres_virtual=var->yres*2”,在檢查參數(shù)的函數(shù)pxafb_check_var()中“var->yres_virtual=max(var->yres_virtual,var->yres)”修 改 為 “var->yres_virtual=max(var->yres_virtual,var->yres*2)”。相對應(yīng)的緩沖長度也要修改為默認(rèn)的兩邊,即在函數(shù)pxafb_decode_mode_info()中添加“smemlen*=2;”。
當(dāng)一個(gè)緩沖區(qū)已寫好,在切換時(shí)就需要調(diào)用到pan函數(shù),該函數(shù)將一個(gè)新的yoffset傳給LCD控制器。在結(jié)構(gòu)體fb_ops pxafb_ops中添加pan函數(shù),即插入“.fb_pan_display=pxafb_pan_display,”到fb_ops pxafb_ops中。在初始化幀緩沖的函數(shù)pxafb_init_fbinfo()中,將“fbi->fb.fix.ypanstep=0;”修改為“fbi->fb.fix.ypanstep=1;”,這里是說明驅(qū)動(dòng)需要用到pan函數(shù)。以下是需要添加或修改的函數(shù)。
對Android的應(yīng)用開發(fā)來說,圖形開發(fā)是其中一個(gè)主要工作,了解Android圖形系統(tǒng)的工作原理可以對應(yīng)用程序性能上的提供有所幫助。在Android移植到其他嵌入式設(shè)備中,Android圖形系統(tǒng)的底層驅(qū)動(dòng)移植是其中一個(gè)關(guān)鍵部分,通過對底層圖形接口以及對幀緩沖驅(qū)動(dòng)移植的研究,將更有效地實(shí)現(xiàn)Android在其他嵌入式設(shè)備上的移植。
1 宋寶華.Linux設(shè)備驅(qū)動(dòng)開發(fā)詳解.北京:人民郵電出版社,2008
2 姚昱旻,劉衛(wèi)國.Android的架構(gòu)與應(yīng)用開發(fā)研究.計(jì)算機(jī)系統(tǒng)應(yīng)用,2008(11)
3 Patrick Brady.Anatomy&Physiology of an Android.http://sites.google.com/site/io/anatomy--physiology-of-an-android
4 David Blythe,Affie Munshi.OpenGL ES 1.0.02 Specification.http://www.khronos.org/registry/gles/specs/1.0/opengles_spec_1_0.pdf