李洪輝,劉志勤
(西南科技大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,四川 綿陽(yáng)621010)
Android系統(tǒng)在智能手機(jī)、數(shù)字電視、機(jī)頂盒等視聽產(chǎn)品中廣泛應(yīng)用,豐富的游戲娛樂軟件對(duì)顯示及3D圖形性能要求越來(lái)越高。顯示系統(tǒng)直接負(fù)責(zé)與用戶交互,是Android核心,其處理速度和顯示效果很大程度上影響到用戶體驗(yàn)。目前,原生Android中顯示系統(tǒng)是在通用處理器上的軟件實(shí)現(xiàn),圖形的繪制、顯示窗口的融合不僅占據(jù)了大量的CPU資源,而且顯示處理速度慢、顯示效果差。因此,提高Android顯示系統(tǒng)性能改善顯示效果成為了亟待解決的關(guān)鍵問題之一。
近年來(lái),集成強(qiáng)大圖形處理能力的嵌入式微處理器的出現(xiàn),不少學(xué)者采用硬件加速技術(shù)對(duì)圖形系統(tǒng)進(jìn)行優(yōu)化。蔣永剛[1]等通過深入分析嵌入式多媒體系統(tǒng)中的2D硬件圖形加速器,設(shè)計(jì)了一種無(wú)縫軟硬件圖形加速架構(gòu),利用設(shè)備驅(qū)動(dòng)統(tǒng)一了繪圖函數(shù)接口。董劍[2]對(duì)在北大眾志Unicore平臺(tái)上利用硬件通道傳遞和更新顯示內(nèi)容,減少跨層函數(shù)調(diào)用以及顯示內(nèi)容的交換次數(shù),這依賴于處理器的硬件通道。凌明[3]也在Unicore平臺(tái)上通過對(duì)GPU驅(qū)動(dòng)模塊性能分析,修改內(nèi)核態(tài)映射空間來(lái)提升用戶態(tài)內(nèi)核圖形數(shù)據(jù)訪問效率,這依賴于處理器對(duì)Linux內(nèi)核虛擬地址空間的映射策略。
本文以O(shè)MAP3530芯片的PowerVR SGX 530圖形處理器內(nèi)核為平臺(tái),借鑒前人經(jīng)驗(yàn)從驅(qū)動(dòng)程序和顯示內(nèi)容兩方面入手,實(shí)現(xiàn)GPU硬件加速技術(shù)在Android顯示系統(tǒng)中的應(yīng)用優(yōu)化,改善顯示系統(tǒng)性能,改善用戶體驗(yàn)。
Android顯示系統(tǒng)采用采用客服端/服務(wù)器 (client/server)模式,通過Android的Binder服務(wù)機(jī)制實(shí)現(xiàn)。服務(wù)端主要由C++語(yǔ)言實(shí)現(xiàn),主要由Surface Flinger系統(tǒng)服務(wù)來(lái)提供服務(wù)??头税?,實(shí)現(xiàn)來(lái)調(diào)用輸入和輸出設(shè)備驅(qū)動(dòng)程序的C語(yǔ)言底層,和為應(yīng)用程序構(gòu)建UI元素的JAVA繪圖接口。顯示系統(tǒng)的C語(yǔ)言部分和Java語(yǔ)言部分通過JNI接口調(diào)用。顯示系統(tǒng)框圖如圖1所示。
圖1 顯示系統(tǒng)框架
(1)C語(yǔ)言部分包括:
Skia(2D圖形圖像引擎),負(fù)責(zé)2D圖形繪制;
OpenGL|ES(3D圖形引擎),負(fù)責(zé)3D圖形繪制和2D圖形搬運(yùn)操作;
libui(顯示系統(tǒng)框架),提供顯示接口框架庫(kù);
Surface是應(yīng)用程序顯示的基本單元,可以包含一個(gè)或多個(gè),是SurfaceFlinger的客服端;
SurfaceFlinger負(fù)責(zé)將各Surface按照Z(yǔ)-order(垂直屏幕序列)融合到顯示緩存中,是Surface的服務(wù)端;
Pixelflinger為OpenGL ES引擎提供的一套軟件渲染器;
FrameBuffer(幀緩存區(qū)),是最終顯示內(nèi)容的存儲(chǔ)區(qū)。
(2)JAVA語(yǔ)言部分主要包括:
android.graphics對(duì)應(yīng)Skia庫(kù),提供繪圖接口;
android.view.Surface:構(gòu)建顯示界面;
android.view.View:包含各UI元素基類;
javax.microedition.khronos.opengles:OpenGL ES接口;
android.opengl:Android系統(tǒng)和OpenGL聯(lián)系層。
在C語(yǔ)言模塊中,libui提供顯示接口框架庫(kù),其他庫(kù)為實(shí)現(xiàn)庫(kù)通過類繼承方式來(lái)實(shí)現(xiàn)。連接JAVA部分的JNI庫(kù)通過libui庫(kù)接口實(shí)現(xiàn)。
Android中顯示系統(tǒng)的繪制依賴于SurfaceFlinger服務(wù),主要有應(yīng)用程序請(qǐng)求、顯示內(nèi)容繪制、顯示更新3個(gè)步驟,其繪制流程請(qǐng)參見文獻(xiàn)[2],如圖2所示。
圖2 顯示系統(tǒng)繪制流程
在顯示系統(tǒng)中看到的每一個(gè)組件就是一個(gè)View。上層應(yīng)用程序通過JAVA的本地方法調(diào)用Skia和OpenGL ES圖形庫(kù)的圖形繪制原語(yǔ),將各視覺元素的繪制在每個(gè)View對(duì)應(yīng)的一個(gè)或多個(gè)Surface上。Surface是服務(wù)端Surface-Flinger創(chuàng)建的,為各應(yīng)用程序進(jìn)行繪圖操作提供的中介。每個(gè)Surface的創(chuàng)建都會(huì)得到一個(gè)Canvas對(duì)象,它是用來(lái)管理View在Surface上的繪圖操作。
每個(gè)Surface上的繪制內(nèi)容存儲(chǔ)在其Canvas對(duì)象對(duì)應(yīng)的一個(gè)Buffer中,這個(gè)Buffer就是Surface的繪制緩存BackBuffer。當(dāng)繪制完成后,Surface通過Binder機(jī)制向SurfaceFlinger請(qǐng)求顯示更新;這時(shí)會(huì)將Surface的顯示緩存Frontbuffer和繪制緩存Backbuffer互換,直接顯示Backbuffer的數(shù)據(jù)到屏幕。這種雙緩沖技術(shù)可以避免屏幕閃爍,減少了數(shù)據(jù)的拷貝。
SurfaceFlinger收到一個(gè)或多個(gè)Surface客戶端請(qǐng)求時(shí),會(huì)通過EGL接口調(diào)用OpenGL ES來(lái)融合顯示畫面 (compose surface)。融合完成后將顯示內(nèi)容輸出到Framebuffer設(shè)備上,以輸出到顯示設(shè)備。Android使用標(biāo)準(zhǔn)Frame-Buffer驅(qū)動(dòng)接口,設(shè)備節(jié)點(diǎn)路徑為/dev/graphics/fb0,該設(shè)備節(jié)點(diǎn)由init進(jìn)程自動(dòng)創(chuàng)建,并由libui調(diào)用。
為了更好了解顯示系統(tǒng)性能,本文對(duì)0xbenchmark基準(zhǔn)測(cè)試工具中2D和3D測(cè)試程序進(jìn)行了函數(shù)級(jí)的Oprofile[4]測(cè)試。測(cè)試環(huán)境如下:CPU主頻設(shè)置為最大600MHz,Android4.0(ICS)版,測(cè)試結(jié)果見表1和表2,其中P為單個(gè)函數(shù)運(yùn)行時(shí)間在系統(tǒng)總運(yùn)行時(shí)間中所占比例。
表1 2D圖形繪制Oprofile結(jié)果
表2 3D圖形繪制Oprofile結(jié)果
由表1、表2可知,2D測(cè)試和3D測(cè)試中P值最大的是libpixelflinger的融合函數(shù)占32%左右,其次為libGLES_android庫(kù)的繪圖函數(shù)占28.50%,libskia.so的繪圖函數(shù)占27.78%。
本文采用Texas Instruments公司的OMAP3530處理器,搭配有256MDDRII內(nèi)存和512M的NAND Flash存儲(chǔ)。OMAP3530是一個(gè)異構(gòu)多核的處理器芯片,不僅具有嵌入式常用的ARM Cortex-A8內(nèi)核,還具有2D/3D圖形加速的 PowerVR SGX 530 1.2.1版 GPU 內(nèi)核[5]。圖像處理器GPU是高度并行化的更適合圖形化操作,SGX530圖形引擎每秒繪制多邊形數(shù)最大可達(dá)到10M個(gè),支持Open-GL ES1.1、OpenGL ES2.0、OpenVG1.0工業(yè)標(biāo)準(zhǔn)接口。OpenGL ES提供了靈活且功能強(qiáng)大的底層的接口,這為圖形加速程序的開發(fā)提供了方便。OpenVG針對(duì)像Flash和SVG矢量圖形算法庫(kù)提供底層硬件加速界面的免授權(quán)、跨平臺(tái)應(yīng)用程序接口。
實(shí)驗(yàn)平臺(tái)硬件方面Cortex-A8CPU主頻設(shè)置為最大600MHz,PowerVR SGX 530GPU主頻為110MHZ,內(nèi)存DDR II 256MB,以太網(wǎng)接口100Mbps,根文件系統(tǒng)通過NFS掛載。
軟件方面,系統(tǒng)引導(dǎo)程序BootLoader包括x-load-1.41、u-boot-2010.06,Linux內(nèi) 核 使 用 2.6.37,Android文件系統(tǒng)使用Android 4.0(ice cream sandwich),交叉編譯器使用 Android源碼中的arm-eabi-gcc 4.4.3。
libpixelflinger是SufaceFlinger在沒有硬件加速情況下,軟件實(shí)現(xiàn)的融合器。在Android 2.0以后SufaceFlinger直接調(diào)用OpenGL ES API,如果存在OpenGL ES硬件庫(kù)則系統(tǒng)自動(dòng)調(diào)用硬件庫(kù)API實(shí)現(xiàn)多窗口融合。
然而,PowerVR SGX 530GPU內(nèi)核支持對(duì)OpenGL ES 3D硬件加速接口,可以使用OpenGL ES硬件接口的實(shí)現(xiàn)窗口融合加速。同時(shí)OpenGL ES接口的集成,可以不在使用libGLES_android軟件實(shí)現(xiàn)的OpenGL接口,而使用硬件來(lái)完成3D圖形繪制。
Skia圖形引擎擁有完整的2D圖形算法,Skia圖形繪制是基于CPU完成地,直接使用GPU實(shí)現(xiàn)Skia繪制可能不會(huì)帶到優(yōu)化效果。文獻(xiàn)[6]中Huang Dongsung使用GPU實(shí)現(xiàn)的Skia和原生Skia進(jìn)行對(duì)比,實(shí)驗(yàn)結(jié)果出乎意料:Skia GPU的渲染速度比CPU的渲染速度慢2倍以上。作者使用GDEBugger、Callgrind工具發(fā)現(xiàn)Skia對(duì)glDraw-Something調(diào)用次數(shù)太多,glstates改變次數(shù)太多,對(duì)framebuffer節(jié)點(diǎn)/graphic/fb0開關(guān)次數(shù)太多。
Skia集成了一個(gè)基于OpenGL ES2加速的后端,被稱為Ganesh。Ganesh已經(jīng)實(shí)驗(yàn)了兩種加速方式[7],一種在渲染過程中使用模板緩存;另一種對(duì)加載紋理進(jìn)行光柵化,讓GPU提供適當(dāng)?shù)目逛忼X覆蓋。Android的2D矢量圖形部分并沒有使用OpenVG而是使用Skia庫(kù),對(duì)OpenVG并不支持。因此這里沒有考慮使用OpenVG來(lái)實(shí)現(xiàn)2D加速,而是集成OpenGL ES接口支持Skia的Ganesh后端來(lái)實(shí)現(xiàn)2D加速。
因此使用OpenGL ES硬件接口來(lái)實(shí)現(xiàn)了GPU在Android顯示系統(tǒng)中的優(yōu)化,在此之前還需要對(duì)GPU設(shè)備驅(qū)動(dòng)進(jìn)行集成。
在分析Android顯示系統(tǒng)框架及其繪制流程的基礎(chǔ)上,利用GPU硬件對(duì)圖形系統(tǒng)進(jìn)行加速優(yōu)化。GPU的開發(fā)使用了TI提供的GPU軟件開發(fā)包[8]Graphics_SDK_setup linux_4_06_00_02.bin。
GPU圖形開發(fā)包包括omaplfb、pvrsrvkm和bufferclass_ti內(nèi)核模塊[8],這些模塊需要在運(yùn)行時(shí)加載到系統(tǒng)中。
Omaplfb.ko:負(fù)責(zé)和平臺(tái)底層特定的FrameBuffer驅(qū)動(dòng)進(jìn)行交互;
Pvrsrvkm.ko:負(fù)責(zé)和用戶空間的PVR服務(wù)層交互;
ufferclass_ti.ko:負(fù)責(zé)將特定后綴的文件流,流向SGX處理器進(jìn)行處理。
進(jìn)入開發(fā)包安裝目錄,編輯Rules.make文件,修改下列環(huán)境變量值:Graphics_SDK安裝目錄、交叉編譯器路徑及其前綴、內(nèi)核安裝路徑、目標(biāo)文件系統(tǒng)安裝路徑。然后,設(shè)置處理器架構(gòu)并編譯make ARCH=armBUILD=release OMAPES=3.x all。順利完成后,安裝內(nèi)核模塊及OpenGL ES庫(kù)等軟件模塊到根文件系統(tǒng)中make ARCH=armBUILD=release OMAPES=3.x install。
在Android的啟動(dòng)文件init.rc中添加sgx_service服務(wù),用以加載內(nèi)核模塊,而且該服務(wù)需要添加在adbd服務(wù)之前。
service pvr/system/bin/sgx/rc.pvr start
class core
oneshot
OpenGL本地庫(kù)有軟件庫(kù)和硬件庫(kù)兩種實(shí)現(xiàn)方式:軟件實(shí)現(xiàn)對(duì)應(yīng)libagl.so;硬件實(shí)現(xiàn)對(duì)應(yīng)libhgl.so。OpenGL本地本地庫(kù)的加載是通過libs/EGL/egl.cpp中egl_init_drivers() (egl_init_drivers_locked()調(diào)用libs/EGL/Loader.c文件中的loader::open()函數(shù)打開軟件和硬件EGL加速驅(qū)動(dòng)。加載流程如圖3所示。根據(jù)/system/lib/egl/egl.cfg文件,分別加載并解析libagl和libhal;獲取其中標(biāo)準(zhǔn)OpenGL函數(shù)的函數(shù)地址 (函數(shù)指針)。系統(tǒng)調(diào)用時(shí),通過函數(shù)指針調(diào)用libagl或libhgl,從而實(shí)現(xiàn)圖形的繪制。
圖3 OpenGL本地庫(kù)加載流程
配 置 文 件 “/system/lib/egl/egl.cfg” 在 libs/EGL/Loader.c文件的Loader::Loader()函數(shù)打開,并賦值給dpy、impl、tag這3個(gè)變量,Loader::open()函數(shù)中通過dpy、impl與tag來(lái)加載默認(rèn)的軟件實(shí)現(xiàn)動(dòng)態(tài)庫(kù)或者硬件實(shí)現(xiàn)動(dòng)態(tài)庫(kù)中的EGL、GLESv1_CM、GLESv2這3個(gè)部分的函數(shù)。如果加載成功則new一個(gè)driver_t架構(gòu),并用加載的函數(shù)進(jìn)行初始化。
將OpenGL ES庫(kù)安裝到Android文件系統(tǒng)中后,修改OpenGL ES接口的配置文件/system/lib/egl/egl.cfg為
0 0android
0 1POWERVR_SGX530_121
Android啟動(dòng)時(shí)讀?。痵ystem/lib/egl/egl.cfg中的dpy=0,impl=1,tag=POWERVR_SGX530_121;Loader::open()函數(shù)中通過獲取該dpy、impl與tag來(lái)加載硬件加速動(dòng)態(tài) 庫(kù)/system/lib/egl/libEGL _POWERVR _SGX530 _121.so中的EGL、GLESv1_CM、GLESv2這3個(gè)部分的函數(shù)。若加載失敗則dpy=0、impl=0、tag=android,使用默 認(rèn) 的 軟 件 實(shí) 現(xiàn) 動(dòng) 態(tài) 庫(kù)/system/lib/egl/libGLES_android.so,繼 續(xù) 使 用 libpix elflinger.so、libGLES _android.so。
實(shí)驗(yàn)測(cè)試硬件環(huán)境、軟件環(huán)境和性能測(cè)試時(shí)一樣。測(cè)試軟件使用0xlab[9]提供的0xbenchmark[10]基準(zhǔn)測(cè)試工具對(duì)2D和3D圖形進(jìn)行測(cè)試,測(cè)試結(jié)果如表3和表4所示。
由表3可以看出,2D圖形每秒幀數(shù)平均是原來(lái)的3.32倍,同時(shí)CPU負(fù)載平均下降了19.19%。其中Draw Circle CPU負(fù)載上升了7.93%,這是因?yàn)楹捅菵raw Circle2相比Draw Circle的每秒幀數(shù)多1.1倍,CPU負(fù)載更高。
表3 使用GPU優(yōu)化前后2D性能測(cè)試數(shù)據(jù)
表4 使用GPU優(yōu)化前后3D性能測(cè)試數(shù)據(jù)
由表4可以看出,3D圖形每秒幀數(shù)平均是原來(lái)的5.53倍,同時(shí)CPU負(fù)載平均下降了70.87%。其中OpenGL Cube和OpenGL Teapot比其他兩個(gè)測(cè)試實(shí)例加速比小,是因?yàn)镺penGL Cube和OpenGL Teapot都需要對(duì)魔方(cube)和茶壺 (teapot)進(jìn)行繪制,而其兩個(gè)實(shí)例主要是紋理映射,繪制計(jì)算量相對(duì)較小。魔方 (cube)的繪制包含多個(gè)立方體及其面不同顏色的繪制,相比茶壺 (teapot)繪制計(jì)算量較大,加速比也就較小。
本文對(duì)Android顯示系統(tǒng)的基本框架和繪制流程分析的基礎(chǔ)上,在OMAP3530處理器平臺(tái)對(duì)顯示系統(tǒng)進(jìn)行性能分析,并提出了使用GPU來(lái)優(yōu)化Android顯示子系統(tǒng)。從GPU設(shè)備驅(qū)動(dòng)和OpenGL ES接口兩方面實(shí)現(xiàn)了GPU在Android顯示系統(tǒng)中的優(yōu)化。使用0xbenchmark對(duì)2D和3D性能測(cè)試,實(shí)驗(yàn)結(jié)果顯示2D和3D每秒幀加速比平均為4.12,同時(shí)CPU負(fù)載平均下降38%,顯示性能大幅提升,達(dá)到了預(yù)期目的。
[1]JANG Yonggang.Apply hardware accelerator in embedded multimedia system[D].Shanghai:Shanghai Jiaotong University,2009(in Chinese).[蔣永剛.嵌入式多媒體系統(tǒng)中硬件加速技術(shù)的應(yīng)用[D].上海:上海交通大學(xué),2009.]
[2]DONG Jian.Research of applying hardware acceleration in the Android display system[D].Shanghai:Fudan University,2011(in Chinese).[董劍.Android顯示系統(tǒng)應(yīng)用硬件加速技術(shù)的研究[D].上海:復(fù)旦大學(xué),2011.]
[3]LING Ming,WU Jianping,LIU Qi,et al.Optimization for Android graphics system based on domestic Unicore architecture[J].Southeast University Journal of Southeast University(Natural Science Edition),2012 (6):1069-1073 (in Chinese).[凌明,武建平,柳琦,等.面向國(guó)產(chǎn)Unicore架構(gòu)的Android圖形系統(tǒng)優(yōu)化[J].東南大學(xué)學(xué)報(bào) (自然科學(xué)版),2012 (6):1069-1073.]
[4]Oprofile.OProfile-A system profiler for Linux[EB/OL].[2013-01-20].http://oprofile.sourceforge.net/.
[5]Texas Instruments.DSP + ARM Cortex-A8-OMAP3525/30 SOC-OMAP3530-TI[EB/OL].[2013-01-21].http://www.ti.com.cn/product/cn/omap3530.
[6]HUANG Dongsung.How much Skia GPU can accelerate Web-Kit rendering on Android[EB/OL].[2013-2-20].http://www.dorothybrowser.com/41/.
[7]Kilgard M J,Bolz J.GPU-accelerated path rendering[J].ACM Trans Graph,2012,31 (6):1-10.
[8]Texas Instruments.Texas instruments Linux graphics SDK[EB/OL].[2013-01-31].http://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/gfxsdk/latest/index_FDS.html.
[9]0xlab. 0xLab-Home[EB/OL].[2013-02-20]. http://0xlab.org/.
[10]0xbench.Benchmarks-comprehensive benchmark suite for Android[EB/OL].[2013-02-20].http://code.google.com/p/0xbench/wiki/Benchmarks.