首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

Android应用程序请求SurfaceFlinger服务点染Surface的过程分析

2012-09-23 
Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析在前面一篇文章中,我们分析了Android应用程

Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析

        在前面一篇文章中,我们分析了Android应用程序请求SurfaceFlinger服务创建Surface的过程。有了Surface之后,Android应用程序就可以在上面绘制自己的UI了,接着再请求SurfaceFlinger服务将这个已经绘制好了UI的Surface渲染到设备显示屏上去。在本文中,我们就将详细分析Android应用程序请求SurfaceFlinger服务渲染Surface的过程。

        Android应用程序在请求SurfaceFlinger服务渲染一个Surface之前,首先要将该Surface作为当前活动的绘图上下文,以便可以使用OpengGL库或者其它库的API来在上面绘制UI,我们以Android系统的开机动画应用程序bootanim为例,来说明这个问题。

        从前面Android应用程序请求SurfaceFlinger服务创建Surface的过程分析一文可以知道,Android系统的开机动画应用程序bootanim是在BootAnimation类的成员函数readyToRun中请求SurfaceFlinger服务创建Surface的。这个Surface创建完成之后,就会被设置为当前活动的绘图上下文,如下所示:

图1 SharedBufferStack的结构示意图


       从图1就可以看出,每一个UI元数据缓冲区都可能对应有一个UI数据缓冲区,这个UI数据缓冲区又可以称为图形缓冲区,它使用一个GraphicBuffer对象来描述。注意,一个UI元数据缓冲区只有第一次被使用时,Android应用程序才会为它创建一个图形缓冲区,因此,我们才说每一个UI元数据缓冲区都可能对应有一个UI数据缓冲区。例如,在图1中,目前只使到了编号为1和2的UI元数据缓冲区,因此,只有它们才有对应的图形缓冲区,而编号为3、4和5的UI元数据缓冲区没有。

       Android应用程序渲染一个Surface的过程大致如下所示:

       1. 从UI元数据缓冲区堆栈中得到一个空闲的UI元数据缓冲区;

       2. 请求SurfaceFlinger服务为这个空闲的UI元数据缓冲区分配一个图形缓冲区;

       3. 在图形缓冲区上面绘制好UI之后,即填充好UI数据之后,就将前面得到的空闲UI元数据缓冲区添加到UI元数据缓冲区堆栈中的待渲染队列中去;

       4. 请求SurfaceFlinger服务渲染前面已经准备好了图形缓冲区的Surface;

       5. SurfaceFlinger服务从即将要渲染的Surface的UI元数据缓冲区堆栈的待渲染队列中找到待渲染的UI元数据缓冲区;

       6. SurfaceFlinger服务得到了待渲染的UI元数据缓冲区之后,接着再找到在前面第2步为它所分配的图形缓冲区,最后就可以将这个图形缓冲区渲染到设备显示屏上去。

       这个过程的第1步、第3步和第5步涉到UI元数据缓冲区堆栈的一些出入栈操作,为了方便后面描述Android应用程序请求SurfaceFlinger服务渲染Surface的过程,我们首先介绍一下UI元数据缓冲区堆栈的一些出入栈操作。

       在前面Android应用程序请求SurfaceFlinger服务创建Surface的过程分析一文中,我们分析了用来描述UI元数据缓冲区堆栈的SharedBufferServer和SharedBufferClient类的父类SharedBufferBase,它有一个成员函数waitForCondition,用来等待一个条件得到满足,它定义在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h中,如下所示:


图2 分配空闲UI元数据缓冲区及其图形缓冲区的过程

      这个过程一共分为12个步骤,接下来我们就详细分析每一个步骤。

      Step 1. Surface.dequeueBuffer


图3 准备就绪的UI元数据缓冲区进入待渲染队列的过程

      这个过程一共分为4个步骤,接下来我们就详细分析每一个步骤。

      Step 1. Surface.queueBuffer


图 4 SurfaceFlinger服务渲染Surface的过程

       这个过程一共分为6个步骤,接下来我们就详细分析每一个步骤。

       Step 1. SurfaceFlinger.threadLoop

status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {    mActiveBuffer = index;    return NO_ERROR;}
       这个函数定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。

       BufferManager类的成员变量mActiveBuffer用来描述一个Surface的当前激活的图形缓冲区的编号。由于参数index正好就是描述一个Surface的当前激活的图形缓冲区的编号,因此,函数就可以将它保存在BufferManager类的成员变量mActiveBuffer中。

       前面在分析空闲UI元数据缓冲区及其图形缓冲区的分配过程的Step 10时提到,BufferManager类有一个类型BufferData数组的成员变量mBufferData,它里面保存了SurfaceFlinger服务为一个Surface所分配的图形缓冲区,这样,后面SurfaceFlinger服务在渲染一个Surface时,就可以通过与它所关联的一个BufferManager对象的成员变量mActiveBuffer来在另外一个成员变量mBufferData中找到当前激活的图形缓冲区。

       这一步执行完成之后,SurfaceFlinger服务渲染Surface的图形缓冲区的过程就分析完成了。这个过程虽然只是一个粗略的过程,但是已经足够我们理解Android应用程序请求SurfaceFlinger服务渲染Surface的过程了,同时也为后面我们从正面分析SurfaceFlinger服务的实现原理理清了思路,以及打下了良好的基础。

       至此,Android应用程序和SurfaceFlinger服务的关系我们就学习完成了。要重新学习,请参考前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文。接下来,我们还会继续分析SurfaceFlinger服务的实现原理,敬请关注!

4楼leihengxin5小时前
顶一下。
3楼www_k2tiyu_com昨天 22:11
整理的比较完善。。。学习了
2楼chinanick028昨天 19:39
很好。很好。
1楼JuneIvan昨天 15:56
书啥时候出啊?等不及了
Re: Luoshengyang昨天 16:25
回复JuneIvann快了,下个月的样子可以出来。
Re: JuneIvan昨天 16:43
回复Luoshengyangn几本?比这个博客有删减吗?到时一定支持
Re: Luoshengyang昨天 19:20
回复JuneIvann一本,出版的书没有UI这部分内容,目录可以看一下这里:http://blog.csdn.net/luoshengyang/article/details/7409491
Re: JuneIvan昨天 19:24
回复Luoshengyangn应该能涵盖除了UI之外的所有博客吧?n另,老罗,UI,audio,connectivity,还有dalvik这些以后会有分析吗?
Re: Luoshengyang昨天 19:33
回复JuneIvann嗯,除了UI部分,都涵盖了,而且会被博客的内容会讲得更详细。UI这部分内容会一直坚持分析下去,之后有计划再分析dalvik。audio和connectivity这些针对性很强的话题可能就不会分析了,博客的宗旨是学习Android系统的基础架构,偏向分析比较通用的话题。

热点排行