当前位置: 首页 > news >正文

网站维护界面承德市宽城县建设局网站

网站维护界面,承德市宽城县建设局网站,学校网站建设工作目标,做竞价推广的网站要求文章转载至CSDN社区罗升阳的安卓之旅#xff0c;原文地址#xff1a;http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应用程序与SurfaceFlinger服务的连接过程了。连接上SurfaceFlinger服务之后#xff0c;Android应用程序就可以请求… 文章转载至CSDN社区罗升阳的安卓之旅原文地址http://blog.csdn.net/luoshengyang/article/details/7884628 前面我们已经学习过Android应用程序与SurfaceFlinger服务的连接过程了。连接上SurfaceFlinger服务之后Android应用程序就可以请求SurfaceFlinger服务创建Surface。而当有了Surface后Android应用程序就可以用来渲染自己的UI了。在本文中我们将详细分析Android应用程序请求SurfaceFlinger服务创建Surface的过程。         在讲述Android应用程序请求SurfaceFlinger服务创建Surface之前我们首先了解一个Surface是由什么组成的。我们可以将Surface理解为一个绘图表面Android应用程序负责往这个绘图表面填内容而SurfaceFlinger服务负责将这个绘图表面的内容取出来并且渲染在显示屏上。         在SurfaceFlinger服务这一侧绘图表面使用Layer类来描述Layer类的实现如图1所示。 图1 Layer类的实现        Layer类继承了LayerBaseClient类LayerBaseClient类继承了LayerBase类LayerBase类继续了RefBase类。从这些继承关系就可以看出我们可以通过Android系统的智能指针来引用Layer对象从而可以自动地维护它们的生命周期。        Layer类内部的成员变量mUserClientRef指向了一个ClientRef对象这个ClientRef对象内部有一个成员变量mControlBlock它指向了一个SharedBufferServer对象。从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一文可以知道SharedBufferServer类是用来在SurfaceFlinger服务这一侧描述一个UI元数据缓冲区堆栈的即在SurfaceFlinger服务中每一个绘图表面即一个Layer对象都关联有一个UI元数据缓冲区堆栈。        LayerBaseClient类内部有一个类型为LayerBaseClient::Surface的弱指针它引用了一个 Layer::SurfaceLayer对象。这个Layer::SurfaceLayer对象是一个Binder本地对象它是 SurfaceFlinger服务用来与Android应用程序建立通信的以便可以共同维护一个绘图表面。        Layer::SurfaceLayer类继承了LayerBaseClient::Surface类它的实现如图2所示。 图2 SurfaceLayer类的实现        理解这个图需要了解Android系统的Binder进程间通信机制具体可以参考Android进程间通信IPC机制Binder简要介绍和学习计划一文。从这里就可以看出Layer::SurfaceLayer类实现了ISurface接口而Android应用程序就是通过这个接口来和SurfaceFlinger服务共同维护一个绘图表面的。        Layer::SurfaceLayer类内部有两个成员变量mFlinger和mOwner前者指向了SurfaceFlinger服务而后者指向了其宿主Layer对象。        ISurface接口定义在文件frameworks/base/include/surfaceflinger/ISurface.h中它有一个重要的成员函数requestBuffer如下所示   [cpp] view plaincopy class ISurface : public IInterface  {      ......    public:      DECLARE_META_INTERFACE(Surface);        /*      * requests a new buffer for the given index. If w, h, or format are      * null the buffer is created with the parameters assigned to the      * surface it is bound to. Otherwise the buffers parameters are      * set to those specified.      */      virtual spGraphicBuffer requestBuffer(int bufferIdx,              uint32_t w, uint32_t h, uint32_t format, uint32_t usage)  0;        ......    };           Android应用程序就是通过ISurface接口的成员函数requestBuffer来请求SurfaceFlinger服务为它的一个绘图表面分配一个图形缓冲区的这个图形缓冲区使用一个GraphicBuffer对象来描述。         由于Layer::SurfaceLayer是一个Binder本地对象类因此就相应地有一个Binder代理对象类它的名称为BpSurface它的实现如图3所示。 图3 BpSurface类的实现        理解这个图同样需要了解Android系统的Binder进程间通信机制具体可以参考Android进程间通信IPC机制Binder简要介绍和学习计划一文。        以上都是从SurfaceFlinger服务这一侧来理解一个Surface下面我们再从Android应用程序这一侧来理解一个Surface。        在Android应用程序这一侧每一个绘图表面都使用一个Surface对象来描述每一个Surface对象都是由一个SurfaceControl对象来创建的。Surface类和SurfaceControl类的关系以及实现如图4所示。 图4 Surface类和SurfaceControl类的关系以及实现        SurfaceControl类的成员变量mClient是一个类型为SurfaceComposerClient的强指针它指向了Android应用程序进程中的一个SurfaceComposerClient单例对象。在前面Android应用程序与SurfaceFlinger服务的连接过程分析一 文中我们已经看到过SurfaceComposerClient类的作用了Android应用程序主要就是通过它来和SurfaceFlinger服 务建立连接的连接的结果就是得到一个类型为Client的Binder代理对象保存它的成员变量mClient中。       SurfaceControl类的成员变量mSurface是一个类型为ISurface的强指针它指向了一个类型为BpSurface的 Binder代理对象而这个Binder代理对象引用的是一个Layer::SurfaceLayer对象。当Android应用程序请求 SurfaceFlinger服务创建一个绘图表面的时候SurfaceFlinger服务就会在内部创建一个Layer::SurfaceLayer 对象并且将这个Layer::SurfaceLayer对象的一个Binder代理对象返回来给Android应用程序然后Android应用程序再 将这个Binder代理对象保存在一个SurfaceControl对象的成员变量mSurface中。       SurfaceControl类的成员变量mSurfaceData是一个类型为Surface的强指针它指向了一个Surface对象。       Surface类就是用来在Android应用程序这一侧描述绘图表面的它的成员变量mSurface与它的宿主类SurfaceControl的成 员变量mSurface指向的是同一个Binder代理对象即它们都引用了在SurfaceFlinger服务内部所创建的一个类型为 Layer::SurfaceLayer的Binder本地对象。       Surface类的成员变量mClient指向了Android应用程序进程中的一个SurfaceClient单例对象。在前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一文中我们已经介绍过SurfaceClient类的实现了Android应用程序就是通过它来请求SurfaceFlinger服务创建共享UI元数据的并且可以通过它来请求SurfaceFlinger服务渲染一个绘图表面。       Surface类的成员变量mSharedBufferClient指向了一个SharedBufferClient对象。从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一文可以知道SharedBufferClient类是用来在Android应用程序这一侧描述一个UI元数据缓冲区堆栈的即在Android应用程序中每一个绘图表面即一个Surface对象都关联有一个UI元数据缓冲区堆栈。       Surface类继承了EGLNativeBase类而EGLNativeBase类又继承了ANativeWindow类。我们知 道Android系统是通过OpenGL库来绘制UI的。OpenGL库在绘制UI的时候需要底层的系统提供一个本地窗口给它以便它可以将UI绘制 在这个本地窗口上。Android系统为OpenGL库定提供的本地窗口使用ANativeWindow类来描述Surface类通过 EGLNativeBase类间接地继承了ANativeWindow类因此Surface类也是用来描述OpenGL绘图所需要的一个本地窗口的。 从这个角度出发我们可以将Surface类看作OpenGL库与Android的UI系统之间的一个桥梁。       讨论到这里我们就可以知道一个绘图表面在SurfaceFlinger服务和Android应用程序中分别对应有一个Layer对象和一个 Surface对象这两个对象在内部分别使用一个SharedBufferServer对象和一个SharedBufferClient对象来描述这个 绘图表面的UI元数据缓冲堆栈。在前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一文中我们已经分析过这个UI元数据的创建过程了接下来我们再简要看一下SharedBufferServer类和SharedBufferClient类的定义。       SharedBufferServer类和SharedBufferClient类均是从SharedBufferBase类继承下来的如图5所示。 图5 SharedBufferBase、SharedBufferServer和SharedBufferClient的关系       在基类SharedBufferBase中有三个成员变量mSharedClient、mSharedStack和mIdentity。成员变量 mSharedClient指向一块UI元数据缓冲区即一个SharedClient对象成员变量mSharedStack指向一个UI元数据堆栈 即一个SharedBufferStack对象成员变量mIdentity用来描述一个绘图表面的ID。       在前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一 文提到每一个与UI相关的Android应用程序内部都有一个唯一的SharedClient对象这个SharedClient对象内部有一个 SharedBufferStack数组surfacesSharedBufferServer类的成员变量mSharedStack所指向的 SharedBufferStack对象正是成员变量mSharedClient所指向的一个SharedClient对象内部的一个 SharedBufferStack数组的一个元素这一点可以从SharedBufferServer类的构造函数实现来看出。       SharedBufferServer类的构造函数frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp文件中如下所示   [cpp] view plaincopy SharedBufferBase::SharedBufferBase(SharedClient* sharedClient,          int surface, int32_t identity)      : mSharedClient(sharedClient),        mSharedStack(sharedClient-surfaces  surface),        mIdentity(identity)  {  }          其中参数surface表示mSharedStack指向的是mSharedClient中的SharedBufferStack数组surfaces的第几个元素。        在SharedBufferClient类中有三个成员变量mNumBuffers、tail和queue_head它们的含义可以参考前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文中的图6如下所示。 图6 SharedBufferClient眼中的SharedBufferStack         在Android应用程序这一侧当它需要渲染一个Surface时它就会首先找到对应的SharedBufferClient对象然后再调用它的成 员函数dequeue来请求分配一个UI元数据缓冲区。有了这个UI元数据缓冲区之后Android应用程序再调用这个 SharedBufferClient对象的成员函数setDirtyRegion、setCrop和setTransform来设置对应的 Surface的裁剪区域、纹理坐标以及旋转方向。此外Android应用程序还会请求SurfaceFlinger服务为这个Surface分配一个 图形缓冲区以便可以往这个图形缓冲区写入实际的UI数据。最后Android应用程序就可以调用这个SharedBufferClient对象的成员 函数queue把前面已经准备好了的UI元数据缓冲区加入到它所描述的一个UI元数据缓冲区堆栈的待渲染队列中以便SurfaceFlinger服务可 以在合适的时候对它进行渲染。这个过程我们在下一篇文章中再详细分析。        SharedBufferServer类的成员变量mNumBuffers的含义可以参考前面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文中的图7如下所示。 图7 SharedBufferServer眼中的SharedBufferStack         当SurfaceFlinger服务需要渲染一个Surface的时候它就会找到对应的一个SharedBufferServer对象然后调用它的 成员函数getQueueCount来检查它所描述的一个UI元数据缓冲区堆栈的待渲染队列的大小。如果这个大小大于0那么 SurfaceFlinger服务就会继续调用它的成员函数retireAndLock来取出队列中的第一个UI元数据缓冲区以及调用它的成员函数 getDirtyRegion、getCrop和getTransform来获得要渲染的Surface的裁剪区域、纹理坐标和旋转方向。最 后SurfaceFlinger服务就可以结合这些信息来将保存这个Surface的图形缓冲区中的UI数据渲染在显示屏中。这个过程我们同样在下一篇 文章中再详细分析。        SharedBufferServer类的另外一个成员变量mBufferList指向了一个BufferList对象这个BufferList对 象是用来管理SharedBufferServer类所描述的一个UI元数据缓冲区堆栈的接下来我们就简要分析它的定义。        BufferList类定义在frameworks/base/include/private/surfaceflinger/SharedBufferStack.h文件中如下所示   [cpp] view plaincopy class SharedBufferServer      : public SharedBufferBase,        public LightRefBaseSharedBufferServer  {      ......    private:      ......        /*      * BufferList is basically a fixed-capacity sorted-vector of      * unsigned 5-bits ints using a 32-bits int as storage.      * it has efficient iterators to find items in the list and not in the list.      */      class BufferList {          size_t mCapacity;          uint32_t mList;      public:          BufferList(size_t c  SharedBufferStack::NUM_BUFFER_MAX)              : mCapacity(c), mList(0) { }          status_t add(int value);          status_t remove(int value);          uint32_t getMask() const { return mList; }            class const_iterator {              friend class BufferList;              uint32_t mask, curr;              const_iterator(uint32_t mask) :                  mask(mask), curr(__builtin_clz(mask)) {              }          public:              inline bool operator  (const const_iterator rhs) const {                  return mask  rhs.mask;              }              inline bool operator ! (const const_iterator rhs) const {                  return mask ! rhs.mask;              }              inline int operator *() const { return curr; }              inline const const_iterator operator () {                  mask  ~(1(31-curr));                  curr  __builtin_clz(mask);                  return *this;              }          };            inline const_iterator begin() const {              return const_iterator(mList);          }          inline const_iterator end() const   {              return const_iterator(0);          }          inline const_iterator free_begin() const {              uint32_t mask  (1  (32-mCapacity)) - 1;              return const_iterator( ~(mList | mask) );          }      };        ......  };          BufferList类的成员变量mCapacity对应于一个UI元数据缓冲区堆栈的容量即最大缓冲区个数。        BufferList类的另外一个成员变量变量mList用来描述这个堆栈中的缓冲区哪个是空闲的哪个是正在使用的。空闲的缓冲区对应的位为0而正在 使用的缓冲区对应的位为1。举个例子假如一个UI元数据缓冲区堆栈的大小为5其中第1、3、5个数据缓冲区是正在使用的而第2、4个数据缓冲区是 空闲的那么对应的mList的值就等于10101000 00000000 00000000 00000000。当我们需要将第2个数据缓冲区设置为正在使用时那么只要调用成员函数add来将左起第2位设置为1即可即得到mList的值就等于 11101000 00000000 00000000 00000000而当我们需要将第1个数据缓冲区设置为空闲时那么只要调用成员函数remove来将左起第1位设置为0即可即得到mList的值就 等于00101000 00000000 00000000 00000000。       在BufferList类内部定义了一个迭代器const_iterator用来从左到右遍历一个UI元数据缓冲区堆栈中的正在使用或者空闲的缓冲区。仍然以前面的例子为例当 我们调用BufferList类的成员函数begin时就可以得到一个const_iterator迭代器沿着这个迭代器往前走就可以依次遍历第 1、3、5个正在使用的缓冲区而当我们调用BufferList类的成员函数free_begin时就可以得到另外一个const_iterator 迭代器沿着这个迭代器往前走就可以依次遍历第2、4个空闲的缓冲区。       关于Surface的概念我们就分析到这里。从这些分析可以知道当Android应用程序请求SurfaceFlinger服务创建一个 Surface的时候需要在SurfaceFlinger服务这一侧创建一个Layer对象、一个Layer::SurfaceLayer对象和一个 SharedBufferServer对象同时又需要在Android应用程序这一侧创建一个SurfaceControl对象、一个Surface对 象和一个SharedBufferClient对象。       在进一步分析Android应用程序请求SurfaceFlinger服务创建Surface的过程之前我们首先看一下Android系统的开机动画 应用程序bootanim是如何请求SurfaceFlinger服务创建一个Surface来显示开机动画的。       在前面Android系统的开机画面显示过程分析一文中 我们分析Android系统的开机动画的显示过程其中开机动画应用程序bootanim是在BootAnimation类的成员函数readyToRun中请求SurfaceFlinger服务创建一个用来显示开机动画的Surface的如下所示 [cpp] view plaincopy status_t BootAnimation::readyToRun() {        ......        // create the native surface        spSurfaceControl control  session()-createSurface(                getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);        ......            spSurface s  control-getSurface();        ......  }           BootAnimation类的成员函数session返回的是一个SurfaceComposerClient对象。有了这个 SurfaceComposerClient对象之后我们就可以调用它的成员函数createSurface来请求请求SurfaceFlinger服 务在内部创建一个Layer::SurfaceLayer对象并且将这个Layer::SurfaceLayer对象的代理对象返回来给 SurfaceComposerClient类SurfaceComposerClient类接着就将这个Layer::SurfaceLayer代理 对象封装成一个SurfaceControl对象并且返回给BootAnimation类最后BootAnimation类就可以调用这个 SurfaceControl对象的成员函数getSurface来获得一个Surface对象。       接下来我们就从SurfaceComposerClient类的成员函数createSurface开始描述Android应用程序请求SurfaceFlinger服务创建Surface的过程如图8所示。 图8 Android应用程序请求SurfaceFlinger服务创建Surface的过程         这个过程可以划分为20个步骤接下来我们就详细分析每一个步骤。        Step 1. SurfaceComposerClient.createSurface [cpp] view plaincopy spSurfaceControl SurfaceComposerClient::createSurface(          int pid,          DisplayID display,          uint32_t w,          uint32_t h,          PixelFormat format,          uint32_t flags)  {      String8 name;      const size_t SIZE  128;      char buffer[SIZE];      snprintf(buffer, SIZE, pid_%d, getpid());      name.append(buffer);        return SurfaceComposerClient::createSurface(pid, name, display,              w, h, format, flags);  }          这个函数定义在文件frameworks/base/libs/surfaceflinger_client/SurfaceComposerClient.cpp文件中。        参数pid用来描述当前进程的PID参数display的值等于0表示要在第一个显示屏上创建一个Surface参数w和h表示要创建的 Surface的宽度和高度它们的值刚好等于第一个显示屏的宽度和高度参数format的值等于PIXEL_FORMAT_RGB_565表示要创 建的Surface的像素格式为PIXEL_FORMAT_RGB_565即每一个点使用2个字节来描述其中R、G和B分量分别占5位、6位和5 位参数flags是一个默认参数它等于默认值0表示要创建的Surface的用途。        这个函数将参数pid格式化成一个字符串之后再调用SurfaceComposerClient类的另外一个版本的成员函数createSurface来请求SurfaceFlinger服务创建一个Surface如下所示 [cpp] view plaincopy spSurfaceControl SurfaceComposerClient::createSurface(          int pid,          const String8 name,          DisplayID display,          uint32_t w,          uint32_t h,          PixelFormat format,          uint32_t flags)  {      spSurfaceControl result;      if (mStatus  NO_ERROR) {          ISurfaceComposerClient::surface_data_t data;          spISurface surface  mClient-createSurface(data, pid, name,                  display, w, h, format, flags);          if (surface ! 0) {              result  new SurfaceControl(this, surface, data, w, h, format, flags);          }      }      return result;  }          SurfaceComposerClient类的成员变量mClient指向了一个类型为BpSurfaceComposerClient的Binder 代理对象它引用了一个类型为Client的Binder本地对象。这个类型Client的Binder本地对象是在SurfaceFlinger服务内 部创建的用来和Android应用程序建立连接。连接的过程可以参考前面Android应用程序与SurfaceFlinger服务的连接过程分析一文。        SurfaceComposerClient类的成员函数createSurface调用成员变量mClient的成员函数 createSurface请求SurfaceFlinger服务创建一个Surface之后就得到了一个类型为BpSurface的Binder代理 对象surface。从前面的描述可以知道Binder代理对象surface引用了在SurfaceFlinger服务这一侧的一个 Layer::SurfaceLayer对象。此外SurfaceComposerClient类的成员函数createSurface还得到了一个 surface_data_t对象data它里面包含了刚才所创建的一个Surface的信息例如宽度、高度、像素格式和ID值等。       最后SurfaceComposerClient类的成员函数createSurface就将SurfaceFlinger服务返回来的Binder 代理对象surface和surface_data_t对象data封装成一个SurfaceControl对象result并且返回给调用者。接下 来我们首先分析SurfaceFlinger服务创建Surface的过程接着再分析SurfaceControl对象result的封装过程。       Step 2. Client.createSurface [cpp] view plaincopy spISurface Client::createSurface(          ISurfaceComposerClient::surface_data_t* params, int pid,          const String8 name,          DisplayID display, uint32_t w, uint32_t h, PixelFormat format,          uint32_t flags)  {      return mFlinger-createSurface(this, pid, name, params,              display, w, h, format, flags);  }         这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。       Client类的成员变量mFlinger指向了SurfaceFlinger服务因此接下来就会调用SurfaceFlinger类的成员函数createSurface来创建一个Surface。       Step 3. SurfaceFlinger.createSurface [cpp] view plaincopy spISurface SurfaceFlinger::createSurface(const spClient client, int pid,          const String8 name, ISurfaceComposerClient::surface_data_t* params,          DisplayID d, uint32_t w, uint32_t h, PixelFormat format,          uint32_t flags)  {      spLayerBaseClient layer;      spLayerBaseClient::Surface surfaceHandle;        if (int32_t(w|h)  0) {          LOGE(createSurface() failed, w or h is negative (w%d, h%d),                  int(w), int(h));          return surfaceHandle;      }        //LOGD(createSurface for pid %d (%d x %d), pid, w, h);      spLayer normalLayer;      switch (flags  eFXSurfaceMask) {          case eFXSurfaceNormal:              if (UNLIKELY(flags  ePushBuffers)) {                  layer  createPushBuffersSurface(client, d, w, h, flags);              } else {                  normalLayer  createNormalSurface(client, d, w, h, flags, format);                  layer  normalLayer;              }              break;          case eFXSurfaceBlur:              layer  createBlurSurface(client, d, w, h, flags);              break;          case eFXSurfaceDim:              layer  createDimSurface(client, d, w, h, flags);              break;      }        if (layer ! 0) {          layer-initStates(w, h, flags);          layer-setName(name);          ssize_t token  addClientLayer(client, layer);            surfaceHandle  layer-getSurface();          if (surfaceHandle ! 0) {              params-token  token;              params-identity  surfaceHandle-getIdentity();              params-width  w;              params-height  h;              params-format  format;              if (normalLayer ! 0) {                  Mutex::Autolock _l(mStateLock);                  mLayerMap.add(surfaceHandle-asBinder(), normalLayer);              }          }            setTransactionFlags(eTransactionNeeded);      }        return surfaceHandle;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。        第一个if语句判断参数w和h的值是否为负数如果是的话那么就直接出错返回了因为创建的Surface的宽度和高度值不可能为负数。        eFXSurfaceNormal、eFXSurfaceBlur、eFXSurfaceDim和eFXSurfaceMask是四个枚举值它们定 义在文件frameworks/base/include/surfaceflinger/ISurfaceComposer.h中如下所示 [cpp] view plaincopy class ISurfaceComposer : public IInterface  {  public:      ......        enum { // (keep in sync with Surface.java)          ......          ePushBuffers         0x00000200,            eFXSurfaceNormal     0x00000000,          eFXSurfaceBlur       0x00010000,          eFXSurfaceDim        0x00020000,          eFXSurfaceMask       0x000F0000,      };        ......  };          回到SurfaceFlinger类的成员函数createSurface中参数flags的值等于0因此在接下来的switch语句中会调用 SurfaceFlinger类的成员函数createNormalSurface来在显示屏上创建一个Layer。顺便提一句如果参数flags的值 等于eFXSurfaceBlur或者eFXSurfaceDim那么就表示要创建的是一个模糊或者渐变的Surface这两种类型的Surface 是在原有的一个Surface上进行创建的用来对原来的Surface进行模糊或者渐变处理。         前面所创建的Layer保存在变量layer中接下来SurfaceFlinger类的成员函数createNormalSurface会调用来另外 一个成员函数addClientLayer来将它保存在内部的一个列表中接着再调用前面所创建的Layer的成员函数getSurface来获得一个 Layer::SurfaceLayer对象surfaceHandle。         在将Layer::SurfaceLayer对象surfaceHandle的一个Binder代理对象返回给Android应用程序之 前SurfaceFlinger类的成员函数createNormalSurface还会以它的一个IBinder接口为关键字将前面所创建的 Layer保存在SurfaceFlinger类的成员变量mLayerMap所描述的一个Map中这样就可以将一个 Layer::SurfaceLayer对象surfaceHandle与它的宿主Layer对象关联起来。         接下来我们首先分析SurfaceFlinger类的成员函数createNormalSurface和addClientLayer的实现接着再分析Layer的成员函数getSurface的实现以便可以了解一个Surface的创建的过程。         Step 4. SurfaceFlinger.createNormalSurface [cpp] view plaincopy spLayer SurfaceFlinger::createNormalSurface(          const spClient client, DisplayID display,          uint32_t w, uint32_t h, uint32_t flags,          PixelFormat format)  {      // initialize the surfaces      switch (format) { // TODO: take h/w into account      case PIXEL_FORMAT_TRANSPARENT:      case PIXEL_FORMAT_TRANSLUCENT:          format  PIXEL_FORMAT_RGBA_8888;          break;      case PIXEL_FORMAT_OPAQUE:  #ifdef NO_RGBX_8888          format  PIXEL_FORMAT_RGB_565;  #else          format  PIXEL_FORMAT_RGBX_8888;  #endif          break;      }    #ifdef NO_RGBX_8888      if (format  PIXEL_FORMAT_RGBX_8888)          format  PIXEL_FORMAT_RGBA_8888;  #endif        spLayer layer  new Layer(this, display, client);      status_t err  layer-setBuffers(w, h, format, flags);      if (LIKELY(err ! NO_ERROR)) {          LOGE(createNormalSurfaceLocked() failed (%s), strerror(-err));          layer.clear();      }      return layer;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。        函数开头的switch语句判断要创建的Surface是否要使用透明色。如果要使用的话那么就将参数format的值修改为 PIXEL_FORMAT_RGBA_8888。另一方面如果要创建的Surface不需要使用透明色那么就将参数format的值修改为 PIXEL_FORMAT_RGB_565或者PIXEL_FORMAT_RGBX_8888取决于是否定义了宏NO_RGBX_8888。       函数接下来创建了一个Layer对象并且调用这个Layer对象的成员函数setBuffers来在内部创建一个Layer::SurfaceLayer对象最后就将这个Layer对象返回给调用者。       接下来我们首先分析Layer对象的创建过程接着再分析Layer对象的成员函数setBuffers的实现。       Step 5. new Layer [cpp] view plaincopy Layer::Layer(SurfaceFlinger* flinger,          DisplayID display, const spClient client)      :   LayerBaseClient(flinger, display, client),          mGLExtensions(GLExtensions::getInstance()),          mNeedsBlending(true),          mNeedsDithering(false),          mSecure(false),          mTextureManager(),          mBufferManager(mTextureManager),          mWidth(0), mHeight(0), mNeedsScaling(false), mFixedSize(false),          mBypassState(false)  {  }         这个函数定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。       Layer类的构造函数只是执行一些简单的初始化工作接下来我们再继续分析它的进一步初始化工作这是通过Layer类的成员函数setBuffers来实现的。       Step 6. Layer.setBuffers [cpp] view plaincopy status_t Layer::setBuffers( uint32_t w, uint32_t h,                              PixelFormat format, uint32_t flags)  {      // this surfaces pixel format      PixelFormatInfo info;      status_t err  getPixelFormatInfo(format, info);      if (err) return err;        // the displays pixel format      const DisplayHardware hw(graphicPlane(0).displayHardware());      uint32_t const maxSurfaceDims  min(              hw.getMaxTextureSize(), hw.getMaxViewportDims());        // never allow a surface larger than what our underlying GL implementation      // can handle.      if ((uint32_t(w)maxSurfaceDims) || (uint32_t(h)maxSurfaceDims)) {          return BAD_VALUE;      }        PixelFormatInfo displayInfo;      getPixelFormatInfo(hw.getFormat(), displayInfo);      const uint32_t hwFlags  hw.getFlags();        mFormat  format;      mWidth   w;      mHeight  h;        mReqFormat  format;      mReqWidth  w;      mReqHeight  h;        mSecure  (flags  ISurfaceComposer::eSecure) ? true : false;      mNeedsBlending  (info.h_alpha - info.l_alpha)  0;        // we use the red index      int displayRedSize  displayInfo.getSize(PixelFormatInfo::INDEX_RED);      int layerRedsize  info.getSize(PixelFormatInfo::INDEX_RED);      mNeedsDithering  layerRedsize  displayRedSize;        mSurface  new SurfaceLayer(mFlinger, this);      return NO_ERROR;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。        参数format是一个整数值用来描述要创建的Surface的像素格式函数首先调用另外一个函数getPixelFormatInfo来将它转换为 一个PixelFormatInfo对象info以便可以获得更多的该种类型的像素格式的信息例如一个像素点占多少个字节每个颜色分量又分别占多 少位等。函数getPixelFormatInfo定义文件frameworks/base/libs/ui/PixelFormat.cpp文件中有 兴趣的读者可以自己研究一下。        Layer类的成员函数graphicPlane是从父类LayerBase继承下来用来获得系统的第N个显示屏这个成员函数最终又是通过调用SurfaceFlinger类的成员函数graphicPlane来实现的如下所示 [cpp] view plaincopy const GraphicPlane LayerBase::graphicPlane(int dpy) const  {      return mFlinger-graphicPlane(dpy);  }         SurfaceFlinger类的成员函数graphicPlane的实现如下示 [cpp] view plaincopy const GraphicPlane SurfaceFlinger::graphicPlane(int dpy) const  {      LOGE_IF(uint32_t(dpy)  DISPLAY_COUNT, Invalid DisplayID %d, dpy);      const GraphicPlane plane(mGraphicPlanes[dpy]);      return plane;  }         SurfaceFlinger类有一个类型为DisplayHardware的数组它的大小等于4表示Android系统最多支持4个显示屏每一 个显示屏都使用一个DisplayHardware对象来描述。实际上Android系统目前只支持一个显示屏因此在调用 SurfaceFlinger类的成员函数graphicPlane的时候传进来的参数dpy的值都是等于0。       回到Layer类的成员函数setBuffers中它接下来获得了用来描述系统第1个显示屏的DisplayHardware对象hw接着再调用函 数getPixelFormatInfo来获得用来描述该显示屏的像素格式信息的PixelFormatInfo对象displayInfo。       Layer类的成员函数setBuffers接下来再将要创建的Surface的像素格式以及大小记录下来即分别将参数format、w和h的值保存 在成员变量mFormat、mWidth、mHeight和mReqFormat、mReqWidth、mReqHeight中。       Layer类的成员函数setBuffers接下来再检查参数flags的ISurfaceComposer::eSecure位是否等于1。如果等于 1的话就将成员变量mSecure的值设置为true否则就设置为false。当参数flags的 ISurfaceComposer::eSecure位等于1的时候就表示正在创建的Surface的UI数据是可以安全地从一个进程拷贝到另外一个进 程的。有些Surface的UI数据是不可以随便拷贝的因为这涉及到安全问题例如用来创建屏幕截图的Surface的UI数据就是不可以随便从一个 进程拷贝到另外一个进程的因为屏幕截图可能会包含隐私信息。       Layer类的成员函数setBuffers接下来又检查要创建的Surface的像素格式的Alpha通道的高8位是否大于低8位。如果是的话就将成员变量mNeedsBlending的值设置为true表示在渲染时要执行混合操作。       Layer类的成员函数setBuffers接下来还检查要创建的Surface的像素格式的Red通道的大小是否大于系统第1个显示屏的像素格式的 Red通道的大小。如果是的话就将成员变量mNeedsDithering的值设置为true表示在渲染时要执行抖动操作。       最后Layer类的成员函数setBuffers就创建了一个SurfaceLayer对象并且保存成员变量mSurface中。       接下来我们就继续分析SurfaceLayer对象的创建过程。       Step 7. new SurfaceLayer [cpp] view plaincopy Layer::SurfaceLayer::SurfaceLayer(const spSurfaceFlinger flinger,          const spLayer owner)      : Surface(flinger, owner-getIdentity(), owner)  {  }          这个函数定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。        SurfaceLayer类的构造函数的实现很简单它只是使用参数flinger以及owner来初始其父类Surface其中参数flinger 指向的是SurfaceFlinger服务而参数owner指向的是正在创建的SurfaceLayer对象的宿主Layer对象。        这一步执行完成之后  沿着调用路径返回到SurfaceFlinger类的成员函数createSurface中这时候就创建好一个Layer对象及其内部的一个 SurfaceLayer对象了接下来我们继续分析SurfaceFlinger类的成员函数addClientLayer的实现以便可以了解 SurfaceFlinger服务是如何维护它所创建的Layer的即它所创建的Surface。        Step 8. SurfaceFlinger.addClientLayer [cpp] view plaincopy ssize_t SurfaceFlinger::addClientLayer(const spClient client,          const spLayerBaseClient lbc)  {      Mutex::Autolock _l(mStateLock);        // attach this layer to the client      ssize_t name  client-attachLayer(lbc);        // add this layer to the current state list      addLayer_l(lbc);        return name;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。        参数client指向了一个Client对象它是用来描述当前正在请求SurfaceFlinger服务的一个Android应用程序的参数lbc指 向的是我们在前面Step 4中所创建的一个Layer对象。函数首先调用参数client所指向的一个Client对象的成员函数attachLayer来关联参数lbc所指向的 一个Layer对象以表示参数lbc所指向的一个Layer对象是由参数client所指向的一个Client对象所描述的一个Android应用程序 请求创建的接下来再调用SurfaceFlinger类的成员函数addLayer_l来将参数lbc所指向的一个Layer对象保存在 SurfaceFlinger的内部。        接下来我们首先分析Client类的成员函数attachLayer的实现接着再分析SurfaceFlinger类的成员函数addLayer_l的实现。        Step 9. Client.attachLayer [cpp] view plaincopy ssize_t Client::attachLayer(const spLayerBaseClient layer)  {      int32_t name  android_atomic_inc(mNameGenerator);      mLayers.add(name, layer);      return name;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。        从前面Android应用程序与SurfaceFlinger服务的连接过程分析一 文可以知道Client类的成员变量mNameGenerator是用来生成Surface名称的它的初始值等于1每当Android应用程序请求 SurfaceFlinger服务为它创建一个SurfaceSurfaceFlinger服务就会将对应的Client对象的成员变量 mNameGenerator的值增加1这样就可以依次得到名称等于1、2、3......的Surface。        为正在创建的Surface生成好名称name之后Client类的成员函数attachLayer就以变量name为关键字将用来描述正在创建的 Surface的一个Layer对象layer保存Client类的成员变量mLayers所描述的一个Map中。从这里就可以知道一个Android 应用程序所创建的Surface都保存在与它所对应的一个Client对象的成员变量mLayers中。       step 10. SurfaceFlinger.addLayer_l [cpp] view plaincopy status_t SurfaceFlinger::addLayer_l(const spLayerBase layer)  {      ssize_t i  mCurrentState.layersSortedByZ.add(layer);      return (i  0) ? status_t(i) : status_t(NO_ERROR);  }         这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。       SurfaceFlinger类的成员变量mCurrentState指向了一个State对象这个State对象内部有一个成员变量 layersSortedByZ它用来描述一个类型为LayerVector的向量用来保存SurfaceFlinger服务所创建的每一个 Layer并且这些Layer是按照Z轴坐示来排列的。这样SurfaceFlinger服务在渲染Surface的时候就可以根据这个向量来计算 可见性。       这一步执行完成之后回到SurfaceFlinger类的成员函数createSurface中这时候SurfaceFlinger服务就将前面所 创建的一个Layer对象保存好在内部了接下来就会调用这个Layer对象的成员函数getSurface来获得在前面Step 6中所创建的一个SurfaceLayer对象以便可以将它的一个Binder代理对象返回请求Surface的Android应用程序。       Layer类的成员函数getSurface是从父类LayerBaseClient继承下来的因此接下来我们就继续分析LayerBaseClient类的成员函数getSurface的实现。       Step 11. LayerBaseClient.getSurface [cpp] view plaincopy spLayerBaseClient::Surface LayerBaseClient::getSurface()  {      spSurface s;      Mutex::Autolock _l(mLock);      s  mClientSurface.promote();      if (s  0) {          s  createSurface();          mClientSurface  s;      }      return s;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/LayerBase.cpp中。        LayerBaseClient类的成员变量mClientSurface是一个类型为Surface的弱指针它指向了一个Surface子类对 象。函数首先将LayerBaseClient类的成员变量mClientSurface升级为一个强指针s。如果升级失败即得到的强指针的值等于0 那么就说明要么还没有初始化LayerBaseClient类的成员变量mClientSurface要么LayerBaseClient类的成员变量 mClientSurface所指向的一个Surface子类对象已经被销毁了。在这种情况下函数就会调用由其子类来重写的成员函数 createSurface来获得一个Surface子类对象并且保存在成员变量mClientSurface中。最后再将得到的Surface子类对 象返回给调用者。弱指针升级为强指针的原理可以参考Android系统的智能指针轻量级指针、强指针和弱指针的实现原理分析一文。       在我们这个场景中LayerBaseClient的子类即为Layer类因此接下来我们就继续分析它的成员函数createSurface的实现。       Step 12. Layer.createSurface [cpp] view plaincopy spLayerBaseClient::Surface Layer::createSurface() const  {      return mSurface;  }         这个函数定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。       从前面的Step 6可以知道 Layer类的成员变量mSurface已经指向了一个SurfaceLayer对象因此函数就可以直接将它返回给调用者。       这一步执行完成之后回到SurfaceFlinger类的成员函数createSurface中这时候SurfaceFlinger服务就完成了 Android应用程序所请求创建的Surface了最后就会将用来描述这个Surface的一个urfaceLayer对象的一个Binder代理对 象返回Android应用程序以便Android应用程序可以将它封装成一个SurfaceControl对象如前面的Step 1所示。       接下来我们就回到Android应用程序这一侧继续分析SurfaceControl对象的创建过程。       Step 13. new SurfaceControl [cpp] view plaincopy SurfaceControl::SurfaceControl(          const spSurfaceComposerClient client,          const spISurface surface,          const ISurfaceComposerClient::surface_data_t data,          uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)      : mClient(client), mSurface(surface),        mToken(data.token), mIdentity(data.identity),        mWidth(data.width), mHeight(data.height), mFormat(data.format),        mFlags(flags)  {  }         这个函数定义在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。       SurfaceControl类的构造函数的实现很简单它只是对各个成员变量进行初始化其中我们需要重点关注的是SurfaceControl 类的成员变量mSurface指向的是一个类型为BpSurface的Binder代理对象这个Binder代理对象引用的是由 SurfaceFlinger服务所创建的一个类型为SurfaceLayer的Binder本地对象。       这一步执行完成之后返回到开机动画应用程序bootanim中即BootAnimation类的成员函数readyToRun中接下来它就会调用 在这一步所创建的SurfaceControl对象的成员函数getSurface来获得一个Surface对象。       接下来我们就继续分析SurfaceControl类的成员函数getSurface的实现。       Step 14. SurfaceControl.getSurface [cpp] view plaincopy spSurface SurfaceControl::getSurface() const  {      Mutex::Autolock _l(mLock);      if (mSurfaceData  0) {          mSurfaceData  new Surface(const_castSurfaceControl*(this));      }      return mSurfaceData;  }         这个函数定义在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。       SurfaceControl类的成员函数getSurface第一次被调用时成员变量mSurfaceData的值等于0因此函数接下来就会创建一个Surface对象并且保存在成员变量mSurfaceData中。       接下来我们就继续分析Surface对象的创建过程。       Step 15. new Surface [cpp] view plaincopy Surface::Surface(const spSurfaceControl surface)      : mBufferMapper(GraphicBufferMapper::get()),        mClient(SurfaceClient::getInstance()),        mSharedBufferClient(NULL),        mInitCheck(NO_INIT),        mSurface(surface-mSurface),        mIdentity(surface-mIdentity),        mFormat(surface-mFormat), mFlags(surface-mFlags),        mWidth(surface-mWidth), mHeight(surface-mHeight)  {      init();  }          这个函数定义在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。        Surface类的成员变量mBufferMapper指向了一个GraphicBufferMapper对象它是用来将分配到的图形缓冲区映射到 Android应用程序进程的地址空间的在接下来的一篇文章介绍Surface的渲染过程时我们再详细分析。        Surface类的成员变量mClient指向了Android应用程序进程中的一个SurfaceClient单例。从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一 文可以知道这个SurfaceClient单例是有来创建Android应用程序与SurfaceFlinger服务的共享UI元数据的。当 SurfaceClient类的成员函数getInstance第一次在进程中被调用时Android应用程序便会请求SurfaceFlinger服 务创建这块共享UI元数据。        Surface类的成员变量mSharedBufferClient指向了一个SharedBufferClient对象。文章开始时提 到SharedBufferClient是用来在Android应用程序这一侧描述一个Surface的UI元数据缓冲区堆栈的后面我们再分析它的创 建过程。        Surface类的成员变量mSurface指向了一个类型为BpSurface的Binder代理对象。从Surface类的构造函数就可以看出这个Binder代理对象引用的是在前面Step 6中创建的一个SurfaceLayer对象。        Surface类的其余成员变量mIdentity、mFormat、mFlags、mWidth和mHeight分别用来描述一个Surface的ID、像素格式、用途、宽度和高度。        Surface类的构造函数接下来调用另外一个成员函数init进一步执行初始化的工作接下来我们就继续分析Surface类的成员函数init的实现。        Step 16. Surface.init [cpp] view plaincopy void Surface::init()  {      ANativeWindow::setSwapInterval   setSwapInterval;      ANativeWindow::dequeueBuffer     dequeueBuffer;      ANativeWindow::cancelBuffer      cancelBuffer;      ANativeWindow::lockBuffer        lockBuffer;      ANativeWindow::queueBuffer       queueBuffer;      ANativeWindow::query             query;      ANativeWindow::perform           perform;        DisplayInfo dinfo;      SurfaceComposerClient::getDisplayInfo(0, dinfo);      const_castfloat(ANativeWindow::xdpi)  dinfo.xdpi;      const_castfloat(ANativeWindow::ydpi)  dinfo.ydpi;      // FIXME: set real values here      const_castint(ANativeWindow::minSwapInterval)  1;      const_castint(ANativeWindow::maxSwapInterval)  1;      const_castuint32_t(ANativeWindow::flags)  0;        mNextBufferTransform  0;      mConnected  0;      mSwapRectangle.makeInvalid();      mNextBufferCrop  Rect(0,0);      // two buffers by default      mBuffers.setCapacity(2);      mBuffers.insertAt(0, 2);        if (mSurface ! 0  mClient.initCheck()  NO_ERROR) {          int32_t token  mClient.getTokenForSurface(mSurface);          if (token  0) {              mSharedBufferClient  new SharedBufferClient(                      mClient.getSharedClient(), token, 2, mIdentity);              mInitCheck  mClient.getSharedClient()-validate(token);          }      }  }          这个函数定义在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。        这个函数的初始化工作分为两部分。        第一部分初始化工作是与OpenGL库相关的主要就是设置OpenGL指定的一系列回调接口以及设置设备显示屏信息。前面提到Surface类是从 ANativeWindow类继承下来的作为OpenGL库与Android系统的本地窗口的连接桥梁。        ANativeWindow类定义了setSwapInterval、dequeueBuffer、cancelBuffer、lockBuffer、 queueBuffer、query和perform一共7个回调接口它们分别被设置为Surface类的静态成员函数 setSwapInterval、dequeueBuffer、cancelBuffer、lockBuffer、queueBuffer、query和 perform。我们主要关注dequeueBuffer和queueBuffer两个回调接口前者用来从UI元数据缓冲区堆栈中获得一个缓冲区而后 者用来将一个缓冲区插入到UI元数据缓冲区堆栈的待渲染队列中。在接下来的一篇文章介绍Surface的渲染过程时我们再详细分析这两个回调接口。       ANativeWindow类还定义了四个成员变量xdpi、ydpi、minSwapInterval、maxSwapInterval和 flags这几个成员变量也是要由Surface类来初始化的。成员变量xdpi和ydpi用来描述设备显示度的密度即每英寸点数。设备显示屏的密码 信息可以通过调用SurfaceComposerClient类的静态成员函数getDisplayInfo来获得。成员变量 minSwapInterval和maxSwapInterval用来描述前后两个缓冲区进行交换的最小和最大时间间隔。成员变量flags用来描述一些 标志信息。       第二部分初始化工作是与UI元数据缓冲区相关。       Surface类的成员变量mNextBufferTransform、mSwapRectangle和mNextBufferCrop分别用来描述下一个要渲染的图形缓冲区的旋转方向、裁剪区域和纹理坐标。       Surface类的成员变量mBuffers用来描述一个类型为spGraphicBuffer的Vector主要是用来保存一个 Surface所使用的图形缓冲区GraphicBuffer的。一开始的时候这个向量的大小被设置为2后面会根据实际需要来增加容量。       Surface类的成员变量mSharedBufferClient指向了一个SharedBufferClient对象用来描述一个UI元数据缓冲区堆栈它的创建过程是最重要的因此接下来我们就详细分析这个过程。       Surface类的成员函数init首先调用成员变量mClient的成员函数getTokenForSurface来获得成员变量mSurface所 描述的一个Surface的token值。有了这个token值之后接下就可以创建一个SharedBufferClient对象并且保存 在 Surface类的成员变量mSharedBufferClient中了。       在前面的Step 15中提到Surface类的成员变量mClient指向的是一个SurfaceClient对象因此接下来我们首先分析 SurfaceClient类的成员函数getTokenForSurface的实现接着再分析SharedBufferClient对象的创建过程。       从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一 文可以知道SurfaceClient类的成员函数getTokenForSurface实际上是调用了其成员变量mClient所指向的一个类型为 BpSurfaceComposerClient的Binder代理对象的成员函数getTokenForSurface来请求 SurfaceFlinger服务返回一个Surface的token值。由于这个Binder代理对象引用的是一个类型为UserClient的 Binder本地对象这个Binder本地对象是运行在SurfaceFlinger服务这一侧的。接下来我们就直接分析UserClient类的成 员函数getTokenForSurface的实现。       Step 17. UserClient.getTokenForSurface [cpp] view plaincopy ssize_t UserClient::getTokenForSurface(const spISurface sur) const  {      int32_t name  NAME_NOT_FOUND;      spLayer layer(mFlinger-getLayer(sur));      if (layer  0) return name;        // if this layer already has a token, just return it      name  layer-getToken();      if ((name  0)  (layer-getClient()  this))          return name;        name  0;      do {          int32_t mask  1LUname;          if ((android_atomic_or(mask, mBitmap)  mask)  0) {              // we found and locked that name              status_t err  layer-setToken(                      const_castUserClient*(this), ctrlblk, name);              if (err ! NO_ERROR) {                  // free the name                  android_atomic_and(~mask, mBitmap);                  name  err;              }              break;          }          if (name  SharedBufferStack::NUM_LAYERS_MAX)              name  NO_MEMORY;      } while(name  0);        //LOGD(getTokenForSurface(%p)  %d (client%p, bitmap%08lx),      //        sur-asBinder().get(), name, this, mBitmap);      return name;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。        从前面的调用过程可以知道参数sur指向了一个SurfaceLayer对象并且这个SurfaceLayer对象是在前面的Step 6中创建的。        UserClient类的成员变量mFlinger指向了SurfaceFlinger服务函数首先调用它的成员函数getLayer来获得参数sur 所指向的SurfaceLayer对象的宿主Layer对象layer接着调用这个Layer对象layer的成员函数getToken来获得它的 token值。如果这个token值大于等于0那么就说明已经为Layer对象layer分配过token值了即已经为参数sur所描述的 Surface分配过token值了。在这种情况下就直接将该token值返回给Android应用程序。否则的话UserClient类的成员函数 getTokenForSurface接下来就需要为参数sur所描述的Surface分配一个token值。        UserClient类的成员变量mBitmap是一个int32_t值它是用来为Android应用程序的Surface分配Token值的即 如果它的第n位等于1那么就表示值等于n的Token已经被分配出去使用了。UserClient类的成员函数getTokenForSurface使 用一个while循环来在成员变量mBitmap中从低位到高位找到一个值等于0的位接着再将位所在的位置值作为参数sur所描述的一个Surface 的token值最后还会将这个token值设置到Layer对象layer里面去这是通过调用Layer类的成员函数setToken来实现的。       接下来我们就继续分析Layer类的成员函数setToken的实现。       Step 18. Layer.setToken [cpp] view plaincopy status_t Layer::setToken(const spUserClient userClient,          SharedClient* sharedClient, int32_t token)  {      spSharedBufferServer lcblk  new SharedBufferServer(              sharedClient, token, mBufferManager.getDefaultBufferCount(),              getIdentity());        status_t err  mUserClientRef.setToken(userClient, lcblk, token);        LOGE_IF(err ! NO_ERROR,              ClientRef::setToken(%p, %p, %u) failed,              userClient.get(), lcblk.get(), token);        if (err  NO_ERROR) {          // we need to free the buffers associated with this surface      }        return err;  }          这个函数定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。        参数userClient指向了一个UserClient对象而参数sharedClient指向了该UserClient对象内部的成员变量ctrlblk所指向的一个SharedClient对象。从前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一文可以知道这个SharedClient对象是用来描述一组UI元数据缓冲区堆栈的。        Layer类的成员变量mBufferManager指向了一个BufferManager对象通过调用它的成员函数 getDefaultBufferCount就可以获得一个UI元数据缓冲区堆栈的大小即这个堆栈里面所包含的UI元数据缓冲区的个数。有了这些信息之 后Layer类的成员函数setToken就可以创建一个SharedBufferServer对象lcblk了并且会将这个 SharedBufferServer对象lcblk保存在Layer类的成员变量mUserClientRef所描述的一个ClientRef对象的内 部。这是通过调用ClientRef类的成员函数setToken来实现的如下所示 [cpp] view plaincopy status_t Layer::ClientRef::setToken(const spUserClient uc,          const spSharedBufferServer sharedClient, int32_t token) {      Mutex::Autolock _l(mLock);        { // scope for strong mUserClient reference          spUserClient userClient(mUserClient.promote());          if (mUserClient ! 0  mControlBlock ! 0) {              mControlBlock-setStatus(NO_INIT);          }      }        mUserClient  uc;      mToken  token;      mControlBlock  sharedClient;      return NO_ERROR;  }         这个函数同样是定义在文件frameworks/base/services/surfaceflinger/Layer.cpp中。       ClientRef类有三个成员变量mUserClient、mToken和mControlBlock。其中mUserClient是一个类型为 UserClient的弱指针它指向了参数uc所描述的一个UserClient对象mToken是一个int32_t值用来描述它的宿主 Layer对象的token值mControlBlock是一个类型为SharedBufferServer强指针它指向了参数 sharedCient所描述一个haredBufferServer对象用来在SurfaceFlinger服务这一侧描述一个UI元数据缓冲区堆 栈。      回到Layer类的成员函数setToken中接下来我们继续分析一个SharedBufferServer对象的创建过程。      Step 19. new SharedBufferServer [cpp] view plaincopy SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,          int surface, int num, int32_t identity)      : SharedBufferBase(sharedClient, surface, identity),        mNumBuffers(num)  {      mSharedStack-init(identity);      mSharedStack-token  surface;      mSharedStack-head  num-1;      mSharedStack-available  num;      mSharedStack-queued  0;      mSharedStack-reallocMask  0;      memset(mSharedStack-buffers, 0, sizeof(mSharedStack-buffers));      for (int i0 ; inum ; i) {          mBufferList.add(i);          mSharedStack-index[i]  i;      }  }          这个函数定义在文件frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp中。        SharedBufferServer类的构造函数主要是用来初始它所描述的一个UI元数据缓冲区堆栈的这个UI元数据缓冲区堆栈是通过其父类的成 员变量mSharedStack所指向的一个SharedBufferStack对象来描述的。SharedBufferStack类的各个成员变量的含 义可以参考前面前面Android应用程序与SurfaceFlinger服务之间的共享UI元数据SharedClient的创建过程分析一文这里不再复述。        这一步执行完成之后沿着调用路径一直返回到前面的Step 16中即Surface类的成员函数init中这时候Android应用程序就获得了正在创建的Surface的token值接下来就可以以这个 token值为参数来创建一个SharedBufferClient对象了。        Step 20. new SharedBufferClient [cpp] view plaincopy SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,          int surface, int num, int32_t identity)      : SharedBufferBase(sharedClient, surface, identity),        mNumBuffers(num), tail(0)  {      SharedBufferStack stack( *mSharedStack );      tail  computeTail();      queued_head  stack.head;  }          这个函数定义在文件frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp中。        SharedBufferClient类的构造函数主要是用来初始化成员变量tail和queued_head的值。这两个成员变量的含义可以参考前 面Android应用程序与SurfaceFlinger服务的关系概述和学习计划一文中的图6这里不再详述。        这里我们需要注意的是这里的参数sharedClient指向了一个SharedClient对象这个SharedClient对象与在前面Step 18中用来创建SharedBufferServer对象的SharedClient对象描述的是同一块匿名共享内存而且这里的参数surface与在 前面Step 18中用来创建SharedBufferServer对象的token的值是相等的这意味着这一步所创建的SharedBufferClient对象与 前面Step 19所创建的SharedBufferServer对象描述的是同一个SharedBufferStack对象即同一个UI元数据缓冲区堆栈并且这个 UI元数据缓冲区堆栈已经在前面的Step 19中初始化好了。        至此Android应用程序请求SurfaceFlinger服务创建Surface的过程就分析完成了。我们需要重点掌握的是当Android应用 程序请求SurfaceFlinger服务创建一个Surface的时候需要在SurfaceFlinger服务这一侧创建一个Layer对象、一个 Layer::SurfaceLayer对象和一个SharedBufferServer对象同时又需要在Android应用程序这一侧创建一个 SurfaceControl对象、一个Surface对象和一个SharedBufferClient对象。掌握了这些知识之后在接下来的一篇文章 中我们就可以分析Android应用程序请求SurfaceFlinger服务渲染Surface的过程了敬请期待 老罗的新浪微博http://weibo.com/shengyangluo欢迎关注 转载于:https://www.cnblogs.com/Free-Thinker/p/4142600.html
http://www.pierceye.com/news/577415/

相关文章:

  • 成交型网站做网站优化的价格
  • 后台网站设计烟台优化网站公司
  • 网站开发中涉及的侵权行为软件开发案例展示
  • 网站开发u盘128够吗网络服务器是指什么
  • 网站空间试用百度搜索引擎关键词优化
  • 中山品牌网站设计阿里云企业网站怎么建设
  • 做网站推广广告房地产行业网站开发
  • 济宁网站建设 企业谷wordpress手机 不适应
  • 如何用php做网站合肥专业手机网站哪家好
  • 如何推广自己的网站和产品如何用dw做网站地图
  • 株洲有名的网站重庆市公路建设信息网官网
  • 网站安全证书出错怎么做dw网页制作素材网站
  • 收录查询 站长工具给网站做解答是干嘛的
  • 成都哪些公司可以做网站建网站现软件
  • 深圳wap网站建设传奇霸主页游
  • 做网站首先要干什么营销软文200字
  • 帝国cms做的网站私人定制女装店
  • 网站建设南沙wordpress video
  • 网站建设开票应该开哪个行业什么网站可以免费做视频的软件
  • 百度seo查询收录查询网站推广策划案seo教程
  • 如何免费建立网站中贤建设集团网站
  • 如何做转运网站黄聪 wordpress
  • 临海市住房与城乡建设规划局网站宁波网络推广培训
  • go 网站开发自己在线制作logo
  • 重庆市网站建设公司企业服务账号
  • 网站建设的市场情况网站系统里不能打印
  • 网站如何适应屏幕做网站时无法上传图片
  • 网站的橱窗怎么做嘉兴住房和城乡建设厅网站
  • 吉林省城乡建设官方网站163企业邮箱登录入口官网
  • 做网站参考文献某企业网站建设方案2000字