Android 12(S) 圖形顯示系統 - SurfaceFlinger的啟動和訊息佇列處理機制(四)

二的次方 發表於 2022-01-24
Android

1 前言

SurfaceFlinger作為Android圖形顯示系統處理邏輯的核心單元,我們有必要去了解其是如何啟動,初始化及進行訊息處理的。這篇文章我們就來簡單分析SurfaceFlinger這個Binder系統服務的一些基本處理邏輯。接下來分兩部分講解:

>> SurfaceFlinger啟動與初始化

>> SurfaceFlinger訊息佇列處理機制


Tips:

本篇涉及的程式碼位置:

/frameworks/native/services/surfaceflinger/


2 SurfaceFlinger的啟動與初始化

SurfaceFlinger是一個Binder系統服務,Android裝置開機啟動時就會帶起SurfaceFlinger服務程式並完成一些初始化動作。

從Android S開始,SurfaceFlinger被編譯為一個可執行二進位制檔案:surfaceflinger(放置於裝置/system/bin/下)。

 

可執行檔surfaceflinger的makefile

如下這段程式碼中,可以看到這個可執行檔與surfaceflinger.rc這個init rc檔相關聯,這樣開機啟動時,init程式就可以解析這個rc檔,帶起SurfaceFlinger服務程式


cc_binary {
    name: "surfaceflinger",
    defaults: ["libsurfaceflinger_binary"],
    init_rc: ["surfaceflinger.rc"],
    srcs: [
        ":surfaceflinger_binary_sources",
        // Note: SurfaceFlingerFactory is not in the filegroup so that it
        // can be easily replaced.
        "SurfaceFlingerFactory.cpp",
    ],
    shared_libs: [
        "libSurfaceFlingerProp",
    ],

     logtags: ["EventLog/EventLogTags.logtags"],
}

再來瞅瞅surfaceflinger.rc這個檔案的內容,主要時設定一些SurfaceFlinger服務程式啟動屬性

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    capabilities SYS_NICE
    onrestart restart zygote
    task_profiles HighPerformance
    socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

這裡我們就簡簡單單理解為:裝置開機啟動時,init程式解析surfaceflinger.rc,然後去執行/system/bin/surfaceflinger,從而啟動了SurfaceFlinger服務程式。

如果在裝置console下執行ps,你就可以看到這個程式PID了

console:/ $ ps -A | grep surfaceflinger
system          210      1  133412  38160 0                   0 S surfaceflinger

 

可執行檔surfaceflinger的main函式入口

在此我們僅摘錄主要的程式碼並註釋如下:

* /frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

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

    ...
    
    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();

    ...
    
    // 建立SurfaceFlinger物件,由強指標指向。
    // SurfaceFlinger繼承RefBase類,所以此處一旦new出物件賦給sp指標後,將立刻觸發SurfaceFlinger類的onFirstRef方法的呼叫。
    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();

    ...

    // SurfaceFlinger類正式初始化
    // initialize before clients can connect
    flinger->init();

    // SurfaceFlinger向ServiceManager註冊Binder服務,
    // 這樣在其他程式中可以通過getService+SERVICE_NAME來獲取SurfaceFlinger服務,繼而可以和SurfaceFlinger類進行Binder通訊。
    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    ...
    
    // SurfaceFlinger類進入主迴圈(此處注意SurfaceFlinger類未繼承Threads類,不遵循Threads類的介面執行順序)
    // run surface flinger in this thread
    flinger->run();

    return 0;
}

對於main函式,簡簡單單把握一下幾點就可以了:

  1. 建立SurfaceFlinger物件,觸發執行 SurfaceFlinger::onFirstRef()
  2. 呼叫SurfaceFlinger::init()進行初始化
  3. 註冊服務到ServiceManager(名字是"SurfaceFlinger")
  4. 呼叫SurfaceFlinger::run()

 Tips:

在裝置console上執行service list命令就可以看到註冊的服務:註冊的名稱是SurfaceFlinger, 這個服務實現的介面是android.ui.ISurfaceComposer

console:/ $  service list | grep Surface
1       SurfaceFlinger: [android.ui.ISurfaceComposer]

 


SurfaceFlinger類定義

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h
class SurfaceFlinger : public BnSurfaceComposer,
                       public PriorityDumper,
                       private IBinder::DeathRecipient,
                       private HWC2::ComposerCallback,
                       private ISchedulerCallback {
♦ SurfaceComposer繼承自BnSurfaceComposer,即為實現了ISurfaceComposer介面的Bn服務端;
♦ 實現了HWC2的ComposerCallback回撥,監聽Composer HAL的一些事件,比如Hotplug, Vsync ...
♦ 死亡通知DeathRecipient,當Binder服務端程式掛掉後,可以通知給繫結的Binder客戶端程式;
♦ Dump資訊PriorityDumper;

建立SurfaceFinger例項物件

呼叫surfaceflinger::createSurfaceFlinger()來建立SurfaceFlinger例項,並傳遞一個factory物件作為引數

* /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

sp<SurfaceFlinger> createSurfaceFlinger() {
    static DefaultFactory factory;

    return new SurfaceFlinger(factory);
}

來簡單看一下Factory的定義:

* /frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.h 

// The interface that SurfaceFlinger uses to create all of the implementations
// of each interface.
class Factory {
public:
    virtual std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) = 0;
    virtual std::unique_ptr<MessageQueue> createMessageQueue() = 0;
    virtual std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
            Fps currentRefreshRate) = 0;
    virtual std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&,
                                                       ISchedulerCallback&) = 0;
    virtual sp<SurfaceInterceptor> createSurfaceInterceptor() = 0;

    virtual sp<StartPropertySetThread> createStartPropertySetThread(
            bool timestampPropertyValue) = 0;
    virtual sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) = 0;
    virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width, uint32_t height,
                                                  PixelFormat format, uint32_t layerCount,
                                                  uint64_t usage, std::string requestorName) = 0;
    virtual void createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
                                   sp<IGraphicBufferConsumer>* outConsumer,
                                   bool consumerIsSurfaceFlinger) = 0;
    virtual sp<IGraphicBufferProducer> createMonitoredProducer(const sp<IGraphicBufferProducer>&,
                                                               const sp<SurfaceFlinger>&,
                                                               const wp<Layer>&) = 0;
    virtual sp<BufferLayerConsumer> createBufferLayerConsumer(const sp<IGraphicBufferConsumer>&,
                                                              renderengine::RenderEngine&,
                                                              uint32_t tex, Layer*) = 0;

    virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
            const sp<IGraphicBufferProducer>&) = 0;

    virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0;

    virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0;
    virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
    virtual sp<EffectLayer> createEffectLayer(const LayerCreationArgs& args) = 0;
    virtual sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) = 0;
    virtual std::unique_ptr<FrameTracer> createFrameTracer() = 0;
    virtual std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
            std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid) = 0;

protected:
    ~Factory() = default;
};

 Factory中定義了各種create方法,其作用如註釋中說明:The interface that SurfaceFlinger uses to create all of the implementations of each interface. 

SurfaceFlinger用Factory來建立所有實現了對應介面的物件。SurfaceFlinger中預設使用的是DefaultFactory,其中定義各種createXXX()方法的實現。具體可參見:/frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

Android 12(S) 圖形顯示系統 - SurfaceFlinger的啟動和訊息佇列處理機制(四)

SurfaceFlinger建構函式

建構函式的程式碼就只擷取部分貼在這裡了,其中主要是讀取一些屬性值來對一些成員變數進行初始化。其中一些屬性值是debug引數。另外就是利用mFactory的createXXX方法去例項化各種物件。

比如 : 建立訊息佇列 mEventQueue(mFactory.createMessageQueue())

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 

SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
      : mFactory(factory),
        mInterceptor(mFactory.createSurfaceInterceptor()),
        mTimeStats(std::make_shared<impl::TimeStats>()),
        mFrameTracer(mFactory.createFrameTracer()),
        mFrameTimeline(mFactory.createFrameTimeline(mTimeStats, getpid())),
        mEventQueue(mFactory.createMessageQueue()),
        mCompositionEngine(mFactory.createCompositionEngine()),
        mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)),
        mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()),
        mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)),
        mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)),
        mPowerAdvisor(*this) {
    ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str());

    mSetInputWindowsListener = new SetInputWindowsListener([&]() { setInputWindowsFinished(); });
}

SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipInitialization) {
    ALOGI("SurfaceFlinger is starting");

    hasSyncFramework = running_without_sync_framework(true);

    dispSyncPresentTimeOffset = present_time_offset_from_vsync_ns(0);

    useHwcForRgbToYuv = force_hwc_copy_for_virtual_displays(false);

    maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);

    maxGraphicsWidth = std::max(max_graphics_width(0), 0);
    maxGraphicsHeight = std::max(max_graphics_height(0), 0);

    hasWideColorDisplay = has_wide_color_display(false);
  
  	...
    
    
  }

surfaceflinger 會去讀取SurfaceFlingerProperties中的系統屬性,具體可以參看原始碼:/frameworks/native/services/surfaceflinger/sysprop/


Tips:

關於系統屬性的知識建議可以參見:

https://source.android.google.cn/devices/architecture/sysprops-apis?hl=zh-cn

https://blog.csdn.net/askfgx2010/article/details/112308665


 

SurfaceFlinger::onFirstRef

上面建立完SurfaceFlinger物件,立即就會執行到SurfaceFlinger::onFirstRef,這個方法中就做了一件事對訊息佇列做初始化,如下:

void SurfaceFlinger::onFirstRef() {
    mEventQueue->init(this);
}

訊息佇列執行的詳細分析我們下節在講,這裡先不展開。

SurfaceFlinger::init

再回到可執行檔surfaceflinger的main函式中,建立完SurfaceFlinger物件後,緊接著呼叫了SurfaceFlinger::init()方法:

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

void SurfaceFlinger::init() {
    ALOGI(  "SurfaceFlinger's main thread ready to run. "
            "Initializing graphics H/W...");
    Mutex::Autolock _l(mStateLock);

    // 對於CompositionEngine 屬性進行設定, 建立 RenderEngine 物件
    // Get a RenderEngine for the given display / config (can't fail)
    // TODO(b/77156734): We need to stop casting and use HAL types when possible.
    // Sending maxFrameBufferAcquiredBuffers as the cache size is tightly tuned to single-display.
    mCompositionEngine->setRenderEngine(renderengine::RenderEngine::create(
            renderengine::RenderEngineCreationArgs::Builder()
                    .setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
                    .setImageCacheSize(maxFrameBufferAcquiredBuffers)
                    .setUseColorManagerment(useColorManagement)
                    .setEnableProtectedContext(enable_protected_contents(false))
                    .setPrecacheToneMapperShaderOnly(false)
                    .setSupportsBackgroundBlur(mSupportsBlur)
                    .setContextPriority(
                            useContextPriority
                                    ? renderengine::RenderEngine::ContextPriority::REALTIME
                                    : renderengine::RenderEngine::ContextPriority::MEDIUM)
                    .build()));

    // Set SF main policy after initializing RenderEngine which has its own policy.
    if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
        ALOGW("Failed to set main task profile");
    }

    // 建立HWComposer物件並傳入一個name屬性,再通過mCompositionEngine->setHwComposer設定物件屬性。
    mCompositionEngine->setTimeStats(mTimeStats);
    mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
    mCompositionEngine->getHwComposer().setCallback(this);
    ClientCache::getInstance().setRenderEngine(&getRenderEngine());

    if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
        enableHalVirtualDisplays(true);
    }

  // processDisplayHotplugEventsLocked(); 處理 任何初始熱插拔和顯示更改的結果
  // 在此方法中主要有呼叫 initScheduler(displayId);
    // Process any initial hotplug and resulting display changes.
    processDisplayHotplugEventsLocked();
    const auto display = getDefaultDisplayDeviceLocked();
    LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
    const auto displayId = display->getPhysicalId();
    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
                        "Internal display is disconnected.");

    // initialize our drawing state
    mDrawingState = mCurrentState;

    // 初始化Display資訊
    // set initial conditions (e.g. unblank default device)
    initializeDisplays();

    mPowerAdvisor.init();

    char primeShaderCache[PROPERTY_VALUE_MAX];
    property_get("service.sf.prime_shader_cache", primeShaderCache, "1");
    if (atoi(primeShaderCache)) {
        if (setSchedFifo(false) != NO_ERROR) {
            ALOGW("Can't set SCHED_OTHER for primeCache");
        }

        mRenderEnginePrimeCacheFuture = getRenderEngine().primeCache();

        if (setSchedFifo(true) != NO_ERROR) {
            ALOGW("Can't set SCHED_OTHER for primeCache");
        }
    }

    getRenderEngine().onPrimaryDisplaySizeChanged(display->getSize());

    // Inform native graphics APIs whether the present timestamp is supported:

    const bool presentFenceReliable =
            !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
    mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
    // 開啟一個設定屬性的執行緒,在這個執行緒中使用property_set去設定一些屬性值
    if (mStartPropertySetThread->Start() != NO_ERROR) {
        ALOGE("Run StartPropertySetThread failed!");
    }

    ALOGV("Done initializing");
}

SurfaceFlinger::init方法,完成的工作大概為:

♦ CompositionEngine的配置,建立RenderEngine物件用於Client合成模式(GPU)合成;

♦ 初始化HWComposer,註冊回撥介面mCompositionEngine->getHwComposer().setCallback(this),HAL會回撥一些方法;

♦ 處理Display顯示螢幕的熱插拔和更改的事件processDisplayHotplugEventsLocked;

♦ 初始化顯示裝置initializeDisplays;

♦ 開啟一個設定屬性的執行緒,在這個執行緒中使用property_set去設定一些屬性值mStartPropertySetThread->Start();

 SurfaceFlinger::run

可執行檔surfaceflinger的main函式中,把SurfaceFinger這個服務註冊進ServiceManger中後,後續執行了SurfaceFlinger::run這個方法,程式碼如下:

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp 

void SurfaceFlinger::run() {
    while (true) {
        mEventQueue->waitMessage();
    }
}

這個方法也很簡單,一個while(true)的無限死迴圈,訊息佇列等待訊息的到來。surfaceflinger主執行緒中等待訊息處理。


講到這裡,大概SurfaceFlinger啟動的流程就完成了,當然,很多細節我們沒有深入去分析。

 

3 SurfaceFlinger的訊息佇列處理機制

上面一節中有提到,在SurfaceFlinger的建構函式中有建立訊息佇列
* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h

//成員變數mEventQueue的宣告
std::unique_ptr<MessageQueue> mEventQueue;

========

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

// SurfaceFlinger建構函式中建立訊息佇列
mEventQueue(mFactory.createMessageQueue()),
 
建立訊息佇列是透過Factory完成的,這裡使用的是DefaultFactory中的方法createMessageQueue,定義如下:
* /frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp

std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() {
    return std::make_unique<android::impl::MessageQueue>();
}
建立訊息佇列時,例項化一個android::impl::MessageQueue物件,MesageQueue的定義位於:
    /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h
    /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
 

Tips:
在繼續閱讀下面的內容前,需要對Android Native Looper/Handler/Message機制有一定了解,所以我建議您閱讀如下兩篇文章:

 
我們先來瞅一瞅2個非常重要的定義:
♦ MessageQueue:維護訊息佇列,並提供傳送訊息的方法等
♦ Handler:主要是實現handleMessage方法,來處理訊息
 

android::impl::MessageQueue的定義

檢視程式碼
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h

namespace impl {

class MessageQueue : public android::MessageQueue {

    sp<SurfaceFlinger> mFlinger;
    sp<Looper> mLooper;
    
    sp<Handler> mHandler;
    
  ...
}
如上程式碼,android::impl::MessageQueue繼承自android::MessageQueue,實現了這個虛基類中定義的方法:
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h

    void init(const sp<SurfaceFlinger>& flinger) override;
    void initVsync(scheduler::VSyncDispatch&, frametimeline::TokenManager&,
                   std::chrono::nanoseconds workDuration) override;
    void setDuration(std::chrono::nanoseconds workDuration) override;
    void setInjector(sp<EventThreadConnection>) override;
    void waitMessage() override;
    void postMessage(sp<MessageHandler>&&) override;

    // sends INVALIDATE message at next VSYNC
    void invalidate() override;

    // sends REFRESH message at next VSYNC
    void refresh() override;
 
android::impl::MessageQueue中含有成員:
♦ mFlinger == 指向SurfaceFlinger的引用,我們前面有提到在SurfaceFlinger::onFirstRef中呼叫mEventQueue->init(this)來設定的;
♦ mLooper == 其中維護了一個訊息佇列和待監測的fd佇列,當使用者呼叫pollOnce或pollAll時,就會去判斷是否有訊息或fd事件要處理;
♦ mHandler == 訊息處理類物件通過實現handleMessage來實現特定Message的處理邏輯;
 
 

重要:
android::impl::MessageQueue這個類,從名字看就知曉這是一個“訊息佇列”,但從其類定義中卻沒有看到有成員是“佇列”這個屬性。
其實,訊息佇列是由mLooper內部來維護的,在Looper這個類中有一個成員   Vector<MessageEnvelope> mMessageEnvelopes,這是一個Vector可變陣列。
這個陣列中儲存著有哪些待處理的Message及對應的Handler
 
如果不理解還是再去看看前面提到的參考文章。

 

MessageQueue::init方法

我們前面有提到在SurfaceFlinger::onFirstRef中呼叫mEventQueue->init(this),init方法中會去建立Looper和Handler物件
* /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp

void MessageQueue::init(const sp<SurfaceFlinger>& flinger) {
    mFlinger = flinger;
    mLooper = new Looper(true);
    mHandler = new Handler(*this);
}
 

MessageQueue::postMessage方法

postMessage用於傳送訊息到佇列中中,並指定處理該訊息的handler
void MessageQueue::postMessage(sp<MessageHandler>&& handler) {
    mLooper->sendMessage(handler, Message());
}
 

MessageQueue::waitMessage方法

waitMessage方法中不斷去呼叫mLooper->pollOnce(-1),檢查Looper中是否有訊息需要處理,如果有,則呼叫該訊息對應的MessageHandler去處理。

void MessageQueue::waitMessage() {
    do {
        IPCThreadState::self()->flushCommands();
        int32_t ret = mLooper->pollOnce(-1);
        ...
    } while (true);
}
 
前面也有講到了SurfaceFlinger::run這個方法在一個while(true)迴圈中不斷呼叫waitMessage
 

Handler的定義

Handler繼承自MessageHandler並實現了handleMessage方法,在這個方法中對訊息進行處理

Handler中還有一個成員mQueue指向MessageQueue物件引用

    class Handler : public MessageHandler {
        enum : uint32_t {
            eventMaskInvalidate = 0x1,
            eventMaskRefresh = 0x2,
            eventMaskTransaction = 0x4
        };
        MessageQueue& mQueue;
        std::atomic<uint32_t> mEventMask;
        std::atomic<int64_t> mVsyncId;
        std::atomic<nsecs_t> mExpectedVSyncTime;

    public:
        explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
        void handleMessage(const Message& message) override;
        virtual void dispatchRefresh();
        virtual void dispatchInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTimestamp);
        virtual bool invalidatePending();
    };

 




 

前面講到的都是一些定義啊,方法呀,他們之間的聯絡,如何運作似乎還是雲裡霧裡,沒有講到。

其實SurfaceFlinger訊息佇列主要處理2個重要事件:Refresh Invalidate

我們就分析下Refresh的處理流程

某些操作下需要進行refresh動作時,會呼叫到SurfaceFlinger::signalRefresh()

void SurfaceFlinger::signalRefresh() {
    mRefreshPending = true;
    mEventQueue->refresh();
}

SurfaceFlinger::signalRefresh()方法中會繼續呼叫mEventQueue->refresh()

void MessageQueue::refresh() {
    mHandler->dispatchRefresh();
}

繼而呼叫到mHandler->dispatchRefresh()

void MessageQueue::Handler::dispatchRefresh() {
    if ((mEventMask.fetch_or(eventMaskRefresh) & eventMaskRefresh) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::REFRESH));
    }
}

Handler::dispatchRefresh()方法中就要準備訊息並指定Handler來處理這個訊息,然後seedMessage到Looper的訊息佇列中去,等待後續處理。

對於refresh訊息,其what欄位為MessageQueue::REFRESH, 處理它就是在MessageQueue::Handler::handleMessage方法中,如下:

void MessageQueue::Handler::handleMessage(const Message& message) {
    switch (message.what) {
        case INVALIDATE:
            mEventMask.fetch_and(~eventMaskInvalidate);
            mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);
            break;
        case REFRESH:
            mEventMask.fetch_and(~eventMaskRefresh);
            mQueue.mFlinger->onMessageReceived(message.what, mVsyncId, mExpectedVSyncTime);
            break;
    }
}

看到這裡是不是稍微清晰一點了,當waitMessage --> Looper::pollOnce 檢測到這個refresh訊息要處理時,就會回撥到MessageQueue::Handler::handleMessage方法,進而執行到SurfaceFlinger::onMessageReceived

void SurfaceFlinger::onMessageReceived(int32_t what, int64_t vsyncId, nsecs_t expectedVSyncTime) {
    switch (what) {
        case MessageQueue::INVALIDATE: {
            onMessageInvalidate(vsyncId, expectedVSyncTime);
            break;
        }
        case MessageQueue::REFRESH: {
            onMessageRefresh();
            break;
        }
    }
}

之後就是具體refresh要完成的具體工作了,此處省略一萬字....

 

講到這裡不知您明白了沒,沒有圖形化的註解確實不太系統,不過只要你理解Android Native Looper/Handler/Message機制應該很容易看懂。

 


 簡簡單單的理解:

  1. SurfaceFlinger主執行緒中不斷去呼叫waitMessage --> Looper::pollOnce 檢測是否有訊息要處理;
  2. 如果有訊息要處理,則Looper就會取出這個訊息並回撥與之對應的MessageHandler::handleMessage方法,處理訊息事件;
  3. 外部可以通過MessageQueue::postMessage,Looper::sendMessage等方法向訊息佇列中傳送待處理的Message;

 


實用技巧

武林中有兩招絕學,一陽指和獅吼功,我用了整整三十年的時間,將兩招絕學併成了一整招。你過來啊!

Android 11之前的一陽指和獅吼功:

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h

// post an asynchronous message to the main thread
status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);

// post a synchronous message to the main thread
status_t postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);

Android 11之後兩招絕學併成了一整招

* /frameworks/native/services/surfaceflinger/SurfaceFlinger.h

// Schedule an asynchronous or synchronous task on the main thread.
template <typename F, typename T = std::invoke_result_t<F>>
[[nodiscard]] std::future<T> schedule(F&&);

這些方法的作用就是把指定的任務放到main thread中去執行。

看一下schedule的定義:

template <typename F, typename T>
inline std::future<T> SurfaceFlinger::schedule(F&& f) {
    auto [task, future] = makeTask(std::move(f));
    mEventQueue->postMessage(std::move(task));
    return std::move(future);
}

再看makeTask和Task的定義:

*  /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h

template <typename F>
class Task : public MessageHandler {
    template <typename G>
    friend auto makeTask(G&&);

    explicit Task(F&& f) : mTask(std::move(f)) {}

    void handleMessage(const Message&) override { mTask(); }

    using T = std::invoke_result_t<F>;
    std::packaged_task<T()> mTask;
};

template <typename F>
inline auto makeTask(F&& f) {
    sp<Task<F>> task = new Task<F>(std::move(f));
    return std::make_pair(task, task->mTask.get_future());
}

MessageQueue::postMessage

*  /frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp

void MessageQueue::postMessage(sp<MessageHandler>&& handler) {
    mLooper->sendMessage(handler, Message());
}

看到這裡是不是基本就清楚了,熟悉的字眼:postMessage,MessageHandler,handleMessage本質還是main thread上訊息佇列處理。

其實換湯不換藥,只是利用C++的新特型做了抽象與封裝,本質還是向主執行緒傳送一個Message並指定其MessageHandler,主執行緒收到訊息時呼叫MessageHandler::handleMessage,進而呼叫到我們指定的函式實體程式碼。

 

我們已一個例子來說明:

    static_cast<void>(schedule([=]()  {
        ALOGD("我在主執行緒被列印");
    }));

我們傳遞給schedule的函式實體將在主執行緒執行。

這在我們修改某些邏輯且要保證主執行緒執行時可能是個不錯的技巧。


 

4 小結

寫到這裡 SurfaceFlinger啟動與初始化流程和SurfaceFlinger訊息佇列處理機制就完了,很多內容自己也沒有完全吃透,本篇的目的還是著重講解流程而忽視具體細節,搞懂流程再去按工作需要分析細節,這樣感覺會更實用主義。

 


必讀:

Android 12(S) 圖形顯示系統 - 開篇


 

 

 


最後分享一份好心情

Android 12(S) 圖形顯示系統 - SurfaceFlinger的啟動和訊息佇列處理機制(四)