<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                原文出處——>[Android應用程序請求SurfaceFlinger服務創建Surface的過程分析](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所示。 ![](https://box.kancloud.cn/c45184496229e560dca49c158ae88e7a_603x422.jpg) 圖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所示。 ![](https://box.kancloud.cn/30a78457cc527b5f94b7600d9020211c_554x581.jpg) 圖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,如下所示: ~~~ 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 buffer's parameters are * set to those specified. */ virtual sp<GraphicBuffer> 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所示。 ![](https://box.kancloud.cn/87976ec6df4692f5dcdcb53f0c9825be_680x463.jpg) 圖3 BpSurface類的實現 理解這個圖同樣需要了解Android系統的Binder進程間通信機制,具體可以參考Android進程間通信(IPC)機制Binder簡要介紹和學習計劃一文。 以上都是從SurfaceFlinger服務這一側來理解一個Surface,下面我們再從Android應用程序這一側來理解一個Surface。 在Android應用程序這一側,每一個繪圖表面都使用一個Surface對象來描述,每一個Surface對象都是由一個SurfaceControl對象來創建的。Surface類和SurfaceControl類的關系以及實現如圖4所示。 ![](https://box.kancloud.cn/f37ca0bded2c322397e01b692246b424_763x484.jpg) 圖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所示。 ![](https://box.kancloud.cn/48fc35c38a40990db5b1c6d7f1518671_674x583.jpg) 圖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數組surfaces,SharedBufferServer類的成員變量mSharedStack所指向的SharedBufferStack對象,正是成員變量mSharedClient所指向的一個SharedClient對象內部的一個SharedBufferStack數組的一個元素,這一點可以從SharedBufferServer類的構造函數實現來看出。 SharedBufferServer類的構造函數frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp文件中,如下所示: ~~~ 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,如下所示。 ![](https://box.kancloud.cn/6604bff992da8b1eab46f7783cee360d_660x403.jpg) 圖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,如下所示。 ![](https://box.kancloud.cn/19d2903159bbeefb5fb191324b0adffe_657x381.jpg) 圖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文件中,如下所示: ~~~ class SharedBufferServer : public SharedBufferBase, public LightRefBase<SharedBufferServer> { ...... 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的,如下所示: ~~~ status_t BootAnimation::readyToRun() { ...... // create the native surface sp<SurfaceControl> control = session()->createSurface( getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565); ...... sp<Surface> 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所示。 ![](https://box.kancloud.cn/9701b0493984955c7809481267191286_820x1024.jpg) 圖8 Android應用程序請求SurfaceFlinger服務創建Surface的過程 這個過程可以劃分為20個步驟,接下來我們就詳細分析每一個步驟。 Step 1. SurfaceComposerClient.createSurface ~~~ sp<SurfaceControl> 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,如下所示: ~~~ sp<SurfaceControl> SurfaceComposerClient::createSurface( int pid, const String8& name, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<SurfaceControl> result; if (mStatus == NO_ERROR) { ISurfaceComposerClient::surface_data_t data; sp<ISurface> 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 ~~~ sp<ISurface> 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 ~~~ sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid, const String8& name, ISurfaceComposerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<LayerBaseClient> layer; sp<LayerBaseClient::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); sp<Layer> 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中,如下所示: ~~~ 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 ~~~ sp<Layer> SurfaceFlinger::createNormalSurface( const sp<Client>& 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 sp<Layer> 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 ~~~ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp<Client>& 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 ~~~ 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 display's 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來實現的,如下所示: ~~~ const GraphicPlane& LayerBase::graphicPlane(int dpy) const { return mFlinger->graphicPlane(dpy); } SurfaceFlinger類的成員函數graphicPlane的實現如下示: [cpp] view plain copy 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 ~~~ Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& 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 ~~~ ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<LayerBaseClient>& 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** ~~~ ssize_t Client::attachLayer(const sp<LayerBaseClient>& 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服務為它創建一個Surface,SurfaceFlinger服務就會將對應的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 ~~~ status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& 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** ~~~ sp<LayerBaseClient::Surface> LayerBaseClient::getSurface() { sp<Surface> 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 ~~~ sp<LayerBaseClient::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 ~~~ SurfaceControl::SurfaceControl( const sp<SurfaceComposerClient>& client, const sp<ISurface>& 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 ~~~ sp<Surface> SurfaceControl::getSurface() const { Mutex::Autolock _l(mLock); if (mSurfaceData == 0) { mSurfaceData = new Surface(const_cast<SurfaceControl*>(this)); } return mSurfaceData; } ~~~ 這個函數定義在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。 SurfaceControl類的成員函數getSurface第一次被調用時,成員變量mSurfaceData的值等于0,因此,函數接下來就會創建一個Surface對象,并且保存在成員變量mSurfaceData中。 接下來,我們就繼續分析Surface對象的創建過程。 Step 15. new Surface ~~~ Surface::Surface(const sp<SurfaceControl>& 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 ~~~ 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_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi; const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi; // FIXME: set real values here const_cast<int&>(ANativeWindow::minSwapInterval) = 1; const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; const_cast<uint32_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用來描述一個類型為sp<GraphicBuffer>的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 ~~~ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const { int32_t name = NAME_NOT_FOUND; sp<Layer> 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 = 1LU<<name; if ((android_atomic_or(mask, &mBitmap) & mask) == 0) { // we found and locked that name status_t err = layer->setToken( const_cast<UserClient*>(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 ~~~ status_t Layer::setToken(const sp<UserClient>& userClient, SharedClient* sharedClient, int32_t token) { sp<SharedBufferServer> 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來實現的,如下所示: ~~~ status_t Layer::ClientRef::setToken(const sp<UserClient>& uc, const sp<SharedBufferServer>& sharedClient, int32_t token) { Mutex::Autolock _l(mLock); { // scope for strong mUserClient reference sp<UserClient> 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 ~~~ 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 i=0 ; i<num ; 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 ~~~ 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的過程了,敬請期待!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看