這個(gè)系列最后一篇文章蓬网,簡單總結(jié)下SurfaceFlinger的啟動(dòng)流程及合成視圖過程瘸味。
一切端、SurfaceFlinger啟動(dòng)流程
SurfaceFlinger 進(jìn)程是由 init 進(jìn)程創(chuàng)建的型将,運(yùn)行在獨(dú)立進(jìn)程中寂祥。
//init.rc
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
writepid /dev/cpuset/system-background/tasks
SurfaceFlinger 的創(chuàng)建會(huì)執(zhí)行 main() 方法:
//main_surfaceflinger.cpp
int main(int, char**) {
ProcessState::self()->setThreadPoolMaxThreadCount(4);
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
//實(shí)例化 surfaceflinger
sp<SurfaceFlinger> flinger = new SurfaceFlinger();
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
//初始化
flinger->init();
//發(fā)布 surface flinger,注冊到 ServiceManager
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false);
// 運(yùn)行在當(dāng)前線程
flinger->run();
return 0;
}
事實(shí)上到這里七兜,SurfaceFlinger進(jìn)程就已經(jīng)啟動(dòng)了丸凭。之后我們再來了解下SurfaceFlinger的一些初始化操作:
首先SurfaceFlinger 的實(shí)例化會(huì)執(zhí)行到:onFirstRef()
//SurfaceFlinger.cpp
void SurfaceFlinger::onFirstRef() {
mEventQueue.init(this); //初始化MessageQueue , mEventQueue.init中又會(huì)創(chuàng)建Looper與Handler。
}
然后會(huì)執(zhí)行到 SurfaceFlinger::init():
//SurfaceFlinger.cpp
void SurfaceFlinger::init() {
Mutex::Autolock _l(mStateLock);
//初始化 EGL腕铸,作為默認(rèn)的顯示
mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(mEGLDisplay, NULL, NULL);
// 初始化硬件 composer 對象
mHwc = new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this));
//獲取 RenderEngine 引擎
mRenderEngine = RenderEngine::create(mEGLDisplay, mHwc->getVisualID());
//檢索創(chuàng)建的 EGL 上下文
mEGLContext = mRenderEngine->getEGLContext();
//初始化非虛擬顯示屏
for (size_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
DisplayDevice::DisplayType type((DisplayDevice::DisplayType)i);
//建立已連接的顯示設(shè)備
if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
bool isSecure = true;
createBuiltinDisplayLocked(type);
wp<IBinder> token = mBuiltinDisplays[i];
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferConsumer> consumer;
//創(chuàng)建 BufferQueue 的生產(chǎn)者和消費(fèi)者
BufferQueue::createBufferQueue(&producer, &consumer,
new GraphicBufferAlloc());
sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, i, consumer);
int32_t hwcId = allocateHwcDisplayId(type);
//創(chuàng)建顯示設(shè)備
sp<DisplayDevice> hw = new DisplayDevice(this,
type, hwcId, mHwc->getFormat(hwcId), isSecure, token,
fbs, producer,
mRenderEngine->getEGLConfig());
if (i > DisplayDevice::DISPLAY_PRIMARY) {
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
mDisplays.add(token, hw);
}
}
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
//當(dāng)應(yīng)用和 sf 的 vsync 偏移量一致時(shí)惜犀,則只創(chuàng)建一個(gè) EventThread 線程
if (vsyncPhaseOffsetNs != sfVsyncPhaseOffsetNs) {
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
} else {
//創(chuàng)建 DispSyncSource 對象
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
vsyncPhaseOffsetNs, true, "sf-app");
//創(chuàng)建線程 EventThread
mEventThread = new EventThread(vsyncSrc);
//設(shè)置 EventThread
mEventQueue.setEventThread(mEventThread);
}
//創(chuàng)建 EventControl
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
//當(dāng)不存在 HWComposer 時(shí),則設(shè)置軟件 vsync
if (mHwc->initCheck() != NO_ERROR) {
mPrimaryDispSync.setPeriod(16666667);
}
//初始化繪圖狀態(tài)
mDrawingState = mCurrentState;
//初始化顯示設(shè)備
initializeDisplays();
//啟動(dòng)開機(jī)動(dòng)畫
startBootAnim();
}
該方法主要是執(zhí)行一些初始化工作狠裹,包括:EGL標(biāo)準(zhǔn)下OpenGL環(huán)境的創(chuàng)建虽界、創(chuàng)建 HWComposer、初始化非虛擬顯示屏涛菠、啟動(dòng) EventThread 線程莉御、啟動(dòng)開機(jī)動(dòng)畫等等撇吞。
在這里,有幾個(gè)比較重要的對象需要介紹下:
EGL:OpenGL是一個(gè)操作GPU的API礁叔,它通過驅(qū)動(dòng)向GPU發(fā)送相關(guān)指令牍颈,控制圖形渲染管線狀態(tài)機(jī)的運(yùn)行狀態(tài)。但OpenGL需要本地視窗系統(tǒng)進(jìn)行交互琅关,這就需要一個(gè)中間控制層煮岁,最好與平臺(tái)無關(guān)。EGL正是這個(gè)中間控制層涣易,它作為OpenGL ES和本地窗口的橋梁画机,主要作用是:其主要作用是為OpenGL指令創(chuàng)建 Context 、繪制目標(biāo)Surface 都毒、配置Framebuffer屬性色罚、Swap提交繪制結(jié)果等。
HWComposer: 硬件組合抽象層账劲,介于SurfaceFlinger和HAL之間戳护,具體到代碼級(jí)別就是一個(gè)類,封裝對于Hwcomposer HAL和Gralloc HAL的使用瀑焦。 主要作用是:一方面處理部分SurfaceFlinger委托過來的合成工作腌且,另一方面就是產(chǎn)生vsync信號(hào)
EventThread: 它是Surfaceflinger中的一個(gè)線程 ,主要作用:接收VSync事件通知榛瓮,并分發(fā)VSync通知給系統(tǒng)中的每一個(gè)感興趣的注冊者铺董。
二、SurfaceFlinger圖層合成過程
2.1 什么是圖層合成
圖層合成就是把多個(gè)圖層按既定的顯示區(qū)域禀晓,展現(xiàn)到顯示屏上精续。
例如Android手機(jī)的Launcher主界面圖層合成如下:
adb shell dumpsys SurfaceFlinger
com.android.systemui.ImageWallpaper
com.miui.home/com.miui.home.launcher.Launcher
StatusBar
2.2 SurfaceFlinger合成消息
SurfaceFlinger合成圖層依賴于Android的異步消息處理機(jī)制。
首先粹懒,它包含了一個(gè)MessageQueue對象(消息隊(duì)列)用于處理各種異步消息重付,在onFirstRef()中對消息隊(duì)列進(jìn)行了初始化:
//SurfaceFlinger.cpp
SurfaceFlinger::onFirstRef()
{
mEventQueue.init(this);
}
分析一下MessageQueue的實(shí)現(xiàn):
//MessageQueue.cpp
void MessageQueue::init(const sp<SurfaceFlinger>& flinger)
{
mFlinger = flinger;//保存MessageQueue的擁有者SurfaceFlinger
mLooper = new Looper(true);//創(chuàng)建Looper對象
mHandler = new Handler(*this);//創(chuàng)建Handler對象
}
調(diào)用Handler::handleMessage()處理INVALIDATE和REFRESH消息,并將其轉(zhuǎn)發(fā)給SurfaceFlinger進(jìn)行處理凫乖,調(diào)用onMessageReceived():
void MessageQueue::Handler::handleMessage(const Message& message) {
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
mQueue.mFlinger->onMessageReceived(message.what);
break;
}
}
接下來看一下SurfaceFlinger對消息的處理:
void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
bool refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
refreshNeeded |= mRepaintEverything;
if (refreshNeeded) {
// Signal a refresh if a transaction modified the window state,
// a new buffer was latched, or if HWC has requested a full
// repaint
signalRefresh();
}
break;
}
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}
SurfaceFlinger處理的消息分為兩種:
INVALIDATE消息:用于處理Layer或者display屬性的變化以及Layer對應(yīng)buffer的更新确垫。
1) Layer或者Display屬性的更新通過調(diào)用handleMessageTransaction()處理;
2) buffer的更新通過調(diào)用handleMessageInvalidate()處理。
REFRESH消息:表示SurfaceFlinger需要進(jìn)行一次合成操作(Refresh),通過handleMessageRefresh()實(shí)現(xiàn)帽芽;主要有三種情況:
1) Layer屬性的變化導(dǎo)致window state發(fā)生變化;
2) Layer有新的buffer到來;
3) HWC請求進(jìn)行一次repaint删掀。
如果這三種情況之一發(fā)生,則置refreshNeeded為true导街,調(diào)用signalRefresh()發(fā)出MessageQueue::REFRESH消息;
當(dāng)VSync信號(hào)來之前披泪,Layer或者display屬性的變化會(huì)做本地保存,只有當(dāng)VSync信號(hào)到來時(shí)搬瑰,SurfaceFlinger才會(huì)通過INVALIDATE和REFRESH消息來做統(tǒng)一的合并渲染和輸出的處理工作付呕。
2.3 handleMessageTransaction()
處理之前對屏幕和應(yīng)用程序窗口的改動(dòng)计福。因這些改動(dòng)很有可能會(huì)改變圖層的可見區(qū)域,進(jìn)而影響臟區(qū)域的計(jì)算徽职。
主要處理以下幾個(gè)方面的transaction:
1)Layer屬性的變化;
2)Layer的增加和減少佩厚;
3)Display屬性的變化;
4)Display的增加和減少姆钉;
2.4 handleMessageInvalidate()
主要調(diào)用handlePageFlip()函數(shù)。這里Page Flip是指從BufferQueue中取下一個(gè)圖形緩沖區(qū)內(nèi)容抄瓦,就好像是“翻頁”一樣潮瓶。該函數(shù)主要是從各Layer對應(yīng)的BufferQueue中拿圖形緩沖區(qū)數(shù)據(jù),并根據(jù)內(nèi)容更新臟區(qū)域(注:臟區(qū)域是需要重繪的屏幕區(qū)域钙姊。)毯辅。并且把GraphicBuffer映射為OpenGL的texture 。
2.5 handleMessageRefresh()
合并和渲染輸出煞额。
void SurfaceFlinger::handleMessageRefresh() {
...
preComposition(); //合成前的準(zhǔn)備
rebuildLayerStacks();//重建layer堆棧
setUpHWComposer();//hwcomposer的設(shè)定
doComposition();//正式的合成處理
postComposition(refreshStartTime);//合成后期的處理
...
}
2.5.1 void SurfaceFlinger::preComposition()
合成前準(zhǔn)備工作思恐。首先得到當(dāng)前所有l(wèi)ayer的集合,然后對所有的Layer調(diào)用其onPreComposition()檢查是否需要ExtralInvalidate,如果需要就調(diào)用一次signalLayerUpdate(),即通過EventThread安排一次vsync膊毁。
2.5.2 void SurfaceFlinger::rebuildLayerStacks()
計(jì)算可見layer及它們的可見區(qū)域胀莹。首先每個(gè)layer都有一個(gè)layerStack來區(qū)別它屬于哪個(gè)Display,系統(tǒng)的Display可能不止一個(gè)婚温,所以需要逐個(gè)處理Display描焰,根據(jù)所有l(wèi)ayers的當(dāng)前狀態(tài)通過SurfaceFlinger::computeVisibleRegions方法計(jì)算各個(gè)Layer在當(dāng)前display上的可見區(qū)域和臟區(qū)域等。最后把需要繪制的layer添加到layersSortedByZ中栅螟。
2.5.3 void SurfaceFlinger::setUpHWComposer()
為合成搭建環(huán)境荆秦。這個(gè)HWComposer并不是真正的Hal模塊,而是surfaceflinger為管理HWComposer模塊而設(shè)計(jì)的一個(gè)類力图,路徑是:frameworks/native/service/surfaceflinger/displayhardware/步绸。依次處理各個(gè)Display,構(gòu)造WorkList搪哪,合成過程既可以有Hwc模塊完成靡努,也可以通過OpengGlEs來完成,具體用哪種方式是有prepare()中的compositionType來決定的晓折。
2.5.4 void SurfaceFlinger::doComposition()
執(zhí)行合成操作惑朦。執(zhí)行openGl合成 or HWC合成。
2.5.5 void SurfaceFlinger::postComposition(refreshStartTime)
將圖像傳遞到物理屏幕漓概。
最后借用一張流程圖做最后的總結(jié):
參考:
https://blog.csdn.net/jxt1234and2010/article/details/46057267
https://blog.csdn.net/freekiteyu/article/details/79483406
https://blog.csdn.net/u012878643/article/details/71104467