<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之旅 廣告
                Transaction是“事務”的意思。在我腦海中,關于事務的知識來自于數據庫。在數據庫操作中,事務意味著一次可以提交多個SQL語句,然后一個commit就可讓它們集中執行,而且數據庫中的事務還可以回滾,即恢復到事務提交前的狀態。 SurfaceFlinger為什么需要事務呢?從上面對數據庫事務的描述來看,是不是意味著一次執行多個請求呢?如直接盯著SF的源碼來分析,可能不太容易搞清楚事務的前因后果,我想還是用老辦法,從一個例子入手吧。 在WindowManagerService.java中,有一個函數之前分析過,現在再看看,代碼如下所示: **WindowManagerService.java::WinState** ~~~ Surface createSurfaceLocked() { Surface.openTransaction(); //開始一次transaction try { try { mSurfaceX = mFrame.left + mXOffset; mSurfaceY = mFrame.top + mYOffset; //設置Surface的位置 mSurface.setPosition(mSurfaceX, mSurfaceY); ...... } }finally { Surface.closeTransaction(); //關閉這次事務 } ~~~ 這個例子很好地展示了事務的調用流程,它會依次調用: - openTransaction - setPosition - closeTransaction 下面就來分析這幾個函數的調用。 1. openTransaction的分析 看JNI對應的函數,代碼如下所示: **android_View_Surface.cpp** ~~~ static void Surface_openTransaction(JNIEnv* env,jobject clazz) { //調用SurfaceComposerClient的openGlobalTransaction函數 SurfaceComposerClient::openGlobalTransaction(); } ~~~ 下面轉到SurfaceComposerClient,代碼如下所示: **SurfaceComposerClient.cpp** ~~~ voidSurfaceComposerClient::openGlobalTransaction() { Mutex::Autolock _l(gLock); ...... constsize_t N = gActiveConnections.size(); for(size_t i=0; i<N; i++) { sp<SurfaceComposerClient>client(gActiveConnections.valueAt(i).promote()); //gOpenTransactions存儲當前提交事務請求的Client if(client != 0 && gOpenTransactions.indexOf(client) < 0) { //Client是保存在全局變量gActiveConnections中的SurfaceComposerClient //對象,調用它的openTransaction。 if (client->openTransaction() == NO_ERROR) { if (gOpenTransactions.add(client) < 0) { client->closeTransaction(); } } ...... } } } ~~~ 上面是一個靜態函數,內部調用了各個SurfaceComposerClient對象的openTranscation,代碼如下所示: **SurfaceComposerClient.cpp** ~~~ status_tSurfaceComposerClient::openTransaction() { if(mStatus != NO_ERROR) return mStatus; Mutex::Autolock _l(mLock); mTransactionOpen++; //一個計數值,用來控制事務的提交。 if(mPrebuiltLayerState == 0) { mPrebuiltLayerState = new layer_state_t; } returnNO_ERROR; } ~~~ layer_state_t是用來保存Surface的一些信息的,比如位置、寬、高等信息。實際上,調用的setPosition等函數,就是為了改變這個layer_state_t中的值。 2. setPosition的分析 上文說過,SFC中有一個layer_state_t對象用來保存Surface的各種信息。這里以setPosition為例,來看它的使用情況。這個函數是用來改變surface在屏幕上的位置的,代碼如下所示: **android_View_Surface.cpp** ~~~ static void Surface_setPosition(JNIEnv* env,jobject clazz, jint x, jint y) { constsp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); if(surface == 0) return; status_t err = surface->setPosition(x, y); } ~~~ **Surface.cpp** ~~~ status_t SurfaceControl::setPosition(int32_t x,int32_t y) { constsp<SurfaceComposerClient>& client(mClient); status_t err = validate(); if (err < 0) return err; //調用SurfaceComposerClient的setPosition函數 returnclient->setPosition(mToken, x, y); } ~~~ **SurfaceComposerClient.cpp** ~~~ status_tSurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y) { layer_state_t* s = _lockLayerState(id); //找到對應的layer_state_t if(!s) return BAD_INDEX; s->what |= ISurfaceComposer::ePositionChanged; s->x = x; s->y = y; //上面幾句修改了這塊layer的參數 _unlockLayerState(); //該函數將unlock一個同步對象,其他沒有做什么工作 returnNO_ERROR; } ~~~ setPosition就是修改了layer_state_t中的一些參數,那么,這個狀態是什么時候傳遞到SurfaceFlinger中的呢? 3. 分析closeTransaction 相信讀者此時已明白為什么叫“事務”了。原來,在openTransaction和closeTransaction中可以有很多操作,然后由closeTransaction一次性地把這些修改提交到SF上,來看代碼: **android_View_Surface.cpp** ~~~ static void Surface_closeTransaction(JNIEnv*env, jobject clazz) { SurfaceComposerClient::closeGlobalTransaction(); } ~~~ **SurfaceComposerClient.cpp** ~~~ voidSurfaceComposerClient::closeGlobalTransaction() { ...... const size_t N = clients.size(); sp<ISurfaceComposer>sm(getComposerService()); //①先調用SF的openGlobalTransaction sm->openGlobalTransaction(); for (size_t i=0; i<N; i++) { //②然后調用每個SurfaceComposerClient對象的closeTransaction clients[i]->closeTransaction(); } //③最后調用SF的closeGlobalTransaction sm->closeGlobalTransaction(); } ~~~ 上面一共列出了三個函數,它們都是跨進程的調用,下面對其一一進行分析。 (1)SurfaceFlinger的openGlobalTransaction分析 這個函數其實很簡單,略看就行了。 **SurfaceFlinger.cpp** ~~~ void SurfaceFlinger::openGlobalTransaction() { android_atomic_inc(&mTransactionCount);//又是一個計數控制 } ~~~ (2)SurfaceComposerClient的closeTransaction分析 代碼如下所示: **SurfaceComposerClient.cpp** ~~~ status_tSurfaceComposerClient::closeTransaction() { if(mStatus != NO_ERROR) return mStatus; Mutex::Autolock _l(mLock); ...... constssize_t count = mStates.size(); if (count) { //mStates是這個SurfaceComposerClient中保存的所有layer_state_t數組,也就是 //每個Surface一個。然后調用跨進程的setState mClient->setState(count, mStates.array()); mStates.clear(); } returnNO_ERROR; } ~~~ BClient的setState,最終會轉到SF的setClientState上,代碼如下所示: **SurfaceFlinger.cpp** ~~~ status_t SurfaceFlinger::setClientState(ClientIDcid, int32_t count, const layer_state_t*states) { Mutex::Autolock _l(mStateLock); uint32_t flags = 0; cid<<= 16; for(int i=0 ; i<count ; i++) { const layer_state_t& s = states[i]; sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid)); if(layer != 0) { const uint32_t what = s.what; if (what & ePositionChanged) { if (layer->setPosition(s.x, s.y)) //eTraversalNeeded表示需要遍歷所有顯示層 flags |= eTraversalNeeded; } .... if(flags) { setTransactionFlags(flags);//這里將會觸發threadLoop的事件。 } returnNO_ERROR; } ~~~ **SurfaceFlinger.cpp** ~~~ uint32_tSurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay) { uint32_t old = android_atomic_or(flags, &mTransactionFlags); if((old & flags)==0) { if(delay > 0) { signalDelayedEvent(delay); }else { signalEvent(); //設置完mTransactionFlags后,觸發事件。 } } returnold; } ~~~ (3)SurfaceFlinger的closeGlobalTransaction分析 來看代碼: **SurfaceFlinger.cpp** ~~~ void SurfaceFlinger::closeGlobalTransaction() { if (android_atomic_dec(&mTransactionCount) ==1) { //注意下面語句的執行條件,當mTransactionCount變為零時才執行,這意味著 //openGlobalTransaction兩次的話,只有最后一個closeGlobalTransaction調用 //才會真正地提交事務 signalEvent(); Mutex::Autolock _l(mStateLock); //如果這次事務涉及尺寸調整,則需要等一段時間 while (mResizeTransationPending) { status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5)); if (CC_UNLIKELY(err != NO_ERROR)) { mResizeTransationPending = false; break; } } } } ~~~ 關于事務的目的,相信讀者已經比較清楚了: - 就是將一些控制操作(例如setPosition)的修改結果,一次性地傳遞給SF進行處理。 那么,哪些操作需要通過事務來傳遞呢?通過查看Surface.h可以知道,下面這些操作需要通過事務來傳遞(這里只列出了幾個經常用的函數):setPosition、setAlpha、show/hide、setSize、setFlag等。 由于這些修改不像重繪那么簡單,有時它會涉及其他的顯示層,例如在顯示層A的位置調整后,之前被A遮住的顯示層B,現在可能變得可見了。對于這種情況,所提交的事務會設置eTraversalNeeded標志,這個標志表示要遍歷所有顯示層進行處理。關于這一點,來看工作線程中的事務處理。 4. 工作線程中的事務處理 還是從代碼入手分析,如下所示: **SurfaceFlinger.cpp** ~~~ bool SurfaceFlinger::threadLoop() { waitForEvent(); if(LIKELY(mTransactionCount == 0)) { const uint32_t mask = eTransactionNeeded | eTraversalNeeded; uint32_ttransactionFlags = getTransactionFlags(mask); if(LIKELY(transactionFlags)) { handleTransaction(transactionFlags); } } ... } ~~~ getTransactionFlags函數的實現蠻有意思,不妨看看其代碼,如下所示: **SurfaceFlinger.cpp** ~~~ uint32_t SurfaceFlinger::getTransactionFlags(uint32_tflags) { //先通過原子操作去掉mTransactionFlags中對應的位。 //而后原子操作返回的舊值和flags進行與操作 return android_atomic_and(~flags,&mTransactionFlags) & flags; } ~~~ getTransactionFlags所做的工作不僅僅是get那么簡單,它還設置了mTransactionFlags,從這個角度來看,getTransactionFlags這個名字有點名不副實。 接著來看最重要的handleTransaction函數,代碼如下所示: **SurfaceFlinger.cpp** ~~~ void SurfaceFlinger::handleTransaction(uint32_ttransactionFlags) { Vector< sp<LayerBase> > ditchedLayers; { Mutex::Autolock _l(mStateLock); //調用handleTransactionLocked函數處理 handleTransactionLocked(transactionFlags, ditchedLayers); } constsize_t count = ditchedLayers.size(); for(size_t i=0 ; i<count ; i++) { if(ditchedLayers[i] != 0) { //ditch是丟棄的意思,有些顯示層可能被hide了,所以這里做些收尾的工作 ditchedLayers[i]->ditch(); } } } ~~~ **SurfaceFlinger.cpp** ~~~ void SurfaceFlinger::handleTransactionLocked( uint32_t transactionFlags, Vector< sp<LayerBase> >&ditchedLayers) { //這里使用了mCurrentState,它的layersSortedByZ數組存儲了SF中所有的顯示層 constLayerVector& currentLayers(mCurrentState.layersSortedByZ); constsize_t count = currentLayers.size(); constbool layersNeedTransaction = transactionFlags & eTraversalNeeded; //如果需要遍歷所有顯示的話。 if(layersNeedTransaction) { for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer = currentLayers[i]; uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) continue; //調用各個顯示層的doTransaction函數。 constuint32_t flags = layer->doTransaction(0); if (flags & Layer::eVisibleRegion) mVisibleRegionsDirty = true; } } if(transactionFlags & eTransactionNeeded) { if(mCurrentState.orientation != mDrawingState.orientation) { //橫豎屏如果發生切換,需要對應變換設置。 const int dpy = 0; const int orientation = mCurrentState.orientation; const uint32_t type = mCurrentState.orientationType; GraphicPlane& plane(graphicPlane(dpy)); plane.setOrientation(orientation); ...... } /* mLayersRemoved變量在顯示層被移除的時候設置,例如removeLayer函數,這些函數 也會觸發handleTranscation函數的執行 */ if(mLayersRemoved) { mLayersRemoved = false; mVisibleRegionsDirty = true; const LayerVector& previousLayers(mDrawingState.layersSortedByZ); const size_t count = previousLayers.size(); for (size_t i=0 ; i<count ; i++) { const sp<LayerBase>& layer(previousLayers[i]); if (currentLayers.indexOf( layer ) < 0) { ditchedLayers.add(layer); mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen); } } } free_resources_l(); } //提交事務處理,有必要進去看看。 commitTransaction(); } ~~~ 每個顯示層對事務的具體處理,都在它們的doTranscation函數中,讀者若有興趣,可進去看看。需要說明的是,每個顯示層內部也有一個狀態變量,doTransaction會更新這些狀態變量。 回到上面的函數,最后它將調用commitTransaction提交事務,代碼如下所示: **SurfaceFlinger.cpp** ~~~ void SurfaceFlinger::commitTransaction() { //mDrawingState將使用更新后的mCurrentState mDrawingState = mCurrentState; mResizeTransationPending = false; //觸發一個條件變量,這樣等待在closeGlobalTransaction函數中的線程可以放心地返回了。 mTransactionCV.broadcast(); } ~~~
                  <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>

                              哎呀哎呀视频在线观看