一、OpenGL/EGL
因?yàn)锳ndroid的GUI系統(tǒng)是基于OpenGL/EGL實(shí)現(xiàn)的,所以先介紹相關(guān)基礎(chǔ)知識。
OpenGL(Open Graphics Library)已占據(jù)虛擬現(xiàn)實(shí)、CAD、能源、游戲研發(fā)等多個(gè)行業(yè)領(lǐng)域,是跨語言,跨平臺的2D/3D圖形處理王者。
OpenGL ES(OpenGL for Embedded Systems)是專門面向嵌入式系統(tǒng)的OpenGL API子集,Android系統(tǒng)從版本早期開始支持此圖形庫。
二、3D圖形學(xué)基礎(chǔ)
3D(Three-Dimensional)一般情況下是指長、寬、深度(高度)三個(gè)維度的圖形。
OpenGL只支持三種基本幾何元素:點(diǎn),線段,三角形。
圖形管線(Graphics Pipiline/Rendering Pipeline)指圖形硬件設(shè)備支持的渲染流程,是以3D數(shù)據(jù)為輸入,最終輸出2D光柵圖形的一種流水線處理過程。
三、Android的OpenGL ES框架

- OpenGL ES
OpenGL本身只是協(xié)議規(guī)范,不是軟件源碼庫。 - Mesa 3D
Mesa是兼容OpenGL協(xié)議的3D圖形處理軟件庫,開放原始代碼。 -
EGL
"Khronos Native Platform Graphics Interface",介于本地窗口系統(tǒng)和Rendering API(即OPenGL ES)之間的一層接口。主要功能如下:
a.創(chuàng)建rendering surfaces,即能承載圖形的介質(zhì)。
b.創(chuàng)造圖形環(huán)境(Graphics context);由于OpenGL是一個(gè)狀態(tài)機(jī),需要對諸多狀態(tài)進(jìn)行管理,因此context主要負(fù)責(zé)狀態(tài)管理,為OpenGL的運(yùn)行提供了統(tǒng)一的環(huán)境。。
c.同步應(yīng)用程序和本地平臺渲染API
d.提供對顯示設(shè)備的訪問和對渲染配置的管理。 - libagl
Android自帶的通過軟件方法實(shí)現(xiàn)的一套OpenGL動態(tài)庫 - libhgl
為區(qū)別libagl,自定義的一種叫法。特指GPU廠商提供的硬件實(shí)現(xiàn)的OpenGL庫。 - egl.cfg
系統(tǒng)根據(jù)egl.cfg文件的解析結(jié)果來選擇圖形渲染方式(硬件/軟件),并自動加載對應(yīng)的OpenGL軟件庫/硬件庫.
四、EGL初始過程
- 獲取一個(gè)設(shè)備Display(與具體系統(tǒng)平臺無關(guān)的對象)
- 對EGL初始化,將EGL內(nèi)部數(shù)據(jù)進(jìn)行初始值設(shè)定。
- 根據(jù)用戶配置返回一個(gè)最佳Surface config。
- 創(chuàng)建EGL context。
- 獲取有效Surface的詳情信息。
- 生成一個(gè)Display Device,創(chuàng)建可在終端屏幕顯示的Window。
- 返回當(dāng)前Context環(huán)境。
五、簡化OpenGL ES開發(fā)——GLSurfaceView
GLSurfaceView特性
Android系統(tǒng)封裝了GLSurfaceView來簡化OpenGL ES的使用。
GLSurfaceView繼承自SurfaceView,意味著它具備View類的所有功能和屬性——特別是接收事件的能力。主要特性如下:
1.管理EGLDisplay,它表示一個(gè)顯示屏
2.管理Surface(本質(zhì)上就是一塊內(nèi)存區(qū)域)
3.GLSurfaceView會創(chuàng)建新的線程,以使整個(gè)渲染過程不至于阻塞UI主線程。
4.可自定義渲染方式,如通過setRender ()設(shè)置一個(gè)Render.GLSurfaceView使用基本步驟
1.創(chuàng)建GLSurfaceView。
2.初始化OpenGL ES環(huán)境。
3.設(shè)置Render。渲染是OpenGL核心工作。setRender()可將用戶自定義的Render加入實(shí)際渲染流程中。
4.設(shè)置RenderMode。默認(rèn)為連續(xù)的渲染方式。
5.狀態(tài)處理。知曉程序的當(dāng)前狀態(tài)(暫停/恢復(fù)等),使OpenGE ES內(nèi)部的運(yùn)行線程做出正確判斷,保證應(yīng)用程序的穩(wěn)定性。Surface創(chuàng)建流程
當(dāng)ViewRoot成功AttachToWindow后,告知View數(shù)中的所有成員。
SurfaceView收到AttachedToWindow成功的消息后,通過WindowSession()向ViewRoot獲取已創(chuàng)建的IWindowSession,這是ViewRoot與WMS間的通信介質(zhì)。
SurfaceView在updateWindow()時(shí),利用IwindowSession.relayout()重新申請一個(gè)Surface。
SurfaceView取得新Surface后,通知注冊callback函數(shù)的對象。啟動一個(gè)新線程GLThread完成渲染。EGL初始過程
1.獲取一個(gè)設(shè)備Display(與具體系統(tǒng)平臺無關(guān)的對象)
2.對EGL初始化,將EGL內(nèi)部數(shù)據(jù)進(jìn)行初始值設(shè)定。
3.根據(jù)用戶配置返回一個(gè)最佳Surface config。
4.創(chuàng)建EGL context。
5.獲取有效Surface的詳情信息。
6.生成一個(gè)Display Device,創(chuàng)建可在終端屏幕顯示的Window。
7.返回當(dāng)前Context環(huán)境。EGL的使用步驟
GLSurfaceView最核心的工作就是,根據(jù)應(yīng)用程序設(shè)置的renderer來進(jìn)行圖形渲染處理。
GLSurfaceView中所涉及的EGL接口都是Java層的,而且都很好地封裝在了GLSurfaceView的框架中。使用EGL的Java層接口步驟如下:
1.獲取EGL實(shí)例
EGLContext.getEGL();
2.獲取一個(gè)EGL Display
eglGetDisplay(Object native_display);
3.利用Display來初始化EGL并返回EGL的版本號
eglInitialize(EGLDisplay display, int[] major_minor);
4.選取EGL的一個(gè)配置(EGL Config)
eglCHooseConfig(EGLDisplay display, int[] attrib_list, EGLConfig[] configs, int config_size, int[] num_config);
5.創(chuàng)建EGL Context
eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);
6.創(chuàng)建EGL Surface
eglCreateWindowSurface(EGLDisplay display, EGLSurface surface);
注:主要內(nèi)容摘錄自書籍 深入理解Android內(nèi)核設(shè)計(jì)思想,林學(xué)森 著