文章都是通过阅读源码分析出来的,还在不断完善与改进中,其中难免有些地方理解得不对,欢迎大家批评指正
转载请注明:From LXS. http://blog.csdn.net/uiop78uiop78/
在进入GUI系统的学习前,建议大家可以先阅读本书应用篇中的“OpenGLES”章节,并参阅OpenGL ES官方指南。因为Android的GUI系统是基于OpenGL/EGL来实现的,如果没有一定基础的话,分析源码时有可能会“事倍功半”。
SurfaceFlinger虽然是GUI的核心,但相对于OpenGL ES来讲,它其实只是一个“应用”。
对于没有做过OpenGLES开发的人来讲,理解这部分的内容还是有一定难度的,特别是容易对系统中既有EGL/OpenGLES,又有SurfaceFlinger、GraphicPlane、DisplayHardware、Gralloc、FramebufferNativeWindow等一系列陌生的模块感到混乱而无序。
的确如此,假如不先理清这些模块的相互关系,对于我们深入研究整个Android显示系统就是一个很大的障碍。有鉴于此,我们先来从框架的高度审视一下它们之间看似错综复杂、剪不断理还乱的依赖。
图 11‑1 SurfaceFlinger与OpenGLES等模块关系
我们根据上面这个图,由底层往上层来逐步分析整个架构:
1. Linux内核提供了统一的framebuffer显示驱动,设备节点/dev/graphics/fb*或者/dev/fb*,以fb0表示第一个Monitor,当前实现中只用到了一个显示屏
2. Android的HAL层提供了Gralloc,分为fb和gralloc两个设备。前者负责打开内核中的framebuffer、初始化配置,以及提供post、setSwapInterval等操作,后者则管理帧缓冲区的分配和释放。上层只能通过Gralloc访问帧缓冲区,这样一来就实现了有序的封装保护
3. 由于OpenGL ES是一个通用的函数库,在不同的平台系统上需要被“本地化”——即把它与具体平台上的窗口系统建立起关联,这样才能保证它正常工作。从FramebufferNativeWindow这个名称就能判断出来,它就是将OpenGL ES在Android平台上本地化的中介之一。后面我们还会看到应用程序端所使用的另一个“本地窗口”。为OpengGL ES配置本地窗口的是EGL
4. OpenGL或者OpenGL ES 更多的只是一个接口协议,实现上既可以采用软件,也能依托于硬件。这一方面给产品开发带来了灵活性,我们可以根据成本与市场定位来决定具体的硬件设计,从而达到很好的定制需求;另一方面,既然有多种实现的可能,那么OpenGL ES在运行时是如何取舍的呢?这也是EGL的作用之一。它会去读取egl.cfg这个配置文件,然后根据用户的设定来动态加载libagl(软件实现)或者libhgl(硬件实现)。然后上层才可以正常使用各种glXXX接口
5. SurfaceFlinger中持有一个GraphicPlane成员变量mGraphicPlanes来描述“显示屏”;GraphicPlane类中又包含了一个DisplayHardware对象实例(mHw)。具体是在SurfaceFlinger::readyToRun中,完成对它们的创建与初始化。并且DisplayHardware在初始化时还将调用eglInitialize、eglCreateWindowSurface等接口,利用EGL来完成对OpenGLES环境的搭建。其中:
surface =eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
mNativeWindow 就是一个FramebufferNativeWindow对象。DisplayHardware为OpenGL ES设置了“本地化”所需的窗口
6. 很多模块都可以调用OpenGLES提供的API(这些接口以“gl”为前缀,比如glViewport、glClear、glMatrixMode、glLoadIdentity等等),包括SurfaceFlinger、DisplayHardware等
7. 与OpenGL ES相关的模块,可以分为如下几类:
Ø 配置类
即帮助OpenGL ES完成配置的,包括EGL、DisplayHardware都可以认为是这一类
Ø 依赖类
也就是OpenGL ES要正常运行起来所依赖的“本地化”的东西,上图中是指FramebufferNativeWindow
Ø 使用类
使用者也可能是配置者,比如DisplayHardware既扮演了“帮助”OpenGL的角色,同时它也是其使用方。另外只要处在与OpenGL ES同一个环境(Context)中的模块,都可以使用它来完成操作,比如SurfaceFlinger
如果是对EGL的作用、工作方式以及它所提供的重要接口等有不明白的,强烈建议大家先阅读官方文档以及本书应用篇中的章节,否则会大大影响后面的学习和理解。