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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                SurfaceComposerClient的出現是因為: Java層SurfaceSession對象的構造函數會調用Native的SurfaceSession_init函數,而該函數的主要目的就是創建SurfaceComposerClient。 先回顧一下SurfaceSession_init函數,代碼如下所示: **android_view_Surface.cpp** ~~~ static void SurfaceSession_init(JNIEnv* env,jobject clazz) { //new 一個SurfaceComposerClient對象 sp<SurfaceComposerClient> client = newSurfaceComposerClient; //sp的使用也有讓人煩惱的地方,有時需要顯式地增加強弱引用計數,要是忘記,可就麻煩了 client->incStrong(clazz); env->SetIntField(clazz, sso.client,(int)client.get()); } ~~~ 上面代碼中,顯式地構造了一個SurfaceComposerClient對象。接下來看它是何方神圣。 1. 創建SurfaceComposerClient SurfaceComposerClient這個名字隱含的意思是: 這個對象會和SurfaceFlinger進行交互,因為SurfaceFlinger派生于SurfaceComposer。 通過它的構造函數來看是否是這樣的。代碼如下所示: **SurfaceComposerClient.cpp** ~~~ SurfaceComposerClient::SurfaceComposerClient() { //getComposerService()將返回SF的Binder代理端的BpSurfaceFlinger對象 sp<ISurfaceComposer> sm(getComposerService()); //先調用SF的createConnection,再調用_init _init(sm, sm->createConnection()); if(mClient != 0) { Mutex::Autolock _l(gLock); //gActiveConnections是全局變量,把剛才創建的client保存到這個map中去 gActiveConnections.add(mClient->asBinder(), this); } } ~~~ 果然如此,SurfaceComposerClient建立了和SF的交互通道,下面直接轉到SF的createConnection函數去觀察。 (1)createConnection的分析 直接看代碼,如下所示: **SurfaceFlinger.cpp** ~~~ sp<ISurfaceFlingerClient>SurfaceFlinger::createConnection() { Mutex::Autolock _l(mStateLock); uint32_t token = mTokens.acquire(); //先創建一個Client。 sp<Client> client = new Client(token, this); //把這個Client對象保存到mClientsMap中,token是它的標識。 status_t err = mClientsMap.add(token, client); /* 創建一個用于Binder通信的BClient,BClient派生于ISurfaceFlingerClient, 它的作用是接受客戶端的請求,然后把處理提交給SF,注意,并不是提交給Client。 Client會創建一塊共享內存,該內存由getControlBlockMemory函數返回 */ sp<BClient> bclient = new BClient(this, token,client->getControlBlockMemory()); returnbclient; } ~~~ 上面代碼中提到,Client會創建一塊共享內存。熟悉Audio的讀者或許會認為,這可能是Surface的ControlBlock對象了!是的。CB對象在協調生產/消費步調時,起到了決定性的控制作用,所以非常重要,下面來看: **SurfaceFlinger.cpp** ~~~ Client::Client(ClientID clientID, constsp<SurfaceFlinger>& flinger) :ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) { const int pgsize = getpagesize(); //下面這個操作會使cblksize為頁的大小,目前是4096字節。 constint cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1)); //MemoryHeapBase是我們的老朋友了,不熟悉的讀者可以回顧Audio系統中所介紹的內容 mCblkHeap = new MemoryHeapBase(cblksize, 0, "SurfaceFlinger Clientcontrol-block"); ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase()); if(ctrlblk) { new(ctrlblk) SharedClient; //再一次覺得眼熟吧?使用了placement new } } ~~~ 原來,Surface的CB對象就是在共享內存中創建的這個SharedClient對象。先來認識一下這個SharedClient。 (2)SharedClient的分析 SharedClient定義了一些成員變量,代碼如下所示: ~~~ class SharedClient { public: SharedClient(); ~SharedClient(); status_t validate(size_t token) const; uint32_t getIdentity(size_t token) const;//取出標識本Client的token private: Mutexlock; Condition cv; //支持跨進程的同步對象 //NUM_LAYERS_MAX為31,SharedBufferStack是什么? SharedBufferStack surfaces[ NUM_LAYERS_MAX ]; }; //SharedClient的構造函數,沒什么新意,不如Audio的CB對象復雜 SharedClient::SharedClient() :lock(Mutex::SHARED), cv(Condition::SHARED) { } ~~~ SharedClient的定義似乎簡單到極致了,不過不要高興得過早,在這個SharedClient的定義中,沒有發現和讀寫控制相關的變量,那怎么控制讀寫呢? 答案就在看起來很別扭的SharedBufferStack數組中,它有31個元素。關于它的作用就不必賣關子了,答案是: 一個Client最多支持31個顯示層。每一個顯示層的生產/消費步調都由會對應的SharedBufferStack來控制。而它內部就用了幾個成員變量來控制讀寫位置。 認識一下SharedBufferStack的這幾個控制變量,如下所示: **SharedBufferStack.h** ~~~ class SharedBufferStack{ ...... //Buffer是按塊使用的,每個Buffer都有自己的編號,其實就是數組中的索引號。 volatile int32_t head; //FrontBuffer的編號 volatile int32_t available; //空閑Buffer的個數 volatile int32_t queued; //臟Buffer的個數,臟Buffer表示有新數據的Buffer volatile int32_t inUse; //SF當前正在使用的Buffer的編號 volatilestatus_t status; //狀態碼 ...... } ~~~ 注意,上面定義的SharedBufferStack是一個通用的控制結構,而不僅是針對于只有兩個Buffer的情況。根據前面介紹的PageFlipping知識,如果只有兩個FB,那么,SharedBufferStack的控制就比較簡單了: 要么SF讀1號Buffer,客戶端寫0號Buffer,要么SF讀0號Buffer,客戶端寫1號Buffer。 圖8-13是展示了SharedClient的示意圖: :-: ![](http://img.blog.csdn.net/20150802162602596?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖8-13 SharedClient的示意圖 從上圖可知: - SF的一個Client分配一個跨進程共享的SharedClient對象。這個對象有31個SharedBufferStack元素,每一個SharedBufferStack對應于一個顯示層。 - 一個顯示層將創建兩個Buffer,后續的PageFlipping就是基于這兩個Buffer展開的。 另外,每一個顯示層中,其數據的生產和消費并不是直接使用SharedClient對象來進行具體控制的,而是基于SharedBufferServer和SharedBufferClient兩個結構,由這兩個結構來對該顯示層使用的SharedBufferStack進行操作,這些內容在以后的分析中還會碰到。 * * * * * **注意**,這里的顯示層指的是Normal類型的顯示層。 * * * * * 來接著分析后面的_init函數。 (3)_init函數的分析 先回顧一下之前的調用,代碼如下所示: **SurfaceComposerClient.cpp** ~~~ SurfaceComposerClient::SurfaceComposerClient() { ...... _init(sm, sm->createConnection()); ...... } ~~~ 來看這個_init函數,代碼如下所示: **SurfaceComposerClient.cpp** ~~~ void SurfaceComposerClient::_init( const sp<ISurfaceComposer>& sm, constsp<ISurfaceFlingerClient>& conn) { mPrebuiltLayerState = 0; mTransactionOpen = 0; mStatus = NO_ERROR; mControl = 0; mClient = conn;//mClient就是BClient的客戶端 mControlMemory =mClient->getControlBlock(); mSignalServer = sm;// mSignalServer就是BpSurfaceFlinger //mControl就是那個創建于共享內存之中的SharedClient mControl = static_cast<SharedClient*>(mControlMemory->getBase()); } ~~~ _init函數的作用,就是初始化SurfaceComposerClient中的一些成員變量。最重要的是得到了三個成員: - mSignalServer ,它其實是SurfaceFlinger在客戶端的代理BpSurfaceFlinger,它的主要作用是,在客戶端更新完BackBuffer后(也就是刷新了界面后),通知SF進行PageFlipping和輸出等工作。 - mControl,它是跨進程共享的SharedClient,是Surface系統的ControlBlock對象。 - mClient,它是BClient在客戶端的對應物。 2. 到底有多少種對象? 這一節,出現了好幾種類型的對象,通過圖8-14來看看它們: :-: ![](http://img.blog.csdn.net/20150802162626479?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖8-14 類之間關系展示圖 從上圖中可以看出: - SurfaceFlinger是從Thread派生的,所以它會有一個單獨運行的工作線程。 - BClient和SF之間采用了Proxy模式,BClient支持Binder通信,它接收客戶端的請求,并派發給SF執行。 - SharedClient構建于一塊共享內存中,SurfaceComposerClient和Client對象均持有這塊共享內存。 在精簡流程中,關于SurfaceComposerClient就分析到這里,下面分析第二個步驟中的SurfaceControl對象。
                  <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>

                              哎呀哎呀视频在线观看