欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中SurfaceFlinger工作原理

 更新時(shí)間:2021年12月19日 15:10:41   作者:大海之狂  
這篇文章介紹了Android中SurfaceFlinger的工作原理,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

概念

SurfaceFlinger是一個(gè)系統(tǒng)服務(wù),如:audioflinger,audiopolicyservice等等,系統(tǒng)的主要服務(wù)通過(guò)這個(gè)文章進(jìn)行了解,Android的系統(tǒng)服務(wù)一覽。這個(gè)系統(tǒng)服務(wù)主要實(shí)現(xiàn)了Surface的建立、控制、管理等功能。換種說(shuō)法就是,在Android?的實(shí)現(xiàn)中它是一個(gè)service,提供系統(tǒng)范圍內(nèi)的surface composer功能,它能夠?qū)⒏鞣N應(yīng)用程序的2D、3D surface進(jìn)行組合。

原理分析

讓我們首先看一下下面的屏幕簡(jiǎn)略圖:

每個(gè)應(yīng)用程序可能對(duì)應(yīng)著一個(gè)或者多個(gè)圖形界面,而每個(gè)界面我們就稱之為一個(gè)surface?,或者說(shuō)是window?,在上面的圖中我們能看到4?個(gè)surface,一個(gè)是home?界面,還有就是紅、綠、藍(lán)分別代表的3?個(gè)surface?,而兩個(gè)button?實(shí)際是home surface?里面的內(nèi)容。在這里我們能看到我們進(jìn)行圖形顯示所需要解決的問(wèn)題:

  • a、首先每個(gè)surface?在屏幕上有它的位置,以及大小,然后每個(gè)surface?里面還有要顯示的內(nèi)容,內(nèi)容,大小,位置?這些元素?在我們改變應(yīng)用程序的時(shí)候都可能會(huì)改變,改變時(shí)應(yīng)該如何處理??
  • b、然后就各個(gè)surface?之間可能有重疊,比如說(shuō)在上面的簡(jiǎn)略圖中,綠色覆蓋了藍(lán)色,而紅色又覆蓋了綠色和藍(lán)色以及下面的home?,而且還具有一定透明度。這種層之間的關(guān)系應(yīng)該如何描述???????

我們首先來(lái)看第二個(gè)問(wèn)題,我們可以想象在屏幕平面的垂直方向還有一個(gè)Z?軸,所有的surface?根據(jù)在Z?軸上的坐標(biāo)來(lái)確定前后,這樣就可以描述各個(gè)surface?之間的上下覆蓋關(guān)系了,而這個(gè)在Z?軸上的順序,圖形上有個(gè)專業(yè)術(shù)語(yǔ)叫Z-order?。??

對(duì)于第一個(gè)問(wèn)題,我們需要一個(gè)結(jié)構(gòu)來(lái)記錄應(yīng)用程序界面的位置,大小,以及一個(gè)buffer?來(lái)記錄需要顯示的內(nèi)容,所以這就是我們surface?的概念,surface?實(shí)際我們可以把它理解成一個(gè)容器,這個(gè)容器記錄著應(yīng)用程序界面的控制信息,比如說(shuō)大小啊,位置啊,而它還有buffer?來(lái)專門(mén)存儲(chǔ)需要顯示的內(nèi)容。

在這里還存在一個(gè)問(wèn)題,那就是當(dāng)存在圖形重合的時(shí)候應(yīng)該如何處理呢,而且可能有些surface?還帶有透明信息,這里就是我們SurfaceFlinger?需要解決問(wèn)題,它要把各個(gè)surface?組合(compose/merge)?成一個(gè)main Surface?,最后將Main Surface?的內(nèi)容發(fā)送給FB/V4l2 Output?,這樣屏幕上就能看到我們想要的效果。??在實(shí)際中對(duì)這些Surface?進(jìn)行merge?可以采用兩種方式,一種就是采用軟件的形式來(lái)merge?,還一種就是采用硬件的方式,軟件的方式就是我們的SurfaceFlinger?,而硬件的方式就是Overlay?。

OverLay

因?yàn)橛布erge?內(nèi)容相對(duì)簡(jiǎn)單,我們首先來(lái)看overlay?。?Overlay?實(shí)現(xiàn)的方式有很多,但都需要硬件的支持。以IMX51?為例子,當(dāng)IPU?向內(nèi)核申請(qǐng)F(tuán)B的時(shí)候它會(huì)申請(qǐng)3?個(gè)FB?,一個(gè)是主屏的,還一個(gè)是副屏的,還一個(gè)就是Overlay?的。?簡(jiǎn)單地來(lái)說(shuō),Overlay就是我們將硬件所能接受的格式數(shù)據(jù)?和控制信息送到這個(gè)Overlay FrameBuffer,由硬件驅(qū)動(dòng)來(lái)負(fù)責(zé)merge Overlay buffer和主屏buffer中的內(nèi)容。

一般來(lái)說(shuō)現(xiàn)在的硬件都只支持一個(gè)Overlay,主要用在視頻播放以及camera preview上,因?yàn)橐曨l內(nèi)容的不斷變化用硬件Merge比用軟件Merge要有效率得多,下面就是使用Overlay和不使用Overlay的過(guò)程:

SurfaceFlinger中加入了Overlay hal,只要實(shí)現(xiàn)這個(gè)Overlay hal可以使用overlay的功能,這個(gè)頭文件在:

/hardware/libhardware/include/harware/Overlay.h

可以使用FB或者V4L2 output來(lái)實(shí)現(xiàn),這個(gè)可能是我們將來(lái)工作的內(nèi)容。實(shí)現(xiàn)Overlay hal以后,使用Overlay接口的sequence就在?:

?/frameworks/base/libs/surfaceflinger/tests/overlays/Overlays.cpp,

這個(gè)sequnce是很重要的,后面我們會(huì)講到。

不過(guò)在實(shí)際中我們不一定需要實(shí)現(xiàn)Overlay hal,如果了解硬件的話,可以在驅(qū)動(dòng)中直接把這些信息送到Overlay Buffer,而不需要走上層的Android。Fsl現(xiàn)在的Camera preview就是采用的這種方式,而且我粗略看了r3補(bǔ)丁的內(nèi)容,應(yīng)該在opencore的視頻播放這塊也實(shí)現(xiàn)了Overlay。

SurfaceFlinger

現(xiàn) 在就來(lái)看看最復(fù)雜的SurfaceFlinger,首先要明確的是SurfaceFlinger只是負(fù)責(zé)merge Surface的控制,比如說(shuō)計(jì)算出兩個(gè)Surface重疊的區(qū)域,至于Surface需要顯示的內(nèi)容,則通過(guò)skia,opengl和 pixflinger來(lái)計(jì)算。?所以我們?cè)诮榻BSurfaceFlinger?之前先忽略里面存儲(chǔ)的內(nèi)容究竟是什么,先弄清楚它對(duì)merge?的一系列控制的過(guò)程,然后再結(jié)合2D?,3D?引擎來(lái)看它的處理過(guò)程。

3.1?、Surface?的創(chuàng)建過(guò)程

前面提到了每個(gè)應(yīng)用程序可能有一個(gè)或者多個(gè)Surface?,?我們需要一些數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)我們的窗口信息,我們還需要buffer?來(lái)存儲(chǔ)我們的窗口內(nèi)容, 而且最主要的是我們應(yīng)該確定一個(gè)方案來(lái)和SurfaceFlinger?來(lái)交互這些信息,讓我們首先看看下面的Surface?創(chuàng)建過(guò)程的類圖?:

在IBinder?左邊的就是客戶端部分,也就是需要窗口顯示的應(yīng)用程序,而右邊就是我們的Surface Flinger service?。?創(chuàng)建一個(gè)surface?分為兩個(gè)過(guò)程,一個(gè)是在SurfaceFlinger?這邊為每個(gè)應(yīng)用程序(Client)?創(chuàng)建一個(gè)管理?結(jié)構(gòu),另一個(gè)就是創(chuàng)建存儲(chǔ)內(nèi)容的buffer?,以及在這個(gè)buffer?上的一系列畫(huà)圖之類的操作。

因?yàn)镾urfaceFlinger?要管理多個(gè)應(yīng)用程序的多個(gè)窗口界面,為了進(jìn)行管理它提供了一個(gè)Client?類,每個(gè)來(lái)請(qǐng)求服務(wù)的應(yīng)用程序就對(duì)應(yīng)了一個(gè)Client?。因?yàn)閟urface?是在SurfaceFlinger?創(chuàng)建的,必須返回一個(gè)結(jié)構(gòu)讓?xiě)?yīng)用程序知道自己申請(qǐng)的surface?信息,因此SurfaceFlinger?將Client?創(chuàng)建的控制結(jié)構(gòu)per_client_cblk_t?經(jīng)過(guò)BClient?的封裝以后返回SurfaceComposerClient?,并向應(yīng)用程序提供了一組創(chuàng)建和銷毀surface?的操作:

為應(yīng)用程序創(chuàng)建一個(gè)?Client?以后,下面需要做的就是為這個(gè)?Client?分配?Surface?,?Flinger?為每個(gè)?Client?提供了?8M的空間,包括控制信息和存儲(chǔ)內(nèi)容的?buffer?。在說(shuō)創(chuàng)建?surface?之前首先要理解?layer?這個(gè)概念,回到我們前面看的屏幕簡(jiǎn)略圖,實(shí)際上每個(gè)窗口就是?z?軸上的一個(gè)?layer?,?layer?提供了對(duì)窗口控制信息的操作,以及內(nèi)容的處理?(?調(diào)用?opengl?或者?skia)?,也就是說(shuō)?SurfaceFlinger?只是控制什么時(shí)候應(yīng)該進(jìn)行這些信息的處理以及處理的過(guò)程,所有實(shí)際的處理都是在?layer?中進(jìn)行的,可以理解為創(chuàng)建一個(gè)?Surface?就是創(chuàng)建一個(gè)?Layer?。不得不說(shuō)?Android?這些亂七八糟的名字,讓我繞了很久……

創(chuàng)建?Layer?的過(guò)程,首先是由這個(gè)應(yīng)用程序的?Client?根據(jù)應(yīng)用程序的?pid?生成一個(gè)唯一的?layer ID?,然后根據(jù)大小,位置,格式啊之類的信息創(chuàng)建出?Layer?。在?Layer?里面有一個(gè)嵌套的?Surface?類,它主要包含一個(gè)?ISurfaceFlingerClient::Surface_data_t?,包含了這個(gè)?Surace?的統(tǒng)一標(biāo)識(shí)符以及?buffer信息等,提供給應(yīng)用程序使用。最后應(yīng)用程序會(huì)根據(jù)返回來(lái)的?ISurface?信息等創(chuàng)建自己的一個(gè)?Surface?。

Android?提供了?4?種類型的?layer?供選擇,每個(gè)?layer?對(duì)應(yīng)一種類型的窗口,并對(duì)應(yīng)這種窗口相應(yīng)的操作:

?Layer?,?LayerBlur?,?LayerBuffer?,LayerDim?。

?LayerBuffer?很容易讓人理解成是?Layer?的?Buffer?,它實(shí)際上是一種?Layer?類型。各個(gè)?Layer的效果大家可以參考?Surface.java?里面的描述:?/frameworks/base/core/java/android/view/surface.java?。這里要重點(diǎn)說(shuō)一下兩種?Layer?,一個(gè)是?Layer (norm layer)?,另一個(gè)是?LayerBuffer?。

Norm Layer?是?Android?種使用最多的一種?Layer?,一般的應(yīng)用程序在創(chuàng)建?surface?的時(shí)候都是采用的這樣的?layer?,了解?Normal Layer?可以讓我們知道?Android?進(jìn)行?display?過(guò)程中的一些基礎(chǔ)原理。?Normal Layer?為每個(gè)?Surface?分配兩個(gè)?buffer?:?front buffer?和?back buffer?,這個(gè)前后是相對(duì)的概念,他們是可以進(jìn)行?Flip?的。?Front buffer?用于?SurfaceFlinger?進(jìn)行顯示,而?Back buffer?用于應(yīng)用程序進(jìn)行畫(huà)圖,當(dāng)?Back buffer?填滿數(shù)據(jù)?(dirty)?以后,就會(huì)?flip,?back buffer?就變成了?front buffer?用于顯示,而?front buffer?就變成了?back buffer?用來(lái)畫(huà)圖,這兩個(gè)?buffer?的大小是根據(jù)?surface?的大小格式動(dòng)態(tài)變化的。這個(gè)動(dòng)態(tài)變化的實(shí)現(xiàn)我沒(méi)仔細(xì)看,可以參照?:?/frameworks/base/lib/surfaceflinger/layer.cpp?中的?setbuffers()?。

兩個(gè)?buffer flip?的方式是?Android display?中的一個(gè)重要實(shí)現(xiàn)方式,不只是每個(gè)?Surface?這么實(shí)現(xiàn),最后寫(xiě)入?FB?的?main surface?也是采用的這種方式。

LayerBuffer?也是將來(lái)必定會(huì)用到的一個(gè)?Layer?,個(gè)人覺(jué)得也是最復(fù)雜的一個(gè)?layer?,它不具備?render buffer?,主要用在?camera preview / video playback?上。它提供了兩種實(shí)現(xiàn)方式,一種就是?post buffer?,另外一種就是我們前面提到的?overlay?,?Overlay?的接口實(shí)際上就是在這個(gè)?layer?上實(shí)現(xiàn)的。不管是?overlay?還是?post buffer?都是指這個(gè)?layer?的數(shù)據(jù)來(lái)源自其他地方,只是?post buffer?是通過(guò)軟件的方式最后還是將這個(gè)?layer merge?主的?FB,而?overlay?則是通過(guò)硬件?merge?的方式來(lái)實(shí)現(xiàn)。與這個(gè)?layer?緊密聯(lián)系在一起的是?ISurface?這個(gè)接口,通過(guò)它來(lái)注冊(cè)數(shù)據(jù)來(lái)源,下面我舉個(gè)例子來(lái)說(shuō)明這兩種方式的使用方法:

前面幾個(gè)步驟是通用的:

//?要使用?Surfaceflinger?的服務(wù)必須先創(chuàng)建一個(gè)?client

sp?client = new SurfaceComposerClient();

//?然后向?Surfaceflinger?申請(qǐng)一個(gè)?Surface?,?surface?類型為?PushBuffers

sp?surface = client->createSurface(getpid(), 0, 320, 240,?PIXEL_FORMAT_UNKNOWN, ISurfaceComposer::ePushBuffers);

//?然后取得?ISurface?這個(gè)接口,?getISurface()?這個(gè)函數(shù)的調(diào)用時(shí)具有權(quán)限限制的,必須在Surface.h?中打開(kāi):?/framewoks/base/include/ui/Surface.h

sp?isurface = Test::getISurface(surface);

//overlay?方式下就創(chuàng)建?overlay?,然后就可以使用?overlay?的接口了

sp?ref = isurface->createOverlay(320, 240, PIXEL_FORMAT_RGB_565);

sp?verlay = new Overlay(ref);

//post buffer?方式下,首先要?jiǎng)?chuàng)建一個(gè)?buffer?,然后將?buffer?注冊(cè)到?ISurface?上

ISurface::BufferHeap buffers(w, h, w, h,

??????????????????????????????????????????PIXEL_FORMAT_YCbCr_420_SP,

?????????????????????????????????????????transform,

?????????????????????????????????????????0,

?????????????????????????????????????????mHardware->getPreviewHeap());

mSurface->registerBuffers(buffers);

3.2?、應(yīng)用程序?qū)Υ翱诘目刂坪彤?huà)圖

Surface 創(chuàng)建以后,應(yīng)用程序就可以在?buffer?中畫(huà)圖了,這里就面對(duì)著下面幾個(gè)問(wèn)題了:

  • a、是怎么知道在哪個(gè)?buffer?上來(lái)畫(huà)圖?
  • b、就是畫(huà)圖以后如何通知?SurfaceFlinger?來(lái)進(jìn)行?flip ?
  • c、除了畫(huà)圖之外,如果我們移動(dòng)窗口以及改變窗口大小的時(shí)候,如何告訴?SurfaceFlinger?來(lái)進(jìn)行處理呢??

在明白這些問(wèn)題之前,首先我們要了解?SurfaceFlinger?這個(gè)服務(wù)是如何運(yùn)作的:

從類圖中可以看到?SurfaceFlinger?是一個(gè)線程類,它繼承了?Thread?類。當(dāng)創(chuàng)建?SurfaceFlinger這個(gè)服務(wù)的時(shí)候會(huì)啟動(dòng)一個(gè)?SurfaceFlinger?監(jiān)聽(tīng)線程,這個(gè)線程會(huì)一直等待事件的發(fā)生,比如說(shuō)需要進(jìn)行?sruface flip?,或者說(shuō)窗口位置大小發(fā)生了變化等等,一旦產(chǎn)生這些事件,SurfaceComposerClient?就會(huì)通過(guò)?IBinder?發(fā)出信號(hào),這個(gè)線程就會(huì)結(jié)束等待處理這些事件,處理完成以后會(huì)繼續(xù)等待,如此循環(huán)。

SurfaceComposerClient?和?SurfaceFlinger?是通過(guò)?SurfaceFlingerSynchro?這個(gè)類來(lái)同步信號(hào)的,其實(shí)說(shuō)穿了就是一個(gè)條件變量。監(jiān)聽(tīng)線程等待條件的值變成?OPEN?,一旦變成?OPEN?就結(jié)束等待并將條件置成?CLOSE?然后進(jìn)行事件處理,處理完成以后再繼續(xù)等待條件的值變成?OPEN?,而?Client?的Surface?一旦改變就通過(guò)?IBinder?通知?SurfaceFlinger?將條件變量的值變成?OPEN?,并喚醒等待的線程,這樣就通過(guò)線程類和條件變量實(shí)現(xiàn)了一個(gè)動(dòng)態(tài)處理機(jī)制。

了解了?SurfaceFlinger?的事件機(jī)制我們?cè)倩仡^看看前面提到的問(wèn)題了。首先在對(duì)?Surface?進(jìn)行畫(huà)圖之前必須鎖定?Surface?的?layer?,實(shí)際上就是鎖定了?Layer_cblk_t?里的?swapstate?這個(gè)變量。SurfaceComposerClient?通過(guò)?swapsate?的值來(lái)確定要使用哪個(gè)?buffer?畫(huà)圖,如果?swapstate?是下面的值就會(huì)阻塞Client?,就不翻譯了直接?copy?過(guò)來(lái):

// We block the client if:

// eNextFlipPending:??we've used both buffers already, so we need to

//????????????????????wait for one to become availlable.

// eResizeRequested:??the buffer we're going to acquire is being

//????????????????????resized. Block until it is done.

// eFlipRequested && eBusy: the buffer we're going to acquire is

//????????????????????currently in use by the server.

// eInvalidSurface:???this is a special case, we don't block in this

//????????????????????case, we just return an error.

所以應(yīng)用程序先調(diào)用?lockSurface()?鎖定?layer?的?swapstate?,并獲得畫(huà)圖的?buffer?然后就可以在上面進(jìn)行畫(huà)圖了,完成以后就會(huì)調(diào)用unlockSurfaceAndPost()?來(lái)通知?SurfaceFlinger?進(jìn)行?Flip?;蛘邇H僅調(diào)用?unlockSurface()?而不通知?SurfaceFlinger?。

一般來(lái)說(shuō)畫(huà)圖的過(guò)程需要重繪?Surface?上的所有像素,因?yàn)橐话闱闆r下顯示過(guò)后的像素是不做保存的,不過(guò)也可以通過(guò)設(shè)定來(lái)保存一些像素,而只繪制部分像素,這里就涉及到像素的拷貝了,需要將?Front buffer?的內(nèi)容拷貝到?Back buffer?。在?SurfaceFlinger?服務(wù)實(shí)現(xiàn)中像素的拷貝是經(jīng)常需要進(jìn)行的操作,而且還可能涉及拷貝過(guò)程的轉(zhuǎn)換,比如說(shuō)屏幕的旋轉(zhuǎn),翻轉(zhuǎn)等一系列操作。因此?Android?提供了拷貝像素的?hal?,這個(gè)也可能是我們將來(lái)需要實(shí)現(xiàn)的,因?yàn)橛糜布瓿上袼氐目截?,以及拷貝過(guò)程中可能的矩陣變換等操作,比用?memcpy?要有效率而且節(jié)省資源。這個(gè)?HAL?頭文件?在:

/hardware/libhardware/hardware/include/copybit.h

窗口狀態(tài)變化的處理是一個(gè)很復(fù)雜的過(guò)程,首先要說(shuō)明一下,?SurfaceFlinger?只是執(zhí)行?Windows?manager?的指令,由?Windows manager?來(lái)決定什么是偶改變大小,位置,設(shè)置?透明度,以及如何調(diào)整?layer?之間的順序,?SurfaceFlinger?僅僅只是執(zhí)行它的指令。?PS?:?Windows Manager?是java?層的一個(gè)服務(wù),提供對(duì)所有窗口的管理?功能,這部分的內(nèi)容我沒(méi)細(xì)看過(guò),覺(jué)得是將來(lái)需要了解的內(nèi)容。

窗口狀態(tài)的變化包括位置的移動(dòng),窗口大小,透明度,?z-order?等等,首先我們來(lái)了解一下SurfaceComposerClient?是如何和?SurfaceFlinger?來(lái)交互這些信息的。當(dāng)應(yīng)用程序需要改變窗口狀態(tài)的時(shí)候它將所有的狀態(tài)改變信息打包,然后一起發(fā)送給?SurfaceFlinger?,?SurfaceFlinger?改變這些狀態(tài)信息以后,就會(huì)喚醒等待的監(jiān)聽(tīng)線程,并設(shè)置一個(gè)標(biāo)志位告訴監(jiān)聽(tīng)線程窗口的狀態(tài)已經(jīng)改變了,必須要進(jìn)行處理,在?Android?的實(shí)現(xiàn)中,這個(gè)打包的過(guò)程就是一個(gè)?Transaction?,所有對(duì)窗口狀態(tài)(layer_state_t)?的改變都必須在一個(gè)?Transaction?中。

到這里應(yīng)用程序客戶端的處理過(guò)程已經(jīng)說(shuō)完了,基本分為兩個(gè)部分,一個(gè)就是在窗口畫(huà)圖,還一個(gè)就是窗口狀態(tài)改變的處理。

4?、?SurfaceFlinger?的處理過(guò)程

了解了?Flinger?和客戶端的交互,我們?cè)賮?lái)仔細(xì)看看?SurfaceFlinger?的處理過(guò)程,前面已經(jīng)說(shuō)過(guò)了SurfaceFlinger?這個(gè)服務(wù)在創(chuàng)建的時(shí)候會(huì)啟動(dòng)一個(gè)監(jiān)聽(tīng)的線程,這個(gè)線程負(fù)責(zé)每次窗口更新時(shí)候的處理,下面我們來(lái)仔細(xì)看看這個(gè)線程的事件的處理,大致就是下面的這個(gè)圖:

先大致講一下?Android?組合各個(gè)窗口的原理?:?Android?實(shí)際上是通過(guò)計(jì)算每一個(gè)窗口的可見(jiàn)區(qū)域,就是我們?cè)谄聊簧峡梢?jiàn)的窗口區(qū)域?(?用?Android的詞匯來(lái)說(shuō)就是?visibleRegionScreen )?,然后將各個(gè)窗口的可見(jiàn)區(qū)域畫(huà)到一個(gè)主?layer?的相應(yīng)部分,最后就拼接成了一個(gè)完整的屏幕,然后將主?layer?輸送到?FB?顯示。在將各個(gè)窗口可見(jiàn)區(qū)域畫(huà)到主?layer?過(guò)程中涉及到一個(gè)硬件實(shí)現(xiàn)和一個(gè)軟件實(shí)現(xiàn)的問(wèn)題,如果是軟件實(shí)現(xiàn)則通過(guò)?Opengl?重新畫(huà)圖,其中還包括存在透明度的?alpha?計(jì)算;如果實(shí)現(xiàn)了?copybit hal?的話,可以直接將窗口的這部分?jǐn)?shù)據(jù)?直接拷貝過(guò)來(lái),并完成可能的旋轉(zhuǎn),翻轉(zhuǎn),以及?alhpa?計(jì)算等。

下面來(lái)看看?Android?組合各個(gè)?layer?并送到?FB?顯示的具體過(guò)程:

4.1?、?handleConsoleEvent

當(dāng)接收到?signal?或者?singalEvent?事件以后,線程就停止等待開(kāi)始對(duì)?Client?的請(qǐng)求進(jìn)行處理,第一個(gè)步驟是?handleConsoleEvent?,這個(gè)步驟我看了下和?/dev/console?這個(gè)設(shè)備有關(guān),它會(huì)取得屏幕或者釋放屏幕,只有取得屏幕的時(shí)候才能夠在屏幕上畫(huà)圖。

4.2?、?handleTransaction

前面提到過(guò),窗口狀態(tài)的改變只能在一個(gè)?Transaction?中進(jìn)行。因?yàn)榇翱跔顟B(tài)的改變可能造成本窗口和其他窗口的可見(jiàn)區(qū)域變化,所以就必須重新來(lái)計(jì)算窗口的可見(jiàn)區(qū)域。在這個(gè)處理子過(guò)程中?Android?會(huì)根據(jù)標(biāo)志位來(lái)對(duì)所有?layer?進(jìn)行遍歷,一旦發(fā)現(xiàn)哪個(gè)窗口的狀態(tài)發(fā)生了變化就設(shè)置標(biāo)志位以在將來(lái)重新計(jì)算這個(gè)窗口的可見(jiàn)區(qū)域。在完成所有子?layer?的遍歷以后,?Android?還會(huì)根據(jù)標(biāo)志位來(lái)處理主?layer?,舉個(gè)例子,比如說(shuō)傳感器感應(yīng)到手機(jī)橫過(guò)來(lái)了,會(huì)將窗口橫向顯示,此時(shí)就要重新設(shè)置主?layer?的方向。

4.3?、?handlePageFlip

????這里會(huì)處理每個(gè)窗口?surface buffer?之間的翻轉(zhuǎn),根據(jù)?layer_state_t?的?swapsate?來(lái)決定是否要翻轉(zhuǎn),當(dāng)?swapsate?的值是?eNextFlipPending?是就會(huì)翻轉(zhuǎn)。處理完翻轉(zhuǎn)以后它會(huì)重新計(jì)算每個(gè)?layer的可見(jiàn)區(qū)域,這個(gè)重新計(jì)算的過(guò)程我還沒(méi)看太明白,但大致是一個(gè)這么的過(guò)程:

從?Z?值最大的?layer?開(kāi)始計(jì)算,也就是說(shuō)從最上層的?layer?計(jì)算,去掉本身的透明區(qū)域和覆蓋在它上面的不透明區(qū)域,得到的就是這個(gè)?layer?的可見(jiàn)區(qū)域。然后這個(gè)?layer?的不透明區(qū)域就會(huì)累加到不透明覆蓋區(qū)域,這個(gè)?layer?的可見(jiàn)區(qū)域會(huì)放入到主?layer?的可見(jiàn)區(qū)域,然后計(jì)算下一個(gè)?layer?,直到計(jì)算完所有的?layer?的可見(jiàn)區(qū)域。這中間的計(jì)算是通過(guò)定義在?skia?中的一種與或非的圖形邏輯運(yùn)算實(shí)現(xiàn)的,類似我們數(shù)學(xué)中的與或非邏輯圖。

4.4?、?handleRepaint

計(jì)算出每個(gè)?layer?的可見(jiàn)區(qū)域以后,這一步就是將所有可見(jiàn)區(qū)域的內(nèi)容畫(huà)到主?layer?的相應(yīng)部分了,也就是說(shuō)將各個(gè)?surface buffer?里面相應(yīng)的內(nèi)容拷貝到主?layer?相應(yīng)的?buffer?,其中可能還涉及到alpha?運(yùn)算,像素的翻轉(zhuǎn),旋轉(zhuǎn)等等操作,這里就像我前面說(shuō)的可以用硬件來(lái)實(shí)現(xiàn)也可以用軟件來(lái)實(shí)現(xiàn)。在使用軟件的?opengl?做計(jì)算的過(guò)程中還會(huì)用到?PixFlinger?來(lái)做像素的合成,這部分內(nèi)容我還沒(méi)時(shí)間來(lái)細(xì)看。

4.5?、?postFrameBuffer

最后的任務(wù)就是翻轉(zhuǎn)主?layer?的兩個(gè)?buffer?,將剛剛寫(xiě)入的內(nèi)容放入?FB?內(nèi)顯示了。

到此這篇關(guān)于Android中SurfaceFlinger工作原理的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論