Android-Fk:[Surface] Android中Surface的使用學(xué)習(xí)總結(jié)

Android-Fk:[Surface] Android中Surface的使用學(xué)習(xí)總結(jié)

一. Surface概述

https://www.cnblogs.com/Sharley/p/5600314.html
Surface對應(yīng)了一塊屏幕緩沖區(qū),每個(gè)window對應(yīng)一個(gè)Surface,任何View都要畫在Surface的Canvas上
Surface中有一個(gè)Canvas成員,專門用于畫圖的。
Surface是用來管理數(shù)據(jù)的。(句柄)
準(zhǔn)確來說應(yīng)該是一個(gè)數(shù)據(jù)容器交由生產(chǎn)者往surface申請對應(yīng)的GraphicBuffer中填數(shù)據(jù),交由consumer消費(fèi),consumer不僅只是surfaceflinger;

二.Surface使用的場景

1. Activity界面顯示

在這里插入圖片描述

主要步驟:

  1. activity創(chuàng)建時(shí)會給Activity創(chuàng)建一個(gè)對應(yīng)的PhoneWindow,而該P(yáng)honeWindow中會創(chuàng)建一個(gè)DecorView,即一個(gè)Activity對應(yīng)一個(gè)PhoneWindow,對應(yīng)一個(gè)DecorView;
  2. Activity生命周期onCreate中調(diào)用setContentView(int ResourceID)方法實(shí)際調(diào)用到了PhoneWindow的該方法,將調(diào)用LayoutInflater的inflater方法將布局文件中的View創(chuàng)建出來加入到PhoneWindow的DercorView中;
  3. 創(chuàng)建viewRootImpl將DercorView中的內(nèi)容數(shù)據(jù)填充到自身的成員變量Surface中
    該Surface實(shí)質(zhì)上是一個(gè)數(shù)據(jù)載體,最終通過WindowsManagerService傳遞給SurfaceFLinger去顯示,準(zhǔn)確的說應(yīng)該是Surface通過BufferQueue的機(jī)制,使得App與Surfaceflinger分別成為生產(chǎn)者和消費(fèi)者去處理Surface中的數(shù)據(jù)。

ViewRoot中的surface通過WMS與SurfaceFlinger中的BufferLayer進(jìn)行關(guān)聯(lián):


在這里插入圖片描述

通過如上過程,知道一點(diǎn),ViewRootImpl中的mSurface對應(yīng)著SurfaceFlinger中的一個(gè)BufferLayer;
以drawSoftware方法來看(新版本Android已經(jīng)不走該方法,通過RenderThread去繪制,下次學(xué)習(xí)完再做整理):


在這里插入圖片描述

繪制的時(shí)候會去dequeuebuffer,生產(chǎn)數(shù)據(jù)完畢后在queueBuffer,之后SurfaceFlinger會拿到buffer數(shù)據(jù)進(jìn)行顯示。

綜上來看,App進(jìn)程作為Activity對應(yīng)的ViewRootImpl中的mSurface的生產(chǎn)者,根據(jù)View的改變不斷的在mSurface中填充View數(shù)據(jù),mSurface通過WindowManagerService進(jìn)程與SurfaceFlinger中的BufferLayer一一對應(yīng),SurfaceFliner作為該mSurface的消費(fèi)者,將數(shù)據(jù)合成并交由硬件顯示出來。

該例子中的BufferQueue由SurfaceFlinger進(jìn)行管理。

2. SurfaceView

SurfaceView本身持有一個(gè)Surface對象,它的特點(diǎn)是:
A. 具有獨(dú)立的繪圖表面;
B. 需要在宿主窗口上挖一個(gè)洞來顯示自己;
C. 它的UI繪制可以在獨(dú)立的線程中進(jìn)行,這樣就可以進(jìn)行復(fù)雜的UI繪制,并且不會影響應(yīng)用程序的主線程響應(yīng)用戶輸入。
原理可以參考學(xué)習(xí):
https://blog.csdn.net/suhaiqiangxue/article/details/52932147
https://blog.csdn.net/luoshengyang/article/details/8661317/

如果layout中有SurfaceView:


在這里插入圖片描述

從上面圖看來,SurfaceView中的mSurface也會通過WMS與SurfaceFlinger中的Bufferlayer進(jìn)行關(guān)聯(lián),及如果一個(gè)window中有SurfaceView控件,PhoneWindow本身會有一個(gè)mSurface對應(yīng)SurfaceFlinger中的一個(gè)Bufferlayer,SurfaceView中的mSurface也會對應(yīng)Surfaceflinger中的一個(gè)Bufferlayer,及SurfaceFlinger為該界面維護(hù)者兩個(gè)BufferQueue。
大致情況如下:


在這里插入圖片描述

3. 相機(jī)中的Surface

相機(jī)preview與takepicture都使用到Surface去作為生產(chǎn)或消費(fèi)的數(shù)據(jù)載體,相機(jī)的細(xì)節(jié)流程這里不討論,下次專門整理下,大概流程如下:


在這里插入圖片描述

1.相機(jī)打開之后會傳兩個(gè)Surface到CameraServer,一個(gè)Surface是用來作為Preview的數(shù)據(jù)載體,另一個(gè)用作拍照時(shí)保存圖片的數(shù)據(jù)載體。一般preview的Surface由TextureView或GLSurfaceView關(guān)聯(lián)的SurfaceTexture來提供,保存圖片的Surface由ImageReader來提供;
2.Surface會在CameraServer進(jìn)程中包裝創(chuàng)建出流,即一個(gè)Surface對應(yīng)著一個(gè)OutputStream,用于HAL層將數(shù)據(jù)填充回來,當(dāng)然這里HAL層就相當(dāng)與該Surface的生產(chǎn)者,而上層的GLSurfaceView和ImageReader相當(dāng)與Surface的消費(fèi)者(分別將Surface中的數(shù)據(jù)預(yù)覽顯示出來和保存成圖片消費(fèi)掉);

  1. CameraServer中初始化時(shí)會起個(gè)RequestThread,不斷循環(huán)等待處理的request:


    在這里插入圖片描述

    這里看出HAL層實(shí)際上是Surface的生產(chǎn)者。
    而Surface的消費(fèi)者正是Camera應(yīng)用中的預(yù)覽使用的TextureView或GLSurfaceView,與保存圖片的ImageReader:

  2. Preview:
    在這里插入圖片描述

    GLSurfaceView中需要創(chuàng)建SurfaceTexture來使用(TextureView自帶一個(gè)SurfaceTexture)SurfaceTexture作為preview的surface的消費(fèi)者,交由GLConsumer消費(fèi)成TextImage繪制到對應(yīng)的GLSurfaceView的mSurface上;這里的BufferQueue由應(yīng)用進(jìn)程分配管理;

GLSurfaceView本質(zhì)上也是個(gè)SurfaceView,在上面提到的SurfaceView的mSurface與SurfaceFlinger中的BufferLayer相關(guān)連,因此此時(shí)GLSurfaceView與SurfaceFlinger又維持著一個(gè)BufferQueue的生產(chǎn)者與消費(fèi)者的關(guān)系,與上一段中的提到的BufferQueue不是一個(gè),mSurface中的內(nèi)容最終交給SurfaceFlinger去合成顯示。

  1. takePicture:
    在這里插入圖片描述

    Camera應(yīng)用作為拍照Surface的消費(fèi)者將Surface中的數(shù)據(jù)消費(fèi)生產(chǎn)出圖片進(jìn)行保存。這里的BufferQueue由應(yīng)用進(jìn)程分配管理;

三. 總結(jié)

Surface一般作為GraphicBuffer數(shù)據(jù)載體,提給給生產(chǎn)者和消費(fèi)者進(jìn)行數(shù)據(jù)的填充和獲取。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容