Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程_第1頁
Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程_第2頁
Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程_第3頁
Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程_第4頁
Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程_第5頁
已閱讀5頁,還剩5頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析在前面一篇文章中,我們分析了Android應(yīng)用程序與SurfaceFlinger服務(wù)的連接過程。Android應(yīng)用程序成功連接上SurfaceFlinger服務(wù)之后,還需要一塊匿名共享內(nèi)存來和SurfaceFlinger服務(wù)共享它的UI元數(shù)據(jù),以便使得SurfaceFlinger服務(wù)可以正確地為它創(chuàng)建以及渲染Surface。在本文中,我們將詳細(xì)地分析這塊用來保存UI元數(shù)據(jù)的匿名共享內(nèi)存的創(chuàng)建過程。 在 一文中提到,用來保存Android應(yīng)用程序的UI元數(shù)據(jù)的匿名共享內(nèi)存最終是被

2、結(jié)構(gòu)化為一個(gè)SharedClient對(duì)象來訪問的。每一個(gè)與UI有關(guān)的Android應(yīng)用程序進(jìn)程有且僅有一個(gè)SharedClient對(duì)象,而且這些SharedClient對(duì)象是由Android應(yīng)用程序請(qǐng)求SurfaceFlinger服務(wù)創(chuàng)建的:Android應(yīng)用程序首先獲得SurfaceFlinger服務(wù)的一個(gè)Binder代理接口,然后再通過這個(gè)代理接口得到另外一個(gè)類型為UserClient的Binder代理接口,最后就可以通過后一個(gè)Binder代理接口來獲得一個(gè)SharedClient對(duì)象。 由于每一個(gè)與UI有關(guān)的Android應(yīng)用程序進(jìn)程有且僅有一個(gè)SharedClient對(duì)象,因此,And

3、roid系統(tǒng)就通過一個(gè)單例模式的類來專負(fù)責(zé)創(chuàng)建和管理這個(gè)SharedClient對(duì)象。這個(gè)類的名稱為SurfaceClient,定義在frameworks/base/libs/surfaceflinger_client/Surface.cpp文件中,如下所示:cpp view plain copy 在CODE上查看代碼片派生到我的代碼片class SurfaceClient : public Singleton<SurfaceClient> / all these attributes are constants sp<ISurfaceComposer> mCompos

4、erService; 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

5、 = 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: statu

6、s_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 mComposerSer

7、vice->signal(); ; 當(dāng)SurfaceClient類的靜態(tài)成員函數(shù)getInstance第一次被調(diào)用的時(shí)候,系統(tǒng)就會(huì)在對(duì)應(yīng)的應(yīng)用程序進(jìn)程中創(chuàng)建一個(gè)SurfaceClient對(duì)象,即會(huì)調(diào)用SurfaceClient類的構(gòu)造函數(shù)。SurfaceClient類的構(gòu)造函數(shù)首先會(huì)調(diào)用ComposerService類的靜態(tài)成員函數(shù)getComposerService來獲得一個(gè)SurfaceFlinger服務(wù)的代理接口,并且保存在SurfaceClient類的成員變量mComposerService中,以便以后可以使用。ComposerService類的靜態(tài)成員函數(shù)getComposer

8、Service在前面 一文中已經(jīng)分析過了,這里不再詳述。有了SurfaceFlinger服務(wù)的代理接口sf之后,SurfaceClient類的構(gòu)造函數(shù)接著就可以調(diào)用它的成員函數(shù)createClientConnection來獲得一個(gè)類型為UserClient的Binder代理接口,這個(gè)Binder代理接口實(shí)現(xiàn)了ISurfaceComposerClient接口,因此,我們可以將它保存在SurfaceClient類的成員變量mClient中。最后,SurfaceClient類的構(gòu)造函數(shù)就調(diào)用前面獲得的類型為ISurfaceComposerClient的Binder代理接口mClient的成員函數(shù)ge

9、tControlBlock來獲得一塊用來描述應(yīng)用程序UI元數(shù)據(jù)的匿名共享內(nèi)存mControlMemory ,并且將這些匿名共享內(nèi)存強(qiáng)制轉(zhuǎn)化為一個(gè)SharedClient對(duì)象mControl,以便后面可以方便地訪問UI元數(shù)據(jù)。 以上就是Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程的總體描述,接下來我們?cè)僭敿?xì)分析每一步的實(shí)現(xiàn)?,F(xiàn)在,我們繼續(xù)分析一下SurfaceClient類的其余成員函數(shù)的實(shí)現(xiàn): 1. 成員函數(shù)initCheck用來檢查一個(gè)Android應(yīng)用程序進(jìn)程是否已經(jīng)成功地請(qǐng)求SurfaceFlinger服務(wù)創(chuàng)建了一塊用

10、來描述UI元數(shù)據(jù)的SharedClient對(duì)象了。 2. 成員函數(shù)getSharedClient用來返回用來描述UI元數(shù)據(jù)的SharedClient對(duì)象mControl。 3. 成員函數(shù)getTokenForSurface用來返回由參數(shù)sur所描述的一個(gè)Surface的Token值。這個(gè)Token值由SurfaceFlinger服務(wù)來創(chuàng)建和管理,并且可以通過前面所獲得的類型為UserClient的Binder代理接口mClient的成員函數(shù)getTokenSurface來獲得。 4. 成員函數(shù)signalServer用來通知SurfaceFlinger服務(wù)更新Android應(yīng)用程序UI,這是通

11、過調(diào)用SurfaceFlinger服務(wù)的代理接口mComposerService的成員函數(shù)signal來實(shí)現(xiàn)的,實(shí)際上就是向SurfaceFlinger服務(wù)發(fā)送一個(gè)信號(hào),以便可以將它喚醒起來更新UI。 介紹完成SurfaceClient類的實(shí)現(xiàn)之后,我們還需要了解一下兩個(gè)類的實(shí)現(xiàn),即UserClient類和SharedClient類的實(shí)現(xiàn),以便可以幫助我們了解用來保存Android應(yīng)用程序的UI元數(shù)據(jù)的匿名共享內(nèi)存的創(chuàng)建過程,以及幫助后面兩篇文章對(duì)Surface的創(chuàng)建和渲染過程的分析。 接下來,我們就首先分析UserClient類的實(shí)現(xiàn),接著再分析SharedClient類的實(shí)現(xiàn)。 在 一文的

12、圖2中,我們介紹了用來連接Android應(yīng)用程序和SurfaceFlinger服務(wù)的Client類,而UserClient類和Client類是類似的,它們都實(shí)現(xiàn)了相同的接口,只不過是側(cè)重點(diǎn)有所不同。 一文的圖2中的Client類替換成UserClient類,就可以得到UserClient類的實(shí)現(xiàn)結(jié)構(gòu)圖,如圖1所示:UserClient類與Client類最重要的區(qū)別是,前者實(shí)現(xiàn)了ISurfaceComposerClient接口的成員函數(shù)getControlBlock,而后者實(shí)現(xiàn)了ISurfaceComposerClient接口的成員函數(shù)createSurface。后面我們就會(huì)分析UserClie

13、nt類是如何實(shí)現(xiàn)ISurfaceComposerClient接口的成員函數(shù)getControlBlock的。 UserClient類的實(shí)現(xiàn)暫時(shí)就介紹到這里,接下來我們來看SharedClient類的實(shí)現(xiàn)。為了方便描述,我們把 一文的圖4和圖5貼出來,如以下圖2和圖3所示:每一個(gè)SharedClient對(duì)象包含了至多31個(gè)SharedBufferStack,而每一個(gè)SharedBufferStack都對(duì)應(yīng)一個(gè)Android應(yīng)用程序進(jìn)程中的一個(gè)Surface。 SharedClient類定義在文件frameworks/base/include/private/surfaceflinger/Shar

14、edBufferStack.h 文件中,如下所示:cpp view plain copy 在CODE上查看代碼片派生到我的代碼片class SharedClient public: SharedClient(); SharedClient(); . private: . SharedBufferStack surfaces SharedBufferStack:NUM_LAYERS_MAX ; ; 它有一個(gè)大小為SharedBufferStack:NUM_LAYERS_MAX的SharedBufferStack數(shù)組。SharedBufferStack:NUM_LAYERS_MAX的值等于31,定

15、義在SharedBufferStack類中。 SharedBufferStack類同樣是定義在文件frameworks/base/include/private/surfaceflinger/SharedBufferStack.h 文件中,如下所示:cpp view plain copy 在CODE上查看代碼片派生到我的代碼片class SharedBufferStack . public: / When changing these values, the COMPILE_TIME_ASSERT at the end of this / file need to be updated. st

16、atic 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 co

17、unt; SmallRect rectsNUM_RECT_MAX; ; struct BufferData FlatRegion dirtyRegion; SmallRect crop; uint8_t transform; uint8_t reserved3; ; SharedBufferStack(); . status_t setDirtyRegion(int buffer, const Region& reg); status_t setCrop(int buffer, const Rect& reg); status_t setTransform(int buffer

18、, uint8_t transform); Region getDirtyRegion(int buffer) const; Rect getCrop(int ffer) 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

19、buffers volatile int32_t queued; / number of buffers waiting for post . / not part of the conditions . volatile int8_t indexNUM_BUFFER_MAX; . int8_t headBuf; / last retired buffer . BufferData buffersNUM_BUFFER_MAX; ; 下面我們簡(jiǎn)要地對(duì)SharedBufferStack類進(jìn)行分析。 首先,SharedBufferStack類在內(nèi)部定義了四個(gè)常量: NUM_LAYERS_MAX -

20、表示一個(gè)Android應(yīng)用程序最多可以有NUM_LAYERS_MAX個(gè)Layer,可以將一個(gè)Layer理解為一個(gè)Surface。 NUM_BUFFER_MAX - 表示一個(gè)SharedBufferStack至多可以有NUM_BUFFER_MAX個(gè)UI元數(shù)據(jù)緩沖區(qū)。 NUM_BUFFER_MIN - 表示一個(gè)SharedBufferStack至少要有UM_BUFFER_MIN個(gè)UI元數(shù)據(jù)緩沖區(qū)。 NUM_DISPLAY_MAX - 表示Android系統(tǒng)至多可以支持NUM_DISPLAY_MAX個(gè)顯示屏。 從這些常量就可以看出: 1. Android系統(tǒng)至多支持4個(gè)顯示屏。 2. 一個(gè)Andro

21、id應(yīng)用程序至多可以同時(shí)創(chuàng)建31個(gè)Surface。 3. 一個(gè)Surface可以有216個(gè)UI元數(shù)據(jù)緩沖區(qū),即可以使用216緩沖區(qū)技術(shù)來渲染Surface。 其次,SharedBufferStack類在內(nèi)部定義了三個(gè)結(jié)構(gòu)體: SmallRect - 用來描述一個(gè)矩形區(qū)域,其中,成員變量l、t,、r和b分別表示左上和右下兩個(gè)角的位置。 FlatRegion - 用來描述一個(gè)SmallRect數(shù)組rects ,數(shù)組的大小為NUM_RECT_MAX,但是實(shí)際個(gè)數(shù)為count。 BufferData - 用來描述一個(gè)UI元數(shù)據(jù)緩沖區(qū),它有四個(gè)成員變量dirtyRegion、crop、transform

22、和reserved,其中,dirtyRegion用來描述一個(gè)Surface需要更新的區(qū)域,即裁剪區(qū)域,crop用來描述一個(gè)Surface的紋理坐標(biāo),transform用來描述一個(gè)Surface的旋轉(zhuǎn)方向,例如,旋轉(zhuǎn)90度或者上下翻轉(zhuǎn)等等,而reserved是保留給以后使用的。通過這個(gè)UI元數(shù)據(jù)緩沖區(qū),SurfaceFlinger服務(wù)就可以正確地把一個(gè)Surface的圖形緩沖區(qū)所描述的圖形渲染到屏幕來。 SharedBufferStack類有一個(gè)BufferData數(shù)組buffers,它的大小為NUM_BUFFER_MAX,即16,就是用來一組UI元數(shù)據(jù)緩沖區(qū)的,這些UI元數(shù)據(jù)緩沖區(qū)的內(nèi)容可以分

23、別通過setDirtyRegion、setCrop、setTransform、getDirtyRegion、getCrop和getTransform這六個(gè)成員函數(shù)來訪問。這六個(gè)成員函數(shù)的第一個(gè)參數(shù)均為一個(gè)int值,用來描述要訪問的是哪一個(gè)BufferData的數(shù)據(jù)。 SharedBufferStack類還有另外一個(gè)類型為int8_t的數(shù)組index,它的大小也為NUM_BUFFER_MAX。這個(gè)index數(shù)組才是一個(gè)真正的Stack,它按照一定的規(guī)則來訪問。index數(shù)組的每一個(gè)元素的值均是一個(gè)索引值,用來映射到數(shù)組buffers中去的。例如,假設(shè)index0的值等于2,那么它就對(duì)應(yīng)數(shù)組buf

24、fers中的第2個(gè)元素,即buffers2。 SharedBufferStack類的其余重要成員變量的含義如下所示: head - 用來描述一個(gè)SharedBufferStack的頭部,它是一個(gè)索引值,是映射到數(shù)組index中去的。 available - 用來描述一個(gè)SharedBufferStack中的空閑UI元數(shù)據(jù)緩沖區(qū)的個(gè)數(shù)。 queued - 用來描述一個(gè)SharedBufferStack中的已經(jīng)補(bǔ)使用了的UI元數(shù)據(jù)緩沖區(qū)的個(gè)數(shù),即那些在排隊(duì)等待SurfaceFlinger服務(wù)使用的UI元數(shù)據(jù)緩沖區(qū)。 headBuf - 用來描述一個(gè)SharedBufferStack的頭部所對(duì)應(yīng)的U

25、I元數(shù)據(jù)緩沖區(qū)的編號(hào),這個(gè)編號(hào)是映射到數(shù)組buffers中去。 關(guān)于SharedBufferStack類的實(shí)現(xiàn),我們就暫時(shí)介紹到這里,在下一篇文章分析Android應(yīng)用程序的Surface創(chuàng)建過程時(shí),我們?cè)偻ㄟ^SharedBufferServer類和SharedBufferClient類的實(shí)現(xiàn)來進(jìn)一步理解SharedBufferStack類的實(shí)現(xiàn)。 現(xiàn)在,我們就開始詳細(xì)分析Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)的創(chuàng)建過程,如圖4所示: 接下來我們就詳細(xì)分析每一個(gè)步驟。 Step 1. SurfaceFlinger:createClientConnectio

26、ncpp view plain copy 在CODE上查看代碼片派生到我的代碼片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; Su

27、rfaceFlinger類的成員函數(shù)createClientConnection實(shí)現(xiàn)在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,它的實(shí)現(xiàn)很簡(jiǎn)單,只是創(chuàng)建了一個(gè)類型為UserClient的Binder對(duì)象client,并且獲得它的一個(gè)ISurfaceComposerClient接口,最后將這個(gè)ISurfaceComposerClient接口,即一個(gè)UserClient代理對(duì)象,返回給Android應(yīng)用程序進(jìn)程。 接下來,我們?cè)倮^續(xù)分析UserClient對(duì)象的創(chuàng)建過程,,即UserClient類的構(gòu)造函數(shù)的實(shí)現(xiàn)。

28、Step 2. new UserClientcpp view plain copy 在CODE上查看代碼片派生到我的代碼片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 MemoryHe

29、apBase(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是一個(gè)類型為SurfaceFlinger的強(qiáng)指針,它指向了SurfaceFlinger服務(wù), UserClient類的另外一個(gè)成員變量mBitmap是一個(gè)int32_t值,它是用來為Android應(yīng)用程序的Surface分配Token值的,即如果它的第n位等于1,那么就表示值等于n的Token已經(jīng)被分配出去使用了。 UserClient類的構(gòu)造函數(shù)首先得到一

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論