Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)渲染應(yīng)用程序UI的過(guò)程分析_第1頁(yè)
Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)渲染應(yīng)用程序UI的過(guò)程分析_第2頁(yè)
Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)渲染應(yīng)用程序UI的過(guò)程分析_第3頁(yè)
Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)渲染應(yīng)用程序UI的過(guò)程分析_第4頁(yè)
Android系統(tǒng)Surface機(jī)制的SurfaceFlinger服務(wù)渲染應(yīng)用程序UI的過(guò)程分析_第5頁(yè)
已閱讀5頁(yè),還剩45頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

Android系統(tǒng)Surface機(jī)制的

SurfaceFlinger服務(wù)渲染應(yīng)用程序UI的

過(guò)程分析在前面的一系列文章中,我們學(xué)習(xí)了Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系,以及SurfaceFlinger服務(wù)的啟動(dòng)過(guò)程、初始化硬件幀緩沖區(qū)的過(guò)程、線程模型。SurfaceFlinger服務(wù)所做的一切都是為了給Android應(yīng)用程序提服務(wù)的,即為Android應(yīng)用程序渲染它們的UI。在本文中,我們就詳細(xì)分析SurfaceFlinger服務(wù)渲染Android應(yīng)用程序UI的過(guò)程。從前面一文可以知道,SurfaceFlinger服務(wù)是通過(guò)它的UI渲染線程來(lái)將應(yīng)用程序的UI渲染到硬件幀緩沖區(qū)中去的,因此,接下來(lái)我們就通過(guò)分析SurfaceFlinger服務(wù)的UI渲染線程的執(zhí)行過(guò)程來(lái)分應(yīng)用程序UI的渲染過(guò)程,這個(gè)過(guò)程如圖1所示。[1■叩帀1[1■叩帀1- 從圖1就可以看出,SurfaceFlinger服務(wù)的UI渲染線程的執(zhí)行過(guò)程如下所示:1.調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)handleConsoleEvents來(lái)處理控制臺(tái)事件。2.調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)handleTransaction來(lái)處理系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化,例如大小、旋轉(zhuǎn)方向變化等。3.調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip來(lái)讓各個(gè)應(yīng)用程序窗口設(shè)置它們當(dāng)前所要渲染的圖形緩沖區(qū)。4.如果SurfaceFlinger服務(wù)在編譯的時(shí)候指定了USE_COMPOSITION_BYPASS宏,并且當(dāng)前需要渲染的應(yīng)用程序窗口只有一個(gè),那么就會(huì)調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)handleBypassLayer來(lái)直接將這個(gè)應(yīng)用程序窗口的圖形緩沖區(qū)渲染到硬件幀緩沖區(qū)中去,否則的話,就要調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)handleRepaint來(lái)合成所有的應(yīng)用程序窗口的圖形緩沖區(qū)到一個(gè)主圖形緩沖區(qū)中去。5.調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)postFramebuffer將前面得到的主圖形緩沖區(qū)渲染到硬件幀緩沖區(qū)中去。前面一文中,我們已經(jīng)分析過(guò)第1步的實(shí)現(xiàn)了,而通過(guò)前面這一系列文章的學(xué)習(xí),我們也已經(jīng)了解了應(yīng)用程序窗口的圖形緩沖區(qū)的創(chuàng)建過(guò)程,因此,接下來(lái)我們就在這些知識(shí)的基礎(chǔ)上來(lái)詳細(xì)分析第2步到第5的實(shí)現(xiàn),即分別分析SurfaceFlinger類(lèi)的成員函數(shù)handleTransaction、handlePageFlip、handleBypassLayer和postFramebuffer的實(shí)現(xiàn)。1.handleTransactionSurfaceFlinger類(lèi)的成員函數(shù)handleTransaction是用來(lái)處理系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化的,這個(gè)過(guò)程如圖2所示。這個(gè)過(guò)程可以分為6個(gè)步驟,接下來(lái)我們就詳細(xì)分析每一個(gè)步驟。Step1.SurfaceFlinger.handleTransaction[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidSurfaceFlinger::handleTransaction(uint32_ttransactionFlags){Vector<sp<LayerBase>>ditchedLayers;/**Performandcommitthetransaction*/{//scopeforthelockMutex::Autolock_l(mStateLock);constnsecs_tnow=systemTime();mDebugInTransaction=now;handleTransactionLocked(transactionFlags,ditchedLayers);mLastTransactionTime=systemTime()-now;mDebugInTransaction=0;//herethetransactionhasbeencommitted}/**Clean-upalllayersthatwentaway*(dothiswithoutthelockheld)*/constsize_tcount=ditchedLayers.size();for(size_ti=0;i<count;i++){if(ditchedLayers[i]!=0){//LOGD("ditchinglayer%p",ditchedLayers[i].get());ditchedLayers[i]->ditch();}}}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。SurfaceFlinger類(lèi)的成員函數(shù)handleTransaction是通過(guò)調(diào)用另外一個(gè)成員函數(shù)handleTransactionLocked來(lái)處理系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化的,而SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked在處理完成系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化之后,會(huì)返回系統(tǒng)中那些已經(jīng)銷(xiāo)毀了的應(yīng)用程序窗口。從這一系列文章可以知道,在SurfaceFlinger服務(wù)這一側(cè),應(yīng)用程序窗口一般是使用一個(gè)Layer對(duì)象來(lái)描述的,又由于Layer類(lèi)是從LayerBase類(lèi)繼承下來(lái)的,因此,我們可以那些已經(jīng)銷(xiāo)毀了的應(yīng)用程序窗口保存在一個(gè)類(lèi)型為spvLayerBase>的向量ditchedLayers中。SurfaceFlinger類(lèi)的成員函數(shù)handleTransaction最后就調(diào)用保存在向量ditchedLayers中的每一個(gè)LayerBase對(duì)象的成員函數(shù)dtich來(lái)執(zhí)行被銷(xiāo)毀的應(yīng)用程序窗口的清理操作,接下來(lái)我們就繼續(xù)分析SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked,看看它是如何處理系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化的。Step2.SurfaceFlinger.handleTransactionLockedSurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked定義在文件rameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中,我們分三段來(lái)閱讀:[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidSurfaceFlinger::handleTransactionLocked(uint32_ttransactionFlags,Vector<sp<LayerBase>>&ditchedLayers){constLayerVector¤tLayers(mCurrentState.layersSortedByZ);constsize_tcount=currentLayers.size();/*Traversalofthechildren(performthetransactionforeachofthemifneeded)*/constboollayersNeedTransaction=transactionFlags&eTraversalNeeded;if(layersNeedTransaction){for(size_ti=0;i<count;i++){constsp<LayerBase>&layer=currentLayers[i];uint32_ttrFlags=layer->getTransactionFlags(eTransactionNeeded);if(!trFlags)continue;constuint32_tflags=layer->doTransaction(0);if(flags&Layer::eVisibleRegion)mVisibleRegionsDirty=true;}}這段代碼用來(lái)處理應(yīng)用程序窗口的屬性變化。參數(shù)transactionFlags最開(kāi)始是從SurfaceFlinger類(lèi)的成員函數(shù)threadLoop傳進(jìn)來(lái)的。從前面一文可以知道,SurfaceFlinger類(lèi)的成員函數(shù)threadLoop在調(diào)用另外一個(gè)成員函數(shù)handleTransaction來(lái)處理系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化之前,首先會(huì)調(diào)用成員函數(shù)getTransactionFlags來(lái)檢查系統(tǒng)顯示屏或者應(yīng)用程序窗口的屬性是否發(fā)生了變化。如果系統(tǒng)顯示屏的屬性發(fā)生了變化,那么傳到這里的參數(shù)transactionFlags的eTransactionNeeded位就會(huì)等于1,而如果有應(yīng)用程序窗口的屬性發(fā)生了變化,那么傳到這里的參數(shù)transactionFlags的eTraversalNeeded位就會(huì)等于1。為了方便描述,我們假設(shè)系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性都發(fā)生了變化。SurfaceFlinger類(lèi)的成員變量mCurrentState指向了一個(gè)State對(duì)象,用來(lái)描述SufaceFlinger服務(wù)的當(dāng)前狀態(tài),其中,這個(gè)State對(duì)象的成員變量layersSortedByZ是一個(gè)類(lèi)型為L(zhǎng)ayerVector的向量,它里面保存了SufaceFlinger服務(wù)當(dāng)前所需要渲染的應(yīng)用程序窗口,而這些應(yīng)用程序窗口都是使用一個(gè)LayerBase對(duì)象來(lái)描述的。這段代碼首先獲得SufaceFlinger服務(wù)當(dāng)前所需要渲染的應(yīng)用程序窗口,接著再通過(guò)一個(gè)for循環(huán)來(lái)依次檢查每一個(gè)應(yīng)用程序窗口的屬性是否發(fā)生了變化。如果某一個(gè)應(yīng)用程序窗口的屬性被修改過(guò),那么調(diào)用用來(lái)描述這個(gè)應(yīng)用程序窗口的一個(gè)LayerBase對(duì)象的成員函數(shù)getTransactionFlags得到的返回值trFlags就不會(huì)等于0,在這種情況下,這段代碼就會(huì)調(diào)用這個(gè)LayerBase對(duì)象的成員函數(shù)doTransaction來(lái)處理對(duì)應(yīng)的應(yīng)用程序窗口的屬性變化。在LayerBase類(lèi)中,有一個(gè)類(lèi)型為int32_t的成員變量mTransactionFlags,每當(dāng)SurfaceFlinger服務(wù)修改某一個(gè)應(yīng)用程序窗口的屬性時(shí),都會(huì)將與其對(duì)應(yīng)的LayerBase的成員變量mTransactionFlags的相應(yīng)的位設(shè)置為1,這樣LayerBase類(lèi)的成員函數(shù)getTransactionFlags就可以通過(guò)這個(gè)成員變量來(lái)判斷一個(gè)應(yīng)用程序窗口的屬性是否發(fā)生變化了。如果一個(gè)應(yīng)用程序窗口發(fā)生的屬性變化是可見(jiàn)區(qū)域發(fā)生了改變,那么對(duì)應(yīng)的LayerBase對(duì)象的成員函數(shù)doTransaction的返回值flags的Layer::eVisibleRegion位就會(huì)等于1。在這種情況下,這段代碼就會(huì)將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值設(shè)置為true,表示后面要重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域。為了方便描述,我們假設(shè)發(fā)生了屬性變化的應(yīng)用程序窗口是一個(gè)普通類(lèi)型的Surface,即用來(lái)描述它的實(shí)際是一個(gè)從LayerBase類(lèi)繼承下來(lái)的Layer對(duì)象。在這種情況下,前面實(shí)際上調(diào)用了Layer類(lèi)的成員函數(shù)doTransaction來(lái)處理一個(gè)應(yīng)用程序窗口的屬性變化。在接下來(lái)的Step3中,我們?cè)僭敿?xì)分析Layer類(lèi)的成員函數(shù)doTransaction的實(shí)現(xiàn),現(xiàn)在我們接著往下閱讀SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked的代碼:[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片/**Performourowntransactionifneeded*/if(transactionFlags&eTransactionNeeded){if(mCurrentState.orientation!=mDrawingState.orientation){//theorientationhaschanged,recomputeallvisibleregions//andinvalidateeverything.constintdpy=0;constintorientation=mCurrentState.orientation;constuint32_ttype=mCurrentState.orientationType;GraphicPlane&plane(graphicPlane(dpy));plane.setOrientation(orientation);//updatethesharedcontrolblockconstDisplayHardware&hw(plane.displayHardware());volatiledisplay_cblk_t*dcblk=mServerCblk->displays+dpy;dcblk->orientation=orientation;dcblk->w=plane.getWidth();dcblk->h=plane.getHeight();mVisibleRegionsDirty=true;mDirtyRegion.set(hw.bounds());}if(mCurrentState.freezeDisplay!=mDrawingState.freezeDisplay){//freezingorunfreezingthedisplay->triggeranimationifneededmFreezeDisplay=mCurrentState.freezeDisplay;if(mFreezeDisplay)mFreezeDisplayTime=0;}if(currentLayers.size()>mDrawingState.layersSortedByZ.size()){//layershavebeenaddedmVisibleRegionsDirty=true;}//somelayersmighthavebeenremoved,so//weneedtoupdatetheregionsthey'reexposing.if(mLayersRemoved){mLayersRemoved=false;mVisibleRegionsDirty=true;constLayerVector&previousLayers(mDrawingState.layersSortedByZ);constsize_tcount=previousLayers.size();for(size_ti=0;i<count;i++){constsp<LayerBase>&layer(previousLayers[i]);if(currentLayers.indexOf(layer)<0){//thislayerisnotvisibleanymoreditchedLayers.add(layer);mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);}}}}這段代碼用來(lái)處理系統(tǒng)顯示屏的屬性變化。在分析這段代碼之前,我們首先了解SurfaceFlinger類(lèi)的另外一個(gè)成員變量mDrawingState的含義。SurfaceFlinger類(lèi)的成員變量mDrawingState與前面所介紹的成員變量mCurrentState類(lèi)似,它的類(lèi)型也為State,不過(guò)它是用來(lái)描述SufaceFlinger服務(wù)的上一次渲染狀態(tài)的。通過(guò)這兩個(gè)成員變量的比較,我們就可以知道系統(tǒng)顯示屏的哪一個(gè)屬性發(fā)生了變化。前面提到,當(dāng)系統(tǒng)顯示屏的屬性發(fā)生了變化,那么參數(shù) transactionFlags的eTransactionNeeded位就會(huì)等于1,在這種情況,這段代碼就需要完成四件事情。第一件事情是判斷系統(tǒng)顯示屏的旋轉(zhuǎn)方向是否發(fā)生變化。State類(lèi)的成員變量orientation用來(lái)描述顯示屏的方向,因此,當(dāng)SurfaceFlinger類(lèi)的成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量orientation的值不等于SurfaceFlinger類(lèi)的成員變量mDrawingState所描述的一個(gè)State對(duì)象的成員變量orientation的值時(shí),就說(shuō)明系統(tǒng)顯示屏的旋轉(zhuǎn)方向發(fā)生了變化。在這種情況下,我們就需要將系統(tǒng)顯示屏的旋轉(zhuǎn)方向設(shè)置為SurfaceFlinger類(lèi)的成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量orientation的值,這是通過(guò)調(diào)用編號(hào)為0的一個(gè)GraphicPlane對(duì)象的成員函數(shù)setOrientation來(lái)實(shí)現(xiàn)的。SurfaceFlinger服務(wù)的UI渲染線程在初始化的過(guò)程中,除了會(huì)初始化硬件幀緩沖區(qū)之外,還會(huì)創(chuàng)建一個(gè)類(lèi)型為surface_flinger_cblk_t的對(duì)象,用來(lái)描述系統(tǒng)顯示屏的信息,例如大小和旋轉(zhuǎn)方向等,以便其它進(jìn)程可以通過(guò)這個(gè)surface_flinger_cblk_t對(duì)象來(lái)獲得系統(tǒng)顯示屏的信息。這個(gè)surface_flinger_cblk_t對(duì)象就保存在SurfaceFlinger類(lèi)的成員變量mServerCblk中。因此,當(dāng)系統(tǒng)顯示屏的旋轉(zhuǎn)方向發(fā)生了變化時(shí),我們還需要將變化后的旋轉(zhuǎn)方向保存在SurfaceFlinger類(lèi)的成員變量mServerCblk所描述的一個(gè)surface_flinger_cblk_t對(duì)象中。由于系統(tǒng)顯示屏的旋轉(zhuǎn)方向變化一般意味著寬度和高度也會(huì)發(fā)生變化,因此,我們還需要將旋轉(zhuǎn)發(fā)生變化后得到的系統(tǒng)顯示屏的寬度和高度值保存在SurfaceFlinger類(lèi)的成員變量mServerCblk所描述的一個(gè)surface_flinger_cblk_t對(duì)象中。系統(tǒng)顯示屏的旋轉(zhuǎn)方向同時(shí)也意味著我們需要重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域以及重新繪制整個(gè)顯示屏,因此,在這種情況下,我們還需要將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值設(shè)置為true,以及將SurfaceFlinger類(lèi)的成員變量mDirtyRegion的大小設(shè)置為整個(gè)顯示屏的大小,即將系統(tǒng)UI的臟區(qū)域設(shè)置為整個(gè)顯示屏的大小。第二件事情是判斷系統(tǒng)顯示屏的凍結(jié)狀態(tài)是否發(fā)生變化。State類(lèi)的成員變量freezeDisplay用來(lái)描述顯示屏的凍結(jié)狀態(tài),因此,當(dāng)SurfaceFlinger類(lèi)的成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量freezeDisplay的值不等于SurfaceFlinger類(lèi)的成員變量mDrawingState所描述的一個(gè)State對(duì)象的成員變量freezeDisplay的值時(shí),就說(shuō)明系統(tǒng)顯示屏的凍結(jié)狀態(tài)發(fā)生了變化。在這種情況下,我們就需要將SurfaceFlinger類(lèi)的成員變量mFreezeDisplay的值設(shè)置為SurfaceFlinger類(lèi)的成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量freezeDisplay的值。如果顯示屏的是由解凍狀態(tài)變化為凍結(jié)狀態(tài)的,那么還需要將顯示屏的凍結(jié)時(shí)間設(shè)置為0,即將SurfaceFlinger類(lèi)的成員變量mFreezeDisplayTime的值設(shè)置為0,以便可以將顯示屏進(jìn)入到凍結(jié)狀態(tài)的最長(zhǎng)時(shí)間設(shè)置為一個(gè)默認(rèn)值,這一點(diǎn)可以參考前面一文。第三件事情是判斷是否新增了應(yīng)用程序窗口。State類(lèi)的成員變量layersSortedByZ是一個(gè)類(lèi)型LayerVector的向量,里面保存的是SurfaceFlinger服務(wù)在某一個(gè)狀態(tài)下所擁有的應(yīng)用程序窗口,因此,當(dāng)SurfaceFlinger類(lèi)的成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量layersSortedByZ所指向的一個(gè)向量的大小值大于SurfaceFlinger類(lèi)的成員變量mDrawingState所描述的一個(gè)State對(duì)象的成員變量layersSortedByZ所指向的一個(gè)向量的大小值時(shí),就說(shuō)明系統(tǒng)新增了應(yīng)用程序窗口。在這種情況下,我們就需要將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值設(shè)置為true,以表示我們需要重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域。第四件事情是判斷是否移除了某些應(yīng)用程序窗口。SurfaceFlinger類(lèi)的成員變量mLayersRemoved用來(lái)描述是否有應(yīng)用程序窗口被移除了。如果有有應(yīng)用程序窗口被移除的話,那么這個(gè)成員變量的值就會(huì)等于true。在這種情況下,我們就需要是哪些應(yīng)用程序窗口被移除了。計(jì)算的方法很簡(jiǎn)單,如果一個(gè)應(yīng)用程序窗口存在于SurfaceFlinger類(lèi)的成員變量mDrawingState所描述的一個(gè)State對(duì)象的成員變量layersSortedByZ所指向的一個(gè)向量中,但是不存在于SurfaceFlinger類(lèi)的成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量layersSortedByZ所指向的一個(gè)向量中,那么就說(shuō)明這個(gè)應(yīng)用程序窗口被移除了,因此,就需要將它保存輸出參數(shù)ditchedLayers所描述的一個(gè)向量中,以便可以返回給上一步來(lái)處理。SurfaceFlinger類(lèi)的成員變量mDirtyRegionRemovedLayer用來(lái)描述那些被移除了的應(yīng)用程序窗口所占用的區(qū)域,因此,每當(dāng)我們移除一個(gè)應(yīng)用程序窗口的時(shí)候,都需要將它所占用的區(qū)域增加到SurfaceFlinger類(lèi)的成員變量mDirtyRegionRemovedLayer所描述的一個(gè)區(qū)域去。當(dāng)處理完成那些被移除的應(yīng)用程序窗口之后,我們就需要將SurfaceFlinger類(lèi)的成員變量mLayersRemoved的值設(shè)置為false,并且將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值設(shè)置為true,以表示我們需要重新計(jì)算現(xiàn)存的各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域。處理完成系統(tǒng)顯示屏的屬性變化之后,我們接著向下閱讀SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked的最后一行代碼:[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片commitTransaction();這段代碼只有一行,即調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)commitTransaction來(lái)告訴SurfaceFlinger服務(wù),系統(tǒng)顯示屏以及各個(gè)應(yīng)用程序窗口的屬性變化已經(jīng)處理完畢,這時(shí)候SurfaceFlinger服務(wù)就可以切換狀態(tài)了。在后面的Step6中,我們?cè)僭敿?xì)分析SurfaceFlinger類(lèi)的成員函數(shù)commitTransaction的實(shí)現(xiàn)。接下來(lái),我們就繼續(xù)分析Layer類(lèi)的成員函數(shù)doTransaction的實(shí)現(xiàn),以便可以了解應(yīng)用程序窗口的屬性變化的處理過(guò)程。Step3.Layer.doTransaction[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片uint32_tLayer::doTransaction(uint32_tflags){constLayer::State&front(drawingState());constLayer::State&temp(currentState());constboolsizeChanged=(front.requested_w!=temp.requested_w)||(front.requested_h!=temp.requested_h);if(sizeChanged){if(!isFixedSize()){//we'rebeingresizedandthereisafreezedisplayrequest,//acquireafreezelock,sothatthescreenstaysput//untilwe'veredrawnatthenewsize;thisistoavoid//glitchesuponorientationchanges.if(mFlinger->hasFreezeRequest()){//ifthesurfaceishidden,don'ttrytoacquirethe//freezelock,sincehiddensurfacesmayneverredrawif(!(front.flags&ISurfaceComposer::eLayerHidden)){

mFreezeLock=mFlinger->getFreezeLock();}}//thiswillmakesureLayerBase::doTransactiondoesn'tupdate//thedrawingstate'ssizeLayer::State&editDraw(mDrawingState);editDraw.requested_w=temp.requested_w;editDraw.requested_h=temp.requested_h;//recordthenewsize,formthispointon,whentheclientrequest//abuffer,it'llgetthenewsize.setBufferSize(temp.requested_w,temp.requested_h);ClientRef::AccesssharedClient(mUserClientRef);SharedBufferServer*lcblk(sharedClient.get());if(lcblk){//allbuffersneedreallocationlcblk->reallocateAll();}}else{//recordthenewsizesetBufferSize(temp.requested_w,temp.requested_h);}}if(temp.sequence!=front.sequence){if(temp.flags&ISurfaceComposer::eLayerHidden||temp.alpha==0){//thissurfaceisnowhidden,soitshouldn'tholdafreezelock//(itmayneverredraw,whichisfineifitishidden)mFreezeLock.clear();}}returnLayerBase::doTransaction(flags);}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。和SurfaceFlinger服務(wù)類(lèi)似,每一個(gè)應(yīng)用程序窗口在內(nèi)部也分別使用兩個(gè)類(lèi)型為State的成員變量mDrawingState和mCurrentState來(lái)描述上一次的渲染狀態(tài)和下一次的渲染狀態(tài)。這兩個(gè)成員變量是從LayerBase類(lèi)繼承下來(lái)的,用來(lái)描述應(yīng)用程序窗口的Layer類(lèi)可以分別通過(guò)從父類(lèi)LayerBase繼承下來(lái)的成員函數(shù)drawingState和currentState來(lái)訪問(wèn)它們。注意,這里所說(shuō)的State類(lèi)是定義在LayerBase類(lèi)內(nèi)部的,而SurfaceFlinger服務(wù)使用的State類(lèi)是定義在SurfaceFlinger類(lèi)內(nèi)部的,它們是不一樣的。Layer類(lèi)的成員函數(shù)doTransaction首先調(diào)用從父類(lèi)LayerBase繼承下來(lái)的成員函數(shù)drawingState和currentstate來(lái)獲得當(dāng)前正在處理的應(yīng)用程序窗口的上一次的渲染狀態(tài)和下一次的渲染狀態(tài),并且分別保存在兩個(gè)類(lèi)型為State的變量front和temp中。State類(lèi)的成員變量requested_w和requested_h分別用來(lái)描述應(yīng)用程序窗口的寬度和高度,因此,當(dāng)State變量front的成員變量requested_w和requested」不等于State變量temp的成員變量requested_w和requested」時(shí),我們就會(huì)得到變量sizeChanged的值等于true,表示當(dāng)前正在處理的應(yīng)用程序窗口的大小發(fā)生了變化。在分析Layer類(lèi)的成員函數(shù)doTransaction處理應(yīng)用程序窗口的大小變化時(shí),我們先介紹Layer類(lèi)的成員變量mFixedSize的含義。Layer類(lèi)的成員變量mFixedSize是一個(gè)布爾變量,它的值可以通過(guò)Layer類(lèi)的成員函數(shù)isFixedSize來(lái)獲得。從前面 一文可以知道,當(dāng)Android應(yīng)用程序請(qǐng)求SurfaceFlinger服務(wù)分配一塊圖形緩沖區(qū)時(shí),Layer類(lèi)的成員函數(shù)requestBuffer就會(huì)被調(diào)用。這時(shí)候Android應(yīng)用程序會(huì)傳遞兩個(gè)參數(shù)reqWidth和reqHeight過(guò)來(lái),表示請(qǐng)求分配的圖形緩沖區(qū)的寬度和高度。這兩個(gè)參數(shù)是可以同時(shí)等于0的,表示使用默認(rèn)的寬度和高度值來(lái)創(chuàng)建所請(qǐng)求的圖形緩沖區(qū)。這兩個(gè)默認(rèn)的寬度和高度值即等于當(dāng)前所處理的應(yīng)用程序窗口的寬度和高度值,而后者的寬度和高度值是在其創(chuàng)建的時(shí)候指定的,這一點(diǎn)可以參考一文。Layer類(lèi)的成員函數(shù)requestBuffer的參數(shù)reqWidth和reqHeight的值等于0意味著什么呢?從前面 一文還可以知道‘Android應(yīng)用程序在請(qǐng)求SurfaceFlinger服務(wù)分配一塊圖形緩沖區(qū)之前,會(huì)通過(guò)在Surface類(lèi)內(nèi)部定義的BufferInfo類(lèi)的成員函數(shù)validateBuffer來(lái)檢查當(dāng)前所處理的應(yīng)用程序窗口的大小是否發(fā)生了變化。如果發(fā)生了變化,那么Android應(yīng)用程序就會(huì)忽略掉緩存自己一側(cè)的圖形緩沖區(qū),而去SurfaceFlinger服務(wù)請(qǐng)求新的圖形緩沖區(qū),因?yàn)槟切┚彺娴膱D形緩沖區(qū)由于與它們所關(guān)聯(lián)的應(yīng)用程序窗口大小發(fā)生了變化而變?yōu)闊o(wú)效了。但是有一種特殊情況,在Android應(yīng)用程序這一側(cè),用來(lái)描述應(yīng)用程序窗口的Surface類(lèi)可以不維護(hù)應(yīng)用程序窗口的大小值。在這種情況下,Surface類(lèi)就會(huì)將與它所關(guān)聯(lián)的應(yīng)用程序窗口的大小值設(shè)置為0,這意味著Android應(yīng)用程序每次為這個(gè)應(yīng)用程序窗口向SurfaceFlinger服務(wù)請(qǐng)求分配圖形緩沖區(qū)之前,都認(rèn)為這個(gè)應(yīng)用程序窗口的大小值沒(méi)有發(fā)生變化,同時(shí)傳遞給Layer類(lèi)的成員函數(shù)requestBuffer的參數(shù)reqWidth和reqHeight的值會(huì)等于0。事實(shí)上,一個(gè)應(yīng)用程序窗口的大小是隨時(shí)都可以發(fā)生變化的,比如,我們可以通過(guò)調(diào)用用來(lái)在Android應(yīng)用程序和SurfaceFlinger服務(wù)建立連接的一個(gè)類(lèi)型為Client的Binder對(duì)象的成員函數(shù)setState來(lái)改變一個(gè)應(yīng)用程序窗口的大小,而一旦一個(gè)應(yīng)用程序窗口的大小發(fā)生了變化,我們正在分析Layer類(lèi)的成員函數(shù)doTransaction就會(huì)被調(diào)用。從上面的分析就可以得出一個(gè)結(jié)論,Layer類(lèi)的成員函數(shù)doTransaction在處理應(yīng)用程序窗口大小變化時(shí),需要考慮Android應(yīng)用程序每次在為該應(yīng)用程序窗口向SurfaceFlinger服務(wù)請(qǐng)求分配圖形緩沖區(qū)之前,是否有能力去判斷之前為該應(yīng)用程序窗口緩存的圖形緩沖區(qū)的有效性。如果沒(méi)有的話,那么Layer類(lèi)的成員函數(shù)doTransaction就需要將為該應(yīng)用程序窗口緩存的圖形緩沖區(qū)設(shè)置為無(wú)效,以便以后Android應(yīng)用程序可以請(qǐng)求SurfaceFlinger服務(wù)分配新的、大小正確的圖形緩沖區(qū)。從前面的分析還可以知道,當(dāng)Android應(yīng)用程序沒(méi)有能力去判斷之前為一個(gè)應(yīng)用程序窗口所緩存的圖形緩沖區(qū)的有效性時(shí),那么之前在請(qǐng)求分配這些圖形緩沖區(qū)時(shí),傳遞給Layer類(lèi)的成員函數(shù)requestBuffer的參數(shù)reqWidth和reqHeight的值就會(huì)等于0,這時(shí)候Layer類(lèi)的成員函數(shù)requestBuffer就會(huì)將Layer類(lèi)的成員變量mFixedSize的值設(shè)置為false。接下來(lái),我們就分別根據(jù)Layer類(lèi)的成員變量mFixedSize是等于true還是false來(lái)分析Layer類(lèi)的成員函數(shù)doTransaction處理一個(gè)應(yīng)用程序窗口大小發(fā)生變化的過(guò)程。當(dāng)Layer類(lèi)的成員變量mFixedSize的值等于true時(shí),Layer類(lèi)的成員函數(shù)doTransaction的處理很簡(jiǎn)單,它只是調(diào)用另外一個(gè)成員函數(shù)setBufferSize來(lái)將新的應(yīng)用程序窗口大小記錄下來(lái),即保存在Layer類(lèi)的成員變量mWidth和mHeight中。當(dāng)Layer類(lèi)的成員變量mFixedSize的值等于false時(shí),由于Android應(yīng)用程序沒(méi)有能力去判斷之前為一個(gè)應(yīng)用程序窗口所緩存的圖形緩沖區(qū)的有效性,因此,Layer類(lèi)的成員函數(shù)doTransaction除了會(huì)調(diào)用外一個(gè)成員函數(shù)setBufferSize來(lái)將新的應(yīng)用程序窗口大小記錄下來(lái)之外,還會(huì)通過(guò)一個(gè)SharedBufferServer對(duì)象的成員函數(shù)reallocateAll來(lái)將為當(dāng)前正在處理的應(yīng)用程序窗口所緩存的圖形緩沖區(qū)設(shè)置為無(wú)效。在前面一文中,我們已經(jīng)分析過(guò)SharedBufferServer類(lèi)的作用了,它是用來(lái)維護(hù)Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)的,通過(guò)它可以將對(duì)應(yīng)的圖形緩沖區(qū)設(shè)置為無(wú)效。當(dāng)Layer類(lèi)的成員變量mFixedSize的值等于false時(shí),Layer類(lèi)的成員函數(shù)doTransaction還會(huì)提前將成員變量mCurrentState所描述的一個(gè)State對(duì)象的成員變量requested_w和requested_h的值保存到成員變量mDrawingState所描述的一個(gè)State對(duì)象的成員變量requested_w和requested_h中去,這是為了避免后面調(diào)用父類(lèi)LayerBase的成員函數(shù)doTransaction時(shí),會(huì)返回一個(gè)Layer::eVisibleRegion位不等于0的標(biāo)志值給前面的Step2,而這將會(huì)導(dǎo)致SurfaceFlinger服務(wù)馬上重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域?,F(xiàn)在不返回一個(gè)Layer::eVisibleRegion位不等于0的標(biāo)志值給前面的Step2,就會(huì)等到下次渲染當(dāng)前正在處理的應(yīng)用程序窗口時(shí)再重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域。此外,當(dāng)Layer類(lèi)的成員變量mFixedSize的值等于false時(shí),Layer類(lèi)的成員函數(shù)doTransaction還會(huì)檢查系統(tǒng)顯示屏是否正處于凍結(jié)的狀態(tài),這是通過(guò)調(diào)用Layer類(lèi)的成員變量mFlinger所指向的SurfaceFlinger服務(wù)的成員函數(shù)hasFreezeRequest來(lái)實(shí)現(xiàn)的。如果系統(tǒng)顯示屏處于凍結(jié)的狀態(tài)中,并且當(dāng)前正在處理的應(yīng)用程序窗口處于可見(jiàn)狀態(tài),即變量front所描述的State對(duì)象的成員變量flags的ISurfaceComposer::eLayerHidden位等于0,那么Layer類(lèi)的成員函數(shù)doTransaction還會(huì)請(qǐng)求獲得一個(gè)用來(lái)凍結(jié)系統(tǒng)顯示屏的類(lèi)型為FreezeLock的鎖,并且將這個(gè)鎖保存在Layer類(lèi)的成員變量mFreezeLock中。這樣就可以等到下次渲染當(dāng)前正在處理的應(yīng)用程序窗口時(shí),再來(lái)刷新系統(tǒng)的UI。State類(lèi)的另外一個(gè)成員變量sequence用來(lái)描述一個(gè)應(yīng)用程序窗口的其它屬性是否發(fā)生過(guò)變化,例如,X、Y和Z軸位置、透明度等除了大小之外的屬性。每當(dāng)這些屬性發(fā)生了變化,那么State類(lèi)的成員變量sequence的值就會(huì)比原來(lái)增加1。Layer類(lèi)的成員函數(shù)doTransaction再接下來(lái)就通過(guò)比較變量temp和front所描述的State對(duì)象的成員變量sequence的值是否相等來(lái)判斷當(dāng)前正在處理的應(yīng)用程序窗口的其它屬性是否發(fā)生變化。如果發(fā)生過(guò)變化,并且當(dāng)前正在處理的應(yīng)用程序窗口處于不可見(jiàn)狀態(tài)或者處于完全透明的狀態(tài),那么Layer類(lèi)的成員函數(shù)doTransaction就會(huì)釋放之前所持有的用來(lái)凍結(jié)系統(tǒng)顯示屏的一個(gè)類(lèi)型為FreezeLock的鎖,這是通過(guò)調(diào)用Layer類(lèi)的成員變量mFreezeLock所指向的一個(gè)FreezeLock對(duì)象的成員函數(shù)clear來(lái)實(shí)現(xiàn)的,這樣就可以避免阻止SurfaceFlinger服務(wù)更新系統(tǒng)UI。最后,Layer類(lèi)的成員函數(shù)doTransaction調(diào)用父類(lèi)LayerBase的成員函數(shù)doTransaction來(lái)繼續(xù)處理應(yīng)用程序窗口的屬性變化。Step4.LayerBase.doTransaction[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片uint32_tLayerBase::doTransaction(uint32_tflags){constLayer::State&front(drawingState());constLayer::State&temp(currentState());if((front.requested_w!=temp.requested_w)||(front.requested_h!=temp.requested_h)){//resizethelayer,setthephysicalsizetotherequestedsizeLayer::State&editTemp(currentState());editTemp.w=temp.requested_w;editTemp.h=temp.requested_h;}if((front.w!=temp.w)||(front.h!=temp.h)){//invalidateandrecomputethevisibleregionsifneededflags|=Layer::eVisibleRegion;}if(temp.sequence!=front.sequence){//invalidateandrecomputethevisibleregionsifneededflags|=eVisibleRegion;this->contentDirty=true;//wemayuselinearfiltering,ifthematrixscalesusconstuint8_ttype=temp.transform.getType();mNeedsFiltering=(!temp.transform.preserveRects()||(type>=Transform::SCALE));}//CommitthetransactioncommitTransaction();returnflags;}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/LayerBase.cpp中。與前面的Step3一樣,LayerBase類(lèi)的成員函數(shù)doTransaction首先通過(guò)成員函數(shù)drawingState和currentState來(lái)獲得用來(lái)描述當(dāng)前正在處理的應(yīng)用程序窗口的當(dāng)前渲染狀態(tài)的一個(gè)State對(duì)象front和下一次渲染狀態(tài)的一個(gè)State對(duì)象temp,接下來(lái)就可以通過(guò)這兩個(gè)State對(duì)象的成員變量requested_w和requested_h來(lái)判斷當(dāng)前正在處理的應(yīng)用程序窗口的大小是否發(fā)生了變化。如果發(fā)生了變化,那么就將新的應(yīng)用程序窗口大小值保存在用來(lái)描述下一次渲染狀態(tài)的State對(duì)象editTemp的成員變量w和h中。State類(lèi)的成員變量requested_w、requested」和w、h的區(qū)別在于,前兩者用來(lái)描述應(yīng)用程序窗口的大小,后兩者雖然也是用來(lái)描述應(yīng)用程序窗口的大小,不過(guò)它們的作用是用來(lái)判斷是否需要重新計(jì)算系統(tǒng)中的各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域的。一旦用來(lái)描述應(yīng)用程序窗口的當(dāng)前渲染狀態(tài)的State對(duì)象front和下一次渲染狀態(tài)的State對(duì)象temp的成員變量w和h不相等,那么就說(shuō)明需要系統(tǒng)中的各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域,這是通過(guò)將將返回值flags的Layer::eVisibleRegion位設(shè)置為1來(lái)實(shí)現(xiàn)的。LayerBase類(lèi)的成員函數(shù)doTransaction接下來(lái)還會(huì)繼續(xù)判斷State對(duì)象front和temp的成員變量sequence的值是否相等。如果不相等,那么就說(shuō)明當(dāng)前正在處理的應(yīng)用程序窗口的其它屬性,例如位置和透明度等發(fā)生了變化。在這種情況下,SurfaceFlinger服務(wù)也是需要重新計(jì)算系統(tǒng)中的各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域的。因此,這時(shí)候LayerBase類(lèi)的成員函數(shù)doTransaction就會(huì)將它的返回值flags的Layer::eVisibleRegion位設(shè)置為1,并且將Layer類(lèi)的成員變量contentDirty的值設(shè)置為true,表示當(dāng)前正在處理的應(yīng)用程序窗口的內(nèi)容是臟的,需要重新渲染。LayerBase類(lèi)的成員函數(shù)doTransaction最后還會(huì)繼續(xù)調(diào)用另外一個(gè)成員函數(shù)commitTransaction來(lái)結(jié)束對(duì)當(dāng)前正在處理的應(yīng)用程序窗口的屬性變化處理,以及將返回值flags返回給前面的Step2,即SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked。SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked一旦發(fā)現(xiàn)這個(gè)返回值的Layer::eVisibleRegion位的值為1,那么就會(huì)將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值設(shè)置為true,以便接下來(lái)可以重新計(jì)算系統(tǒng)中的各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域。接下來(lái),我們就繼續(xù)分析LayerBase類(lèi)的成員函數(shù)commitTransaction的實(shí)現(xiàn)。Step5.LayerBmitTransaction[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidLayerBase::commitTransaction(){mDrawingState=mCurrentState;}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/LayerBase.cpp中。由于此時(shí)當(dāng)前正在處理的應(yīng)用程序窗口的屬性變化已經(jīng)處理完成了,因此,LayerBase類(lèi)的成員函數(shù)commitTransaction就將用來(lái)描述下一次渲染狀態(tài)的成員變量mCurrentState所描述的一個(gè)State對(duì)象保存在另外一個(gè)用來(lái)描述當(dāng)前渲染狀態(tài)的成員變量mDrawingState中去。這一步執(zhí)行完成之后,返回到前面的Step2中,即SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked中,這時(shí)候系統(tǒng)顯示屏的屬性變化以及各個(gè)應(yīng)用程序的屬性變化就都已經(jīng)處理完成了,SurfaceFlinger類(lèi)的成員函數(shù)handleTransactionLocked最后就會(huì)調(diào)用另外一個(gè)成員函數(shù)commitTransaction來(lái)結(jié)束整個(gè)屬性變化處理過(guò)程。Step6.SurfaceFmitTransaction[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidSurfaceFlinger::commitTransaction(){mDrawingState=mCurrentState;mResizeTransationPending=false;mTransactionCV.broadcast();}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。前面提到,SurfaceFlinger類(lèi)的成員變量mDrawingState用來(lái)描述SufaceFlinger服務(wù)的當(dāng)前狀態(tài),而成員變量mCurrentState用來(lái)描述SufaceFlinger服務(wù)的下一個(gè)狀態(tài),由于這時(shí)候SufaceFlinger服務(wù)的狀態(tài)變化已經(jīng)處理完成了,因此,SurfaceFlinger類(lèi)的commitTransaction就將成員變量mCurrentState所指向的一個(gè)State對(duì)象保存在成員變量mDrawingState中,接著又將成員變量mResizeTransationPending的值設(shè)置為false,表示SufaceFlinger服務(wù)已經(jīng)處理過(guò)系統(tǒng)顯示屏或者應(yīng)用程序窗口的大小變化了,最后調(diào)用成員變量mTransactionCV所描述的一個(gè)條件變量的成員函數(shù)broadcast來(lái)通知其它線程,例如Binder線程,SufaceFlinger服務(wù)已經(jīng)處理完成一次屬性變化了。至此,我們就分析完成系統(tǒng)顯示屏以及應(yīng)用程序窗口的屬性變化的處理過(guò)程,接下來(lái)我們繼續(xù)分析各個(gè)應(yīng)用程序窗口是如何設(shè)置它們當(dāng)前所要渲染的圖形緩沖區(qū)的,即SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip的實(shí)現(xiàn)。2.handlePageFlip

SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip是用來(lái)讓各個(gè)應(yīng)用程序窗口設(shè)置它們當(dāng)前所要渲染的圖形緩沖區(qū)的,在這個(gè)過(guò)程中,SurfaceFlinger服務(wù)還會(huì)計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域,如圖3所示。圖M應(yīng)用程序窗口設(shè)置當(dāng)前所要痘染的閣形緩沖區(qū)的過(guò)程這個(gè)過(guò)程可以分為7個(gè)步驟,接下來(lái)我們就詳細(xì)分析每一個(gè)步驟。Step1.SurfaceFlinger.handlePageFlip[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidSurfaceFlinger::handlePageFlip(){boolvisibleRegions=mVisibleRegionsDirty;LayerVector¤tLayers=const_cast<LayerVector&>(mDrawingState.layersSortedByZ);visibleRegions|=lockPageFlip(currentLayers);constDisplayHardware&hw=graphicPlane(0).displayHardware();constRegionscreenRegion(hw.bounds());if(visibleRegions){RegionopaqueRegion;computeVisibleRegions(currentLayers,mDirtyRegion,opaqueRegion);/**rebuildthevisiblelayerlist*/mVisibleLayersSortedByZ.clear();constLayerVector¤tLayers(mDrawingState.layersSortedByZ);size_tcount=currentLayers.size();mVisibleLayersSortedByZ.setCapacity(count);for(size_ti=0;i<count;i++){if(!currentLayers[i]->visibleRegionScreen.isEmpty())mVisibleLayersSortedByZ.add(currentLayers[i]);}#ifdefUSE_COMPOSITION_BYPASSsp<LayerBase>bypassLayer;constsize_tnumVisibleLayers=mVisibleLayersSortedByZ.size();if(numVisibleLayers==1){constsp<LayerBase>&candidate(mVisibleLayersSortedByZ[0]);constRegion&visibleRegion(candidate->visibleRegionScreen);constRegionreminder(screenRegion.subtract(visibleRegion));if(reminder.isEmpty()){//fullscreencandidate!bypassLayer=candidate;}}setBypassLayer(bypassLayer);#endifmWormholeRegion=screenRegion.subtract(opaqueRegion);mVisibleRegionsDirty=false;}unlockPageFlip(currentLayers);mDirtyRegion.andSelf(screenRegion);}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。函數(shù)首先將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值保存在變量visibleRegions中。從前面第1部分的內(nèi)容可以知道,當(dāng)SurfaceFlinger服務(wù)在處理系統(tǒng)顯示屏以及各個(gè)應(yīng)用程序窗口的屬性變化時(shí),如果發(fā)現(xiàn)需要重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域,那么就會(huì)將SurfaceFlinger類(lèi)的成員變量mVisibleRegionsDirty的值設(shè)置為true。函數(shù)接下來(lái)通過(guò)SurfaceFlinger類(lèi)的成員變量mDrawingState所描述的一個(gè)State對(duì)象的成員變量layersSortedByZ來(lái)獲得系統(tǒng)當(dāng)前所有的應(yīng)用程序窗口,并且保存在一個(gè)類(lèi)型為L(zhǎng)ayerVector的向量currentLayers中。有了系統(tǒng)當(dāng)前所有的應(yīng)用程序窗口之后,就可以通過(guò)調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)lockPageFlip來(lái)讓它們?cè)O(shè)置自己當(dāng)前所要渲染的圖形緩沖區(qū)。在后面的Step2中,我們?cè)僭敿?xì)分析SurfaceFlinger類(lèi)的成員函數(shù)lockPageFlip的實(shí)現(xiàn)。系統(tǒng)中的各個(gè)應(yīng)用程序窗口在設(shè)置自己當(dāng)前所要渲染的圖形緩沖區(qū)的過(guò)程中,有可能會(huì)改變自己的大小。在這種情況下,它們就會(huì)通過(guò)SurfaceFlinger類(lèi)的成員函數(shù)lockPageFlip來(lái)返回一個(gè)true值來(lái)給SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip,這時(shí)候得到的變量visibleRegions的值就會(huì)等于true,表示需要重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域。綜合上述情況,無(wú)論變量visibleRegions的值是由于什么原因等于true,都說(shuō)明SurfaceFlinger服務(wù)需要重新計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域,這個(gè)計(jì)算的工作是通過(guò)調(diào)用SurfaceFlinger類(lèi)的另外一個(gè)成員函數(shù)computeVisibleRegions來(lái)完成的。在后面的Step5中,我們?cè)僭敿?xì)分析SurfaceFlinger類(lèi)的成員函數(shù)computeVisibleRegions的實(shí)現(xiàn)。SurfaceFlinger類(lèi)的成員函數(shù)computeVisibleRegions在計(jì)算完成各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域之后,會(huì)得到一個(gè)全局不透明區(qū)域,保存在輸出參數(shù)opaqueRegion中。這個(gè)全局不透明區(qū)域就是接下來(lái)需要渲染的,一般情況下,它的大小就應(yīng)該等于顯示屏的大小,即變量screenRegion所描述的區(qū)域。在異常情況下,可能會(huì)導(dǎo)致顯示屏區(qū)域screenRegion大于全局不透明區(qū)域opaqueRegion,這時(shí)候前者減去后者就可以得到一些稱(chēng)為“蟲(chóng)洞”的區(qū)域,它們保存在SurfaceFlinger類(lèi)的成員變量mWormholeRegion中。由于這些蟲(chóng)洞區(qū)域不會(huì)被各個(gè)應(yīng)用程序窗口覆蓋,因此,SurfaceFlinger服務(wù)需要對(duì)它們進(jìn)行特殊處理,即以一種特殊的方式來(lái)渲染它們。在后面的第4部分內(nèi)容中,我們就會(huì)看到SurfaceFlinger服務(wù)是通過(guò)調(diào)用SurfaceFlinger類(lèi)的成員函數(shù)drawWormhole來(lái)渲染這些蟲(chóng)洞的。SurfaceFlinger類(lèi)的成員函數(shù)computeVisibleRegions在計(jì)算完成各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域之后,各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域就會(huì)保存在用來(lái)描述它們的一個(gè)LayerBase對(duì)象的成員變量visibleRegionScreen中,因此,SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip就會(huì)通過(guò)這個(gè)成員變量來(lái)排除掉那些可見(jiàn)區(qū)域?yàn)榭盏膽?yīng)用程序窗口,并且將所有可見(jiàn)區(qū)域不為空的應(yīng)用程序窗口按照它們的Z軸大小保存在SurfaceFlinger類(lèi)的成員變量mVisibleLayersSortedByZ所描述的一個(gè)向量中。經(jīng)過(guò)前面的操作之后,SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip就可以將成員變量mVisibleRegionsDirty的值設(shè)置為false了,因?yàn)檫@時(shí)候系統(tǒng)中各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域都已經(jīng)重新計(jì)算過(guò)了。SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip最后就調(diào)用另外一個(gè)成員函數(shù)unlockPageFlip來(lái)讓各個(gè)應(yīng)用程序窗口執(zhí)行一些善后的工作,例如,讓各個(gè)應(yīng)用程序窗口檢查自己的可見(jiàn)區(qū)域是否等于空,如果等于空的話,那么就需要將它們之前所獲得的用來(lái)凍結(jié)顯示屏的鎖釋放掉,以避免阻止SurfaceFlinger服務(wù)渲染系統(tǒng)UI。在后面的Step6中,我們?cè)僭敿?xì)分析SurfaceFlinger類(lèi)的成員函數(shù)unlockPageFlip的實(shí)現(xiàn)。SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip最后還需要做的另外一件事情是將設(shè)置系統(tǒng)的臟區(qū)域,這個(gè)臟區(qū)域保存在SurfaceFlinger類(lèi)的成員變量mDirtyRegion中,它同樣是作為一個(gè)輸出參數(shù)來(lái)傳遞給SurfaceFlinger類(lèi)的成員函數(shù)computeVisibleRegions的,以便后者在計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域時(shí),可以將獲得的系統(tǒng)臟區(qū)域保存在它里面。我們同樣是在后面的Step5中分析SurfaceFlinger類(lèi)的成員函數(shù)computeVisibleRegions的實(shí)現(xiàn)時(shí),再看看系統(tǒng)的臟區(qū)域是如何計(jì)算的。有一種特殊情況,即SurfaceFlinger類(lèi)的成員函數(shù)handlePageFlip在重新計(jì)算完成各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域后,如果滿(mǎn)足以下三個(gè)條件:SurfaceFlinger服務(wù)在編譯時(shí)指定了宏USE_COMPOSITION_BYPASS;當(dāng)前要渲染的應(yīng)用程序窗口只有一個(gè),即SurfaceFlinger類(lèi)的成員變量mVisibleLayersSortedByZ所描述的一個(gè)向量的大小等于1;當(dāng)前要渲染的一個(gè)唯一的應(yīng)用程序窗口的可見(jiàn)區(qū)域的大小不為空。那么SurfaceFlinger服務(wù)就會(huì)直接將這個(gè)唯一需要渲染的應(yīng)用程序窗口的圖形緩沖區(qū)渲染到硬件幀緩沖區(qū)中去,以跳過(guò)后面的合成各個(gè)應(yīng)用程序窗口的圖形緩沖區(qū)的操作。在這種情況下,這個(gè)唯一需要渲染的應(yīng)用程序窗口會(huì)通過(guò)SurfaceFlinger類(lèi)的成員函數(shù)setBypassLayer記錄起來(lái)。SurfaceFlinger類(lèi)的成員函數(shù)setBypassLayer的實(shí)現(xiàn)如下所示:[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidSurfaceFlinger::setBypassLayer(constsp<LayerBase>&layer){//ifthislayerisalreadythebypasslayer,donothingsp<Layer>cur(mBypassLmote());if(mBypassLayer==layer){if(cur!=NULL){cur->updateBuffersOrientation();}return;}//clearthecurrentbypasslayermBypassLayer.clear();if(cur!=0){cur->setBypass(false);cur.clear();}//setnewbypasslayerif(layer!=0){if(layer->setBypass(true)){mBypassLayer=static_cast<Layer*>(layer.get());}}}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。從這里就可以看出,在指定了編譯宏USE_COMPOSITION_BYPASS的情況下,SurfaceFlinger服務(wù)唯一需要渲染的應(yīng)用程序窗口就保存在SurfaceFlinger類(lèi)的一個(gè)類(lèi)型為L(zhǎng)ayer的成員變量mBypassLayer中,并且會(huì)調(diào)用用來(lái)這個(gè)Layer對(duì)象的成員函數(shù)setBypass來(lái)將它里面的一個(gè)成員變量mBypassState的值設(shè)置為true。在后面的第3部分內(nèi)容中,我們?cè)僭敿?xì)分析這個(gè)唯一需要渲染的應(yīng)用程序窗口的圖形緩沖區(qū)是如何直接渲染到硬件幀緩沖區(qū)中去的。接下來(lái),我們就繼續(xù)分析SurfaceFlinger類(lèi)的成員函數(shù)lockPageFlip、computeVisibleRegions和unlockPageFlip的實(shí)現(xiàn),以便可以分別了解各個(gè)應(yīng)用程序窗口是如何設(shè)置自己當(dāng)前需要渲染的圖形緩沖區(qū)的、SurfaceFlinger服務(wù)是如何計(jì)算各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域的,以及各個(gè)應(yīng)用程序窗口的可見(jiàn)區(qū)域計(jì)算完成之后的善后工作是什么。Step2.SurfaceFlinger.lockPageFlip[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片boolSurfaceFlinger::lockPageFlip(constLayerVector¤tLayers)boolrecomputeVisibleRegions=false;size_tcount=currentLayers.size();sp<LayerBase>const*layers=currentLayers.array();for(size_ti=0;i<count;i++){constsp<LayerBase>&layer(layers[i]);layer->lockPageFlip(recomputeVisibleRegions);}returnrecomputeVisibleRegions;}這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。在前面的一系列文章中,我們假設(shè)在SurfaceFlinger服務(wù)這一側(cè),每一個(gè)應(yīng)用程序窗口都是使用一個(gè)Layer對(duì)象來(lái)描述,這些Layer對(duì)象都是從LayerBase繼承下來(lái)的,因此它們可以保存在一個(gè)類(lèi)型為L(zhǎng)ayerBase的向量中。從前面的調(diào)用過(guò)程可以知道,參數(shù)currentLayers里面保存的一系列LayerBase對(duì)象正是用來(lái)描述系統(tǒng)當(dāng)前的各個(gè)應(yīng)用程序窗口的,SurfaceFlinger類(lèi)的成員函數(shù)lockPageFlip依次調(diào)用這些LayerBase對(duì)象的成員函數(shù)lockPageFlip來(lái)讓它們?cè)O(shè)置當(dāng)前需要渲染的圖形緩沖區(qū)。由于前面我們假設(shè)這些LayerBase對(duì)象的實(shí)際類(lèi)型為L(zhǎng)ayer,因此,前面調(diào)用的實(shí)際上就是Layer類(lèi)的成員函數(shù)lockPageFlip。接下來(lái),我們就繼續(xù)分析Layer類(lèi)的成員函數(shù)lockPageFlip的實(shí)現(xiàn)。Step3.Layer.lockPageFlip這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。在前面一文中,我們已經(jīng)分析過(guò)這個(gè)函數(shù)的實(shí)現(xiàn)了,不過(guò)當(dāng)時(shí)分析得不是太完整,現(xiàn)在我們?cè)僦匦聛?lái)閱讀一下。這個(gè)函數(shù)比較長(zhǎng),我們分段來(lái)閱讀:[cpp]viewplaincopy在CODE上查看代碼片派生到我的代碼片voidLayer::lockPageFlip(bool&recomputeVisibleRegions){ClientRef::AccesssharedClient(mUserClientRef);SharedBufferServer*lcblk(sharedClient.get());if(!lcblk){//clientdiedrecomputeVisibleRegions=true;return;}ssize_tbuf=lcblk->retireAndLock();if(buf==NOT_ENOUGH_DATA){//NOTE:Thisisnotanerror,itsimplymeansthereisnothingto//retire.Thebufferislockedbecausewewilluseit//forcompositionlaterintheloopreturn;if(buf<NO_ERROR){LOGE("retireAndLock()bufferindex(%d)outofrange",int(buf));mPostedDirtyRegion.clear();return;}//weretiredabuffer,whichbecomesthenewfrontbufferif(mBufferManager.

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論