Android4.2.2 SurfaceFlinger啟動流程詳解(一)

來源:互聯網
上載者:User

 

 

這周繼續我的Blog,前面幾篇博文簡單的介紹了閱讀Android FW的源碼所需要的基礎知識,主要和C++相關。從這篇博文開始將會和大家一起學習並總結SurfaceFlinger模組在Android中的相關內容,本文主要描述的是SurfaceFlinger的詳細啟動流程。

 

1.SurfaceFlinger在哪裡啟動?

在android系統中一個核心的Service都有ServiceManager管理,核心Service啟動一般是在SystemServer來啟動,但是比較重要的Service會在Zygote啟動前,由init進程來負責直接啟動。故SurfaceFlinger作為一個核心Service,一般有下面2種啟動方式。

a.在systemserver中如何啟動。

源碼目錄/android/frameworks/base/cmds/system_server/library/system_init.cpp.

extern C status_t system_init(){    ALOGI(Entered system_init());    sp proc(ProcessState::self());    sp sm = defaultServiceManager();    ALOGI(ServiceManager: %p, sm.get());    sp grim = new GrimReaper();    sm->asBinder()->linkToDeath(grim, grim.get(), 0);    char propBuf[PROPERTY_VALUE_MAX];    property_get(system_init.startsurfaceflinger, propBuf, 1);    if (strcmp(propBuf, 1) == 0) {        // Start the SurfaceFlinger        SurfaceFlinger::instantiate();    }    property_get(system_init.startsensorservice, propBuf, 1);    if (strcmp(propBuf, 1) == 0) {        // Start the sensor service        SensorService::instantiate();    }......}

在這裡可以看到在systemserver的啟動過程中,property_get通過擷取system_init.startsurfaceflinger的屬性值,這個屬性值一般在init.rc中進配置,如果該數值為0,則賦值propBuf=1,故以此會使用system_init中來啟動SF。

 

b.相對比上面的啟動,另一種啟動就是直接像ServiceManager一樣,作為init進程中的一個Service來啟動。

在init.rc中添加如下配置代碼:

# Set this property so surfaceflinger is not started by system_init
setprop system_init.startsurfaceflinger 0

啟動SurfaceFlinger的過程:

469 service surfaceflinger /system/bin/surfaceflinger470     class main471     user system472     group graphics drmrpc473     onrestart restart zygote474 

對於Service如何啟動,可以查看Blog:android系統啟動流程啟動畫面學習之init和init.rc分析的相關內容即可理解。

 

2.以第二種方式啟動來進一步分析SF,看看SurfaceFlinger的main函數源碼。

路徑:android/frameworks/native/cmds/surfaceflinger/main_surfaceflinger.cpp

int main(int argc, char** argv) {    SurfaceFlinger::publishAndJoinThreadPool(true);    // When SF is launched in its own process, limit the number of    // binder threads to 4.    ProcessState::self()->setThreadPoolMaxThreadCount(4);    return 0;}

要開始結束SurfaceFlinger的函數處理過程時,有必要先進SF的基本UML圖提出來,如下所示:

 

step1: 調用publishAndJoinThreadPool函數:

該函數是C++裡一個帶預設參數的函數的,這裡傳入的參數的true。

    static void publishAndJoinThreadPool(bool allowIsolated = false) {        sp sm(defaultServiceManager());        sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);        ProcessState::self()->startThreadPool();        IPCThreadState::self()->joinThreadPool();    }

這裡會涉及到和ServerManger的互動,變數sm是SM在當前進程的一個代理proxy,用於Binder驅動的互動,而addService正是將SurfaceFlinger做為一個核心的系統服務註冊到SM當中。隨後就是當前進程由ProcessState通過依次調用會新run起來一個thread如下所示,Poolthread繼承與Thread類,故一旦run起來就運行thread的run函數故而依舊前面介紹的thread類是依次會執行PoolThread類的readyToRun和threadLoop;

void ProcessState::spawnPooledThread(bool isMain){    if (mThreadPoolStarted) {        int32_t s = android_atomic_add(1, &mThreadPoolSeq);        char buf[16];        snprintf(buf, sizeof(buf), Binder_%X, s);        ALOGV(Spawning new pooled thread, name=%s, buf);        sp t = new PoolThread(isMain);        t->run(buf);    }}

在對應的threadLoop裡面可以找到IPCThreadState::self()->joinThreadPool(mIsMain);即建立一個IPCThreadState處理序間通訊的線程狀態類,該類的函數joinThreadPool
即是與Binder驅動互動的介面,核心是和核心Binder驅動進行talkWithDriver()以及executeCommand(), 因為當前的SurfaceFlinger已經進入了正常的運行狀態。

當然在本主線程也會 調用IPCThreadState::self()->joinThreadPool();進行Binder間的通訊,確保通訊的穩定性。

 

step2: 迴歸SurfaceFlinger對象的建立
作為繼承了public BinderService模板類的SF,他的建立就在上文提到的publishAndJoinThreadPool函數中的

       sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated);

new SERVICE() = new SurfaceFlinger().從這裡該進入SF的建立和相關初始化了

SF類的定義和初始化成員函數的檔案目錄:

源檔案/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp;標頭檔/android/frameworks/native/services/surfaceflinger/SurfaceFlinger.h;

如下是SF的狗建構函式,首先對基類BnSurfaceComposer、Thread進行初始化

SurfaceFlinger::SurfaceFlinger()    :   BnSurfaceComposer(), Thread(false),        mTransactionFlags(0),        mTransactionPending(false),        mAnimTransactionPending(false),        mLayersRemoved(false),        mRepaintEverything(0),        mBootTime(systemTime()),        mVisibleRegionsDirty(false),        mHwWorkListDirty(false),        mDebugRegion(0),        mDebugDDMS(0),        mDebugDisableHWC(0),        mDebugDisableTransformHint(0),        mDebugInSwapBuffers(0),        mLastSwapBufferTime(0),        mDebugInTransaction(0),        mLastTransactionTime(0),        mBootFinished(false)

這裡乘熱打鐵來看thread類,很容易知道必然有地方會run起thread類所屬的線程,好吧接下去揭開謎底所在,來看這個:

void SurfaceFlinger::onFirstRef(){    mEventQueue.init(this);    run(SurfaceFlinger, PRIORITY_URGENT_DISPLAY);//啟動一個新的thread線程,調用thread類的run函數    // Wait for the main thread to be done with its initialization    mReadyToRunBarrier.wait();//等待線程完成相關的初始化}

OK這個onFirstRef似乎特別熟悉,的確在Android FrameWork中的SP、RefBase、weakref_impl,Thread類裡面詳細說明了他的由來,其實也就是和RefBase的關係特別密切。一般new一個SP的模板類,會最終調用該類對象對Refase重載的onFirstRef()。這裡就可以看到進行了mEventQueue(在介紹SF的訊息機制時再深入分析)的初始化以及啟動一個run函數。故最終調用SF的readyToRun和threadLoop。

 

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.