<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                原文出處——>[Android應用程序與SurfaceFlinger服務之間的共享UI元數據(SharedClient)的創建過程分析](http://blog.csdn.net/luoshengyang/article/details/7867340) 在前面一篇文章中,我們分析了Android應用程序與SurfaceFlinger服務的連接過程。Android應用程序成功連接上SurfaceFlinger服務之后,還需要一塊匿名共享內存來和SurfaceFlinger服務共享它的UI元數據,以便使得SurfaceFlinger服務可以正確地為它創建以及渲染Surface。在本文中,我們將詳細地分析這塊用來保存UI元數據的匿名共享內存的創建過程。 在Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文中提到,用來保存Android應用程序的UI元數據的匿名共享內存最終是被結構化為一個SharedClient對象來訪問的。每一個與UI有關的Android應用程序進程有且僅有一個SharedClient對象,而且這些SharedClient對象是由Android應用程序請求SurfaceFlinger服務創建的:Android應用程序首先獲得SurfaceFlinger服務的一個Binder代理接口,然后再通過這個代理接口得到另外一個類型為UserClient的Binder代理接口,最后就可以通過后一個Binder代理接口來獲得一個SharedClient對象。 由于每一個與UI有關的Android應用程序進程有且僅有一個SharedClient對象,因此,Android系統就通過一個單例模式的類來專負責創建和管理這個SharedClient對象。這個類的名稱為SurfaceClient,定義在frameworks/base/libs/surfaceflinger_client/Surface.cpp文件中,如下所示: ~~~ class SurfaceClient : public Singleton<SurfaceClient> { // all these attributes are constants sp<ISurfaceComposer> mComposerService; sp<ISurfaceComposerClient> mClient; status_t mStatus; SharedClient* mControl; sp<IMemoryHeap> mControlMemory; SurfaceClient() : Singleton<SurfaceClient>(), mStatus(NO_INIT) { sp<ISurfaceComposer> sf(ComposerService::getComposerService()); mComposerService = sf; mClient = sf->createClientConnection(); if (mClient != NULL) { mControlMemory = mClient->getControlBlock(); if (mControlMemory != NULL) { mControl = static_cast<SharedClient *>( mControlMemory->getBase()); if (mControl) { mStatus = NO_ERROR; } } } } friend class Singleton<SurfaceClient>; public: status_t initCheck() const { return mStatus; } SharedClient* getSharedClient() const { return mControl; } ssize_t getTokenForSurface(const sp<ISurface>& sur) const { // TODO: we could cache a few tokens here to avoid an IPC return mClient->getTokenForSurface(sur); } void signalServer() const { mComposerService->signal(); } }; ~~~ 當SurfaceClient類的靜態成員函數getInstance第一次被調用的時候,系統就會在對應的應用程序進程中創建一個SurfaceClient對象,即會調用SurfaceClient類的構造函數。SurfaceClient類的構造函數首先會調用ComposerService類的靜態成員函數getComposerService來獲得一個SurfaceFlinger服務的代理接口,并且保存在SurfaceClient類的成員變量mComposerService中,以便以后可以使用。ComposerService類的靜態成員函數getComposerService在前面Android應用程序與SurfaceFlinger服務的連接過程分析一文中已經分析過了,這里不再詳述。有了SurfaceFlinger服務的代理接口sf之后,SurfaceClient類的構造函數接著就可以調用它的成員函數createClientConnection來獲得一個類型為UserClient的Binder代理接口,這個Binder代理接口實現了ISurfaceComposerClient接口,因此,我們可以將它保存在SurfaceClient類的成員變量mClient中。最后,SurfaceClient類的構造函數就調用前面獲得的類型為ISurfaceComposerClient的Binder代理接口mClient的成員函數getControlBlock來獲得一塊用來描述應用程序UI元數據的匿名共享內存mControlMemory ,并且將這些匿名共享內存強制轉化為一個SharedClient對象mControl,以便后面可以方便地訪問UI元數據。 以上就是Android應用程序與SurfaceFlinger服務之間的共享UI元數據(SharedClient)的創建過程的總體描述,接下來我們再詳細分析每一步的實現。現在,我們繼續分析一下SurfaceClient類的其余成員函數的實現: 1. 成員函數initCheck用來檢查一個Android應用程序進程是否已經成功地請求SurfaceFlinger服務創建了一塊用來描述UI元數據的SharedClient對象了。 2. 成員函數getSharedClient用來返回用來描述UI元數據的SharedClient對象mControl。 3. 成員函數getTokenForSurface用來返回由參數sur所描述的一個Surface的Token值。這個Token值由SurfaceFlinger服務來創建和管理,并且可以通過前面所獲得的類型為UserClient的Binder代理接口mClient的成員函數getTokenSurface來獲得。 4. 成員函數signalServer用來通知SurfaceFlinger服務更新Android應用程序UI,這是通過調用SurfaceFlinger服務的代理接口mComposerService的成員函數signal來實現的,實際上就是向SurfaceFlinger服務發送一個信號,以便可以將它喚醒起來更新UI。 介紹完成SurfaceClient類的實現之后,我們還需要了解一下兩個類的實現,即UserClient類和SharedClient類的實現,以便可以幫助我們了解用來保存Android應用程序的UI元數據的匿名共享內存的創建過程,以及幫助后面兩篇文章對Surface的創建和渲染過程的分析。 接下來,我們就首先分析UserClient類的實現,接著再分析SharedClient類的實現。 在Android應用程序與SurfaceFlinger服務的連接過程分析一文的圖2中,我們介紹了用來連接Android應用程序和SurfaceFlinger服務的Client類,而UserClient類和Client類是類似的,它們都實現了相同的接口,只不過是側重點有所不同。Android應用程序與SurfaceFlinger服務的連接過程分析一文的圖2中的Client類替換成UserClient類,就可以得到UserClient類的實現結構圖,如圖1所示: ![](https://box.kancloud.cn/c1f1f5df9582fee3cfb83362fec9a913_687x492.jpg) 圖1 UserClient類的實現結構圖 UserClient類與Client類最重要的區別是,前者實現了ISurfaceComposerClient接口的成員函數getControlBlock,而后者實現了ISurfaceComposerClient接口的成員函數createSurface。后面我們就會分析UserClient類是如何實現ISurfaceComposerClient接口的成員函數getControlBlock的。 UserClient類的實現暫時就介紹到這里,接下來我們來看SharedClient類的實現。為了方便描述,我們把Android應用程序與SurfaceFlinger服務的關系概述和學習計劃一文的圖4和圖5貼出來,如以下圖2和圖3所示: ![](https://box.kancloud.cn/8bf549fcb8720f263b9595724490c92f_540x347.jpg) 圖2 用來描述Android應用程序的UI元數據的SharedClient ![](https://box.kancloud.cn/3bb7bdaf74bd82c0f9c2b8cb05f977d5_659x412.jpg) 圖3 SharedBufferStack的結構示意圖 每一個SharedClient對象包含了至多31個SharedBufferStack,而每一個SharedBufferStack都對應一個Android應用程序進程中的一個Surface。 SharedClient類定義在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示: ~~~ class SharedClient { public: SharedClient(); ~SharedClient(); ...... private: ...... SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ]; }; ~~~ 它有一個大小為SharedBufferStack::NUM_LAYERS_MAX的SharedBufferStack數組。SharedBufferStack::NUM_LAYERS_MAX的值等于31,定義在SharedBufferStack類中。 SharedBufferStack類同樣是定義在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示: ~~~ class SharedBufferStack { ...... public: // When changing these values, the COMPILE_TIME_ASSERT at the end of this // file need to be updated. static const unsigned int NUM_LAYERS_MAX = 31; static const unsigned int NUM_BUFFER_MAX = 16; static const unsigned int NUM_BUFFER_MIN = 2; static const unsigned int NUM_DISPLAY_MAX = 4; ...... struct SmallRect { uint16_t l, t, r, b; }; struct FlatRegion { static const unsigned int NUM_RECT_MAX = 5; uint32_t count; SmallRect rects[NUM_RECT_MAX]; }; struct BufferData { FlatRegion dirtyRegion; SmallRect crop; uint8_t transform; uint8_t reserved[3]; }; SharedBufferStack(); ...... status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setTransform(int buffer, uint8_t transform); Region getDirtyRegion(int buffer) const; Rect getCrop(int buffer) const; uint32_t getTransform(int buffer) const; // these attributes are part of the conditions/updates volatile int32_t head; // server's current front buffer volatile int32_t available; // number of dequeue-able buffers volatile int32_t queued; // number of buffers waiting for post ...... // not part of the conditions ...... volatile int8_t index[NUM_BUFFER_MAX]; ...... int8_t headBuf; // last retired buffer ...... BufferData buffers[NUM_BUFFER_MAX]; }; ~~~ 下面我們簡要地對SharedBufferStack類進行分析。 首先,SharedBufferStack類在內部定義了四個常量: * NUM_LAYERS_MAX -- 表示一個Android應用程序最多可以有NUM_LAYERS_MAX個Layer,可以將一個Layer理解為一個Surface。 * NUM_BUFFER_MAX -- 表示一個SharedBufferStack至多可以有NUM_BUFFER_MAX個UI元數據緩沖區。 * NUM_BUFFER_MIN -- 表示一個SharedBufferStack至少要有UM_BUFFER_MIN個UI元數據緩沖區。 * NUM_DISPLAY_MAX -- 表示Android系統至多可以支持NUM_DISPLAY_MAX個顯示屏。 從這些常量就可以看出: 1. Android系統至多支持4個顯示屏。 2. 一個Android應用程序至多可以同時創建31個Surface。 3. 一個Surface可以有2~16個UI元數據緩沖區,即可以使用2~16緩沖區技術來渲染Surface。 其次,SharedBufferStack類在內部定義了三個結構體: * SmallRect -- 用來描述一個矩形區域,其中,成員變量l、t,、r和b分別表示左上和右下兩個角的位置。 * FlatRegion -- 用來描述一個SmallRect數組rects ,數組的大小為NUM_RECT_MAX,但是實際個數為count。 * BufferData -- 用來描述一個UI元數據緩沖區,它有四個成員變量dirtyRegion、crop、transform和reserved,其中,dirtyRegion用來描述一個Surface需要更新的區域,即裁剪區域,crop用來描述一個Surface的紋理坐標,transform用來描述一個Surface的旋轉方向,例如,旋轉90度或者上下翻轉等等,而reserved是保留給以后使用的。通過這個UI元數據緩沖區,SurfaceFlinger服務就可以正確地把一個Surface的圖形緩沖區所描述的圖形渲染到屏幕來。 SharedBufferStack類有一個BufferData數組buffers,它的大小為NUM_BUFFER_MAX,即16,就是用來一組UI元數據緩沖區的,這些UI元數據緩沖區的內容可以分別通過setDirtyRegion、setCrop、setTransform、getDirtyRegion、getCrop和getTransform這六個成員函數來訪問。這六個成員函數的第一個參數均為一個int值,用來描述要訪問的是哪一個BufferData的數據。 SharedBufferStack類還有另外一個類型為int8_t的數組index,它的大小也為NUM_BUFFER_MAX。這個index數組才是一個真正的Stack,它按照一定的規則來訪問。index數組的每一個元素的值均是一個索引值,用來映射到數組buffers中去的。例如,假設index[0]的值等于2,那么它就對應數組buffers中的第2個元素,即buffers[2]。 SharedBufferStack類的其余重要成員變量的含義如下所示: * head -- 用來描述一個SharedBufferStack的頭部,它是一個索引值,是映射到數組index中去的。 * available -- 用來描述一個SharedBufferStack中的空閑UI元數據緩沖區的個數。 * queued -- 用來描述一個SharedBufferStack中的已經補使用了的UI元數據緩沖區的個數,即那些在排隊等待SurfaceFlinger服務使用的UI元數據緩沖區。 * headBuf -- 用來描述一個SharedBufferStack的頭部所對應的UI元數據緩沖區的編號,這個編號是映射到數組buffers中去。 關于SharedBufferStack類的實現,我們就暫時介紹到這里,在下一篇文章分析Android應用程序的Surface創建過程時,我們再通過SharedBufferServer類和SharedBufferClient類的實現來進一步理解SharedBufferStack類的實現。 現在,我們就開始詳細分析Android應用程序與SurfaceFlinger服務之間的共享UI元數據的創建過程,如圖4所示: ![](https://box.kancloud.cn/02e412ab67878f42292bd129a6493338_519x530.jpg) 圖 4 Android應用程序的共享UI元數據的創建過程 接下來我們就詳細分析每一個步驟。 Step 1. SurfaceFlinger::createClientConnection ~~~ sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection() { sp<ISurfaceComposerClient> bclient; sp<UserClient> client(new UserClient(this)); status_t err = client->initCheck(); if (err == NO_ERROR) { bclient = client; } return bclient; } ~~~ SurfaceFlinger類的成員函數createClientConnection實現在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,它的實現很簡單,只是創建了一個類型為UserClient的Binder對象client,并且獲得它的一個ISurfaceComposerClient接口,最后將這個ISurfaceComposerClient接口,即一個UserClient代理對象,返回給Android應用程序進程。 接下來,我們再繼續分析UserClient對象的創建過程,,即UserClient類的構造函數的實現。 Step 2. new UserClient ~~~ UserClient::UserClient(const sp<SurfaceFlinger>& flinger) : ctrlblk(0), mBitmap(0), mFlinger(flinger) { const int pgsize = getpagesize(); const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); mCblkHeap = new MemoryHeapBase(cblksize, 0, "SurfaceFlinger Client control-block"); ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); if (ctrlblk) { // construct the shared structure in-place. new(ctrlblk) SharedClient; } } ~~~ UserClient類的成員變量mFlinger是一個類型為SurfaceFlinger的強指針,它指向了SurfaceFlinger服務, UserClient類的另外一個成員變量mBitmap是一個int32_t值,它是用來為Android應用程序的Surface分配Token值的,即如果它的第n位等于1,那么就表示值等于n的Token已經被分配出去使用了。 UserClient類的構造函數首先得到一個SharedClient對象的大小,接著再將這個大小對齊到頁面邊界,于是就得到了接下來要創建的匿名共享塊的大小cblksize。這塊匿名共享內存是一個MemoryHeapBase對象描述的,并且保存在UserClient類的成員變量mCblkHeap。MemoryHeapBase類是用來創建匿名共享內存的一個C++接口,它的實現原理可以參考Android系統匿名共享內存(Anonymous Shared Memory)C++調用接口分析一文。 UserClient類的構造函數得到了一塊匿名共享內存之后,緊接著就在這塊匿名共享內存上創建了一個SharedClient對象,并且保存在UserClient類的成員變量ctrlblk中,以便后面可以通過它來訪問Android應用程序的UI元數據。 回到SurfaceFlinger類的成員函數createClientConnection中,它將一個指向了一個UserClient對象的ISurfaceComposerClient接口返回到Android應用程序進程之后,Android應用程序進程就可以將它封裝成一個類型為BpSurfaceComposerClient的Binder代理對象。 Step 3. return BpSurfaceComposerClient 將一個Binder代理對象封裝成一個BpSurfaceComposerClient的過程可以參考前面Android應用程序與SurfaceFlinger服務的連接過程分析一文中的Step 4。 Step 4. UserClient::getControlBlock ~~~ sp<IMemoryHeap> UserClient::getControlBlock() const { return mCblkHeap; } ~~~ 從前面的Step 2可以知道,UserClient類的成員變量mCblkHeap指向了一塊匿名共享內存,UserClient類將這塊匿名共享內存返回給Android應用程序之后,Android應用程序就會將它結構化成一個SharedClient對象來訪問,并且保存在SurfaceClient類的成員變量mControl中,這個結構化過程就可以參考前面所描述的SurfaceClient類的構造函數了。 至此,用來描述Android應用程序的UI元數據的一個SharedClient對象的創建過程就分析完了。以后當Android應用程序請求SurfaceFlinger服務創建一個Surface的時候,SurfaceFlinger服務就會從這個SharedClient對象中取出一個SharedBufferStack出來,以便可以用作這個Surface的UI元數據緩沖區。在接下來的一篇文章中,我們將詳細描述Android應用程序請求SurfaceFlinger服務創建Surface的過程,敬請期待!
                  <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>

                              哎呀哎呀视频在线观看