<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之旅 廣告
                1. SurfaceControl的來歷 根據精簡的流程可知,這一節要分析的是SurfaceControl對象。先回顧一下這個對象的創建過程,代碼如下所示: **android_view_Surface.cpp** ~~~ static void Surface_init(JNIEnv* env, jobjectclazz, jobject session, jint pid, jstring jname, jint dpy, jint w, jint h, jint format, jintflags) { SurfaceComposerClient* client = (SurfaceComposerClient*)env->GetIntField(session, sso.client); //注意這個變量,類型是SurfaceControl,名字卻叫surface,稍不留神就出錯了。 sp<SurfaceControl>surface; if (jname == NULL) { //調用Client的createSurface函數,得到一個SurfaceControl對象。 surface= client->createSurface(pid, dpy, w, h, format, flags); } ...... //將這個SurfaceControl對象設置到Java層的對象中保存。 setSurfaceControl(env, clazz, surface); } ~~~ 通過上面的代碼可知,SurfaceControl對象由createSurface得來,下面看看這個函數。 此時,讀者或許會被代碼中隨意起的變量名搞糊涂,因為我的處理方法碰到了容易混淆的地方,盡量以對象類型來表示這個對象。 (1)分析createSurface的請求端 在createSurface內部會使用Binder通信將請求發給SF,所以它分為請求和響應兩端,先看請求端,代碼如下所示: **SurfaceComposerClient.cpp** ~~~ sp<SurfaceControl>SurfaceComposerClient::createSurface( int pid, DisplayID display,//DisplayID是什么意思? uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { String8 name; constsize_t SIZE = 128; charbuffer[SIZE]; snprintf(buffer, SIZE, "<pid_%d>", getpid()); name.append(buffer); //調用另外一個createSurface,多一個name參數 returnSurfaceComposerClient::createSurface(pid, name, display, w, h, format, flags); } ~~~ 在分析另外一個createSurface之前,應先介紹一下DisplayID的含義: ~~~ typedef int32_t DisplayID; ~~~ DisplayID是一個int整型,它的意義是屏幕編號,例如雙屏手機就有內屏和外屏兩塊屏幕。由于目前Android的Surface系統只支持一塊屏幕,所以這個變量的取值都是0。 再分析另外一個createSurface函數,它的代碼如下所示: **SurfaceComposerClient.cpp** ~~~ 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) { ISurfaceFlingerClient::surface_data_t data; //調用BpSurfaceFlingerClient的createSurface函數 sp<ISurface> surface = mClient->createSurface(&data, pid,name, display, w, h,format, flags); if(surface != 0) { if (uint32_t(data.token) < NUM_LAYERS_MAX) { //以返回的ISurface對象創建一個SurfaceControl對象 result = new SurfaceControl(this, surface, data, w, h, format, flags); } } } returnresult;//返回的是SurfaceControl對象 } ~~~ 請求端的處理比較簡單: - 調用跨進程的createSurface函數,得到一個ISurface對象,根據Binder一章的知識可知,這個對象的真實類型是BpSurface。不過以后統稱之為ISurface。 - 以這個ISurface對象為參數,構造一個SurfaceControl對象。 createSurface函數的響應端在SurfaceFlinger進程中,下面去看這個函數。 在Surface系統定義了很多類型,咱們也中途休息一下,不妨來看看和字符串“Surface”有關的有多少個類,權當其為小小的 娛樂: Native層有Surface、ISurface、SurfaceControl、SurfaceComposerClient。 Java層有Surface、SurfaceSession。 上面列出的還只是一部分,后面還有呢!*&@&*%¥* (2)分析createSurface的響應端 前面講過,可把BClient看作是SF的Proxy,它會把來自客戶端的請求派發給SF處理,通過代碼來看看,是不是這樣的?如下所示: **SurfaceFlinger.cpp** ~~~ sp<ISurface> BClient::createSurface( ISurfaceFlingerClient::surface_data_t* params, int pid, const String8& name, DisplayID display, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { //果然是交給SF處理,以后我們將跳過BClient這個代理。 return mFlinger->createSurface(mId, pid,name, params, display, w, h, format, flags); } ~~~ 來看createSurface函數,它的目的就是創建一個ISurface對象,不過這中間的玄機還挺多,代碼如下所示: **SurfaceFlinger.cpp** ~~~ sp<ISurface>SurfaceFlinger::createSurface(ClientID clientId, int pid, const String8& name, ISurfaceFlingerClient::surface_data_t* params, DisplayID d, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { sp<LayerBaseClient> layer;//LayerBaseClient是Layer家族的基類 //這里又冒出一個LayerBaseClient的內部類,它也叫Surface,是不是有點頭暈了? sp<LayerBaseClient::Surface> surfaceHandle; Mutex::Autolock _l(mStateLock); //根據clientId找到createConnection時加入的那個Client對象 sp<Client> client = mClientsMap.valueFor(clientId); ...... //注意這個id,它的值表示Client創建的是第幾個顯示層,根據圖8-14可以看出,這個id //同時也表示將使用SharedBufferStatck數組的第id個元素。 int32_t id = client->generateId(pid); //一個Client不能創建多于NUM_LAYERS_MAX個的Layer。 if(uint32_t(id) >= NUM_LAYERS_MAX) { return surfaceHandle; } //根據flags參數來創建不同類型的顯示層,我們在8.4.1節介紹過相關知識 switch(flags & eFXSurfaceMask) { case eFXSurfaceNormal: if (UNLIKELY(flags & ePushBuffers)) { //創建PushBuffer類型的顯示層,我們將在拓展思考部分分析它 layer = createPushBuffersSurfaceLocked(client, d, id, w, h, flags); } else { //①創建Normal類型的顯示層,我們分析待會這個 layer = createNormalSurfaceLocked(client, d, id, w, h, flags, format); } break; case eFXSurfaceBlur: //創建Blur類型的顯示層 layer = createBlurSurfaceLocked(client, d, id, w, h, flags); break; case eFXSurfaceDim: //創建Dim類型的顯示層 layer = createDimSurfaceLocked(client, d, id, w, h, flags); break; } if(layer != 0) { layer->setName(name); setTransactionFlags(eTransactionNeeded); //從顯示層對象中取出一個ISurface對象賦值給SurfaceHandle surfaceHandle = layer->getSurface(); if(surfaceHandle != 0) { params->token = surfaceHandle->getToken(); params->identity = surfaceHandle->getIdentity(); params->width = w; params->height = h; params->format = format; } } returnsurfaceHandle;//ISurface的Bn端就是這個對象。 } ~~~ 上面代碼中的函數倒是很簡單,知識代碼里面冒出來的幾個新類型和它們的名字卻讓人有點頭暈。先用文字總結一下: - LayerBaseClient:前面提到的顯示層在代碼中的對應物,就是這個LayerBaseClient,不過這是一個大家族,不同類型的顯示層將創建不同類型的LayerBaseClient。 - LayerBaseClient中有一個內部類,名字叫Surface,這是一個支持Binder通信的類,它派生于ISurface。 關于Layer的故事,后面會有單獨的章節來介紹。這里先繼續分析createNormalSurfaceLocked函數。它的代碼如下所示: **SurfaceFlinger.cpp** ~~~ sp<LayerBaseClient>SurfaceFlinger::createNormalSurfaceLocked( const sp<Client>& client, DisplayID display, int32_t id, uint32_t w, uint32_t h, uint32_t flags, PixelFormat& format) { switch(format) { //一些圖像方面的參數設置,可以不去管它。 casePIXEL_FORMAT_TRANSPARENT: casePIXEL_FORMAT_TRANSLUCENT: format = PIXEL_FORMAT_RGBA_8888; break; casePIXEL_FORMAT_OPAQUE: format = PIXEL_FORMAT_RGB_565; break; } //①創建一個Layer類型的對象 sp<Layer> layer = new Layer(this, display,client, id); //②設置Buffer status_t err = layer->setBuffers(w, h, format, flags); if (LIKELY(err == NO_ERROR)) { //初始化這個新layer的一些狀態 layer->initStates(w, h, flags); //③ 還記得在圖8-10中提到的Z軸嗎?下面這個函數把這個layer加入到Z軸大軍中。 addLayer_l(layer); } ...... returnlayer; } ~~~ createNormalSurfaceLocked函數有三個關鍵點,它們是: - 構造一個Layer對象。 - 調用Layer對象的setBuffers函數。 - 調用SF的addLayer_l函數。 暫且記住這三個關鍵點,后文有單獨章節分析它們。先繼續分析SurfaceControl的流程。 (3)創建SurfaceControl對象 當跨進程的createSurface調用返回一個ISurface對象時,將通過下面的代碼創建一個SurfaceControl對象: ~~~ result = new SurfaceControl(this, surface, data,w, h,format, flags); ~~~ 下面來看這個SurfaceControl對象為何物。它的代碼如下所示: **SurfaceControl.cpp** ~~~ SurfaceControl::SurfaceControl( const sp<SurfaceComposerClient>& client, const sp<ISurface>& surface, const ISurfaceFlingerClient::surface_data_t& data, uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) //mClient為SurfaceComposerClient,而mSurface指向跨進程createSurface調用 //返回的ISurface對象。 :mClient(client), mSurface(surface), mToken(data.token), mIdentity(data.identity), mWidth(data.width), mHeight(data.height), mFormat(data.format), mFlags(flags) { } ~~~ SurfaceControl類可以看作是一個wrapper類: 它封裝了一些函數,通過這些函數可以方便地調用mClient或ISurface提供的函數。 在SurfaceControl的分析過程中,還遺留了和Layer相關的部分,下面就來解決它們。 2. Layer和它的家族 我們在createSurface中創建的是Normal的Layer,下面先看這個Layer的構造函數。 (1)Layer的構造 Layer是從LayerBaseClient派生的,其代碼如下所示: **Layer.cpp** ~~~ Layer::Layer(SurfaceFlinger* flinger, DisplayIDdisplay, const sp<Client>& c, int32_t i)//這個i表示SharedBufferStack數組的索引 : LayerBaseClient(flinger, display, c, i),//先調用基類構造函數 mSecure(false), mNoEGLImageForSwBuffers(false), mNeedsBlending(true), mNeedsDithering(false) { //getFrontBuffer實際取出的是FrontBuffer的位置 mFrontBufferIndex = lcblk->getFrontBuffer(); } ~~~ 再來看基類LayerBaseClient的構造函數,代碼如下所示: **LayerBaseClient.cpp** ~~~ LayerBaseClient::LayerBaseClient(SurfaceFlinger*flinger, DisplayID display, const sp<Client>& client, int32_t i) :LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i), mIdentity(uint32_t(android_atomic_inc(&sIdentity))) { /* 創建一個SharedBufferServer對象,注意它使用了SharedClient對象, 并且傳入了表示SharedBufferStack數組索引的i和一個常量NUM_BUFFERS */ lcblk = new SharedBufferServer( client->ctrlblk, i, NUM_BUFFERS,//該值為常量2,在Layer.h中定義 mIdentity); } ~~~ SharedBufferServer是什么?它和SharedClient有什么關系? 其實,之前在介紹SharedClient時曾提過與此相關的內容,這里再來認識一下,先看圖8-15: :-: ![](http://img.blog.csdn.net/20150802162659551?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖8-15 ShardBufferServer的示意圖 根據上圖并結合前面的介紹,可以得出以下結論: - 在SF進程中,Client的一個Layer將使用SharedBufferStack數組中的一個成員,并通過SharedBufferServer結構來控制這個成員,我們知道SF是消費者,所以可由SharedBufferServer來控制數據的讀取。 - 與之相對應,客戶端的進程也會有一個對象來使用這個SharedBufferStatck,可它是通過另外一個叫SharedBufferClient的結構來控制的。客戶端為SF提供數據,所以可由SharedBufferClient控制數據的寫入。在后文的分析中還會碰到SharedBufferClient。 注意,在拓展思考部分,會有單獨章節來分析生產/消費過程中的讀寫控制。 通過前面的代碼可知,Layer對象被new出來后,傳給了一個sp對象,讀者還記得sp中的onFirstRef函數嗎?Layer家族在這個函數中還有一些處理。一起去看看,但這個函數由基類LayerBaseClient實現。 **LayerBase.cpp** ~~~ void LayerBaseClient::onFirstRef() { sp<Client> client(this->client.promote()); if (client != 0) { //把自己加入client對象的mLayers數組中,這部分內容比較簡單,讀者可以自行研究 client->bindLayer(this, mIndex); } } ~~~ 好,Layer創建完畢,下面來看第二個重要的函數setBuffers。 (2)setBuffers的分析 setBuffers,Layer類以及Layer的基類都有實現。由于創建的是Layer類型的對象,所以請讀者直接到Layer.cpp中尋找setBuffers函數。這個函數的目的就是創建用于PageFlipping的FrontBuffer和BackBuffer。一起來看,代碼如下所示: **Layer.cpp** ~~~ status_t Layer::setBuffers( uint32_t w, uint32_th, PixelFormat format,uint32_t flags) { PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if(err) return err; //DisplayHardware是代表顯示設備的HAL對象,0代表第一塊屏幕的顯示設備。 //這里將從HAL中取出一些和顯示相關的信息。 constDisplayHardware& hw(graphicPlane(0).displayHardware()); uint32_t const maxSurfaceDims = min( hw.getMaxTextureSize(), hw.getMaxViewportDims()); PixelFormatInfo displayInfo; getPixelFormatInfo(hw.getFormat(),&displayInfo); constuint32_t hwFlags = hw.getFlags(); ...... /* 創建Buffer,這里將創建兩個GraphicBuffer。這兩個GraphicBuffer就是我們前面 所說的FrontBuffer和BackBuffer。 */ for (size_t i=0 ; i<NUM_BUFFERS ; i++) { //注意,這里調用的是GraphicBuffer的無參構造函數,mBuffers是一個二元數組。 mBuffers[i] = new GraphicBuffer(); } //又冒出來一個SurfaceLayer類型,#¥%……&*!@ mSurface = new SurfaceLayer(mFlinger, clientIndex(), this); returnNO_ERROR; } ~~~ setBuffers函數的工作內容比較簡單,就是: - 創建一個GraphicBuffer緩沖數組,元素個數為2,即FrontBuffer和BackBuffer。 - 創建一個SurfaceLayer,關于它的身世我們后續再介紹。 GraphicBuffer是Android提供的顯示內存管理類,關于它的故事,將在8.4.7節中介紹。我們暫把它當做普通的Buffer即可。 setBuffers中出現的SurfaceLayer類是什么?讀者可能對此感覺有些暈乎。待把最后一個關鍵函數addLayer_l介紹完,或許就不太暈了。 (3)addLayer_l的分析 addLayer_l把這個新創建的layer加入自己的Z軸大軍,下面來看: **SurfaceFlinger.cpp** ~~~ status_t SurfaceFlinger::addLayer_l(constsp<LayerBase>& layer) { /* mCurrentState是SurfaceFlinger定義的一個結構,它有一個成員變量叫 layersSortedByZ,其實就是一個排序數組。下面這個add函數將把這個新的layer按照 它在Z軸的位置加入到排序數組中。mCurrentState保存了所有的顯示層。 */ ssize_t i = mCurrentState.layersSortedByZ.add( layer,&LayerBase::compareCurrentStateZ); sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient*>(layer.get()); if(lbc != 0) { mLayerMap.add(lbc->serverIndex(), lbc); } returnNO_ERROR; } ~~~ 對Layer的三個關鍵函數都已分析過了,下面正式介紹Layer家族。 (4)Layer家族的介紹 前面的內容確讓人頭暈眼花,現在應該幫大家恢復清晰的頭腦。先來“一劑猛藥”,見圖8-16: :-: ![](http://img.blog.csdn.net/20150802162717491?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖8-16 Layer家族 通過上圖可知: - LayerBaseClient從LayerBase類派生。 - LayerBaseClient還有四個派生類,分別是Layer、LayerBuffer、LayerDim和LayerBlur。 - LayerBaseClient定義了一個內部類Surface,這個Surface從ISurface類派生,它支持Binder通信。 - 針對不同的類型,Layer和LayerBuffer分別有一個內部類SurfaceLayer和SurfaceLayerBuffer,它們繼承了LayerBaseClient的Surface類。所以對于Normal類型的顯示層來說,getSurface返回的ISurface對象的真正類型是SurfaceLayer。 - LayerDim和LayerBlur類沒有定義自己的內部類,所以對于這兩種類型的顯示層來說,它們直接使用了LayerBaseClient的Surface。 - ISurface接口提供了非常簡單的函數,如requestBuffer、postBuffer等。 這里大量使用了內部類。我們知道,內部類最終都會把請求派發給外部類對象來處理,既然如此,在以后分析中,如果沒有特殊情況,就會直接跳到外部類的處理函數中。 強烈建議Google把Surface相關代碼好好整理一下,至少讓類型名取得更直觀些,現在這樣確實有點讓人頭暈。好,來小小娛樂一下。看之前介紹的和“Surface”有關的名字: Native層有Surface、ISurface、SurfaceControl、SurfaceComposerClient。 Java層有Surface、SurfaceSession。 在介紹完Layer家族后,與它相關的名字又多了幾個,它們是 LayerBaseClient::Surface、Layer::SurfaceLayer、LayerBuffer::SurfaceLayerBuffer。 3. SurfaceControl總結 SurfaceControl創建后得到了什么呢?可用圖8-17來表示: :-: ![](http://img.blog.csdn.net/20150802162734012?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center) 圖8-17 SurfaceControl創建后的結果圖 通過上圖可以知道: - mClient成員變量指向SurfaceComposerClient。 - mSurface的Binder通信響應端為SurfaceLayer。 - SurfaceLayer有一個變量mOwner指向它的外部類Layer,而Layer有一個成員變量mSurface指向SurfaceLayer。這個SurfaceLayer對象由getSurface函數返回。 >[info] **注意**,mOwner變量由SurfaceLayer的基類Surface(LayBaseClient的內部類)定義。 接下來就是writeToParcel分析和Native Surface對象的創建了。注意,這個Native的Surface可不是LayBaseClient的內部類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>

                              哎呀哎呀视频在线观看