編輯:Android開發實例
SurfaceFinger按英文翻譯過來就是Surface投遞者。SufaceFlinger的構成並不是太復雜,復雜的是他的客戶端建構。SufaceFlinger主要功能是:
1) 將Layers (Surfaces) 內容的刷新到屏幕上
2) 維持Layer的Zorder序列,並對Layer最終輸出做出裁剪計算。
3) 響應Client要求,創建Layer與客戶端的Surface建立連接
4) 接收Client要求,修改Layer屬性(輸出大小,Alpha等設定)
但是作為投遞者的實際意義,我們首先需要知道的是如何投遞,投擲物,投遞路線,投遞目的地。
SurfaceFlinger管理對象為:
mClientsMap:管理客戶端與服務端的連接。
ISurface,IsurfaceComposer:AIDL調用接口實例
mLayerMap:服務端的Surface的管理對象。
mCurrentState.layersSortedByZ :以Surface的Z-order序列排列的Layer數組。
graphicPlane 緩沖區輸出管理
OpenGL ES:圖形計算,圖像合成等圖形庫。
gralloc.xxx.so這是個跟平台相關的圖形緩沖區管理器。
pmem Device:提供共享內存,在這裡只是在gralloc.xxx.so可見,在上層被gralloc.xxx.so抽象了。
Client端與SurfaceFlinger連接圖:
Client對象:一般的在客戶端都是通過SurfaceComposerClient來跟SurfaceFlinger打交道。
首先SurfaceFlinger需要操作到屏幕,需要建立一個屏幕硬件緩沖區管理框架。Android在設計支持時,考慮多個屏幕的情況,引入了graphicPlane的概念。在SurfaceFlinger上有一個graphicPlane數組,每一個graphicPlane對象都對應一個DisplayHardware.在當前的Android(2.1)版本的設計中,系統支持一個graphicPlane,所以也就支持一個DisplayHardware。
SurfaceFlinger,Hardware硬件緩沖區的數據結構關系圖。
method:setBuffer 在SurfaceFlinger端建立顯示緩沖區。這裡的緩沖區是指的HW性質的,PMEM設備文件映射的內存。
1) layer的繪制
void Layer::onDraw(const Region& clip) const
{
int index = mFrontBufferIndex;
GLuint textureName = mTextures[index].name;
…
drawWithOpenGL(clip, mTextures[index]);
}
以Surface的Z-order序列排列的LayerBase數組,該數組是層顯示遮擋的依據。在每個層計算自己的可見區域時,從Z-order 頂層開始計算,是考慮到遮擋區域的裁減,自己之前層的可見區域就是自己的不可見區域。而繪制Layer時,則從Z-order底層開始繪制,這個考慮到透明層的疊加。
我們從前面的章節<Android Service>的基本原理可以知道,SurfaceFlinger的運行框架存在於:threadLoop,他是SurfaceFlinger的主循環體。SurfaceFlinger在進入主體循環之前會首先運行:SurfaceFlinger::readyToRun()。
(1)建立GraphicPanle
(2)建立FrameBufferHardware(確定輸出目標)
初始化:OpenGL ES
建立兼容的mainSurface.利用eglCreateWindowSurface。
建立OpenGL ES進程上下文。
建立主Surface(OpenGL ES)。 DisplayHardware的Init()@DisplayHardware.cpp函數對OpenGL做了初始化,並創建立主Surface。為什麼叫主Surface,因為所有的Layer在繪制時,都需要先繪制在這個主Surface上,最後系統才將主Surface的內容”投擲”到真正的屏幕上。
(3) 主Surface的綁定
1)在DisplayHandware初始完畢後,hw.makeCurrent()將主Surface,OpenGL ES進程上下文綁定到SurfaceFlinger的上下文中,
2)之後所有的SurfaceFlinger進程中使用EGL的所有的操作目的地都是[email protected]。
這樣,在OpenGL繪制圖形時,主Surface被記錄在進程的上下文中,所以看不到顯示的主Surfce相關參數的傳遞。下面是Layer-Draw,Hardware.flip的動作示意圖:
(1)handleTransaction(…):主要計算每個Layer有無屬性修改,如果有修改著內用需要重畫。
(2)handlePageFlip()
computeVisibleRegions:根據Z-Order序列計算每個Layer的可見區域和被覆蓋區域。裁剪輸出范圍計算-
在生成裁剪區域的時候,根據Z_order依次,每個Layer在計算自己在屏幕的可顯示區域時,需要經歷如下步驟:
1)以自己的W,H給出自己初始的可見區域
2)減去自己上面窗口所覆蓋的區域
在繪制時,Layer將根據自己的可將區域做相應的區域數據Copy。
(3)handleRepaint()
composeSurfaces(需要刷新區域):
根據每個Layer的可見區域與需要刷新區域的交集區域從Z-Order序列從底部開始繪制到主Surface上。
(4)postFramebuffer()
(DisplayHardware)hw.flip(mInvalidRegion);
eglSwapBuffers(display,mSurface) :將mSruface投遞到屏幕。
現在SurfaceFlinger干的事情利用下面的示意圖表示出來:
本文實例講述了Android實現模仿UCweb菜單效果的方法。分享給大家供大家參考。具體如下: UCWeb的菜單看起來不錯,自己模仿做一個,思路實現如下: 1、保
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放
關於ListView拖拽移動位置,想必大家並不陌生,比較不錯的軟件都用到如此功能了.如:搜狐,網易,百度等,但是相比來說還是百度的用戶體驗較好,不偏心了,下面看幾
Android應用程序可以在許多不同地區的許多設備上運行。為了使應用程序更具交互性,應用程序應該處理以適合應用程序將要使用的語言環境方面的文字,數字,文件等。在本章中,我