随笔-118  评论-133  文章-4  trackbacks-0


出处:http://blog.csdn.net/myarrow/article/details/7180561


1. 简介      

        网上已经有很多兄弟对Android的显示系统做了深入解剖,很是佩服。可最近小弟在研究Android4.0时发现出入比较大,也许是Android4.0的修改比较多吧!因为小弟没有看Android4.0以前的代码。

       面对这么复杂一个Android显示系统,如何入手呢? 根据以前的经验,不管它有多么复杂,其功能不就是以下三步曲吗?

  1)显示系统的创建及初始化

       2)画图

       3)销毁

       哪我的分析就从显示系统的创建及初始化开始吧!由于小弟对Java没有什么研究兴趣,所有重点就分析Native部分。当然Native的入口就在android_view_Surface.cpp中,此文件主要包含以下两部分给Java层调用:

       1)gSurfaceSessionMethods: 操作SurfaceSession的方法

       2)gSurfaceMethods:操作Surface的方法

2. android_view_Surface.cpp

 

2.1 SurfaceSession操作方法

 

  1. static JNINativeMethod gSurfaceSessionMethods[] = {    
  2.     {"init",     "()V",  (void*)SurfaceSession_init }, //创建SurfaceComposerClient   
  3.     {"destroy",  "()V",  (void*)SurfaceSession_destroy }, //直接销毁SurfaceComposerClient   
  4.     {"kill",     "()V",  (void*)SurfaceSession_kill },//先clear,再销毁SurfaceComposerClient  
  5. };    



 2.1.1 SurfaceSession_init

        其功能如下:

        1)创建SurfaceComposerClient对象

        2)调用SurfaceComposerClient::onFirstRef方法

        现在已经进入到SurfaceComposerClient的地盘,根据其名字含义,它应该是一个进行Surface合成的客户端,通过它发命令给SurfaceFlinger来进行需要的操作。其初始化流程如下图所示:

2.1.2 SurfaceComposerClient.cpp中的宝贝

        为了方便后面的理解,先看看SurfaceComposerClient中有些什么宝贝来完成这个任务。在其中定义了如下几个类:

2.1.2.1 ComposerService(获取SurfaceFlinger服务)

        一看到名字为Service,应该是用于从SurfaceFlinger中获取Service以建立连接关系<它是一个单实例,一个进程有且只有一个实例对象>,然后供后面进行相关的操作。其构造函数代码如下:      

 

  1. class ComposerService : public Singleton<ComposerService>  
  2. {  
  3.     //实质为BpSurfaceComposer,通过它与SurfaceFlinger进行通信,  
  4.     //BnSurfaceComposer是SurfaceFlinger基类中的一个  
  5.     sp<ISurfaceComposer> mComposerService;  
  6.   
  7.     //实质为BpMemoryHeap,它在SurfaceFlinger中对应为管理一个4096字节的  
  8.     //一个MemoryHeapBase对象,在SurfaceFlinger::readyToRun中创建  
  9.     sp<IMemoryHeap> mServerCblkMemory;  
  10.       
  11.     //为MemoryHeapBase管理的内存在用户空间的基地址,通过mmap而来,  
  12.     //具体见MemoryHeapBase::mapfd  
  13.     surface_flinger_cblk_t volatile* mServerCblk;  
  14.     ComposerService();  
  15.     friend class Singleton<ComposerService>;  
  16. public:  
  17.     static sp<ISurfaceComposer> getComposerService();  
  18.     static surface_flinger_cblk_t const volatile * getControlBlock();  
  19. };  
  20.   
  21. ComposerService::ComposerService()  
  22. : Singleton<ComposerService>() {  
  23.     const String16 name("SurfaceFlinger");  
  24.     //获取SurfaceFlinger服务,即BpSurfaceComposer对象  
  25.     while (getService(name, &mComposerService) != NO_ERROR) {  
  26.         usleep(250000);  
  27.     }  
  28.     //获取共享内存块  
  29.     mServerCblkMemory = mComposerService->getCblk();  
  30.     //获取共享内存块基地址  
  31.     mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(  
  32.             mServerCblkMemory->getBase());  
  33. }  

      由此可见,ComposerService主要是获取SurfaceFlinger服务、获取在SurfaceFlinger::readyToRun中创建的共享内存块及其基地址。在Client中,谁要想与SurfaceFlinger通信,需要通过接口getComposerService来获取此BpSurfaceComposer

     此ComposerService是在调用ComposerService::getInstance时进行有且只有一个的实例化,因为前面讲过,它是一个单实例。

 

2.1.2.2 Composer

      它也是一个单实例,管理并发送每个layer的ComposerState。其定义如下:

 

  1. struct ComposerState {  
  2.     sp<ISurfaceComposerClient> client;  
  3.     layer_state_t state;  
  4.     status_t    write(Parcel& output) const;  
  5.     status_t    read(const Parcel& input);  
  6. };  
  7.   
  8. class Composer : public Singleton<Composer>  
  9. {  
  10.     friend class Singleton<Composer>;  
  11.   
  12.     mutable Mutex               mLock;  
  13.     //SurfaceComposerClient+SurfaceID与一个ComposerState一一对应  
  14.     SortedVector<ComposerState> mStates;       
  15.     int                         mOrientation;//整个屏幕的方向  
  16.     Composer() : Singleton<Composer>(),  
  17.         mOrientation(ISurfaceComposer::eOrientationUnchanged) { }  
  18.     //通过BpSurfaceComposer把mStates发送给SurfaceFlinger处理  
  19.     void closeGlobalTransactionImpl();  
  20.   
  21.     //根据client和id从mStates中获取对应原ComposerState,从而获取对应的layer_state_t  
  22.     layer_state_t* getLayerStateLocked(  
  23.             const sp<SurfaceComposerClient>& client, SurfaceID id);  
  24.   
  25. public:  
  26.     //设置与client和id对应的layer_state_t中的位置信息,并保存在mStates中  
  27.     status_t setPosition(const sp<SurfaceComposerClient>& client, SurfaceID id,  
  28.             float x, float y);  
  29.     //设置与client和id对应的layer_state_t中的Size信息,并保存在mStates中  
  30.     status_t setSize(const sp<SurfaceComposerClient>& client, SurfaceID id,  
  31.             uint32_t w, uint32_t h);  
  32.     //设置与client和id对应的layer_state_t中的z-order信息,并保存在mStates中  
  33.     status_t setLayer(const sp<SurfaceComposerClient>& client, SurfaceID id,  
  34.             int32_t z);  
  35.     //设置与client和id对应的layer_state_t中的flags信息,并保存在mStates中  
  36.     status_t setFlags(const sp<SurfaceComposerClient>& client, SurfaceID id,  
  37.             uint32_t flags, uint32_t mask);  
  38.     //设置与client和id对应的layer_state_t中的透明区域信息,并保存在mStates中  
  39.     status_t setTransparentRegionHint(  
  40.             const sp<SurfaceComposerClient>& client, SurfaceID id,  
  41.             const Region& transparentRegion);  
  42.     //设置与client和id对应的layer_state_t中的alpha信息,并保存在mStates中  
  43.     status_t setAlpha(const sp<SurfaceComposerClient>& client, SurfaceID id,  
  44.             float alpha);  
  45.     //设置与client和id对应的layer_state_t中的矩阵信息,并保存在mStates中  
  46.     status_t setMatrix(const sp<SurfaceComposerClient>& client, SurfaceID id,  
  47.             float dsdx, float dtdx, float dsdy, float dtdy);  
  48.     //设置与client和id对应的layer_state_t中的位置信息,并保存在mStates中  
  49.     status_t setFreezeTint(  
  50.             const sp<SurfaceComposerClient>& client, SurfaceID id,  
  51.             uint32_t tint);  
  52.     //设置整个屏幕的方向  
  53.     status_t setOrientation(int orientation);  
  54.     //通过BpSurfaceComposer把mStates发送给SurfaceFlinger处理  
  55.     static void closeGlobalTransaction() {  
  56.         Composer::getInstance().closeGlobalTransactionImpl();  
  57.     }  
  58. }  

      把上面的comments看完就明白了,Composer管理每个SurfaceComposerClient中的每一个Surface的状态,并记录在ComposerState的layer_state_t中,然后调用者可以调用其closeGlobalTransaction方法把这些mStates发送给SurfaceFlinger处理(处理函数为:SurfaceFlinger::setTransactionState)。

      谁来调用它的方法设置层的属性及发送mStates呢? -----答案是由SurfaceComposerClient来调用。

  2.1.2.3  SurfaceComposerClient

       前面介绍的两个类一个用于获取SurfaceFlinger服务;一个 用于记录每个Layer的状态,且可按要求把这些CoposerState发送给SurfaceFlinger。这个类是不是来使用前面两个类提供的服务 呢? --答案是肯定的。其定义及详细注释如下:

 

  1. #define NUM_DISPLAY_MAX 4  //最多支持四个显示屏  
  2. struct display_cblk_t //每个显示屏的配置参数  
  3. {  
  4.     uint16_t    w;  
  5.     uint16_t    h;  
  6.     uint8_t     format;  
  7.     uint8_t     orientation;  
  8.     uint8_t     reserved[2];  
  9.     float       fps;  
  10.     float       density;  
  11.     float       xdpi;  
  12.     float       ydpi;  
  13.     uint32_t    pad[2];  
  14. };  
  15. //在SurfaceFlinger::readyToRun中创建的共享控制块  
  16. struct surface_flinger_cblk_t   // 4KB max,管理系统中所有的显示屏  
  17. {  
  18.     uint8_t         connected; //每一个bit表示一个显示屏  
  19.     uint8_t         reserved[3];  
  20.     uint32_t        pad[7];  
  21.     display_cblk_t  displays[NUM_DISPLAY_MAX];  
  22. };  
  23.   
  24. class SurfaceComposerClient : public RefBase  
  25. {  
  26.     friend class Composer;  
  27. public:           
  28.     //获取Composer实例,并保存在mComposer中  
  29.                 SurfaceComposerClient();  
  30.     virtual     ~SurfaceComposerClient();  
  31.   
  32.     //通过BpSurfaceComposerClient<mClient>创建Surface,  
  33.     //同时通过ISurfaceComposerClient::surface_data_t返回SurfaceID.然后创建一个SurfaceControl  
  34.     //并把返回的BpSurface和当前的SurfaceComposerClient保存在SurfaceControl中,  
  35.     //然后返回此SurfaceControl  
  36.     sp<SurfaceControl> createSurface(  
  37.             const String8& name,// name of the surface  
  38.             DisplayID display,  // Display to create this surface on  
  39.             uint32_t w,         // width in pixel  
  40.             uint32_t h,         // height in pixel  
  41.             PixelFormat format, // pixel-format desired  
  42.             uint32_t flags = 0  // usage flags  
  43.     );  
  44.   
  45.   
  46.     // Composer parameters <合成参数>  
  47.     //所有的合成参数必须在一个transaction中被修改,多个surface可在一个transaction中被更新,  
  48.     //所有的变化在关闭transaction时被一次性提交(通过调用closeGlobalTransaction来提交所有变化)。  
  49.   
  50.     //什么都没有做  
  51.     static void openGlobalTransaction();  
  52.           
  53.     //通过调用Composer::closeGlobalTransaction(),  
  54.     // 把Composer中记录的ComposerState(即mStates)发送给SurfaceFlinger  
  55.     static void closeGlobalTransaction();  
  56.       
  57.     //什么都没做  
  58.     static status_t freezeDisplay(DisplayID dpy, uint32_t flags = 0);  
  59.           
  60.     //什么都没做  
  61.     static status_t unfreezeDisplay(DisplayID dpy, uint32_t flags = 0);  
  62.   
  63.     //把新的显示方向保存在Composer实例中  
  64.     static int setOrientation(DisplayID dpy, int orientation, uint32_t flags);  
  65.   
  66.     //从surface_flinger_cblk_t.connected中获取显示屏个数  
  67.     static ssize_t getNumberOfDisplays();  
  68.   
  69.     //获取显示屏的信息  
  70.     static status_t getDisplayInfo(DisplayID dpy, DisplayInfo* info);  
  71.     static ssize_t getDisplayWidth(DisplayID dpy);  
  72.     static ssize_t getDisplayHeight(DisplayID dpy);  
  73.     static ssize_t getDisplayOrientation(DisplayID dpy);  
  74.       
  75.     //通过注册,当Binder异常退出时,可以获得通知  
  76.     status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,  
  77.             void* cookie = NULL, uint32_t flags = 0);  
  78.   
  79.     //Start####: 以下函数都是把相应的修改状态记录在Composer的mStates中  
  80.     //调用Composer::setFlags来设置对应(client+id)的layer状态〈即ComposerState中的layer_state_t〉  
  81.     status_t    hide(SurfaceID id);  
  82.     status_t    show(SurfaceID id, int32_t layer = -1);  
  83.     status_t    freeze(SurfaceID id);  
  84.     status_t    unfreeze(SurfaceID id);  
  85.     status_t    setFlags(SurfaceID id, uint32_t flags, uint32_t mask);  
  86.     //调用Composer::setTransparentRegionHint  
  87.     status_t    setTransparentRegionHint(SurfaceID id, const Region& transparent);  
  88.     //调用Composer::setLayer  
  89.     status_t    setLayer(SurfaceID id, int32_t layer);  
  90.     //调用Composer::setAlpha  
  91.     status_t    setAlpha(SurfaceID id, float alpha=1.0f);  
  92.     //调用Composer::setFreezeTint  
  93.     status_t    setFreezeTint(SurfaceID id, uint32_t tint);  
  94.     //调用Composer::setMatrix  
  95.     status_t    setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);  
  96.     //调用Composer::setPosition  
  97.     status_t    setPosition(SurfaceID id, float x, float y);  
  98.     //调用Composer::setSize  
  99.     status_t    setSize(SurfaceID id, uint32_t w, uint32_t h);  
  100.     //End####:  
  101.     status_t    destroySurface(SurfaceID sid);//通过BpSurfaceComposerClient销毁Surface  
  102.   
  103. private:  
  104.     //通过BpSurfaceComposer从SurfaceFlinger获取BpSurfaceComposerClient,  
  105.     //并把它保存在mClient中  
  106.     virtual void onFirstRef();  
  107.     Composer& getComposer();  
  108.   
  109.     mutable     Mutex                       mLock;  
  110.                 status_t                    mStatus;  
  111.                 //实质为BpSurfaceComposerClient,与SurfaceFlinger.cpp中的Client相对应   
  112.                   sp<ISurfaceComposerClient>  mClient;   
  113.                 //Composer实例  
  114.                   Composer&                   mComposer;  
  115. }  

    其功能列表如下:

     1)获取BpSurfaceComposerClient(即mClient),在onFirstRef中实现

     2)通过BpSurfaceComposerClient(即mClient)创建和销毁Surface

     3)通过Composer来记录Surface和显示屏状态变化,及在Composer中通过BpSurfaceComposer把状态变化发给SurfaceFlinger处理

     至此,SurfaceComposerClient功能已经分析清楚。可是从这三个类中,我们已经看到三个 Bp(BpSurfaceComposer,BpSurfaceComposerClient和BpSurface)及三个对应的接口。下面总结一下,每 个接口的功能,在客户端由谁使用,在服务器端谁来实现。

 2.1.2.4 Surface相关接口总结

     

 

 2.2 Surface操作

其相关接口如下:

  1. static JNINativeMethod gSurfaceMethods[] = {  
  2.     {"nativeClassInit",     "()V",  (void*)nativeClassInit },  
  3.     {"init",                "(Landroid/view/SurfaceSession;ILjava/lang/String;IIIII)V",  (void*)Surface_init },  
  4.     {"init",                "(Landroid/os/Parcel;)V",  (void*)Surface_initParcel },  
  5.     {"initFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)V", (void*)Surface_initFromSurfaceTexture },  
  6.     {"getIdentity",         "()I",  (void*)Surface_getIdentity },  
  7.     {"destroy",             "()V",  (void*)Surface_destroy },  
  8.     {"release",             "()V",  (void*)Surface_release },  
  9.     {"copyFrom",            "(Landroid/view/Surface;)V",  (void*)Surface_copyFrom },  
  10.     {"isValid",             "()Z",  (void*)Surface_isValid },  
  11.     {"lockCanvasNative",    "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",  (void*)Surface_lockCanvas },  
  12.     {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost },  
  13.     {"unlockCanvas",        "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas },  
  14.     {"openTransaction",     "()V",  (void*)Surface_openTransaction },  
  15.     {"closeTransaction",    "()V",  (void*)Surface_closeTransaction },  
  16.     {"setOrientation",      "(III)V", (void*)Surface_setOrientation },  
  17.     {"freezeDisplay",       "(I)V", (void*)Surface_freezeDisplay },  
  18.     {"unfreezeDisplay",     "(I)V", (void*)Surface_unfreezeDisplay },  
  19.     {"screenshot",          "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll },  
  20.     {"screenshot",          "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },  
  21.     {"setLayer",            "(I)V", (void*)Surface_setLayer },  
  22.     {"setPosition",         "(FF)V",(void*)Surface_setPosition },  
  23.     {"setSize",             "(II)V",(void*)Surface_setSize },  
  24.     {"hide",                "()V",  (void*)Surface_hide },  
  25.     {"show",                "()V",  (void*)Surface_show },  
  26.     {"freeze",              "()V",  (void*)Surface_freeze },  
  27.     {"unfreeze",            "()V",  (void*)Surface_unfreeze },  
  28.     {"setFlags",            "(II)V",(void*)Surface_setFlags },  
  29.     {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion },  
  30.     {"setAlpha",            "(F)V", (void*)Surface_setAlpha },  
  31.     {"setMatrix",           "(FFFF)V",  (void*)Surface_setMatrix },  
  32.     {"setFreezeTint",       "(I)V",  (void*)Surface_setFreezeTint },  
  33.     {"readFromParcel",      "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel },  
  34.     {"writeToParcel",       "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel },  
  35. };  


2.2.1 Surface_init调用流程

     在SurfaceFlinger端创建BSurface,在客户端返回SurfaceControl,同时在SurfaceControl中拥有了BpSurface用于与BSurface交互。

 

2.2.1.1 调用流程分析

     BpSurfaceComposerClient->createSurface返回BpSurface。且通过参数返回ISurfaceComposerClient::surface_data_t,其定义如下:

     其中token在SurfaceComposerClient的函数参数中,对应于SurfaceID。即在客户端,它就是SurfaceID。

     token: 加入到Client::mLayers中的序号,在Client中单调递增,初始值为:1,一个Layer创建一个BSurface

     identity: LayerBaseClient中的mIdentity,在所有的Layer中单调递增,初始值为:1

  1. struct surface_data_t {  
  2.     int32_t             token;  //加入到Client::mLayers中的序号,在Client中单调递增,初始值为:1  
  3.     int32_t             identity; //LayerBaseClient中的mIdentity,在所有的Layer中单调递增,初始值为:1  
  4.     status_t readFromParcel(const Parcel& parcel);  
  5.     status_t writeToParcel(Parcel* parcel) const;  
  6. };  
2.2.1.2 创建真正的Surface

      在Layer::createSurface中创建真正的BSurface,在SurfaceFlinger::createSurface中调用layer->getSurface时创建的。此BSurface定义如下:

  1. sp<ISurface> Layer::createSurface()  
  2. {  
  3.     class BSurface : public BnSurface, public LayerCleaner {  
  4.         wp<const Layer> mOwner;  
  5.         virtual sp<ISurfaceTexture> getSurfaceTexture() const { //实现了ISurface的接口  
  6.             sp<ISurfaceTexture> res;  
  7.             sp<const Layer> that( mOwner.promote() );  
  8.             if (that != NULL) {  
  9.                 res = that->mSurfaceTexture;  
  10.             }  
  11.             return res;  
  12.         }  
  13.     public:  
  14.         BSurface(const sp<SurfaceFlinger>& flinger,  
  15.                 const sp<Layer>& layer)  
  16.             : LayerCleaner(flinger, layer), mOwner(layer) { }  
  17.     };  
  18.     sp<ISurface> sur(new BSurface(mFlinger, this));  
  19.     return sur;  
  20. }  

         在此BSurface中实现了ISurface的接口getSurfaceTexture,在此接口中返回 Layer::mSurfaceTexture(类型为:SurfaceTextureLayer,它才是真正操作内存的东东),此成员在 Layer::onFirstRef中创建,SurfaceTextureLayer是SurfaceTexture的派生类,代码如下:

  1. void Layer::onFirstRef()  
  2. {  
  3.     LayerBaseClient::onFirstRef();  
  4.   
  5.     struct FrameQueuedListener : public SurfaceTexture::FrameAvailableListener {  
  6.         FrameQueuedListener(Layer* layer) : mLayer(layer) { }  
  7.     private:  
  8.         wp<Layer> mLayer;  
  9.         virtual void onFrameAvailable() {  
  10.             sp<Layer> that(mLayer.promote());  
  11.             if (that != 0) {  
  12.                 that->onFrameQueued();  
  13.             }  
  14.         }  
  15.     };  
  16.     mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this); //创建Layer中的mSurfaceTexture  
  17.     mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));  
  18.     mSurfaceTexture->setSynchronousMode(true);  
  19.     mSurfaceTexture->setBufferCountServer(2);  
  20. }  

2.2.1.3 不得不说的SurfaceControl

       本来Surface_init调用SurfaceComposerClient::createSurface创建一个Surface,可却返回了一个SurfaceControl,下面看看SurfaceCotrol到底做了些什么,以及如何做的?

        相关数据结构如下图所示:

 

 SurfaceControl定义如下:

 

  1. class SurfaceControl : public RefBase  
  2. {  
  3. public:  
  4.     // release surface data from java  
  5.     void        clear();  
  6.       
  7.     //调用SurfaceComposerClient中对应方法,把对应信息保存在  
  8.     //Composer的ComposerState中      
  9.     status_t    setLayer(int32_t layer);  
  10.     status_t    setPosition(int32_t x, int32_t y);  
  11.     status_t    setSize(uint32_t w, uint32_t h);  
  12.     status_t    hide();  
  13.     status_t    show(int32_t layer = -1);  
  14.     status_t    freeze();  
  15.     status_t    unfreeze();  
  16.     status_t    setFlags(uint32_t flags, uint32_t mask);  
  17.     status_t    setTransparentRegionHint(const Region& transparent);  
  18.     status_t    setAlpha(float alpha=1.0f);  
  19.     status_t    setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);  
  20.     status_t    setFreezeTint(uint32_t tint);  
  21.       
  22.     //把SurfaceControl中的mSurface和mIdentity写入parcel  
  23.     static status_t writeSurfaceToParcel(  
  24.             const sp<SurfaceControl>& control, Parcel* parcel);  
  25.       
  26.     //以SurfaceControl为参数创建一个Surface返回,此Surface派生关系如下:  
  27.     //class Surface : public SurfaceTextureClient  
  28.     //class SurfaceTextureClient: public ANativeWindow, RefBase  
  29.     //struct ANativeWindow  
  30.     sp<Surface> getSurface() const;  
  31.   
  32. private:  
  33.     SurfaceControl(  
  34.             const sp<SurfaceComposerClient>& client,  
  35.             const sp<ISurface>& surface,  
  36.             const ISurfaceComposerClient::surface_data_t& data);  
  37.   
  38.     ~SurfaceControl();  
  39.   
  40.     void destroy();  
  41.       
  42.     sp<SurfaceComposerClient>   mClient;  
  43.     sp<ISurface>                mSurface;  
  44.     SurfaceID                   mToken;  //对应SurfaceID,在Client中单调递增  
  45.     uint32_t                    mIdentity;  //Layer在系统中唯一的序列号,在系统中单调递增  
  46.     mutable Mutex               mLock;  
  47.       
  48.     mutable sp<Surface>         mSurfaceData;  
  49. }  


       从其定义中可以看出,在getSurface中将有新花样,其它操作函数都是直接以mToken作为SurfaceID,直接调用 SurfaceComposerClient中对应方法。 经过这样一分析,SurfaceControl也没什么神秘的了。但它的getSurface 到有点神秘。

 

 2.2.2 getSurface流程

      getSurface在客户端返回Surface(派生于SurfaceTextureClient),并在Surface的mSurfaceTexture域中保存了BpSurfaceTexture。

      前面Surface初始化之后,就可以getSurface了。getSurface流程如下图所示:

           有了Surface,且在Surface中又有了BpSurfaceTexture,下一步就操作GraphicBuffer了。

 

 3. 画图流程

对于画图流程,可以从ViewRootImpl(ViewRootImpl.java)的draw函数看起,在画图之间,它要调用java层的surface.lockCanvas,画完图之后调用surface.unlockCanvasAndPost来提交显示。

surface.lockCanvas->

lockCanvasNative(Java)->

(C++)Surface_lockCanvas<android_view_Surface.cpp>

surface.unlockCanvasAndPost(Java)->

(C++)Surface_unlockCanvasAndPost<android_view_Surface.cpp>

本章主要分析这两个函数到底做了些什么>

 3.1 Surface_lockCanvas

       Android图形系统中一个重要的概念是surface。View及其子类(如TextView, Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理view在surface上的绘图操 作,如画点画线。每个canvas对象对应一个bitmap,存储画在surface上的内容。

3.1.1 相关数据结构定义

 3.1.1.1 ANativeWindow_Buffer
  1. typedef struct ANativeWindow_Buffer {  
  2.     // The number of pixels that are show horizontally.  
  3.     int32_t width;  
  4.   
  5.     // The number of pixels that are shown vertically.  
  6.     int32_t height;  
  7.   
  8.     // The number of *pixels* that a line in the buffer takes in  
  9.     // memory.  This may be >= width.  
  10.     int32_t stride;  
  11.   
  12.     // The format of the buffer.  One of WINDOW_FORMAT_*  
  13.     int32_t format;  
  14.   
  15.     // The actual bits.  
  16.     void* bits;  //显示内存基地址,通过服务器端fd通过flat_binder_object传给客户端, 然后客户端通过mmap获取。  
  17.       
  18.     // Do not touch.  
  19.     uint32_t reserved[6];  
  20. } ANativeWindow_Buffer;  
3.1.1.2 SurfaceInfo
  1. struct SurfaceInfo {  
  2.     uint32_t    w;  
  3.     uint32_t    h;  
  4.     uint32_t    s;  
  5.     uint32_t    usage;  
  6.     PixelFormat format;  
  7.     void*       bits;//显示内存基地址,通过服务器端fd通过flat_binder_object传给客户端, 然后客户端通过mmap获取。  
  8.     uint32_t    reserved[2];  
  9. };  

3.1.1.3 二者对应关系
  1. SurfaceInfo* other;  
  2. ANativeWindow_Buffer outBuffer;  
  3. other->w = uint32_t(outBuffer.width);  
  4. other->h = uint32_t(outBuffer.height);  
  5. other->s = uint32_t(outBuffer.stride);  
  6. other->usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN;  
  7. other->format = uint32_t(outBuffer.format);  
  8. other->bits = outBuffer.bits;  

 3.1.1.4 GraphicBuffer

     在分析下面的流程时, 不得不对GraphicBuffer进行深入了解,特别是其Flattenable interface,这是实现画图buffer的关键。其相关定义如下:

  1. typedef struct native_handle  
  2. {  
  3.     int version;        /* sizeof(native_handle_t) */  
  4.     int numFds;         /* number of file-descriptors at &data[0] */  
  5.     int numInts;        /* number of ints at &data[numFds] */  
  6.     int data[0];        /* numFds + numInts ints */  
  7. } native_handle_t;  
  8.   
  9. typedef const native_handle_t* buffer_handle_t;  
  10.   
  11. class GraphicBuffer  
  12.     : public EGLNativeBase<  
  13.         ANativeWindowBuffer,  
  14.         GraphicBuffer,   
  15.         LightRefBase<GraphicBuffer> >, public Flattenable  
  16. {  
  17.     ...  
  18.     // Flattenable interface  
  19.     size_t getFlattenedSize() const;  
  20.     size_t getFdCount() const;  
  21.     status_t flatten(void* buffer, size_t size,  
  22.             int fds[], size_t count) const;  
  23.     status_t unflatten(void const* buffer, size_t size,  
  24.             int fds[], size_t count);  
  25.     ...  
  26.     buffer_handle_t handle; //定义于基类ANativeWindowBuffer中  
  27. };  
3.1.1.5 Flattenable interface

下面看看每个Flattenable interface是如何实现的:

3.1.1.5.1 getFlattenedSize
  1. size_t GraphicBuffer::getFlattenedSize() const {  
  2.     return (8 + (handle ? handle->numInts : 0))*sizeof(int);  
  3. }  
3.1.1.5.2 getFdCount
  1. size_t GraphicBuffer::getFdCount() const {  
  2.     return handle ? handle->numFds : 0;  
  3. }  
3.1.1.5.3 flatten
  1. status_t GraphicBuffer::flatten(void* buffer, size_t size,  
  2.         int fds[], size_t count) const  
  3. {  
  4.     size_t sizeNeeded = GraphicBuffer::getFlattenedSize();  
  5.     if (size < sizeNeeded) return NO_MEMORY;  
  6.   
  7.     size_t fdCountNeeded = GraphicBuffer::getFdCount();  
  8.     if (count < fdCountNeeded) return NO_MEMORY;  
  9.   
  10.     int* buf = static_cast<int*>(buffer);  
  11.     buf[0] = 'GBFR';  
  12.     buf[1] = width;  
  13.     buf[2] = height;  
  14.     buf[3] = stride;  
  15.     buf[4] = format;  
  16.     buf[5] = usage;  
  17.     buf[6] = 0;  
  18.     buf[7] = 0;  
  19.   
  20.     if (handle) {  
  21.         buf[6] = handle->numFds;  
  22.         buf[7] = handle->numInts;  
  23.         native_handle_t const* const h = handle;  
  24.         memcpy(fds,     h->data,             h->numFds*sizeof(int));  
  25.         memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));  
  26.     }  
  27.   
  28.     return NO_ERROR;  
  29. }  


     把handle中的numFds拷贝到fds中,把handle中的numInts拷贝到buffer中。

 3.1.1.5.4 unflatten 
  1. status_t GraphicBuffer::unflatten(void const* buffer, size_t size,  
  2.         int fds[], size_t count)  
  3. {  
  4.     if (size < 8*sizeof(int)) return NO_MEMORY;  
  5.   
  6.     int const* buf = static_cast<int const*>(buffer);  
  7.     if (buf[0] != 'GBFR') return BAD_TYPE;  
  8.   
  9.     const size_t numFds  = buf[6];  
  10.     const size_t numInts = buf[7];  
  11.   
  12.     const size_t sizeNeeded = (8 + numInts) * sizeof(int);  
  13.     if (size < sizeNeeded) return NO_MEMORY;  
  14.   
  15.     size_t fdCountNeeded = 0;  
  16.     if (count < fdCountNeeded) return NO_MEMORY;  
  17.   
  18.     if (handle) {  
  19.         // free previous handle if any  
  20.         free_handle();  
  21.     }  
  22.   
  23.     if (numFds || numInts) {  
  24.         width  = buf[1];  
  25.         height = buf[2];  
  26.         stride = buf[3];  
  27.         format = buf[4];  
  28.         usage  = buf[5];  
  29.         native_handle* h = native_handle_create(numFds, numInts);  
  30.         memcpy(h->data,          fds,     numFds*sizeof(int));  
  31.         memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));  
  32.         handle = h;  
  33.     } else {  
  34.         width = height = stride = format = usage = 0;  
  35.         handle = NULL;  
  36.     }  
  37.   
  38.     mOwner = ownHandle;  
  39.   
  40.     if (handle != 0) {  
  41.         mBufferMapper.registerBuffer(handle);  
  42.     }  
  43.   
  44.     return NO_ERROR;  
  45. }  

       把width,height,stride,format和usage保存到成员变量中,并创建一个native_handle,然后把numFds和 numInts拷贝到handle的data中。同时把此handle注册到mBufferMapper中,mBufferMapper的注册函数实现代码如下:

  1. status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)  
  2. {  
  3.     status_t err;  
  4.     //gralloc_module_t const *mAllocMod;是一个硬件抽象层实现。通过hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)方式获取  
  5.     err = mAllocMod->registerBuffer(mAllocMod, handle);  
  6.   
  7.     LOGW_IF(err, "registerBuffer(%p) failed %d (%s)",  
  8.             handle, err, strerror(-err));  
  9.     return err;  
  10. }  

 

  1. GraphicBufferMapper::GraphicBufferMapper()  
  2.     : mAllocMod(0)  
  3. {  
  4.     hw_module_t const* module;  
  5.     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);  
  6.     LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);  
  7.     if (err == 0) {  
  8.         mAllocMod = (gralloc_module_t const *)module;  
  9.     }  
  10. }  
 3.1.1.5.4  GRALLOC_HARDWARE_MODULE_ID实例

      对于GRALLOC_HARDWARE_MODULE_ID,以hardware/msm7k/libgralloc/gralloc.cpp为例进行分 析。其registerBuffer实现函数:gralloc_register_buffer(hardware/msm7k/libgralloc /mapper.cpp),其相关代码如下:

  1. int gralloc_register_buffer(gralloc_module_t const* module,  
  2.         buffer_handle_t handle)  
  3. {  
  4.     if (private_handle_t::validate(handle) < 0)  
  5.         return -EINVAL;  
  6.   
  7.     // if this handle was created in this process, then we keep it as is.  
  8.     int err = 0;  
  9.     private_handle_t* hnd = (private_handle_t*)handle;  
  10.     if (hnd->pid != getpid()) {  
  11.         hnd->base = NULL;  
  12.         if (!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_GPU)) {  
  13.             void *vaddr;  
  14.             err = gralloc_map(module, handle, &vaddr);  
  15.         }  
  16.     }  
  17.     return err;  
  18. }  
  19.   
  20. static int gralloc_map(gralloc_module_t const* module,  
  21.         buffer_handle_t handle,  
  22.         void** vaddr)  
  23. {  
  24.     private_handle_t* hnd = (private_handle_t*)handle;  
  25.     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {  
  26.         size_t size = hnd->size;  
  27. #if PMEM_HACK  
  28.         size += hnd->offset;  
  29. #endif  
  30.         void* mappedAddress = mmap(0, size,  
  31.                 PROT_READ|PROT_WRITE, MAP_SHARED, hnd->fd, 0);  
  32.         if (mappedAddress == MAP_FAILED) {  
  33.             LOGE("Could not mmap handle %p, fd=%d (%s)",  
  34.                     handle, hnd->fd, strerror(errno));  
  35.             hnd->base = 0;  
  36.             return -errno;  
  37.         }  
  38.         hnd->base = intptr_t(mappedAddress) + hnd->offset;  
  39.         //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",   
  40.         //        hnd->fd, hnd->offset, hnd->size, mappedAddress);  
  41.     }  
  42.     *vaddr = (void*)hnd->base;  
  43.     return 0;  
  44. }  

    从gralloc_map可以看出,这个registerBuffer主要做了一件事:

    1)根据handle中传过来的fd和size进行mmap映射(把kernel中的内存映射到用户空间),映射之后的地址再加上hnd->offset便获得hnd->base供后面使用。

      从这里可以初步看出,这个图形buffer数据并不是真正的从client传递到server,而是在lock是从server把fd传递给client,由客户端进行mmap,然后进行使用。关于这个是怎么实现的,后面将详细分析其实现过程。

    对于如何从native_handle转换为private_handle_t,且在private_handle_t中可以获取fd和offset? 看一下其数据结构和flatten的实现方式就可以得知:
native_handle:

  1. typedef struct native_handle  
  2. {  
  3.     int version;        /* sizeof(native_handle_t) */  
  4.     int numFds;         /* number of file-descriptors at &data[0] */  
  5.     int numInts;        /* number of ints at &data[numFds] */  
  6.     int data[0];        /* numFds + numInts ints */  
  7. } native_handle_t;  

     这个data[0]是关键,虽然分配了哪么多buffer,但实质上native_handle只占了3个int.其它的数据由包含它的数据结构来解析。

private_handle_t:

  1. struct private_handle_t {  
  2.     native_handle_t nativeHandle;  
  3. #endif  
  4.       
  5.     enum {  
  6.         PRIV_FLAGS_FRAMEBUFFER = 0x00000001,  
  7.         PRIV_FLAGS_USES_PMEM   = 0x00000002,  
  8.         PRIV_FLAGS_USES_GPU    = 0x00000004,  
  9.     };  
  10.   
  11.     // file-descriptors  
  12.     int     fd;  
  13.     // ints  
  14.     int     magic;  
  15.     int     flags;  
  16.     int     size;  
  17.     int     offset;  
  18.     int     gpu_fd; // stored as an int, b/c we don't want it marshalled  
  19.   
  20.     // FIXME: the attributes below should be out-of-line  
  21.     int     base;  
  22.     int     map_offset;  
  23.     int     pid;  
  24.   
  25. #ifdef __cplusplus  
  26.     static const int sNumInts = 8;  //numInts在这儿明确指定  
  27.     static const int sNumFds = 1;   //numFds在这儿明确指定  
  28.     static const int sMagic = 'gmsm';  
  29.   
  30.     private_handle_t(int fd, int size, int flags) :  
  31.         fd(fd), magic(sMagic), flags(flags), size(size), offset(0),  
  32.         base(0), pid(getpid())  
  33.     {  
  34.         version = sizeof(native_handle);  
  35.         numInts = sNumInts;  
  36.         numFds = sNumFds;  
  37.     }  
  38.     ~private_handle_t() {  
  39.         magic = 0;  
  40.     }  
  41.   
  42.     static int validate(const native_handle* h) {  
  43.         const private_handle_t* hnd = (const private_handle_t*)h;  
  44.         if (!h || h->version != sizeof(native_handle) ||  
  45.                 h->numInts != sNumInts || h->numFds != sNumFds ||  
  46.                 hnd->magic != sMagic)   
  47.         {  
  48.             LOGE("invalid gralloc handle (at %p)", h);  
  49.             return -EINVAL;  
  50.         }  
  51.         return 0;  
  52.     }  
  53. #endif  
  54. }  

3.1.2 Surface_lockCanvas执行流程

查看高清大图


3.1.3 Surface_lockCanvas总结 

功能:Surface_lockCanvas获取显示buffer在本进程用户空间的地址,并据此创建一个SkBitmap给Java使用。
关键技术:BINDER_TYPE_FD类型的Binder、mmap、gralloc硬件抽象层

 

3.1.4 SurfaceTexture::dequeueBuffer如何创建GraphicBuffer

       相关代码如下:

  1. const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);  
  2. if ((buffer == NULL) ||  
  3.     (uint32_t(buffer->width)  != w) ||  
  4.     (uint32_t(buffer->height) != h) ||  
  5.     (uint32_t(buffer->format) != format) ||  
  6.     ((uint32_t(buffer->usage) & usage) != usage))  
  7. {  
  8.     usage |= GraphicBuffer::USAGE_HW_TEXTURE;  
  9.     status_t error;  
  10.     sp<GraphicBuffer> graphicBuffer( //创建GraphicBuffer  
  11.             mGraphicBufferAlloc->createGraphicBuffer(  
  12.                     w, h, format, usage, &error));  
  13.     if (graphicBuffer == 0) {  
  14.         ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer "  
  15.                 "failed");  
  16.         return error;  
  17.     }  
  18.     if (updateFormat) {  
  19.         mPixelFormat = format;  
  20.     }  
  21.     mSlots[buf].mGraphicBuffer = graphicBuffer;  
  22.     mSlots[buf].mRequestBufferCalled = false;  
  23.     if (mSlots[buf].mEglImage != EGL_NO_IMAGE_KHR) {  
  24.         eglDestroyImageKHR(mSlots[buf].mEglDisplay, mSlots[buf].mEglImage);  
  25.         mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;  
  26.         mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;  
  27.     }  
  28.     returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;  
  29. }  


     mGraphicBufferAlloc也是通过调用BpSurfaceComposer->createGraphicBufferAlloc而获取,它对应的服务器为SufaceFlinger中的GraphicBufferAlloc。

     mGraphicBufferAlloc实质为一个BpGraphicBufferAlloc,它真正创建GraphicBuffer的代码位于GraphicBufferAlloc::createGraphicBuffer中。代码关键调用流程如下:

     new GraphicBuffer(w, h, format, usage)->

       initSize(w, h, reqFormat, reqUsage)->

         GraphicBufferAllocator::get()->

            allocator.alloc(w, h, format, reqUsage, &handle, &stride)->

            返回handle,此handle为ANativeWindowBuffer成员,类型为native_handle。

              GraphicBufferAllocator::alloc->

                mAllocDev->alloc->

                 mAllocDev类型为alloc_device_t,它通过gralloc_open向

                 GRALLOC_HARDWARE_MODULE_ID获取,根据上面的实例msm7k,

                 它最终执行gralloc_device_open而获取gralloc_context_t.device.common,

                  alloc的实现函数为gralloc_alloc.

                   gralloc_alloc->

                    gralloc_alloc_buffer->

                     1)获取GPU内存(调用SimpleBestFitAllocator::allocate进行分配)

                     2)fd = open("/dev/null", O_RDONLY)获取fd

                     3)根据fd、size和flags创建private_handle_t,其相关代码如下:

 

  1. private_handle_t* hnd = new private_handle_t(fd, size, flags);  
  2. if (base == NULL) {...  
  3.     }  
  4. else {  
  5.     private_module_t* m = reinterpret_cast<private_module_t*>(  
  6.             dev->common.module);  
  7.     hnd->offset = offset;  
  8.     hnd->base = int(base)+offset;  
  9.     hnd->gpu_fd = gpu_fd;  
  10.     hnd->map_offset = m->fb_map_offset;  
  11.     *pHandle = hnd;  
  12. }  


3.2 Surface_unlockCanvasAndPost

 

 

 

 

 

 

 

 

 

 

posted on 2013-09-18 11:31 lfc 阅读(2027) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。