[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 的整體工作流程之後,再來針對裏面的機制進行單點突破,最後再將這些機制帶入到整體的流程中。