Android应用程序请求SurfaceFlinger服务创建Surface的过程分析
文章轉(zhuǎn)載至CSDN社區(qū)羅升陽的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/7884628
前面我們已經(jīng)學(xué)習(xí)過Android應(yīng)用程序與SurfaceFlinger服務(wù)的連接過程了。連接上SurfaceFlinger服務(wù)之后,Android應(yīng)用程序就可以請求SurfaceFlinger服務(wù)創(chuàng)建Surface。而當(dāng)有了Surface后,Android應(yīng)用程序就可以用來渲染自己的UI了。在本文中,我們將詳細(xì)分析Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建Surface的過程。
?? ? ? ?在講述Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建Surface之前,我們首先了解一個(gè)Surface是由什么組成的。我們可以將Surface理解為一個(gè)繪圖表面,Android應(yīng)用程序負(fù)責(zé)往這個(gè)繪圖表面填內(nèi)容,而SurfaceFlinger服務(wù)負(fù)責(zé)將這個(gè)繪圖表面的內(nèi)容取出來,并且渲染在顯示屏上。
?? ? ? ?在SurfaceFlinger服務(wù)這一側(cè),繪圖表面使用Layer類來描述,Layer類的實(shí)現(xiàn)如圖1所示。
圖1 Layer類的實(shí)現(xiàn)
?? ? ? Layer類繼承了LayerBaseClient類;LayerBaseClient類繼承了LayerBase類;LayerBase類繼續(xù)了RefBase類。從這些繼承關(guān)系就可以看出,我們可以通過Android系統(tǒng)的智能指針來引用Layer對象,從而可以自動地維護(hù)它們的生命周期。
?? ? ? Layer類內(nèi)部的成員變量mUserClientRef指向了一個(gè)ClientRef對象,這個(gè)ClientRef對象內(nèi)部有一個(gè)成員變量mControlBlock,它指向了一個(gè)SharedBufferServer對象。從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一文可以知道,SharedBufferServer類是用來在SurfaceFlinger服務(wù)這一側(cè)描述一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的,即在SurfaceFlinger服務(wù)中,每一個(gè)繪圖表面,即一個(gè)Layer對象,都關(guān)聯(lián)有一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧。
?? ? ? LayerBaseClient類內(nèi)部有一個(gè)類型為LayerBaseClient::Surface的弱指針,它引用了一個(gè) Layer::SurfaceLayer對象。這個(gè)Layer::SurfaceLayer對象是一個(gè)Binder本地對象,它是 SurfaceFlinger服務(wù)用來與Android應(yīng)用程序建立通信的,以便可以共同維護(hù)一個(gè)繪圖表面。
?? ? ? Layer::SurfaceLayer類繼承了LayerBaseClient::Surface類,它的實(shí)現(xiàn)如圖2所示。
圖2 SurfaceLayer類的實(shí)現(xiàn)
?? ? ? 理解這個(gè)圖需要了解Android系統(tǒng)的Binder進(jìn)程間通信機(jī)制,具體可以參考Android進(jìn)程間通信(IPC)機(jī)制Binder簡要介紹和學(xué)習(xí)計(jì)劃一文。從這里就可以看出,Layer::SurfaceLayer類實(shí)現(xiàn)了ISurface接口,而Android應(yīng)用程序就是通過這個(gè)接口來和SurfaceFlinger服務(wù)共同維護(hù)一個(gè)繪圖表面的。
?? ? ??Layer::SurfaceLayer類內(nèi)部有兩個(gè)成員變量mFlinger和mOwner,前者指向了SurfaceFlinger服務(wù),而后者指向了其宿主Layer對象。
?? ? ??ISurface接口定義在文件frameworks/base/include/surfaceflinger/ISurface.h中,它有一個(gè)重要的成員函數(shù)requestBuffer,如下所示:
?
[cpp] view plaincopy
?? ? ? ?Android應(yīng)用程序就是通過ISurface接口的成員函數(shù)requestBuffer來請求SurfaceFlinger服務(wù)為它的一個(gè)繪圖表面分配一個(gè)圖形緩沖區(qū)的,這個(gè)圖形緩沖區(qū)使用一個(gè)GraphicBuffer對象來描述。
?? ? ? ?由于Layer::SurfaceLayer是一個(gè)Binder本地對象類,因此,就相應(yīng)地有一個(gè)Binder代理對象類,它的名稱為BpSurface,它的實(shí)現(xiàn)如圖3所示。
圖3 BpSurface類的實(shí)現(xiàn)
?? ? ? 理解這個(gè)圖同樣需要了解Android系統(tǒng)的Binder進(jìn)程間通信機(jī)制,具體可以參考Android進(jìn)程間通信(IPC)機(jī)制Binder簡要介紹和學(xué)習(xí)計(jì)劃一文。
?? ? ? 以上都是從SurfaceFlinger服務(wù)這一側(cè)來理解一個(gè)Surface,下面我們再從Android應(yīng)用程序這一側(cè)來理解一個(gè)Surface。
?? ? ? 在Android應(yīng)用程序這一側(cè),每一個(gè)繪圖表面都使用一個(gè)Surface對象來描述,每一個(gè)Surface對象都是由一個(gè)SurfaceControl對象來創(chuàng)建的。Surface類和SurfaceControl類的關(guān)系以及實(shí)現(xiàn)如圖4所示。
圖4 Surface類和SurfaceControl類的關(guān)系以及實(shí)現(xiàn)
?? ? ? SurfaceControl類的成員變量mClient是一個(gè)類型為SurfaceComposerClient的強(qiáng)指針,它指向了Android應(yīng)用程序進(jìn)程中的一個(gè)SurfaceComposerClient單例對象。在前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的連接過程分析一 文中,我們已經(jīng)看到過SurfaceComposerClient類的作用了,Android應(yīng)用程序主要就是通過它來和SurfaceFlinger服 務(wù)建立連接的,連接的結(jié)果就是得到一個(gè)類型為Client的Binder代理對象,保存它的成員變量mClient中。
?? ? ?SurfaceControl類的成員變量mSurface是一個(gè)類型為ISurface的強(qiáng)指針,它指向了一個(gè)類型為BpSurface的 Binder代理對象,而這個(gè)Binder代理對象引用的是一個(gè)Layer::SurfaceLayer對象。當(dāng)Android應(yīng)用程序請求 SurfaceFlinger服務(wù)創(chuàng)建一個(gè)繪圖表面的時(shí)候,SurfaceFlinger服務(wù)就會在內(nèi)部創(chuàng)建一個(gè)Layer::SurfaceLayer 對象,并且將這個(gè)Layer::SurfaceLayer對象的一個(gè)Binder代理對象返回來給Android應(yīng)用程序,然后Android應(yīng)用程序再 將這個(gè)Binder代理對象保存在一個(gè)SurfaceControl對象的成員變量mSurface中。
?? ? ?SurfaceControl類的成員變量mSurfaceData是一個(gè)類型為Surface的強(qiáng)指針,它指向了一個(gè)Surface對象。
?? ? ?Surface類就是用來在Android應(yīng)用程序這一側(cè)描述繪圖表面的,它的成員變量mSurface與它的宿主類SurfaceControl的成 員變量mSurface指向的是同一個(gè)Binder代理對象,即它們都引用了在SurfaceFlinger服務(wù)內(nèi)部所創(chuàng)建的一個(gè)類型為 Layer::SurfaceLayer的Binder本地對象。
?? ? ?Surface類的成員變量mClient指向了Android應(yīng)用程序進(jìn)程中的一個(gè)SurfaceClient單例對象。在前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一文中,我們已經(jīng)介紹過SurfaceClient類的實(shí)現(xiàn)了,Android應(yīng)用程序就是通過它來請求SurfaceFlinger服務(wù)創(chuàng)建共享UI元數(shù)據(jù)的,并且可以通過它來請求SurfaceFlinger服務(wù)渲染一個(gè)繪圖表面。
?? ? ?Surface類的成員變量mSharedBufferClient指向了一個(gè)SharedBufferClient對象。從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一文可以知道,SharedBufferClient類是用來在Android應(yīng)用程序這一側(cè)描述一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的,即在Android應(yīng)用程序中,每一個(gè)繪圖表面,即一個(gè)Surface對象,都關(guān)聯(lián)有一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧。
?? ? ?Surface類繼承了EGLNativeBase類,而EGLNativeBase類又繼承了ANativeWindow類。我們知 道,Android系統(tǒng)是通過OpenGL庫來繪制UI的。OpenGL庫在繪制UI的時(shí)候,需要底層的系統(tǒng)提供一個(gè)本地窗口給它,以便它可以將UI繪制 在這個(gè)本地窗口上。Android系統(tǒng)為OpenGL庫定提供的本地窗口使用ANativeWindow類來描述,Surface類通過 EGLNativeBase類間接地繼承了ANativeWindow類,因此,Surface類也是用來描述OpenGL繪圖所需要的一個(gè)本地窗口的。 從這個(gè)角度出發(fā),我們可以將Surface類看作OpenGL庫與Android的UI系統(tǒng)之間的一個(gè)橋梁。
?? ? ?討論到這里,我們就可以知道,一個(gè)繪圖表面,在SurfaceFlinger服務(wù)和Android應(yīng)用程序中分別對應(yīng)有一個(gè)Layer對象和一個(gè) Surface對象,這兩個(gè)對象在內(nèi)部分別使用一個(gè)SharedBufferServer對象和一個(gè)SharedBufferClient對象來描述這個(gè) 繪圖表面的UI元數(shù)據(jù)緩沖堆棧。在前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一文中,我們已經(jīng)分析過這個(gè)UI元數(shù)據(jù)的創(chuàng)建過程了,接下來,我們再簡要看一下SharedBufferServer類和SharedBufferClient類的定義。
?? ? ?SharedBufferServer類和SharedBufferClient類均是從SharedBufferBase類繼承下來的,如圖5所示。
圖5 SharedBufferBase、SharedBufferServer和SharedBufferClient的關(guān)系
?? ? ?在基類SharedBufferBase中,有三個(gè)成員變量mSharedClient、mSharedStack和mIdentity。成員變量 mSharedClient指向一塊UI元數(shù)據(jù)緩沖區(qū),即一個(gè)SharedClient對象;成員變量mSharedStack指向一個(gè)UI元數(shù)據(jù)堆棧, 即一個(gè)SharedBufferStack對象;成員變量mIdentity用來描述一個(gè)繪圖表面的ID。
?? ? ?在前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一 文提到,每一個(gè)與UI相關(guān)的Android應(yīng)用程序內(nèi)部都有一個(gè)唯一的SharedClient對象,這個(gè)SharedClient對象內(nèi)部有一個(gè) SharedBufferStack數(shù)組surfaces,SharedBufferServer類的成員變量mSharedStack所指向的 SharedBufferStack對象,正是成員變量mSharedClient所指向的一個(gè)SharedClient對象內(nèi)部的一個(gè) SharedBufferStack數(shù)組的一個(gè)元素,這一點(diǎn)可以從SharedBufferServer類的構(gòu)造函數(shù)實(shí)現(xiàn)來看出。
?? ? ?SharedBufferServer類的構(gòu)造函數(shù)frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp文件中,如下所示:
?
[cpp] view plaincopy?? ? ? 其中,參數(shù)surface表示mSharedStack指向的是mSharedClient中的SharedBufferStack數(shù)組surfaces的第幾個(gè)元素。
?? ? ? 在SharedBufferClient類中,有三個(gè)成員變量mNumBuffers、tail和queue_head,它們的含義可以參考前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系概述和學(xué)習(xí)計(jì)劃一文中的圖6,如下所示。
圖6 SharedBufferClient眼中的SharedBufferStack?
?? ? ? 在Android應(yīng)用程序這一側(cè),當(dāng)它需要渲染一個(gè)Surface時(shí),它就會首先找到對應(yīng)的SharedBufferClient對象,然后再調(diào)用它的成 員函數(shù)dequeue來請求分配一個(gè)UI元數(shù)據(jù)緩沖區(qū)。有了這個(gè)UI元數(shù)據(jù)緩沖區(qū)之后,Android應(yīng)用程序再調(diào)用這個(gè) SharedBufferClient對象的成員函數(shù)setDirtyRegion、setCrop和setTransform來設(shè)置對應(yīng)的 Surface的裁剪區(qū)域、紋理坐標(biāo)以及旋轉(zhuǎn)方向。此外,Android應(yīng)用程序還會請求SurfaceFlinger服務(wù)為這個(gè)Surface分配一個(gè) 圖形緩沖區(qū),以便可以往這個(gè)圖形緩沖區(qū)寫入實(shí)際的UI數(shù)據(jù)。最后,Android應(yīng)用程序就可以調(diào)用這個(gè)SharedBufferClient對象的成員 函數(shù)queue把前面已經(jīng)準(zhǔn)備好了的UI元數(shù)據(jù)緩沖區(qū)加入到它所描述的一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的待渲染隊(duì)列中,以便SurfaceFlinger服務(wù)可 以在合適的時(shí)候?qū)λM(jìn)行渲染。這個(gè)過程我們在下一篇文章中再詳細(xì)分析。
?? ? ??SharedBufferServer類的成員變量mNumBuffers的含義可以參考前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系概述和學(xué)習(xí)計(jì)劃一文中的圖7,如下所示。
圖7 SharedBufferServer眼中的SharedBufferStack
?? ? ? ?當(dāng)SurfaceFlinger服務(wù)需要渲染一個(gè)Surface的時(shí)候,它就會找到對應(yīng)的一個(gè)SharedBufferServer對象,然后調(diào)用它的 成員函數(shù)getQueueCount來檢查它所描述的一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的待渲染隊(duì)列的大小。如果這個(gè)大小大于0,那么 SurfaceFlinger服務(wù)就會繼續(xù)調(diào)用它的成員函數(shù)retireAndLock來取出隊(duì)列中的第一個(gè)UI元數(shù)據(jù)緩沖區(qū),以及調(diào)用它的成員函數(shù) getDirtyRegion、getCrop和getTransform來獲得要渲染的Surface的裁剪區(qū)域、紋理坐標(biāo)和旋轉(zhuǎn)方向。最 后,SurfaceFlinger服務(wù)就可以結(jié)合這些信息來將保存這個(gè)Surface的圖形緩沖區(qū)中的UI數(shù)據(jù)渲染在顯示屏中。這個(gè)過程我們同樣在下一篇 文章中再詳細(xì)分析。
?? ? ??SharedBufferServer類的另外一個(gè)成員變量mBufferList指向了一個(gè)BufferList對象,這個(gè)BufferList對 象是用來管理SharedBufferServer類所描述的一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的,接下來我們就簡要分析它的定義。
?? ? ??BufferList類定義在frameworks/base/include/private/surfaceflinger/SharedBufferStack.h文件中,如下所示:
?
[cpp] view plaincopy?? ? ? BufferList類的成員變量mCapacity對應(yīng)于一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的容量,即最大緩沖區(qū)個(gè)數(shù)。
?? ? ? BufferList類的另外一個(gè)成員變量變量mList用來描述這個(gè)堆棧中的緩沖區(qū)哪個(gè)是空閑的,哪個(gè)是正在使用的。空閑的緩沖區(qū)對應(yīng)的位為0,而正在 使用的緩沖區(qū)對應(yīng)的位為1。舉個(gè)例子,假如一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的大小為5,其中,第1、3、5個(gè)數(shù)據(jù)緩沖區(qū)是正在使用的,而第2、4個(gè)數(shù)據(jù)緩沖區(qū)是 空閑的,那么對應(yīng)的mList的值就等于10101000 00000000 00000000 00000000。當(dāng)我們需要將第2個(gè)數(shù)據(jù)緩沖區(qū)設(shè)置為正在使用時(shí),那么只要調(diào)用成員函數(shù)add來將左起第2位設(shè)置為1即可,即得到mList的值就等于 11101000 00000000 00000000 00000000,而當(dāng)我們需要將第1個(gè)數(shù)據(jù)緩沖區(qū)設(shè)置為空閑時(shí),那么只要調(diào)用成員函數(shù)remove來將左起第1位設(shè)置為0即可,即得到mList的值就 等于00101000 00000000 00000000 00000000。
?? ? ?在BufferList類內(nèi)部定義了一個(gè)迭代器const_iterator,用來從左到右遍歷一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧中的正在使用或者空閑的緩沖區(qū)。仍然以前面的例子為例,當(dāng) 我們調(diào)用BufferList類的成員函數(shù)begin時(shí),就可以得到一個(gè)const_iterator迭代器,沿著這個(gè)迭代器往前走,就可以依次遍歷第 1、3、5個(gè)正在使用的緩沖區(qū),而當(dāng)我們調(diào)用BufferList類的成員函數(shù)free_begin時(shí),就可以得到另外一個(gè)const_iterator 迭代器,沿著這個(gè)迭代器往前走,就可以依次遍歷第2、4個(gè)空閑的緩沖區(qū)。
?? ? ?關(guān)于Surface的概念我們就分析到這里。從這些分析可以知道,當(dāng)Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建一個(gè) Surface的時(shí)候,需要在SurfaceFlinger服務(wù)這一側(cè)創(chuàng)建一個(gè)Layer對象、一個(gè)Layer::SurfaceLayer對象和一個(gè) SharedBufferServer對象,同時(shí)又需要在Android應(yīng)用程序這一側(cè)創(chuàng)建一個(gè)SurfaceControl對象、一個(gè)Surface對 象和一個(gè)SharedBufferClient對象。
?? ? ?在進(jìn)一步分析Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建Surface的過程之前,我們首先看一下Android系統(tǒng)的開機(jī)動畫 應(yīng)用程序bootanim是如何請求SurfaceFlinger服務(wù)創(chuàng)建一個(gè)Surface來顯示開機(jī)動畫的。
?? ? ?在前面Android系統(tǒng)的開機(jī)畫面顯示過程分析一文中, 我們分析Android系統(tǒng)的開機(jī)動畫的顯示過程,其中,開機(jī)動畫應(yīng)用程序bootanim是在BootAnimation類的成員函數(shù)readyToRun中請求SurfaceFlinger服務(wù)創(chuàng)建一個(gè)用來顯示開機(jī)動畫的Surface的,如下所示:
[cpp] view plaincopy ?? ? ?BootAnimation類的成員函數(shù)session返回的是一個(gè)SurfaceComposerClient對象。有了這個(gè) SurfaceComposerClient對象之后,我們就可以調(diào)用它的成員函數(shù)createSurface來請求請求SurfaceFlinger服 務(wù)在內(nèi)部創(chuàng)建一個(gè)Layer::SurfaceLayer對象,并且將這個(gè)Layer::SurfaceLayer對象的代理對象返回來給 SurfaceComposerClient類,SurfaceComposerClient類接著就將這個(gè)Layer::SurfaceLayer代理 對象封裝成一個(gè)SurfaceControl對象,并且返回給BootAnimation類,最后BootAnimation類就可以調(diào)用這個(gè) SurfaceControl對象的成員函數(shù)getSurface來獲得一個(gè)Surface對象。
?? ? ?接下來,我們就從SurfaceComposerClient類的成員函數(shù)createSurface開始描述Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建Surface的過程,如圖8所示。
圖8 Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建Surface的過程?
?? ? ? 這個(gè)過程可以劃分為20個(gè)步驟,接下來我們就詳細(xì)分析每一個(gè)步驟。
?? ? ? Step 1.?SurfaceComposerClient.createSurface
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/SurfaceComposerClient.cpp文件中。
?? ? ? 參數(shù)pid用來描述當(dāng)前進(jìn)程的PID,參數(shù)display的值等于0,表示要在第一個(gè)顯示屏上創(chuàng)建一個(gè)Surface,參數(shù)w和h表示要創(chuàng)建的 Surface的寬度和高度,它們的值剛好等于第一個(gè)顯示屏的寬度和高度,參數(shù)format的值等于PIXEL_FORMAT_RGB_565,表示要創(chuàng) 建的Surface的像素格式為PIXEL_FORMAT_RGB_565,即每一個(gè)點(diǎn)使用2個(gè)字節(jié)來描述,其中,R、G和B分量分別占5位、6位和5 位,參數(shù)flags是一個(gè)默認(rèn)參數(shù),它等于默認(rèn)值0,表示要創(chuàng)建的Surface的用途。
?? ? ? 這個(gè)函數(shù)將參數(shù)pid格式化成一個(gè)字符串之后,再調(diào)用SurfaceComposerClient類的另外一個(gè)版本的成員函數(shù)createSurface來請求SurfaceFlinger服務(wù)創(chuàng)建一個(gè)Surface,如下所示:
[cpp] view plaincopy
?? ? ? SurfaceComposerClient類的成員變量mClient指向了一個(gè)類型為BpSurfaceComposerClient的Binder 代理對象,它引用了一個(gè)類型為Client的Binder本地對象。這個(gè)類型Client的Binder本地對象是在SurfaceFlinger服務(wù)內(nèi) 部創(chuàng)建的,用來和Android應(yīng)用程序建立連接。連接的過程可以參考前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的連接過程分析一文。
?? ? ??SurfaceComposerClient類的成員函數(shù)createSurface調(diào)用成員變量mClient的成員函數(shù) createSurface請求SurfaceFlinger服務(wù)創(chuàng)建一個(gè)Surface之后,就得到了一個(gè)類型為BpSurface的Binder代理 對象surface。從前面的描述可以知道,Binder代理對象surface引用了在SurfaceFlinger服務(wù)這一側(cè)的一個(gè) Layer::SurfaceLayer對象。此外,SurfaceComposerClient類的成員函數(shù)createSurface還得到了一個(gè) surface_data_t對象data,它里面包含了剛才所創(chuàng)建的一個(gè)Surface的信息,例如,寬度、高度、像素格式和ID值等。
?? ? ?最后,SurfaceComposerClient類的成員函數(shù)createSurface就將SurfaceFlinger服務(wù)返回來的Binder 代理對象surface和surface_data_t對象data封裝成一個(gè)SurfaceControl對象result,并且返回給調(diào)用者。接下 來,我們首先分析SurfaceFlinger服務(wù)創(chuàng)建Surface的過程,接著再分析SurfaceControl對象result的封裝過程。
?? ? ?Step 2. Client.createSurface
[cpp] view plaincopy?? ? ?這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ?Client類的成員變量mFlinger指向了SurfaceFlinger服務(wù),因此,接下來就會調(diào)用SurfaceFlinger類的成員函數(shù)createSurface來創(chuàng)建一個(gè)Surface。
?? ? ?Step 3.?SurfaceFlinger.createSurface
[cpp] view plaincopy?? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ? 第一個(gè)if語句判斷參數(shù)w和h的值是否為負(fù)數(shù),如果是的話,那么就直接出錯(cuò)返回了,因?yàn)閯?chuàng)建的Surface的寬度和高度值不可能為負(fù)數(shù)。
?? ? ??eFXSurfaceNormal、eFXSurfaceBlur、eFXSurfaceDim和eFXSurfaceMask是四個(gè)枚舉值,它們定 義在文件frameworks/base/include/surfaceflinger/ISurfaceComposer.h中,如下所示:
[cpp] view plaincopy?? ? ? 回到SurfaceFlinger類的成員函數(shù)createSurface中,參數(shù)flags的值等于0,因此,在接下來的switch語句中,會調(diào)用 SurfaceFlinger類的成員函數(shù)createNormalSurface來在顯示屏上創(chuàng)建一個(gè)Layer。順便提一句,如果參數(shù)flags的值 等于eFXSurfaceBlur或者eFXSurfaceDim,那么就表示要創(chuàng)建的是一個(gè)模糊或者漸變的Surface,這兩種類型的Surface 是在原有的一個(gè)Surface上進(jìn)行創(chuàng)建的,用來對原來的Surface進(jìn)行模糊或者漸變處理。
?? ? ? ?前面所創(chuàng)建的Layer保存在變量layer中,接下來SurfaceFlinger類的成員函數(shù)createNormalSurface會調(diào)用來另外 一個(gè)成員函數(shù)addClientLayer來將它保存在內(nèi)部的一個(gè)列表中,接著再調(diào)用前面所創(chuàng)建的Layer的成員函數(shù)getSurface來獲得一個(gè) Layer::SurfaceLayer對象surfaceHandle。
?? ? ? ?在將Layer::SurfaceLayer對象surfaceHandle的一個(gè)Binder代理對象返回給Android應(yīng)用程序之 前,SurfaceFlinger類的成員函數(shù)createNormalSurface還會以它的一個(gè)IBinder接口為關(guān)鍵字,將前面所創(chuàng)建的 Layer保存在SurfaceFlinger類的成員變量mLayerMap所描述的一個(gè)Map中,這樣就可以將一個(gè) Layer::SurfaceLayer對象surfaceHandle與它的宿主Layer對象關(guān)聯(lián)起來。
?? ? ? ?接下來,我們首先分析SurfaceFlinger類的成員函數(shù)createNormalSurface和addClientLayer的實(shí)現(xiàn),接著再分析Layer的成員函數(shù)getSurface的實(shí)現(xiàn),以便可以了解一個(gè)Surface的創(chuàng)建的過程。
?? ? ? ?Step 4.?SurfaceFlinger.createNormalSurface
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ? 函數(shù)開頭的switch語句判斷要創(chuàng)建的Surface是否要使用透明色。如果要使用的話,那么就將參數(shù)format的值修改為 PIXEL_FORMAT_RGBA_8888。另一方面,如果要創(chuàng)建的Surface不需要使用透明色,那么就將參數(shù)format的值修改為 PIXEL_FORMAT_RGB_565或者PIXEL_FORMAT_RGBX_8888,取決于是否定義了宏NO_RGBX_8888。
?? ? ?函數(shù)接下來創(chuàng)建了一個(gè)Layer對象,并且調(diào)用這個(gè)Layer對象的成員函數(shù)setBuffers來在內(nèi)部創(chuàng)建一個(gè)Layer::SurfaceLayer對象,最后就將這個(gè)Layer對象返回給調(diào)用者。
?? ? ?接下來,我們首先分析Layer對象的創(chuàng)建過程,接著再分析Layer對象的成員函數(shù)setBuffers的實(shí)現(xiàn)。
?? ? ?Step 5. new Layer
[cpp] view plaincopy?? ? ?這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。
?? ? ?Layer類的構(gòu)造函數(shù)只是執(zhí)行一些簡單的初始化工作,接下來我們再繼續(xù)分析它的進(jìn)一步初始化工作,這是通過Layer類的成員函數(shù)setBuffers來實(shí)現(xiàn)的。
?? ? ?Step 6. Layer.setBuffers
[cpp] view plaincopy?? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。
?? ? ? 參數(shù)format是一個(gè)整數(shù)值,用來描述要創(chuàng)建的Surface的像素格式,函數(shù)首先調(diào)用另外一個(gè)函數(shù)getPixelFormatInfo來將它轉(zhuǎn)換為 一個(gè)PixelFormatInfo對象info,以便可以獲得更多的該種類型的像素格式的信息,例如,一個(gè)像素點(diǎn)占多少個(gè)字節(jié),每個(gè)顏色分量又分別占多 少位等。函數(shù)getPixelFormatInfo定義文件frameworks/base/libs/ui/PixelFormat.cpp文件中,有 興趣的讀者可以自己研究一下。
?? ? ? Layer類的成員函數(shù)graphicPlane是從父類LayerBase繼承下來,用來獲得系統(tǒng)的第N個(gè)顯示屏,這個(gè)成員函數(shù)最終又是通過調(diào)用SurfaceFlinger類的成員函數(shù)graphicPlane來實(shí)現(xiàn)的,如下所示:
[cpp] view plaincopy?? ? ?SurfaceFlinger類的成員函數(shù)graphicPlane的實(shí)現(xiàn)如下示:
[cpp] view plaincopy?? ? ?SurfaceFlinger類有一個(gè)類型為DisplayHardware的數(shù)組,它的大小等于4,表示Android系統(tǒng)最多支持4個(gè)顯示屏,每一 個(gè)顯示屏都使用一個(gè)DisplayHardware對象來描述。實(shí)際上,Android系統(tǒng)目前只支持一個(gè)顯示屏,因此,在調(diào)用 SurfaceFlinger類的成員函數(shù)graphicPlane的時(shí)候,傳進(jìn)來的參數(shù)dpy的值都是等于0。
?? ? ?回到Layer類的成員函數(shù)setBuffers中,它接下來獲得了用來描述系統(tǒng)第1個(gè)顯示屏的DisplayHardware對象hw,接著再調(diào)用函 數(shù)getPixelFormatInfo來獲得用來描述該顯示屏的像素格式信息的PixelFormatInfo對象displayInfo。
?? ? ?Layer類的成員函數(shù)setBuffers接下來再將要創(chuàng)建的Surface的像素格式以及大小記錄下來,即分別將參數(shù)format、w和h的值保存 在成員變量mFormat、mWidth、mHeight和mReqFormat、mReqWidth、mReqHeight中。
?? ? ?Layer類的成員函數(shù)setBuffers接下來再檢查參數(shù)flags的ISurfaceComposer::eSecure位是否等于1。如果等于 1的話,就將成員變量mSecure的值設(shè)置為true,否則就設(shè)置為false。當(dāng)參數(shù)flags的 ISurfaceComposer::eSecure位等于1的時(shí)候,就表示正在創(chuàng)建的Surface的UI數(shù)據(jù)是可以安全地從一個(gè)進(jìn)程拷貝到另外一個(gè)進(jìn) 程的。有些Surface的UI數(shù)據(jù)是不可以隨便拷貝的,因?yàn)檫@涉及到安全問題,例如,用來創(chuàng)建屏幕截圖的Surface的UI數(shù)據(jù)就是不可以隨便從一個(gè) 進(jìn)程拷貝到另外一個(gè)進(jìn)程的,因?yàn)槠聊唤貓D可能會包含隱私信息。
?? ? ?Layer類的成員函數(shù)setBuffers接下來又檢查要創(chuàng)建的Surface的像素格式的Alpha通道的高8位是否大于低8位。如果是的話,就將成員變量mNeedsBlending的值設(shè)置為true,表示在渲染時(shí)要執(zhí)行混合操作。
?? ? ?Layer類的成員函數(shù)setBuffers接下來還檢查要創(chuàng)建的Surface的像素格式的Red通道的大小是否大于系統(tǒng)第1個(gè)顯示屏的像素格式的 Red通道的大小。如果是的話,就將成員變量mNeedsDithering的值設(shè)置為true,表示在渲染時(shí)要執(zhí)行抖動操作。
?? ? ?最后,Layer類的成員函數(shù)setBuffers就創(chuàng)建了一個(gè)SurfaceLayer對象,并且保存成員變量mSurface中。
?? ? ?接下來,我們就繼續(xù)分析SurfaceLayer對象的創(chuàng)建過程。
?? ? ?Step 7. new SurfaceLayer
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。
?? ? ? SurfaceLayer類的構(gòu)造函數(shù)的實(shí)現(xiàn)很簡單,它只是使用參數(shù)flinger以及owner來初始其父類Surface,其中,參數(shù)flinger 指向的是SurfaceFlinger服務(wù),而參數(shù)owner指向的是正在創(chuàng)建的SurfaceLayer對象的宿主Layer對象。
?? ? ? 這一步執(zhí)行完成之后, ?沿著調(diào)用路徑返回到SurfaceFlinger類的成員函數(shù)createSurface中,這時(shí)候就創(chuàng)建好一個(gè)Layer對象及其內(nèi)部的一個(gè) SurfaceLayer對象了,接下來,我們繼續(xù)分析SurfaceFlinger類的成員函數(shù)addClientLayer的實(shí)現(xiàn),以便可以了解 SurfaceFlinger服務(wù)是如何維護(hù)它所創(chuàng)建的Layer的,即它所創(chuàng)建的Surface。
?? ? ? Step 8.?SurfaceFlinger.addClientLayer
[cpp] view plaincopy?? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ? 參數(shù)client指向了一個(gè)Client對象,它是用來描述當(dāng)前正在請求SurfaceFlinger服務(wù)的一個(gè)Android應(yīng)用程序的;參數(shù)lbc指 向的是我們在前面Step 4中所創(chuàng)建的一個(gè)Layer對象。函數(shù)首先調(diào)用參數(shù)client所指向的一個(gè)Client對象的成員函數(shù)attachLayer來關(guān)聯(lián)參數(shù)lbc所指向的 一個(gè)Layer對象,以表示參數(shù)lbc所指向的一個(gè)Layer對象是由參數(shù)client所指向的一個(gè)Client對象所描述的一個(gè)Android應(yīng)用程序 請求創(chuàng)建的,接下來再調(diào)用SurfaceFlinger類的成員函數(shù)addLayer_l來將參數(shù)lbc所指向的一個(gè)Layer對象保存在 SurfaceFlinger的內(nèi)部。
?? ? ? 接下來,我們首先分析Client類的成員函數(shù)attachLayer的實(shí)現(xiàn),接著再分析SurfaceFlinger類的成員函數(shù)addLayer_l的實(shí)現(xiàn)。
?? ? ? Step 9.?Client.attachLayer
[cpp] view plaincopy?? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ? 從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)的連接過程分析一 文可以知道,Client類的成員變量mNameGenerator是用來生成Surface名稱的,它的初始值等于1,每當(dāng)Android應(yīng)用程序請求 SurfaceFlinger服務(wù)為它創(chuàng)建一個(gè)Surface,SurfaceFlinger服務(wù)就會將對應(yīng)的Client對象的成員變量 mNameGenerator的值增加1,這樣就可以依次得到名稱等于1、2、3......的Surface。
?? ? ? 為正在創(chuàng)建的Surface生成好名稱name之后,Client類的成員函數(shù)attachLayer就以變量name為關(guān)鍵字,將用來描述正在創(chuàng)建的 Surface的一個(gè)Layer對象layer保存Client類的成員變量mLayers所描述的一個(gè)Map中。從這里就可以知道,一個(gè)Android 應(yīng)用程序所創(chuàng)建的Surface,都保存在與它所對應(yīng)的一個(gè)Client對象的成員變量mLayers中。
?? ? ?step 10.?SurfaceFlinger.addLayer_l
[cpp] view plaincopy?? ? ?這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ?SurfaceFlinger類的成員變量mCurrentState指向了一個(gè)State對象,這個(gè)State對象內(nèi)部有一個(gè)成員變量 layersSortedByZ,它用來描述一個(gè)類型為LayerVector的向量,用來保存SurfaceFlinger服務(wù)所創(chuàng)建的每一個(gè) Layer,并且這些Layer是按照Z軸坐示來排列的。這樣,SurfaceFlinger服務(wù)在渲染Surface的時(shí)候,就可以根據(jù)這個(gè)向量來計(jì)算 可見性。
?? ? ?這一步執(zhí)行完成之后,回到SurfaceFlinger類的成員函數(shù)createSurface中,這時(shí)候SurfaceFlinger服務(wù)就將前面所 創(chuàng)建的一個(gè)Layer對象保存好在內(nèi)部了,接下來就會調(diào)用這個(gè)Layer對象的成員函數(shù)getSurface來獲得在前面Step 6中所創(chuàng)建的一個(gè)SurfaceLayer對象,以便可以將它的一個(gè)Binder代理對象返回請求Surface的Android應(yīng)用程序。
?? ? ?Layer類的成員函數(shù)getSurface是從父類LayerBaseClient繼承下來的,因此,接下來我們就繼續(xù)分析LayerBaseClient類的成員函數(shù)getSurface的實(shí)現(xiàn)。
?? ? ?Step 11.?LayerBaseClient.getSurface
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/LayerBase.cpp中。
?? ? ??LayerBaseClient類的成員變量mClientSurface是一個(gè)類型為Surface的弱指針,它指向了一個(gè)Surface子類對 象。函數(shù)首先將LayerBaseClient類的成員變量mClientSurface升級為一個(gè)強(qiáng)指針s。如果升級失敗,即得到的強(qiáng)指針的值等于0, 那么就說明要么還沒有初始化LayerBaseClient類的成員變量mClientSurface,要么LayerBaseClient類的成員變量 mClientSurface所指向的一個(gè)Surface子類對象已經(jīng)被銷毀了。在這種情況下,函數(shù)就會調(diào)用由其子類來重寫的成員函數(shù) createSurface來獲得一個(gè)Surface子類對象,并且保存在成員變量mClientSurface中。最后再將得到的Surface子類對 象返回給調(diào)用者。弱指針升級為強(qiáng)指針的原理,可以參考Android系統(tǒng)的智能指針(輕量級指針、強(qiáng)指針和弱指針)的實(shí)現(xiàn)原理分析一文。
?? ? ?在我們這個(gè)場景中,LayerBaseClient的子類即為Layer類,因此,接下來我們就繼續(xù)分析它的成員函數(shù)createSurface的實(shí)現(xiàn)。
?? ? ?Step 12. Layer.createSurface
[cpp] view plaincopy?? ? ?這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。
?? ? ?從前面的Step 6可以知道,?Layer類的成員變量mSurface已經(jīng)指向了一個(gè)SurfaceLayer對象,因此,函數(shù)就可以直接將它返回給調(diào)用者。
?? ? ?這一步執(zhí)行完成之后,回到SurfaceFlinger類的成員函數(shù)createSurface中,這時(shí)候SurfaceFlinger服務(wù)就完成了 Android應(yīng)用程序所請求創(chuàng)建的Surface了,最后就會將用來描述這個(gè)Surface的一個(gè)urfaceLayer對象的一個(gè)Binder代理對 象返回Android應(yīng)用程序,以便Android應(yīng)用程序可以將它封裝成一個(gè)SurfaceControl對象,如前面的Step 1所示。
?? ? ?接下來,我們就回到Android應(yīng)用程序這一側(cè),繼續(xù)分析SurfaceControl對象的創(chuàng)建過程。
?? ? ?Step 13. new SurfaceControl
[cpp] view plaincopy?? ? ?這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。
?? ? ?SurfaceControl類的構(gòu)造函數(shù)的實(shí)現(xiàn)很簡單,它只是對各個(gè)成員變量進(jìn)行初始化,其中,我們需要重點(diǎn)關(guān)注的是,SurfaceControl 類的成員變量mSurface指向的是一個(gè)類型為BpSurface的Binder代理對象,這個(gè)Binder代理對象引用的是由 SurfaceFlinger服務(wù)所創(chuàng)建的一個(gè)類型為SurfaceLayer的Binder本地對象。
?? ? ?這一步執(zhí)行完成之后,返回到開機(jī)動畫應(yīng)用程序bootanim中,即BootAnimation類的成員函數(shù)readyToRun中,接下來它就會調(diào)用 在這一步所創(chuàng)建的SurfaceControl對象的成員函數(shù)getSurface來獲得一個(gè)Surface對象。
?? ? ?接下來,我們就繼續(xù)分析SurfaceControl類的成員函數(shù)getSurface的實(shí)現(xiàn)。
?? ? ?Step 14. SurfaceControl.getSurface
[cpp] view plaincopy ?? ? ?這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。
?? ? ?SurfaceControl類的成員函數(shù)getSurface第一次被調(diào)用時(shí),成員變量mSurfaceData的值等于0,因此,函數(shù)接下來就會創(chuàng)建一個(gè)Surface對象,并且保存在成員變量mSurfaceData中。
?? ? ?接下來,我們就繼續(xù)分析Surface對象的創(chuàng)建過程。
?? ? ?Step 15. new Surface
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。
?? ? ? Surface類的成員變量mBufferMapper指向了一個(gè)GraphicBufferMapper對象,它是用來將分配到的圖形緩沖區(qū)映射到 Android應(yīng)用程序進(jìn)程的地址空間的,在接下來的一篇文章介紹Surface的渲染過程時(shí),我們再詳細(xì)分析。
?? ? ? Surface類的成員變量mClient指向了Android應(yīng)用程序進(jìn)程中的一個(gè)SurfaceClient單例。從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一 文可以知道,這個(gè)SurfaceClient單例是有來創(chuàng)建Android應(yīng)用程序與SurfaceFlinger服務(wù)的共享UI元數(shù)據(jù)的。當(dāng) SurfaceClient類的成員函數(shù)getInstance第一次在進(jìn)程中被調(diào)用時(shí),Android應(yīng)用程序便會請求SurfaceFlinger服 務(wù)創(chuàng)建這塊共享UI元數(shù)據(jù)。
?? ? ? Surface類的成員變量mSharedBufferClient指向了一個(gè)SharedBufferClient對象。文章開始時(shí)提 到,SharedBufferClient是用來在Android應(yīng)用程序這一側(cè)描述一個(gè)Surface的UI元數(shù)據(jù)緩沖區(qū)堆棧的,后面我們再分析它的創(chuàng) 建過程。
?? ? ??Surface類的成員變量mSurface指向了一個(gè)類型為BpSurface的Binder代理對象。從Surface類的構(gòu)造函數(shù)就可以看出,這個(gè)Binder代理對象引用的是在前面Step 6中創(chuàng)建的一個(gè)SurfaceLayer對象。
?? ? ??Surface類的其余成員變量mIdentity、mFormat、mFlags、mWidth和mHeight分別用來描述一個(gè)Surface的ID、像素格式、用途、寬度和高度。
?? ? ??Surface類的構(gòu)造函數(shù)接下來調(diào)用另外一個(gè)成員函數(shù)init進(jìn)一步執(zhí)行初始化的工作,接下來,我們就繼續(xù)分析Surface類的成員函數(shù)init的實(shí)現(xiàn)。
?? ? ? Step 16. Surface.init
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/Surface.cpp中。
?? ? ? 這個(gè)函數(shù)的初始化工作分為兩部分。
?? ? ? 第一部分初始化工作是與OpenGL庫相關(guān)的,主要就是設(shè)置OpenGL指定的一系列回調(diào)接口,以及設(shè)置設(shè)備顯示屏信息。前面提到,Surface類是從 ANativeWindow類繼承下來的,作為OpenGL庫與Android系統(tǒng)的本地窗口的連接橋梁。
?? ? ? ANativeWindow類定義了setSwapInterval、dequeueBuffer、cancelBuffer、lockBuffer、 queueBuffer、query和perform一共7個(gè)回調(diào)接口,它們分別被設(shè)置為Surface類的靜態(tài)成員函數(shù) setSwapInterval、dequeueBuffer、cancelBuffer、lockBuffer、queueBuffer、query和 perform。我們主要關(guān)注dequeueBuffer和queueBuffer兩個(gè)回調(diào)接口,前者用來從UI元數(shù)據(jù)緩沖區(qū)堆棧中獲得一個(gè)緩沖區(qū),而后 者用來將一個(gè)緩沖區(qū)插入到UI元數(shù)據(jù)緩沖區(qū)堆棧的待渲染隊(duì)列中。在接下來的一篇文章介紹Surface的渲染過程時(shí),我們再詳細(xì)分析這兩個(gè)回調(diào)接口。
?? ? ?ANativeWindow類還定義了四個(gè)成員變量xdpi、ydpi、minSwapInterval、maxSwapInterval和 flags,這幾個(gè)成員變量也是要由Surface類來初始化的。成員變量xdpi和ydpi用來描述設(shè)備顯示度的密度,即每英寸點(diǎn)數(shù)。設(shè)備顯示屏的密碼 信息可以通過調(diào)用SurfaceComposerClient類的靜態(tài)成員函數(shù)getDisplayInfo來獲得。成員變量 minSwapInterval和maxSwapInterval用來描述前后兩個(gè)緩沖區(qū)進(jìn)行交換的最小和最大時(shí)間間隔。成員變量flags用來描述一些 標(biāo)志信息。
?? ? ?第二部分初始化工作是與UI元數(shù)據(jù)緩沖區(qū)相關(guān)。
?? ? ?Surface類的成員變量mNextBufferTransform、mSwapRectangle和mNextBufferCrop分別用來描述下一個(gè)要渲染的圖形緩沖區(qū)的旋轉(zhuǎn)方向、裁剪區(qū)域和紋理坐標(biāo)。
?? ? ?Surface類的成員變量mBuffers用來描述一個(gè)類型為sp<GraphicBuffer>的Vector,主要是用來保存一個(gè) Surface所使用的圖形緩沖區(qū)(GraphicBuffer)的。一開始的時(shí)候,這個(gè)向量的大小被設(shè)置為2,后面會根據(jù)實(shí)際需要來增加容量。
?? ? ?Surface類的成員變量mSharedBufferClient指向了一個(gè)SharedBufferClient對象,用來描述一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧,它的創(chuàng)建過程是最重要的,因此,接下來我們就詳細(xì)分析這個(gè)過程。
?? ? ?Surface類的成員函數(shù)init首先調(diào)用成員變量mClient的成員函數(shù)getTokenForSurface來獲得成員變量mSurface所 描述的一個(gè)Surface的token值。有了這個(gè)token值之后,接下就可以創(chuàng)建一個(gè)SharedBufferClient對象,并且保存 在?Surface類的成員變量mSharedBufferClient中了。
?? ? ?在前面的Step 15中提到,Surface類的成員變量mClient指向的是一個(gè)SurfaceClient對象,因此,接下來我們首先分析 SurfaceClient類的成員函數(shù)getTokenForSurface的實(shí)現(xiàn),接著再分析SharedBufferClient對象的創(chuàng)建過程。
?? ? ?從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一 文可以知道,SurfaceClient類的成員函數(shù)getTokenForSurface實(shí)際上是調(diào)用了其成員變量mClient所指向的一個(gè)類型為 BpSurfaceComposerClient的Binder代理對象的成員函數(shù)getTokenForSurface來請求 SurfaceFlinger服務(wù)返回一個(gè)Surface的token值。由于這個(gè)Binder代理對象引用的是一個(gè)類型為UserClient的 Binder本地對象,這個(gè)Binder本地對象是運(yùn)行在SurfaceFlinger服務(wù)這一側(cè)的。接下來,我們就直接分析UserClient類的成 員函數(shù)getTokenForSurface的實(shí)現(xiàn)。
?? ? ?Step 17.?UserClient.getTokenForSurface
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp中。
?? ? ? 從前面的調(diào)用過程可以知道,參數(shù)sur指向了一個(gè)SurfaceLayer對象,并且這個(gè)SurfaceLayer對象是在前面的Step 6中創(chuàng)建的。
?? ? ? UserClient類的成員變量mFlinger指向了SurfaceFlinger服務(wù),函數(shù)首先調(diào)用它的成員函數(shù)getLayer來獲得參數(shù)sur 所指向的SurfaceLayer對象的宿主Layer對象layer,接著調(diào)用這個(gè)Layer對象layer的成員函數(shù)getToken來獲得它的 token值。如果這個(gè)token值大于等于0,那么就說明已經(jīng)為Layer對象layer分配過token值了,即已經(jīng)為參數(shù)sur所描述的 Surface分配過token值了。在這種情況下,就直接將該token值返回給Android應(yīng)用程序。否則的話,UserClient類的成員函數(shù) getTokenForSurface接下來就需要為參數(shù)sur所描述的Surface分配一個(gè)token值。
?? ? ??UserClient類的成員變量mBitmap是一個(gè)int32_t值,它是用來為Android應(yīng)用程序的Surface分配Token值的,即 如果它的第n位等于1,那么就表示值等于n的Token已經(jīng)被分配出去使用了。UserClient類的成員函數(shù)getTokenForSurface使 用一個(gè)while循環(huán)來在成員變量mBitmap中從低位到高位找到一個(gè)值等于0的位,接著再將位所在的位置值作為參數(shù)sur所描述的一個(gè)Surface 的token值,最后還會將這個(gè)token值設(shè)置到Layer對象layer里面去,這是通過調(diào)用Layer類的成員函數(shù)setToken來實(shí)現(xiàn)的。
?? ? ?接下來,我們就繼續(xù)分析Layer類的成員函數(shù)setToken的實(shí)現(xiàn)。
?? ? ?Step 18. Layer.setToken
[cpp] view plaincopy?? ? ??這個(gè)函數(shù)定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。
?? ? ? 參數(shù)userClient指向了一個(gè)UserClient對象,而參數(shù)sharedClient指向了該UserClient對象內(nèi)部的成員變量ctrlblk所指向的一個(gè)SharedClient對象。從前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一文可以知道,這個(gè)SharedClient對象是用來描述一組UI元數(shù)據(jù)緩沖區(qū)堆棧的。
?? ? ? Layer類的成員變量mBufferManager指向了一個(gè)BufferManager對象,通過調(diào)用它的成員函數(shù) getDefaultBufferCount就可以獲得一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的大小,即這個(gè)堆棧里面所包含的UI元數(shù)據(jù)緩沖區(qū)的個(gè)數(shù)。有了這些信息之 后,Layer類的成員函數(shù)setToken就可以創(chuàng)建一個(gè)SharedBufferServer對象lcblk了,并且會將這個(gè) SharedBufferServer對象lcblk保存在Layer類的成員變量mUserClientRef所描述的一個(gè)ClientRef對象的內(nèi) 部。這是通過調(diào)用ClientRef類的成員函數(shù)setToken來實(shí)現(xiàn)的,如下所示:
[cpp] view plaincopy?? ? ?這個(gè)函數(shù)同樣是定義在文件frameworks/base/services/surfaceflinger/Layer.cpp中。
?? ? ?ClientRef類有三個(gè)成員變量mUserClient、mToken和mControlBlock。其中,mUserClient是一個(gè)類型為 UserClient的弱指針,它指向了參數(shù)uc所描述的一個(gè)UserClient對象,mToken是一個(gè)int32_t值,用來描述它的宿主 Layer對象的token值,mControlBlock是一個(gè)類型為SharedBufferServer強(qiáng)指針,它指向了參數(shù) sharedCient所描述一個(gè)haredBufferServer對象,用來在SurfaceFlinger服務(wù)這一側(cè)描述一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆 棧。
?? ? 回到Layer類的成員函數(shù)setToken中,接下來我們繼續(xù)分析一個(gè)SharedBufferServer對象的創(chuàng)建過程。
?? ? Step 19. new SharedBufferServer
[cpp] view plaincopy?? ? ? 這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp中。
?? ? ??SharedBufferServer類的構(gòu)造函數(shù)主要是用來初始它所描述的一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧的,這個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧是通過其父類的成 員變量mSharedStack所指向的一個(gè)SharedBufferStack對象來描述的。SharedBufferStack類的各個(gè)成員變量的含 義可以參考前面前面Android應(yīng)用程序與SurfaceFlinger服務(wù)之間的共享UI元數(shù)據(jù)(SharedClient)的創(chuàng)建過程分析一文,這里不再復(fù)述。
?? ? ? 這一步執(zhí)行完成之后,沿著調(diào)用路徑,一直返回到前面的Step 16中,即Surface類的成員函數(shù)init中,這時(shí)候Android應(yīng)用程序就獲得了正在創(chuàng)建的Surface的token值,接下來就可以以這個(gè) token值為參數(shù),來創(chuàng)建一個(gè)SharedBufferClient對象了。
?? ? ? Step 20. new SharedBufferClient
[cpp] view plaincopy?? ? ??這個(gè)函數(shù)定義在文件frameworks/base/libs/surfaceflinger_client/SharedBufferStack.cpp中。
?? ? ??SharedBufferClient類的構(gòu)造函數(shù)主要是用來初始化成員變量tail和queued_head的值。這兩個(gè)成員變量的含義可以參考前 面Android應(yīng)用程序與SurfaceFlinger服務(wù)的關(guān)系概述和學(xué)習(xí)計(jì)劃一文中的圖6,這里不再詳述。
?? ? ? 這里我們需要注意的是,這里的參數(shù)sharedClient指向了一個(gè)SharedClient對象,這個(gè)SharedClient對象與在前面Step 18中用來創(chuàng)建SharedBufferServer對象的SharedClient對象描述的是同一塊匿名共享內(nèi)存,而且這里的參數(shù)surface與在 前面Step 18中用來創(chuàng)建SharedBufferServer對象的token的值是相等的,這意味著這一步所創(chuàng)建的SharedBufferClient對象與 前面Step 19所創(chuàng)建的SharedBufferServer對象描述的是同一個(gè)SharedBufferStack對象,即同一個(gè)UI元數(shù)據(jù)緩沖區(qū)堆棧,并且這個(gè) UI元數(shù)據(jù)緩沖區(qū)堆棧已經(jīng)在前面的Step 19中初始化好了。
?? ? ? 至此,Android應(yīng)用程序請求SurfaceFlinger服務(wù)創(chuàng)建Surface的過程就分析完成了。我們需要重點(diǎn)掌握的是,當(dāng)Android應(yīng)用 程序請求SurfaceFlinger服務(wù)創(chuàng)建一個(gè)Surface的時(shí)候,需要在SurfaceFlinger服務(wù)這一側(cè)創(chuàng)建一個(gè)Layer對象、一個(gè) Layer::SurfaceLayer對象和一個(gè)SharedBufferServer對象,同時(shí)又需要在Android應(yīng)用程序這一側(cè)創(chuàng)建一個(gè) SurfaceControl對象、一個(gè)Surface對象和一個(gè)SharedBufferClient對象。掌握了這些知識之后,在接下來的一篇文章 中,我們就可以分析Android應(yīng)用程序請求SurfaceFlinger服務(wù)渲染Surface的過程了,敬請期待!
老羅的新浪微博:http://weibo.com/shengyangluo,歡迎關(guān)注!
總結(jié)
以上是生活随笔為你收集整理的Android应用程序请求SurfaceFlinger服务创建Surface的过程分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lync 小技巧-42-动态-IP-统一
- 下一篇: 连接WiFi工具类