出自:http://blog.csdn.net/luoshengyang/article/details/7867340

在前面一篇文章中,我们分析了Android应用程序与SurfaceFlinger服务的连接过程。Android应用程序成功连接上SurfaceFlinger服务之后,还需要一块匿名共享内存来和SurfaceFlinger服务共享它的UI元数据,以便使得SurfaceFlinger服务可以正确地为它创建以及渲染Surface。在本文中,我们将详细地分析这块用来保存UI元数据的匿名共享内存的创建过程。

Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文中提到,用来保存Android应用程序的UI元数据的匿名共享内存最终是被结构化为一个SharedClient对象来访问的。每一个与UI有关的Android应用程序进程有且仅有一个SharedClient对象,而且这些SharedClient对象是由Android应用程序请求SurfaceFlinger服务创建的:Android应用程序首先获得SurfaceFlinger服务的一个Binder代理接口,然后再通过这个代理接口得到另外一个类型为UserClient的Binder代理接口,最后就可以通过后一个Binder代理接口来获得一个SharedClient对象。

由于每一个与UI有关的Android应用程序进程有且仅有一个SharedClient对象,因此,Android系统就通过一个单例模式的类来专负责创建和管理这个SharedClient对象。这个类的名称为SurfaceClient,定义在frameworks/base/libs/surfaceflinger_client/Surface.cpp文件中,如下所示:

[cpp] view plain copy
  1. classSurfaceClient:publicSingleton<SurfaceClient>
  2. {
  3. //alltheseattributesareconstants
  4. sp<ISurfaceComposer>mComposerService;
  5. sp<ISurfaceComposerClient>mClient;
  6. status_tmStatus;
  7. SharedClient*mControl;
  8. sp<IMemoryHeap>mControlMemory;
  9. SurfaceClient()
  10. :Singleton<SurfaceClient>(),mStatus(NO_INIT)
  11. {
  12. sp<ISurfaceComposer>sf(ComposerService::getComposerService());
  13. mComposerService=sf;
  14. mClient=sf->createClientConnection();
  15. if(mClient!=NULL){
  16. mControlMemory=mClient->getControlBlock();
  17. if(mControlMemory!=NULL){
  18. mControl=static_cast<SharedClient*>(
  19. mControlMemory->getBase());
  20. if(mControl){
  21. mStatus=NO_ERROR;
  22. }
  23. }
  24. }
  25. }
  26. friendclassSingleton<SurfaceClient>;
  27. public:
  28. status_tinitCheck()const{
  29. returnmStatus;
  30. }
  31. SharedClient*getSharedClient()const{
  32. returnmControl;
  33. }
  34. ssize_tgetTokenForSurface(constsp<ISurface>&sur)const{
  35. //TODO:wecouldcacheafewtokensheretoavoidanIPC
  36. returnmClient->getTokenForSurface(sur);
  37. }
  38. voidsignalServer()const{
  39. mComposerService->signal();
  40. }
  41. };

当SurfaceClient类的静态成员函数getInstance第一次被调用的时候,系统就会在对应的应用程序进程中创建一个SurfaceClient对象,即会调用SurfaceClient类的构造函数。SurfaceClient类的构造函数首先会调用ComposerService类的静态成员函数getComposerService来获得一个SurfaceFlinger服务的代理接口,并且保存在SurfaceClient类的成员变量mComposerService中,以便以后可以使用。ComposerService类的静态成员函数getComposerService在前面Android应用程序与SurfaceFlinger服务的连接过程分析一文中已经分析过了,这里不再详述。有了SurfaceFlinger服务的代理接口sf之后,SurfaceClient类的构造函数接着就可以调用它的成员函数createClientConnection来获得一个类型为UserClient的Binder代理接口,这个Binder代理接口实现了ISurfaceComposerClient接口,因此,我们可以将它保存在SurfaceClient类的成员变量mClient中。最后,SurfaceClient类的构造函数就调用前面获得的类型为ISurfaceComposerClient的Binder代理接口mClient的成员函数getControlBlock来获得一块用来描述应用程序UI元数据的匿名共享内存mControlMemory,并且将这些匿名共享内存强制转化为一个SharedClient对象mControl,以便后面可以方便地访问UI元数据。

以上就是Android应用程序与SurfaceFlinger服务之间的共享UI元数据(SharedClient)的创建过程的总体描述,接下来我们再详细分析每一步的实现。现在,我们继续分析一下SurfaceClient类的其余成员函数的实现:

1. 成员函数initCheck用来检查一个Android应用程序进程是否已经成功地请求SurfaceFlinger服务创建了一块用来描述UI元数据的SharedClient对象了。

2. 成员函数getSharedClient用来返回用来描述UI元数据的SharedClient对象mControl。

3. 成员函数getTokenForSurface用来返回由参数sur所描述的一个Surface的Token值。这个Token值由SurfaceFlinger服务来创建和管理,并且可以通过前面所获得的类型为UserClient的Binder代理接口mClient的成员函数getTokenSurface来获得。

4. 成员函数signalServer用来通知SurfaceFlinger服务更新Android应用程序UI,这是通过调用SurfaceFlinger服务的代理接口mComposerService的成员函数signal来实现的,实际上就是向SurfaceFlinger服务发送一个信号,以便可以将它唤醒起来更新UI。

介绍完成SurfaceClient类的实现之后,我们还需要了解一下两个类的实现,即UserClient类和SharedClient类的实现,以便可以帮助我们了解用来保存Android应用程序的UI元数据的匿名共享内存的创建过程,以及帮助后面两篇文章对Surface的创建和渲染过程的分析。

接下来,我们就首先分析UserClient类的实现,接着再分析SharedClient类的实现。

在Android应用程序与SurfaceFlinger服务的连接过程分析一文的图2中,我们介绍了用来连接Android应用程序和SurfaceFlinger服务的Client类,而UserClient类和Client类是类似的,它们都实现了相同的接口,只不过是侧重点有所不同。Android应用程序与SurfaceFlinger服务的连接过程分析一文的图2中的Client类替换成UserClient类,就可以得到UserClient类的实现结构图,如图1所示:

图1 UserClient类的实现结构图

UserClient类与Client类最重要的区别是,前者实现了ISurfaceComposerClient接口的成员函数getControlBlock,而后者实现了ISurfaceComposerClient接口的成员函数createSurface。后面我们就会分析UserClient类是如何实现ISurfaceComposerClient接口的成员函数getControlBlock的。

UserClient类的实现暂时就介绍到这里,接下来我们来看SharedClient类的实现。为了方便描述,我们把Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文的图4和图5贴出来,如以下图2和图3所示:

图2 用来描述Android应用程序的UI元数据的SharedClient

图3 SharedBufferStack的结构示意图

每一个SharedClient对象包含了至多31个SharedBufferStack,而每一个SharedBufferStack都对应一个Android应用程序进程中的一个Surface。

SharedClient类定义在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h文件中,如下所示:

[cpp] view plain copy
  1. classSharedClient
  2. {
  3. public:
  4. SharedClient();
  5. ~SharedClient();
  6. ......
  7. private:
  8. ......
  9. SharedBufferStacksurfaces[SharedBufferStack::NUM_LAYERS_MAX];
  10. };

它有一个大小为SharedBufferStack::NUM_LAYERS_MAX的SharedBufferStack数组。SharedBufferStack::NUM_LAYERS_MAX的值等于31,定义在SharedBufferStack类中。

SharedBufferStack类同样是定义在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h文件中,如下所示:

[cpp] view plain copy
  1. classSharedBufferStack
  2. {
  3. ......
  4. public:
  5. //Whenchangingthesevalues,theCOMPILE_TIME_ASSERTattheendofthis
  6. //fileneedtobeupdated.
  7. staticconstunsignedintNUM_LAYERS_MAX=31;
  8. staticconstunsignedintNUM_BUFFER_MAX=16;
  9. staticconstunsignedintNUM_BUFFER_MIN=2;
  10. staticconstunsignedintNUM_DISPLAY_MAX=4;
  11. ......
  12. structSmallRect{
  13. uint16_tl,t,r,b;
  14. };
  15. structFlatRegion{
  16. staticconstunsignedintNUM_RECT_MAX=5;
  17. uint32_tcount;
  18. SmallRectrects[NUM_RECT_MAX];
  19. };
  20. structBufferData{
  21. FlatRegiondirtyRegion;
  22. SmallRectcrop;
  23. uint8_ttransform;
  24. uint8_treserved[3];
  25. };
  26. SharedBufferStack();
  27. ......
  28. status_tsetDirtyRegion(intbuffer,constRegion&reg);
  29. status_tsetCrop(intbuffer,constRect&reg);
  30. status_tsetTransform(intbuffer,uint8_ttransform);
  31. RegiongetDirtyRegion(intbuffer)const;
  32. RectgetCrop(intbuffer)const;
  33. uint32_tgetTransform(intbuffer)const;
  34. //theseattributesarepartoftheconditions/updates
  35. volatileint32_thead;//server'scurrentfrontbuffer
  36. volatileint32_tavailable;//numberofdequeue-ablebuffers
  37. volatileint32_tqueued;//numberofbufferswaitingforpost
  38. ......
  39. //notpartoftheconditions
  40. ......
  41. volatileint8_tindex[NUM_BUFFER_MAX];
  42. ......
  43. int8_theadBuf;//lastretiredbuffer
  44. ......
  45. BufferDatabuffers[NUM_BUFFER_MAX];
  46. };


下面我们简要地对SharedBufferStack类进行分析。

首先,SharedBufferStack类在内部定义了四个常量:

NUM_LAYERS_MAX-- 表示一个Android应用程序最多可以有NUM_LAYERS_MAX个Layer,可以将一个Layer理解为一个Surface。

NUM_BUFFER_MAX-- 表示一个SharedBufferStack至多可以有NUM_BUFFER_MAX个UI元数据缓冲区。

NUM_BUFFER_MIN-- 表示一个SharedBufferStack至少要有UM_BUFFER_MIN个UI元数据缓冲区。

NUM_DISPLAY_MAX-- 表示Android系统至多可以支持NUM_DISPLAY_MAX个显示屏。

从这些常量就可以看出:

1. Android系统至多支持4个显示屏。

2. 一个Android应用程序至多可以同时创建31个Surface。

3. 一个Surface可以有2~16个UI元数据缓冲区,即可以使用2~16缓冲区技术来渲染Surface。

其次,SharedBufferStack类在内部定义了三个结构体:

SmallRect-- 用来描述一个矩形区域,其中,成员变量l、t,、r和b分别表示左上和右下两个角的位置。

FlatRegion-- 用来描述一个SmallRect数组rects ,数组的大小为NUM_RECT_MAX,但是实际个数为count。

BufferData-- 用来描述一个UI元数据缓冲区,它有四个成员变量dirtyRegion、crop、transform和reserved,其中,dirtyRegion用来描述一个Surface需要更新的区域,即裁剪区域,crop用来描述一个Surface的纹理坐标,transform用来描述一个Surface的旋转方向,例如,旋转90度或者上下翻转等等,而reserved是保留给以后使用的。通过这个UI元数据缓冲区,SurfaceFlinger服务就可以正确地把一个Surface的图形缓冲区所描述的图形渲染到屏幕来。

SharedBufferStack类有一个BufferData数组buffers,它的大小为NUM_BUFFER_MAX,即16,就是用来一组UI元数据缓冲区的,这些UI元数据缓冲区的内容可以分别通过setDirtyRegion、setCrop、setTransform、getDirtyRegion、getCropgetTransform这六个成员函数来访问。这六个成员函数的第一个参数均为一个int值,用来描述要访问的是哪一个BufferData的数据。

SharedBufferStack类还有另外一个类型为int8_t的数组index,它的大小也为NUM_BUFFER_MAX。这个index数组才是一个真正的Stack,它按照一定的规则来访问。index数组的每一个元素的值均是一个索引值,用来映射到数组buffers中去的。例如,假设index[0]的值等于2,那么它就对应数组buffers中的第2个元素,即buffers[2]

SharedBufferStack类的其余重要成员变量的含义如下所示:

head-- 用来描述一个SharedBufferStack的头部,它是一个索引值,是映射到数组index中去的。

available-- 用来描述一个SharedBufferStack中的空闲UI元数据缓冲区的个数。

queued-- 用来描述一个SharedBufferStack中的已经补使用了的UI元数据缓冲区的个数,即那些在排队等待SurfaceFlinger服务使用的UI元数据缓冲区。

headBuf-- 用来描述一个SharedBufferStack的头部所对应的UI元数据缓冲区的编号,这个编号是映射到数组buffers中去。

关于SharedBufferStack类的实现,我们就暂时介绍到这里,在下一篇文章分析Android应用程序的Surface创建过程时,我们再通过SharedBufferServer类和SharedBufferClient类的实现来进一步理解SharedBufferStack类的实现。

现在,我们就开始详细分析Android应用程序与SurfaceFlinger服务之间的共享UI元数据的创建过程,如图4所示:

图 4 Android应用程序的共享UI元数据的创建过程

接下来我们就详细分析每一个步骤。

Step 1. SurfaceFlinger::createClientConnection

[cpp] view plain copy
  1. sp<ISurfaceComposerClient>SurfaceFlinger::createClientConnection()
  2. {
  3. sp<ISurfaceComposerClient>bclient;
  4. sp<UserClient>client(newUserClient(this));
  5. status_terr=client->initCheck();
  6. if(err==NO_ERROR){
  7. bclient=client;
  8. }
  9. returnbclient;
  10. }

SurfaceFlinger类的成员函数createClientConnection实现在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,它的实现很简单,只是创建了一个类型为UserClient的Binder对象client,并且获得它的一个ISurfaceComposerClient接口,最后将这个ISurfaceComposerClient接口,即一个UserClient代理对象,返回给Android应用程序进程。

接下来,我们再继续分析UserClient对象的创建过程,,即UserClient类的构造函数的实现。

Step 2. new UserClient

[cpp] view plain copy
  1. UserClient::UserClient(constsp<SurfaceFlinger>&flinger)
  2. :ctrlblk(0),mBitmap(0),mFlinger(flinger)
  3. {
  4. constintpgsize=getpagesize();
  5. constintcblksize=((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
  6. mCblkHeap=newMemoryHeapBase(cblksize,0,
  7. "SurfaceFlingerClientcontrol-block");
  8. ctrlblk=static_cast<SharedClient*>(mCblkHeap->getBase());
  9. if(ctrlblk){//constructthesharedstructurein-place.
  10. new(ctrlblk)SharedClient;
  11. }
  12. }


UserClient类的成员变量mFlinger是一个类型为SurfaceFlinger的强指针,它指向了SurfaceFlinger服务,UserClient类的另外一个成员变量mBitmap是一个int32_t值,它是用来为Android应用程序的Surface分配Token值的,即如果它的第n位等于1,那么就表示值等于n的Token已经被分配出去使用了。

UserClient类的构造函数首先得到一个SharedClient对象的大小,接着再将这个大小对齐到页面边界,于是就得到了接下来要创建的匿名共享块的大小cblksize。这块匿名共享内存是一个MemoryHeapBase对象描述的,并且保存在UserClient类的成员变量mCblkHeap。MemoryHeapBase类是用来创建匿名共享内存的一个C++接口,它的实现原理可以参考Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析一文。

UserClient类的构造函数得到了一块匿名共享内存之后,紧接着就在这块匿名共享内存上创建了一个SharedClient对象,并且保存在UserClient类的成员变量ctrlblk中,以便后面可以通过它来访问Android应用程序的UI元数据。

回到SurfaceFlinger类的成员函数createClientConnection中,它将一个指向了一个UserClient对象的ISurfaceComposerClient接口返回到Android应用程序进程之后,Android应用程序进程就可以将它封装成一个类型为BpSurfaceComposerClient的Binder代理对象。

Step 3. returnBpSurfaceComposerClient

将一个Binder代理对象封装成一个BpSurfaceComposerClient的过程可以参考前面Android应用程序与SurfaceFlinger服务的连接过程分析一文中的Step 4。

Step 4.UserClient::getControlBlock

[cpp] view plain copy
  1. sp<IMemoryHeap>UserClient::getControlBlock()const{
  2. returnmCblkHeap;
  3. }

从前面的Step 2可以知道,UserClient类的成员变量mCblkHeap指向了一块匿名共享内存,UserClient类将这块匿名共享内存返回给Android应用程序之后,Android应用程序就会将它结构化成一个SharedClient对象来访问,并且保存在SurfaceClient类的成员变量mControl中,这个结构化过程就可以参考前面所描述的SurfaceClient类的构造函数了。

至此,用来描述Android应用程序的UI元数据的一个SharedClient对象的创建过程就分析完了。以后当Android应用程序请求SurfaceFlinger服务创建一个Surface的时候,SurfaceFlinger服务就会从这个SharedClient对象中取出一个SharedBufferStack出来,以便可以用作这个Surface的UI元数据缓冲区。在接下来的一篇文章中,我们将详细描述Android应用程序请求SurfaceFlinger服务创建Surface的过程,敬请期待!

老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

更多相关文章

  1. 箭头函数的基础使用
  2. Python技巧匿名函数、回调函数和高阶函数
  3. 转:RTC搭建android下三层应用程序访问服务器MsSql-客户端
  4. AndroidManifest.xml学习
  5. Android(安卓)configChanges用法
  6. Android(安卓)Camera 使用小结
  7. Android模拟器环境中安装和删除应用程序
  8. android wifi
  9. Android(安卓)4高级编程(第三版)Android简介

随机推荐

  1. Android 垂直的Slidebar 代码
  2. ch028 Android 断点续传
  3. My Android Camera Notes
  4. Android:GridView+AbsoluteLayout作一个
  5. Android 数据库技术
  6. android ImageView scaleType属性
  7. RadioButton修改标志图片
  8. android 主题
  9. Android下单元测试
  10. 最近总结的android疑惑