[Android禪修之路] SurfaceFlinger的啟動過程

語言: CN / TW / HK

theme: channing-cyan

[Android禪修之路] SurfaceFlinger的啟動過程

Android禪修之路

一 概述

SurfaceFlinger 是系統服務的一種,所以它的啟動方式也是和其他系統服務一樣的,在 Android 中,有系統服務有兩種啟動方式。

  1. 由 ServiceManager 啟動
  2. 配置在 rc 檔案中單獨啟動

對於 SurfaceFlinger 來說,它使用的是第二種方式。

當然,系統服務的啟動原理這裡並不會深入,我們需要關注的,是 SurfaceFlinger 啟動的過程。Android 系統在啟動時,會通過 surfaceflinger.rc 檔案來啟動 SurfaceFlinger 服務,SurfaceFlinger 原始檔配置在 frameworks/native/services/surfaceflinger/Android.bp 檔案中。Android.bp 是 Android 新版本的編譯配置檔案,通過 Android.bp 檔案的指定,最終會執行main_surfaceflinger.cpp檔案中的 main 函式。所以我們從 SurfaceFlinger 啟動的第一個 main 函式開始看。

二 main_surfaceflinger

2.1 main_surfaceflinger:main

```cpp int main(int, char**) { signal(SIGPIPE, SIG_IGN);

// 設定 hwbinder 通訊的最大執行緒數:
hardware::configureRpcThreadpool(1 /* maxThreads */,
        false /* callerWillJoin */);

// //啟動Graphics Allocator服務,這個是用於 GraphicBuffer 分配的
startGraphicsAllocatorService();

//現在 SF 程序的 Binder 執行緒數為4
ProcessState::self()->setThreadPoolMaxThreadCount(4);

// 啟動執行緒池
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();

// 建立 SF 物件
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();

// 設定執行緒優先順序
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

// 設定排程策略,優先順序
set_sched_policy(0, SP_FOREGROUND);

if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);

// 初始化 SF
flinger->init();

// 釋出 SF 系統服務到 ServiceManager
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
               IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

// 啟動 DisplayService
startDisplayService();

struct sched_param param = {0};
param.sched_priority = 2;
if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) {
    ALOGE("Couldn't set SCHED_FIFO");
}

// 啟動 SF 執行緒
flinger->run();

return 0;

} ```

main函式中的邏輯較長,這裡可以簡單分為一下幾步

  1. 設定hwbinder中的最大執行緒數為4,這個hwbinder其實就是binder,如果看的是早期的Android程式碼,就不會有hwbinder這個概念,hwbinder是Android對binder的進一步劃分,比如binder,hwbinder,vndbinder,這裡我們看作binder即可
  2. 啟動Graphics Allocator服務
  3. 通過surfaceflinger::createSurfaceFlinger建立SurfaceFlinger
  4. 初始化SurfaceFlinger
  5. 釋出SurfaceFlinger服務到ServiceManager
  6. 啟動DisplayService
  7. 呼叫SurfaceFlinger的run方法

關於 SurfaceFlinger 有很多重要的地方,這裡我們先簡單的分析它的啟動過程即可

在 SurfaceFlinger 啟動的過程中,主要做的就是啟動 SurfaceFlinger 系統服務,並將它釋出到 ServiceManager 中,並啟動了它自己的 Binder 執行緒。當然,在這附帶的過程中,還啟動了一些其他 SurfaceFlinger 會依賴的服務。例如 Graphics Allocator 就是一個非常重要的服務,後面我們會單獨提到,不過這些服務暫時不是本篇的重點。

與 SurfaceFlinger 啟動和初始化相關的其實就兩行程式碼,只需要關注與它們就行 c // 1. 建立 SurfaceFlinger 物件 sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger(); // 2. 呼叫 SurfaceFlinger 的初始化函式 flinger->init();

2.2 SurfaceFlinger的定義

在看著兩行程式碼之前,我們先看一下 SurfaceFlinger 這個類的定義:

c [frameworks/native/services/surfaceflinger/SurfaceFlinger.h] class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, public ClientCache::ErasedRecipient, private IBinder::DeathRecipient, private HWC2::ComposerCallback {

  • 首先 SurfaceFlinger 繼承的類中有一個 BnSurfaceComposer,看到Bn開頭,就知道它是一個Binder通訊的實現類,對應的還有Bp應該就在應用端
  • 然後還看到它實現了一個 HWC2 的回撥函式,HWC2 是和硬體相關的,這個回撥函式處理的就是 Vsync 相關的邏輯

當然, SurfaceFlinger 這個類的實現了哪些類,我們並不需要全部記住,之後如果不記得了,回頭看一眼便是。

三 SurfaceFlinger.cpp

3.1 SurfaceFlingerFactory

SurfaceFlinger 的建立使用的是一個工廠類 SurfaceFlingerFactory,這個工廠類實際上就是呼叫的 SurfaceFlinger 建構函式,引數為工廠本身。 c sp<SurfaceFlinger> createSurfaceFlinger() { ... return new SurfaceFlinger(factory); }

這裡將 SurfaceFlingerFactory 物件傳進了 SurfaceFlinger 的建構函式,後面在 SurfaceFlinger 建立其他的物件時,都會使用這個 SurfaceFlingerFactory 來建立。

3.2 SurfaceFlinger 的建構函式

SurfaceFlinger 的建構函式比較簡單,只是做了一些成員變數的初始化工作,它通過 SurfaceFlingerFactory 物件建立了一大堆自己依賴的物件,這裡我們先略過對這些成員變數的介紹,對於這些成員變數,後續用到的時候再進行說明。

cpp [frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp] SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) : mFactory(factory), mPhaseOffsets(mFactory.createPhaseOffsets()), mInterceptor(mFactory.createSurfaceInterceptor(this)), mTimeStats(mFactory.createTimeStats()), mEventQueue(mFactory.createMessageQueue()), mCompositionEngine(mFactory.createCompositionEngine()) {}

3.3 SurfaceFlinger::init

接下來就是在 main 函式中呼叫的 init 函式,這個也是 SurfaceFlinger 主要初始化的工作

```c [frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp] void SurfaceFlinger::init() { ... // 1 首先啟動EventThread,EventThread有兩個,分別是App EventThread和SF EventThread // getFactory()拿到的是SurfaceFlingerDefaultFactory
mAppConnectionHandle = mScheduler->createConnection("app", mVsyncModulator.getOffsets().app, mPhaseOffsets->getOffsetThresholdForNextVsync(), resyncCallback, impl::EventThread::InterceptVSyncsCallback()); mSfConnectionHandle = mScheduler->createConnection("sf", mVsyncModulator.getOffsets().sf, mPhaseOffsets->getOffsetThresholdForNextVsync(), resyncCallback, this { mInterceptor->saveVSyncEvent(timestamp); }); ... // 2 初始化EGL // 2.1 EGL 配置 int32_t renderEngineFeature = 0; renderEngineFeature |= (useColorManagement ? renderengine::RenderEngine::USE_COLOR_MANAGEMENT : 0); renderEngineFeature |= (useContextPriority ? renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0); renderEngineFeature |= (enable_protected_contents(false) ? renderengine::RenderEngine::ENABLE_PROTECTED_CONTEXT : 0);

// 2.2 EGL建立
mCompositionEngine->setRenderEngine(
    renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
                                           renderEngineFeature, maxFrameBufferAcquiredBuffers));

// 2.3 建立HWComposer
mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
//3 處理熱插拔事件
processDisplayHotplugEventsLocked();
const auto display = getDefaultDisplayDeviceLocked();

// 啟用VR Flinger則執行,一般是false
if (useVrFlinger) {
    auto vrFlingerRequestDisplayCallback = [this](bool requestDisplay) {
        postMessageAsync(new LambdaMessage([=] {
            ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
            mVrFlingerRequestsDisplay = requestDisplay;
            signalTransaction();
        }));
    };
    mVrFlinger = dvr::VrFlinger::Create(getHwComposer().getComposer(),
                                        getHwComposer()
                                                .fromPhysicalDisplayId(*display->getId())
                                                .value_or(0),
                                        vrFlingerRequestDisplayCallback);
}

mDrawingState = mCurrentState;

// 4 初始化事件
initializeDisplays();

getRenderEngine().primeCache();

const bool presentFenceReliable =
        !getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);

//5 開機動畫
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);

...

} ```

這裡出現了很多其他知識相關的地方,例如 SurfaceFlinger 中的 EventQueue 機制,Vsync 機制,硬體 Vsync 和 軟體 Vsync 的回撥等等,這些機制都非常複雜,我們暫時先把它記錄下來,後續針對每種機制再單獨說明。這裡我們暫時假設自己瞭解這些,已學習主要流程為主。

init 函式中的邏輯很多,這裡簡單整理一下: 1. 建立一個Scheduler 2. 構造一個回撥函式ResyncCallback 3. 建立兩個連線處理器ConnectionHandle, 1. 首先是建立兩個EventThread, 分別是app EventThread和 sf EventThread 2. EventThread中有一個VSync的回撥 3. EventThread中有一個Thread, 這個Thread是一個死迴圈, 用於監聽VSync事件,並且消費分發,在沒有事件的時候等待 4. 然後通過這個EventThread進行連線,呼叫Scheduler中的createConnectionInternal 4. 將 mSfConnectionHandle 對應的 EventThreadConnection 注入 mEventQueue 5. 設定Vsync 監控和區域取樣 6. 初始化EGL(配置, 建立) 7. 處理熱插拔事件 8. 初始化事件 9. 開機動畫

3.4 SurfaceFlinger 初始化中的其他操作

其實除了 init 函式做的一些初始化之外,還有其他地方也做了一些初始化。例如通過 Binder 機制,當 SurfaceFlinger 第一次生成強指標的時候,會呼叫到 onFirstRef 函式。通過 ServiceManager 釋出系統服務,會通過 Binder 的死亡代理呼叫到 binderDied 函式,這裡我們也是將他們列舉出來。

```cpp void SurfaceFlinger::onFirstRef() { // 初始化訊息佇列 mEventQueue->init(this); }

void SurfaceFlinger::binderDied(const wp& / who /) {

// 重新初始化顯示裝置
initializeDisplays();

// 啟動 Boot 動畫
startBootAnim();

} ```

四 總結

SurfaceFlinger 的啟動流程大體來說還是比較簡單,但是裡面涉及到的其他機制非常多,如果我們全部深入,又容易陷入原始碼的海洋,最終忘記自己最初的目的,所以這一篇我們僅僅只是瞭解 SurfaceFlinger 的啟動過程,對於裡面涉及到的 SurfaceFlinger 的機制,我們先假設自己已經掌握,等到我們掌握了 SurfaceFlinger 的整體工作流程之後,再來針對裡面的機制進行單點突破,最後再將這些機制帶入到整體的流程中。