Android渲染(三)_SurfaceFlinger的启动(基于Android10)

1,014 阅读19分钟

一 、概述

SurfaceFlinger 在Android渲染中扮演着非常重要的作用。 它既要为应用层提供可绘制的GraphicBuffer缓冲区,也要对生成的 Layer进行排序、合成,最终通过本地化窗口调用 FrameBuffer 内核缓冲区的 post()接口显示到屏幕上。

那么它是如何启动的呢?

二、解析surfaceflinger.rc

frameworks/native/services/surfaceflinger/surfaceflinger.rc

我们知道,init 进程作为第一个用户空间的进程,它会在main.cpp的 main()方法完成一些列的初始化。其中会调用 SecondStageMain()方法,进而调用 LoadBootScripts(am, sm)解析init.rc配置文件,最终解析 surfaceflinger.rc

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    capabilities SYS_NICE
    onrestart restart --only-if-running 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

拉起 SurfaceFlinger进程后,会执行 main_surfaceflinger.cpp 的 main()方法。

2.1 入口main()

frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

int main(int, char**) {
    // 
    signal(SIGPIPE, SIG_IGN);
    // 配置 hwBinder binder线程池参数 
    hardware::configureRpcThreadpool(1 /* maxThreads */,
            false /* callerWillJoin */);

    // 初始化 HAL 硬件抽象层的图元生成器服务
    // hal 包含了fb*和 Gralloc
    startGraphicsAllocatorService();

    // When SF is launched in its own process, limit the number of
    // binder threads to 4.
    // 设置SF进程的 binder线程数为4 
    ProcessState::self()->setThreadPoolMaxThreadCount(4);

    // Set uclamp.min setting on all threads, maybe an overkill but we want
    // to cover important threads like RenderEngine.
    if (SurfaceFlinger::setSchedAttr(true) != NO_ERROR) {
        ALOGW("Couldn't set uclamp.min: %s\n", strerror(errno));
    }

    // The binder threadpool we start will inherit sched policy and priority
    // of (this) creating thread. We want the binder thread pool to have
    // SCHED_FIFO policy and priority 1 (lowest RT priority)
    // Once the pool is created we reset this thread's priority back to
    // original.
    int newPriority = 0;
    int origPolicy = sched_getscheduler(0);
    struct sched_param origSchedParam;
    // ...
    // start the thread pool 获取ProcessState对象
    sp<ProcessState> ps(ProcessState::self());
    // 开启binder线程池 
    ps->startThreadPool();

    // Reset current thread's policy and priority
    if (errorInPriorityModification == 0) {
        errorInPriorityModification = sched_setscheduler(0, origPolicy, &origSchedParam);
    } else {
        ALOGE("Failed to set SurfaceFlinger binder threadpool priority to SCHED_FIFO");
    }

    // instantiate surfaceflinger
    //实例化 SurfaceFlinger 对象
    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();

    // Set the minimum policy of surfaceflinger node to be SCHED_FIFO.
    // So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run
    // at least with SCHED_FIFO policy and priority 1.
    if (errorInPriorityModification == 0) {
        flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
    }
    // 提高SF进程的优先级
    setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);

    set_sched_policy(0, SP_FOREGROUND);

    // Put most SurfaceFlinger threads in the system-background cpuset
    // Keeps us from unnecessarily using big cores
    // Do this after the binder thread pool init
    if (cpusets_enabled()) set_cpuset_policy(0, SP_SYSTEM);

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

    // publish surface flinger
    sp<IServiceManager> sm(defaultServiceManager());
    // 注册服务到 SM中 名字:SurfaceFlinger的服务。    static char const* getServiceName() ANDROID_API { return 
    "SurfaceFlinger"; }
    sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);

    // 开启 display
    startDisplayService(); // dependency on SF getting registered above

    if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
        ALOGW("Couldn't set to SCHED_FIFO: %s", strerror(errno));
    }

    // run surface flinger in this thread
    // 开启run 
    flinger->run();

    return 0;
}
  1. 设置SurfaceFlinger进程的 binder线程池的线程数为4,同时开启binder线程
  2. 实例化 SurfaceFlinger 对象
  3. 在客户端连接前,调用 SF 的init()方法完成初始化
  4. 往SM中注册binder服务,服务名字为:SurfaceFlinger。
  5. 开启displayService ,这一步依赖第4步的注册。
  6. 在当前主线程执行SF的run()方法。

2.2 SF实例化 createSurfaceFlinger()

frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

sp<SurfaceFlinger> createSurfaceFlinger() {
    // 创建静态的 factory对象 
    static DefaultFactory factory;

    return new SurfaceFlinger(factory);
}

创建静态的 factory对象,new 一个 SF对象,传入factory。

2.2.1 SurfaceFlinger 继承关系

class SurfaceFlinger : public BnSurfaceComposer,
                       public PriorityDumper,
                       private IBinder::DeathRecipient,
                       private HWC2::ComposerCallback
{ 
    //...

重点:

  • 继承了 BnSurfaceComposer ,Bn开头立马想到是Binder服务端,那么Bp肯定在应用端。
  • 实现了HWC2::ComposerCallback接口,这个跟硬件有关系,onVsync信号就是从这里出来的。

2.2.2 SF构造方法

前面有传入factory对象。


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);
    
    maxVirtualDisplaySize = max_virtual_display_dimension(0);

    // Vr flinger is only enabled on Daydream ready devices.
    useVrFlinger = use_vr_flinger(false);
    
    maxFrameBufferAcquiredBuffers = max_frame_buffer_acquired_buffers(2);

    hasWideColorDisplay = has_wide_color_display(false);

    useColorManagement = use_color_management(false);

    mDefaultCompositionDataspace =
            static_cast<ui::Dataspace>(default_composition_dataspace(Dataspace::V0_SRGB));
    mWideColorGamutCompositionDataspace = static_cast<ui::Dataspace>(wcg_composition_dataspace(
            hasWideColorDisplay ? Dataspace::DISPLAY_P3 : Dataspace::V0_SRGB));
    defaultCompositionDataspace = mDefaultCompositionDataspace;
    wideColorGamutCompositionDataspace = mWideColorGamutCompositionDataspace;
    defaultCompositionPixelFormat = static_cast<ui::PixelFormat>(
            default_composition_pixel_format(ui::PixelFormat::RGBA_8888));
    wideColorGamutCompositionPixelFormat =
            static_cast<ui::PixelFormat>(wcg_composition_pixel_format(ui::PixelFormat::RGBA_8888));

    useContextPriority = use_context_priority(true);

    auto tmpPrimaryDisplayOrientation = primary_display_orientation(
            SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_0);
    switch (tmpPrimaryDisplayOrientation) {
        case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_90:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation90;
            break;
        case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_180:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation180;
            break;
        case SurfaceFlingerProperties::primary_display_orientation_values::ORIENTATION_270:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientation270;
            break;
        default:
            SurfaceFlinger::primaryDisplayOrientation = DisplayState::eOrientationDefault;
            break;
    }
    ALOGV("Primary Display Orientation is set to %2d.", SurfaceFlinger::primaryDisplayOrientation);

    mInternalDisplayPrimaries = sysprop::getDisplayNativePrimaries();

    // debugging stuff...
    char value[PROPERTY_VALUE_MAX];

    property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
    mGpuToCpuSupported = !atoi(value);

    property_get("debug.sf.showupdates", value, "0");
    mDebugRegion = atoi(value);

    ALOGI_IF(mDebugRegion, "showupdates enabled");

    // DDMS debugging deprecated (b/120782499)
    property_get("debug.sf.ddms", value, "0");
    int debugDdms = atoi(value);
    ALOGI_IF(debugDdms, "DDMS debugging not supported");

    property_get("debug.sf.disable_backpressure", value, "0");
    mPropagateBackpressure = !atoi(value);
    ALOGI_IF(!mPropagateBackpressure, "Disabling backpressure propagation");

    property_get("debug.sf.enable_gl_backpressure", value, "0");
    mPropagateBackpressureClientComposition = atoi(value);
    ALOGI_IF(mPropagateBackpressureClientComposition,
             "Enabling backpressure propagation for Client Composition");

    property_get("debug.sf.enable_hwc_vds", value, "0");
    mUseHwcVirtualDisplays = atoi(value);
    ALOGI_IF(mUseHwcVirtualDisplays, "Enabling HWC virtual displays");

    property_get("ro.sf.disable_triple_buffer", value, "0");
    mLayerTripleBufferingDisabled = atoi(value);
    ALOGI_IF(mLayerTripleBufferingDisabled, "Disabling Triple Buffering");

    const size_t defaultListSize = MAX_LAYERS;
    auto listSize = property_get_int32("debug.sf.max_igbp_list_size", int32_t(defaultListSize));
    mMaxGraphicBufferProducerListSize = (listSize > 0) ? size_t(listSize) : defaultListSize;

    mUseSmart90ForVideo = use_smart_90_for_video(false);
    property_get("debug.sf.use_smart_90_for_video", value, "0");

    int int_value = atoi(value);
    if (int_value) {
        mUseSmart90ForVideo = true;
    }

    property_get("debug.sf.luma_sampling", value, "1");
    mLumaSampling = atoi(value);

    const auto [early, gl, late] = mPhaseOffsets->getCurrentOffsets();
    mVsyncModulator.setPhaseOffsets(early, gl, late);

    // We should be reading 'persist.sys.sf.color_saturation' here
    // but since /data may be encrypted, we need to wait until after vold
    // comes online to attempt to read the property. The property is
    // instead read after the boot animation

    if (useTrebleTestingOverride()) {
        // Without the override SurfaceFlinger cannot connect to HIDL
        // services that are not listed in the manifests.  Considered
        // deriving the setting from the set service name, but it
        // would be brittle if the name that's not 'default' is used
        // for production purposes later on.
        setenv("TREBLE_TESTING_OVERRIDE", "true", true);
    }
}

一些列属性的配置。

继续调用另一个构造方法:

2.2.3 SF构造方法2

SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag)
      : mFactory(factory), // 赋值 mFactory成员变量
        mPhaseOffsets(mFactory.createPhaseOffsets()), //相位偏移
        mInterceptor(mFactory.createSurfaceInterceptor(this)),
        mTimeStats(mFactory.createTimeStats()),
        mEventQueue(mFactory.createMessageQueue()), //  创建 MessageQueue对象,mEventQueue 赋值
        mCompositionEngine(mFactory.createCompositionEngine()) {} // mCompositionEngine引擎赋值 
  • 赋值mFactory成员。
  • 调用mFactory的方法,创建 mPhaseOffsets相位偏移、mEventQueue、mConpositionEngine等成员变量。

2.2.4 mFactory.createMessageQueue()

frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

 std::unique_ptr<MessageQueue> createMessageQueue() override {
            return std::make_unique<android::impl::MessageQueue>();
        }

2.2.5 mFactory.createCompositionEngine()

std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {

    return compositionengine::impl::createCompositionEngine();

}

继续调用 CompositionEngine.cpp中的方法。

2.2.5.1 createCompositionEngine()

frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp


std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
    return std::make_unique<CompositionEngine>();
}

返回了一个 CompositionEngine 对象。

2.3 SF.init()方法

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

    ALOGI("Phase offset NS: %" PRId64 "", mPhaseOffsets->getCurrentAppOffset());

    // SF主线程开始初始化 
    Mutex::Autolock _l(mStateLock);
    // start the EventThread
    // 创建一个 Scheduler 调度对象
    mScheduler =
            getFactory().createScheduler([this](bool enabled) { 
          
               setPrimaryVsyncEnabled(enabled); 
            },mRefreshRateConfigs);
            // 通过 mScheduler 构造一个callback,用来回调 Resync()方法
            
    auto resyncCallback =
      mScheduler>makeResyncCallback(std::bind(&SurfaceFlinger::getVsyncPeriod, this));

    // 创建跟app 线程,且返回app的 connectionHandler
    mAppConnectionHandle =
            mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
                                         resyncCallback,
                                         impl::EventThread::InterceptVSyncsCallback());
    // 创建 sf 线程 ,且返回 sf 的 connectionHandler                                 
    mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),resyncCallback, [this](nsecs_t timestamp) {
     mInterceptor->saveVSyncEvent(timestamp);
                                                       });
    // 将 mSfConnectionHandle对应的 EventThreadConnection注入到 mEventQueue
    mEventQueue->setEventConnection(mScheduler->getEventConnection(mSfConnectionHandle));
    
    mVsyncModulator.setSchedulerAndHandles(mScheduler.get(), mAppConnectionHandle.get(),mSfConnectionHandle.get());

    mRegionSamplingThread =
            new RegionSamplingThread(*this, *mScheduler,
                                     RegionSamplingThread::EnvironmentTimingTunables());

    // Get a RenderEngine for the given display / config (can't fail)
    int32_t renderEngineFeature = 0;
    // 初始化 egl
    // 设置渲染引擎标志位,是否使用着色器?? 
    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);

    // 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.
    //maxFrameBufferAcquiredBuffers :最大FrameBuffer数。
    // 创建EGL  RenderEngine::create?? 是的 对应 GLESRenderEngine 渲染引擎
    // 参数:格式、feature、size
    mCompositionEngine->setRenderEngine(
            renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
                                               renderEngineFeature, maxFrameBufferAcquiredBuffers));


    LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
            "Starting with vr flinger active is not currently supported.");
            // createHWComposer 创建硬件 composer 对象。
    // 往 mCompositionEngine 里面设置 HwComposer 
    mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
    //Hw合成器 注册callback
    mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
    // 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.");
    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
                        "Internal display is disconnected.");
    
    if (useVrFlinger) {
        // 如果使用vr flinger。 一般是false??
       //...
    }

    // initialize our drawing state
    //初始化绘制状态 
    mDrawingState = mCurrentState;

    // set initial conditions (e.g. unblank default device)
    //初始化屏幕
    initializeDisplays();

    getRenderEngine().primeCache();

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

    const bool presentFenceReliable =
            !getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);
    // 开启动画       
    mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);

    mScheduler->setChangeRefreshRateCallback(
            [this](RefreshRateType type, Scheduler::ConfigEvent event) {
                Mutex::Autolock lock(mStateLock);
                setRefreshRateTo(type, event);
            });
    // callback获取vsync周期回调         
    mScheduler->setGetVsyncPeriodCallback([this] {
        Mutex::Autolock lock(mStateLock);
        return getVsyncPeriod();
    });

    mRefreshRateConfigs.populate(getHwComposer().getConfigs(*display->getId()));
    mRefreshRateStats.setConfigMode(getHwComposer().getActiveConfigIndex(*display->getId()));
    ALOGV("Done initializing");
}

  1. 创建 Scheduler 调度对象(SF很多的工作就转移到了这里!), Scheduler构造函数中会创建 DispVysnc、EventControlThread、scheduler::IdleTimer触摸事件计时器等对象。还定义了内部类 ConnectionHandlerConnection(持有ConnectionHandler、EvntThreadConnection、EvntThread对象的引用)。
  2. 返回一个 resyncCallback,后续用来调用是否需要重新请求vsync信号
  3. 创建名字为app、sfEventThread线程,创建EvntThreadConnection。返回Scheduler的内部类Connection对象
  4. 设置 MessageQueue的 setEventConnection(),把sf线程的connection注册进去
  5. 初始化EGL。设置合成器的渲染引擎 GLESRenderEngine
  6. 处理热插拔事件和屏幕变化事件

2.3.1 getFactory().createScheduler

frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

std::unique_ptr<Scheduler> createScheduler(
        std::function<void(bool)> callback,
        const scheduler::RefreshRateConfigs& refreshRateConfig) override {
        // 通过make_unique创建对象 Scheduler,传入callback和 refreshRateConfig 参数
    return std::make_unique<Scheduler>(callback, refreshRateConfig);
}

通过make_unique创建对象 Scheduler,传入callback和 refreshRateConfig 参数。

2.3.2 setPrimaryVsyncEnabled()

void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) {
    ATRACE_CALL();
    Mutex::Autolock lock(mStateLock);
    if (const auto displayId = getInternalDisplayIdLocked()) {
        getHwComposer().setVsyncEnabled(*displayId,
                                        enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
    }
}

调用hwComposer的 setVsyncEnabled()方法。

2.3.3 mScheduler->createConnection()

  • 传入名字:app -偏移量纳秒

frameworks/native/services/surfaceflinger/Surfaceflinger.cpp

sp<Scheduler::ConnectionHandle> Scheduler::createConnection(
        const char* connectionName, int64_t phaseOffsetNs, ResyncCallback resyncCallback,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
        // 
    const int64_t id = sNextId++;
    ALOGV("Creating a connection handle with ID: %" PRId64 "\n", id);
    // 创建 EventThread对象 
    std::unique_ptr<EventThread> eventThread =
            makeEventThread(connectionName, mPrimaryDispSync.get(), phaseOffsetNs,
                            std::move(interceptCallback));
    // 创建 EventThread内部 Connection对象
    auto eventThreadConnection =
            createConnectionInternal(eventThread.get(), std::move(resyncCallback));
     //创建 Scheduler中的 connection对象       
    mConnections.emplace(id,std::make_unique<Connection>(new ConnectionHandle(id),
                                                      std::move(eventThread)));
    return mConnections[id]->handle;
}
  • 创建EventThread对象,
  • 创建EventThread内部的 InnerConnection 对象
  • 在根据 InnerConnection对象、创建ConnectionHandle对象,得到新的 Connection 对象
  • 创建 Connection 对象,封装了 ConnectionHandle(每个handler都有自己的id)+ eventThreadConnection+ eventThread。

2.3.4 MessageQueue.setEventConnection()

void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
    if (mEventTube.getFd() >= 0) {
        mLooper->removeFd(mEventTube.getFd());
    }

    mEvents = connection;
    mEvents->stealReceiveChannel(&mEventTube);
    mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
                   this);
}

looper监听 mEventTube 的fd句柄,一旦mEventTube有事件传来,立马会回调 MessageQueue的cb_eventReceiver()方法。

2.4 startDisplayService()

frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp

static status_t startDisplayService() {
    using android::frameworks::displayservice::V1_0::implementation::DisplayService;
    using android::frameworks::displayservice::V1_0::IDisplayService;

    sp<IDisplayService> displayservice = new DisplayService();
    status_t err = displayservice->registerAsService();

    if (err != OK) {
        ALOGE("Could not register IDisplayService service.");
    }

    return err;
}

创建 DisplayService 对象,注册一个display服务到SM,名字默认为default。

2.5 SF.run()方法

2.5.1 onFirstRef()

在分析 SF的run()函数之前,由于 SurfaceFlinger是通过sp<SurfaceFlinger>来引用的,因此当首次被强指针引用时会执行 onFirstRef()方法。

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

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

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

初始化了looper、handler。至此,SF的 消息队列模型就建立起来了!继续分析run()函数。

2.5.2 run()

void SurfaceFlinger::run() {
    do { 
        waitForEvent();
    } while (true);
}

开启循环,SF一直等待应用投递过来的事件,时刻准备处理。

2.5.3 waitForEvent()

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

void SurfaceFlinger::waitForEvent() {
    mEventQueue->waitMessage();
}

事件队列等待获取消息。

2.5.4 waitMessage()

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

void MessageQueue::waitMessage() {
    do {
        //IPCThreadState一看就是进程间通信的数据
        IPCThreadState::self()->flushCommands();
        int32_t ret = mLooper->pollOnce(-1);
        switch (ret) {
            case Looper::POLL_WAKE:
            case Looper::POLL_CALLBACK:
                continue;
            case Looper::POLL_ERROR:
                ALOGE("Looper::POLL_ERROR");
                continue;
            case Looper::POLL_TIMEOUT:
                // timeout (should not happen)
                continue;
            default:
                // should not happen
                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                continue;
        }
    } while (true);
}

2.5.3 Looper::pollOnce()

一旦有消息就弹出返回,如果没有则阻塞等待。

int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    int result = 0;
    for (;;) {
        while (mResponseIndex < mResponses.size()) {
            const Response& response = mResponses.itemAt(mResponseIndex++);
            int ident = response.request.ident;
            if (ident >= 0) {
                int fd = response.request.fd;
                int events = response.events;
                void* data = response.request.data;
#if DEBUG_POLL_AND_WAKE
                ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
                        "fd=%d, events=0x%x, data=%p",
                        this, ident, fd, events, data);
#endif
                if (outFd != nullptr) *outFd = fd;
                if (outEvents != nullptr) *outEvents = events;
                if (outData != nullptr) *outData = data;
                return ident;
            }
        }

        if (result != 0) {
#if DEBUG_POLL_AND_WAKE
            ALOGD("%p ~ pollOnce - returning result %d", this, result);
#endif
            if (outFd != nullptr) *outFd = 0;
            if (outEvents != nullptr) *outEvents = 0;
            if (outData != nullptr) *outData = nullptr;
            return result;
        }
        // 调用 pollInner 
        result = pollInner(timeoutMillis);
    }
}

调用继续调用 pollInner()。

2.5.5 Looper::pollInner()

int Looper::pollInner(int timeoutMillis) {
   //...
   int eventCount = epoll_wait(mEpollFd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
   //...
}

这里用到了linux的epoll机制。 没有消息的时候,会阻塞释放CPU资源,一旦有消息进来则会重新获取CPU的执行权,开始分发消息。

Android java层的 looper机制本质上也是这样实现的。

三、HWComposer的vsync产生和接收

HWComposer 负责接收硬件产生的vsync信号。

在SF的init()方法中创建了 HWComposer 对象,同时调用 HWComposer的registerCallback()方法。

3.1 createHWComposer()


std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override {
         // 
        return std::make_unique<android::impl::HWComposer>(
                std::make_unique<Hwc2::impl::Composer>(serviceName));
    }

factory 创建一个Composer对象作为参数,创建HWComposer()对象。 继续看看 HWComposer的构造方法:

3.1.1 HWComposer 的构造方法

HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
      : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}

又创建了 Device 对象赋值给 mHwcDevice

我们在看看HWComposer的 注册回调方法:

3.2 HWComposer.registerCallback()

frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp

void HWComposer::registerCallback(HWC2::ComposerCallback* callback,
                                  int32_t sequenceId) {
    mHwcDevice->registerCallback(callback, sequenceId);
}

callback 就是SurfaceFlinger对象,因为SurfaceFlinger继承HWC2::ComposerCallback接口。我们看看这个接口是怎么定义的:

class ComposerCallback {
 public:
    virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
                                   Connection connection) = 0;
    virtual void onRefreshReceived(int32_t sequenceId,
                                   hwc2_display_t display) = 0;
                //硬件产生的vsync信号就会回调这里                      
    virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
                                 int64_t timestamp) = 0;
    virtual ~ComposerCallback() = default;
};

包含了三个回调方法。

继续,看看 mHwcDevice 的 registerCallback():

3.2.1 Device.registerCallback()

frameworks/native/services/surfaceflinger/DisplayHardware/HWC2.cpp

void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {
    if (mRegisteredCallback) {
        ALOGW("Callback already registered. Ignored extra registration "
                "attempt.");
        return;
    }
    mRegisteredCallback = true;
    // 新建了ComposerCallbackBridge对象,用来接收回调
    sp<ComposerCallbackBridge> callbackBridge(
            new ComposerCallbackBridge(callback, sequenceId));
           // 继续调用  Composer 的方法
    mComposer->registerCallback(callbackBridge);
}

3.2.2 ComposerCallbackBridge 对象

class ComposerCallbackBridge : public Hwc2::IComposerCallback {
public:
    ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
            : mCallback(callback), mSequenceId(sequenceId) {}

    Return<void> onHotplug(Hwc2::Display display,
                           IComposerCallback::Connection conn) override
    {
        HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
        mCallback->onHotplugReceived(mSequenceId, display, connection);
        return Void();
    }

    Return<void> onRefresh(Hwc2::Display display) override
    {
        mCallback->onRefreshReceived(mSequenceId, display);
        return Void();
    }

    Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
    {
        mCallback->onVsyncReceived(mSequenceId, display, timestamp);
        return Void();
    }

private:
    ComposerCallback* mCallback;
    int32_t mSequenceId;
};

mCallback 就是 HWComposer传入的ComposerCallback(也就是SF),因此当接收到vsync信号时,就会回调SF的 onVsyncReceived()方法。

但 mComposer 具体做了啥? mComposer是 Composer对象。它定义在ComposerHal.h中。我们直接看它的.cpp实现文件:

3.2.3 Composer.registerCallback()

frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp

void Composer::registerCallback(const sp<IComposerCallback>& callback)
{
    auto ret = mClient->registerCallback(callback);
    if (!ret.isOk()) {
        ALOGE("failed to register IComposerCallback");
    }
}

xxxhal结尾可以看出,这肯定是hal层的Composer对象。通过client向硬件注册事件回调,其中就包含了vsync信号。

HAL层是对硬件接口的抽象,具体的实现要看厂商如何支持。HAL层是用户空间到内核空间的接口层,隔离具体的变化,因此,屏蔽了硬件厂商的具体实现,保证了Android系统的稳定兼容性。

3.2.4 小结

HWCompose内部通过层层注册,最终到硬件。至此硬件源产生的vsync信号,最终会调用 SF的 onVsyncReceived()方法。

3.3 SF.onVsyncReceived()

我们看看 SF的 onVsyncReceived():

void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
                                     int64_t timestamp) {
    ATRACE_NAME("SF onVsync");

    Mutex::Autolock lock(mStateLock);
    // Ignore any vsyncs from a previous hardware composer.
    // 忽略上一次相同的vsync信号
    if (sequenceId != getBE().mComposerSequenceId) {
        return;
    }
    // 忽略无效的 vsync
    if (!getHwComposer().onVsync(hwcDisplayId, timestamp)) {
        return;
    }

    if (hwcDisplayId != getHwComposer().getInternalHwcDisplayId()) {
        // For now, we don't do anything with external display vsyncs.
        return;
    }

    bool periodChanged = false;
    // mScheduler帮忙做了很多事情
    mScheduler->addResyncSample(timestamp, &periodChanged);
    if (periodChanged) {
        mVsyncModulator.onRefreshRateChangeDetected();
    }
}

继续看 Scheduler的 addResyncSample():

3.3.1 Scheduler.addResyncSample()

Scheduler.cpp

void Scheduler::addResyncSample(const nsecs_t timestamp, bool* periodChanged) {
    bool needsHwVsync = false; // 是否需要硬件vsync信号?
    *periodChanged = false;
    { // Scope for the lock
        std::lock_guard<std::mutex> lock(mHWVsyncLock);
        // 主屏幕的vsync功能是否开启
        if (mPrimaryHWVsyncEnabled) {
            //mPrimaryDispSync 是在构造方法中创建的 DispSync 对象,返回值表示是否需要再次请求硬件vsync信号
            needsHwVsync = mPrimaryDispSync->addResyncSample(timestamp, periodChanged);
        }
    }

    if (needsHwVsync) {
        //开启硬件vsync
        enableHardwareVsync();
    } else {
        //关闭硬件vsync
        disableHardwareVsync(false);
    }
}

可以看到 通过 needsHwVsync 标记来控制硬件是否继续发送vsync信号。也就是说,可以有上层SF的scheduler来控制是否继续发送vsync信号。

3.3.2 enableHardwareVsync()/ disableHardwareVsync()

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


void Scheduler::enableHardwareVsync() {
    std::lock_guard<std::mutex> lock(mHWVsyncLock);
    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
        // DispSync线程对象
        mPrimaryDispSync->beginResync();
        // evnetControlThread线程
        mEventControlThread->setVsyncEnabled(true);
        mPrimaryHWVsyncEnabled = true;
    }
}

void Scheduler::disableHardwareVsync(bool makeUnavailable) {
    std::lock_guard<std::mutex> lock(mHWVsyncLock);
    if (mPrimaryHWVsyncEnabled) {
        mEventControlThread->setVsyncEnabled(false);
        mPrimaryDispSync->endResync();
        mPrimaryHWVsyncEnabled = false;
    }
    if (makeUnavailable) {
        mHWVsyncAvailable = false;
    }
}

可以看到,是通过 EventControlThread 单独线程来控制硬件是否启动vsync信号的。

3.4 EventControlThread

EventControlThread 用来控制HWC是否应该发送vsync信号,它是在 Scheduler的构造函数中创建的。

3.4.1 Scheduler 构造函数

Scheduler::Scheduler(impl::EventControlThread::SetVSyncEnabledFunction function,
                     const scheduler::RefreshRateConfigs& refreshRateConfig)
      : mHasSyncFramework(running_without_sync_framework(true)),
        mDispSyncPresentTimeOffset(present_time_offset_from_vsync_ns(0)),
        mPrimaryHWVsyncEnabled(false),
        mHWVsyncAvailable(false),
        mRefreshRateConfigs(refreshRateConfig) {
    //1 
    auto primaryDispSync = std::make_unique<impl::DispSync>("SchedulerDispSync");
    primaryDispSync->init(mHasSyncFramework, mDispSyncPresentTimeOffset);
    mPrimaryDispSync = std::move(primaryDispSync);
    // 2
    mEventControlThread = std::make_unique<impl::EventControlThread>(function);

   // ...
   
}
  1. 创建了 DispSync 对象
  2. 创建 EventControlThread 对象,赋值给 mEventControlThread。

3.4.2 EventControlThread

EventControlThread::EventControlThread(EventControlThread::SetVSyncEnabledFunction function)
      : mSetVSyncEnabled(function) { //function赋值
      //创建了线程 EventControlThread。
    pthread_setname_np(mThread.native_handle(), "EventControlThread");

    pid_t tid = pthread_gettid_np(mThread.native_handle());
    setpriority(PRIO_PROCESS, tid, ANDROID_PRIORITY_URGENT_DISPLAY);
    set_sched_policy(tid, SP_FOREGROUND);
}

void EventControlThread::setVsyncEnabled(bool enabled) {
    std::lock_guard<std::mutex> lock(mMutex);
    mVsyncEnabled = enabled;
   
    mCondition.notify_all();
}

// Unfortunately std::unique_lock gives warnings with -Wthread-safety
void EventControlThread::threadMain() NO_THREAD_SAFETY_ANALYSIS {
    auto keepRunning = true;
    auto currentVsyncEnabled = false;

    while (keepRunning) {
        // 回调SF中的 setVsync 。默认是关闭的。
        mSetVSyncEnabled(currentVsyncEnabled); 

        std::unique_lock<std::mutex> lock(mMutex);
        mCondition.wait(lock, [this, currentVsyncEnabled, keepRunning]() NO_THREAD_SAFETY_ANALYSIS {
            return currentVsyncEnabled != mVsyncEnabled || keepRunning != mKeepRunning;
        });
        currentVsyncEnabled = mVsyncEnabled;
        keepRunning = mKeepRunning;
    }
}

  • 开启了线程 EventControlThread 。
  • 回调SF的setPrimaryVsyncEnabled()函数。在哪里传递过来的呢? 还记得在SF的init()方法中:
...
mScheduler =
            getFactory().createScheduler([this](bool enabled) { 
            // 创建线程后,执行这里的callback代码。注意此时是在
            setPrimaryVsyncEnabled(enabled); 
            },mRefreshRateConfigs);
            ...

注意此时是在 EventControlThread线程环境执行的。

3.4.3 SF.setPrimaryVsyncEnabled()

void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) {
    ATRACE_CALL();
    Mutex::Autolock lock(mStateLock);
    if (const auto displayId = getInternalDisplayIdLocked()) {
        // 调用了HwComposer的方法。
        getHwComposer().setVsyncEnabled(*displayId,
                                        enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable);
    }
}

3.4.4 小结

SF通过在EventControlThread线程上,调用HwComposer的setVsyncEnabled()来控制是否继续产生vsync信号。

还有一个问题 DispSync 是干啥的呢?

还记的在 3.4.1 的 Scheduler构造函数中创建了 DispSync对象。

3.5 DispSync 同步模型

3.5.1 DispSync构造函数

frameworks/native/services/surfaceflinger/Scheduler/DispSync.cpp

DispSync::DispSync(const char* name) : mName(name), mRefreshSkipCount(0) {
    // This flag offers the ability to turn on systrace logging from the shell.
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.sf.dispsync_trace_detailed_info", value, "0");
    mTraceDetailedInfo = atoi(value);
    //创建 DispSyncThread线程 ,
    mThread = new DispSyncThread(name, mTraceDetailedInfo);
}

3.5.2 DispSync 的init()

frameworks/native/services/surfaceflinger/Scheduler/DispSync.cpp

void DispSync::init(bool hasSyncFramework, int64_t dispSyncPresentTimeOffset) {
    mIgnorePresentFences = !hasSyncFramework;
    mPresentTimeOffset = dispSyncPresentTimeOffset;
    // 开始threadLoop()
    mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);

   // ...

    reset();
    beginResync();

    // ...
}

run()后,会走threadLoop()

3.5.3 DispSyncThread.threadLoop()

virtual bool threadLoop() {
        status_t err;
        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);

        while (true) {
            std::vector<CallbackInvocation> callbackInvocations;

            nsecs_t targetTime = 0;

            { // Scope for lock
                Mutex::Autolock lock(mMutex);
                //...

                if (mPeriod == 0) {
                    //进入阻塞,等待vsync信号到来。当调用 addResyncSample()方法时候,会调用mCond.signal()来唤醒
                    // 进入 2 逻辑
                    err = mCond.wait(mMutex);
                    if (err != NO_ERROR) {
                        ALOGE("error waiting for new events: %s (%d)", strerror(-err), err);
                        return false;
                    }
                    continue;
                }
                // 2,计算下一个 vsync时间
                targetTime = computeNextEventTimeLocked(now);

                bool isWakeup = false;
                if (now < targetTime) {
                    //...还没到,则wait()
                }

                //...

                callbackInvocations = gatherCallbackInvocationsLocked(now);
            }
            // 回调 callbackInvocations
            if (callbackInvocations.size() > 0) {
                fireCallbackInvocations(callbackInvocations);
            }
        }

        return false;
    }

  1. 启动DispSync 线程后,进入阻塞,等待vsync信号到来。当调用 addResyncSample()方法时候,会调用mCond.signal()来唤醒 进入 2 逻辑。
  2. 计算下一次sync的时间,回调 callbackInvocations

3.5.4 DispSync.callbackInvocations 是什么?

CallbackInvocation 是结构体,持有 Callback的地址。 Callback是一个类,里面定义了onDispSyncEvent()方法。

frameworks/native/services/surfaceflinger/Scheduler/DispSync.cpp

 struct CallbackInvocation {
        DispSync::Callback* mCallback;
        nsecs_t mEventTime;
    };

3.5.5 DispSync.gatherCallbackInvocationsLocked()

 std::vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) {
        if (mTraceDetailedInfo) ATRACE_CALL();
        ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName, ns2us(now));

        std::vector<CallbackInvocation> callbackInvocations;
        nsecs_t onePeriodAgo = now - mPeriod;
        //遍历所有的 mEventListeners,监听者
        for (auto& eventListener : mEventListeners) {
            //计算下一次触发的vsync信号时间
            nsecs_t t = computeListenerNextEventTimeLocked(eventListener, onePeriodAgo);

            if (t < now) {
                // 如果需要触发
                if (isCloseToPeriod(now - eventListener.mLastCallbackTime)) {
                    eventListener.mLastEventTime = t;
                    ALOGV("[%s] [%s] Skipping event due to model error", mName,
                          eventListener.mName);
                    continue;
                }
                if (eventListener.mHasFired && !mModelLocked) {
                    eventListener.mLastEventTime = t;
                    ALOGV("[%s] [%s] Skipping event due to already firing", mName,
                          eventListener.mName);
                    continue;
                }
                CallbackInvocation ci; //新建 CallbackInvocation 对象,赋值callback地址
                ci.mCallback = eventListener.mCallback;
                ci.mEventTime = t;
                ALOGV("[%s] [%s] Preparing to fire, latency: %" PRId64, mName, eventListener.mName,
                      t - eventListener.mLastEventTime);
                callbackInvocations.push_back(ci);
                eventListener.mLastEventTime = t;
                eventListener.mLastCallbackTime = now;
                eventListener.mHasFired = true;
            }
        }
        // 返回结果
        return callbackInvocations;
    }

mEventListeners 集合中找出需要触发vsync信号的,监听者,封装成 CallbackInvocation,加入到集合返回。

3.5.6 fireCallbackInvocations()

void fireCallbackInvocations(const std::vector<CallbackInvocation>& callbacks) {
    if (mTraceDetailedInfo) ATRACE_CALL();
    for (size_t i = 0; i < callbacks.size(); i++) {
        
        callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
    }
}

遍历CallbackInvocation集合,回调 onDispSyncEvent()方法。

现在的问题是 mEventListeners 是谁注册呢 ? 谁调用了 addEventListener()?

status_t DispSync::addEventListener(const char* name, nsecs_t phase, Callback* callback,
                                    nsecs_t lastCallbackTime) {
    Mutex::Autolock lock(mMutex);
    return mThread->addEventListener(name, phase, callback, lastCallbackTime);
}

3.6 mEventListeners 是什么?

还记得在SF.init()方法中,我们创建了两个EventThread线程:app、sf

// 创建跟app 线程,且返回app的 connectionHandler
   mAppConnectionHandle =
           mScheduler->createConnection("app", mPhaseOffsets->getCurrentAppOffset(),
                                        resyncCallback,
                                        impl::EventThread::InterceptVSyncsCallback());
   // 创建 sf 线程 ,且返回 sf 的 connectionHandler                                 
   mSfConnectionHandle = mScheduler->createConnection("sf", mPhaseOffsets->getCurrentSfOffset(),
                                                      resyncCallback, [this](nsecs_t timestamp) {
                                                          mInterceptor->saveVSyncEvent(timestamp);
                                                      });

mScheduler 的 createConnection()内部会调用 makeEventThread()来创建EventThread线程。

3.6.1 Scheduler::makeEventThread()

std::unique_ptr<EventThread> Scheduler::makeEventThread(
        const char* connectionName, DispSync* dispSync, int64_t phaseOffsetNs,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
        // 创建 DispSyncSource 对象,传入了 dispSync
    std::unique_ptr<VSyncSource> eventThreadSource =
            std::make_unique<DispSyncSource>(dispSync, phaseOffsetNs, true, connectionName);
            // 创建 EventThread 线程
    return std::make_unique<impl::EventThread>(std::move(eventThreadSource),
                                               std::move(interceptCallback), connectionName);
}

创建 DispSyncSource 对象。创建 EventThread 线程。

3.6.2 DispSyncSource

//构造函数
DispSyncSource::DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
                               const char* name)
      : mName(name),
        mTraceVsync(traceVsync),
        mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
        mVsyncEventLabel(base::StringPrintf("VSYNC-%s", name)),
        mDispSync(dispSync),
        mPhaseOffset(phaseOffset) {}

// 往 dispSync 添加/移除监听
void DispSyncSource::setVSyncEnabled(bool enable) {
    std::lock_guard lock(mVsyncMutex);
    if (enable) {
        // 注册 vsync 监听
        status_t err = mDispSync->addEventListener(mName, mPhaseOffset,
                                                   static_cast<DispSync::Callback*>(this),
                                                   mLastCallbackTime);
        if (err != NO_ERROR) {
            ALOGE("error registering DispSyncSource callback: %s (%d)", strerror(-err), err);
        }
        // ATRACE_INT(mVsyncOnLabel.c_str(), 1);
    } else {
        // 移除监听
        status_t err = mDispSync->removeEventListener(static_cast<DispSync::Callback*>(this),
                                                      &mLastCallbackTime);
        if (err != NO_ERROR) {
            ALOGE("error unregistering vsync callback: %s (%d)", strerror(-err), err);
        }
        // ATRACE_INT(mVsyncOnLabel.c_str(), 0);
    }
    mEnabled = enable;
}

至此,原来是app、sf两个 DispSyncSource 对象 向 DispSync中 注册了vsync监听。

因此,当接收到vsync信号后,接下来便是回调 DispSyncSourceonDispSyncEvent()方法:

3.7 DispSyncSource::onDispSyncEvent()

void DispSyncSource::onDispSyncEvent(nsecs_t when) {
    VSyncSource::Callback* callback;
    {
        std::lock_guard lock(mCallbackMutex);
        callback = mCallback;

        if (mTraceVsync) {
            mValue = (mValue + 1) % 2;
            ATRACE_INT(mVsyncEventLabel.c_str(), mValue);
        }
    }

    if (callback != nullptr) {
        callback->onVSyncEvent(when);
    }
}

mCallback 是什么对象呢? 答案是 EventThread 对象。

3.8 EventThread

EventThread::EventThread(VSyncSource* src, std::unique_ptr<VSyncSource> uniqueSrc,
                         InterceptVSyncsCallback interceptVSyncsCallback, const char* threadName)
      : mVSyncSource(src),
        mVSyncSourceUnique(std::move(uniqueSrc)),
        mInterceptVSyncsCallback(std::move(interceptVSyncsCallback)),
        mThreadName(threadName) {
    if (src == nullptr) {
        mVSyncSource = mVSyncSourceUnique.get();
    }
    // 向 DispSyncSource 中设置 callback
    mVSyncSource->setCallback(this);
    //创建线程
    mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
        std::unique_lock<std::mutex> lock(mMutex);
        // 执行threadMain()
        threadMain(lock);
    });

    pthread_setname_np(mThread.native_handle(), threadName);

    pid_t tid = pthread_gettid_np(mThread.native_handle());
    //...

    set_sched_policy(tid, SP_FOREGROUND);
}

由此可见,DispSyncSource中的mCallback就是 是 EventThread。接着看 onVSyncEvent()。不过在看 zhonVSyncEvent() 之前,我们先看看 EventThread的threadMain()

3.8.1 threadMain()

void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
    DisplayEventConsumers consumers;
    // 只要没有退出 就一直循环
    while (mState != State::Quit) {
        std::optional<DisplayEventReceiver::Event> event;

        // Determine next event to dispatch.
        if (!mPendingEvents.empty()) {
        // mPendingEvents不为空
            event = mPendingEvents.front();
            mPendingEvents.pop_front();

            switch (event->header.type) {
                case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
                    if (event->hotplug.connected && !mVSyncState) {
                        mVSyncState.emplace(event->header.displayId);
                    } else if (!event->hotplug.connected && mVSyncState &&
                               mVSyncState->displayId == event->header.displayId) {
                        mVSyncState.reset();
                    }
                    break;

                case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
                    if (mInterceptVSyncsCallback) {
                        mInterceptVSyncsCallback(event->header.timestamp);
                    }
                    break;
            }
        }

        bool vsyncRequested = false;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        
        
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
                // 遍历  mDisplayEventConnections vector集合
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);
                }

                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }
        // 回调 consumers
        if (!consumers.empty()) {
            dispatchEvent(*event, consumers);
            consumers.clear();
        }

        // 下一次vsync 
        State nextState;
        if (mVSyncState && vsyncRequested) {
            nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
        } else {
            ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
            nextState = State::Idle;
        }

        if (mState != nextState) {
            if (mState == State::VSync) {
                // 移除vsync监听
                mVSyncSource->setVSyncEnabled(false);
            } else if (nextState == State::VSync) {
                //添加vsync监听
                mVSyncSource->setVSyncEnabled(true);
            }

            mState = nextState;
        }

        if (event) {
            continue;
        }

        // Wait for event or client registration/request.
        if (mState == State::Idle) {
            //等待
            mCondition.wait(lock);
        } else {
            // Generate a fake VSYNC after a long timeout in case the driver stalls. When the
            // display is off, keep feeding clients at 60 Hz.
            const auto timeout = mState == State::SyntheticVSync ? 16ms : 1000ms;
            if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
                ALOGW_IF(mState == State::VSync, "Faking VSYNC due to driver stall");

                LOG_FATAL_IF(!mVSyncState);
                mPendingEvents.push_back(makeVSync(mVSyncState->displayId,
                                                   systemTime(SYSTEM_TIME_MONOTONIC),
                                                   ++mVSyncState->count));
            }
        }
    }
}

如果有vsync事件,则调用 dispatchEvent(),内部会回调 consumer 的 postEvent()方法。

void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
                                const DisplayEventConsumers& consumers) {
    for (const auto& consumer : consumers) {
        switch (consumer->postEvent(event)) {
            case NO_ERROR:
                break;

            case -EAGAIN:
                // TODO: Try again if pipe is full.
                ALOGW("Failed dispatching %s for %s", toString(event).c_str(),
                      toString(*consumer).c_str());
                break;

            default:
                // Treat EPIPE and other errors as fatal.
                removeDisplayEventConnectionLocked(consumer);
        }
    }
}

那么什么时候触发呢,就是上一步的 onVSyncEvent()方法。

3.8.2 EventThread.onVSyncEvent()

void EventThread::onVSyncEvent(nsecs_t timestamp) {
    std::lock_guard<std::mutex> lock(mMutex);

    LOG_FATAL_IF(!mVSyncState);
    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count));
    // 唤醒 EventThread 线程
    mCondition.notify_all();
}

唤醒 EventThread 线程后,此时执行环境就从 DispSync线程 切换到了EventThread线程(也就是app或者sf), 就回调 postEvent():

3.8.3 EventThreadConnection::postEvent()

status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
    ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
    return size < 0 ? status_t(size) : status_t(NO_ERROR);
}

3.8.4 DisplayEventReceiver::sendEvents()

frameworks/native/libs/gui/DisplayEventReceiver.cpp

ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
        Event const* events, size_t count)
{
    return gui::BitTube::sendObjects(dataChannel, events, count);
}

我们知道 2.3.4 中注册了BitTube fd的监听,因此,接下里会回调 SF主线程的 MessageQueue::cb_eventReceiver()方法。

3.8.5 小结

创建的 sf 线程,会主动添加vsync监听。收到vsync信号后,从DispVsync线程切换到 sf对应的线程 EventThread,一旦收到数据,则通过BitTube::sendObjects(),再次切换到SF主线程执行cb_eventReceiver()

3.9 MessageQueue::cb_eventReceiver()

int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
    MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
    return queue->eventReceiver(fd, events);
}

3.9.1 MessageQueue::eventReceiver()

int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
    ssize_t n;
    DisplayEventReceiver::Event buffer[8];
    while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
        for (int i = 0; i < n; i++) {
            if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                mHandler->dispatchInvalidate();
                break;
            }
        }
    }
    return 1;
}

3.9.2 MessageQueue::Handler::dispatchInvalidate()

void MessageQueue::Handler::dispatchInvalidate() {
    if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
        mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
    }
}

3.9.3 Handler::handleMessage()

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;
    }
}

3.9.3 SurfaceFlinger::onMessageReceived()

void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
    ATRACE_CALL();
    switch (what) {
        case MessageQueue::INVALIDATE: {
            //...
            updateVrFlinger();

            bool refreshNeeded = handleMessageTransaction();
            refreshNeeded |= handleMessageInvalidate();

            updateCursorAsync();
            updateInputFlinger();

            refreshNeeded |= mRepaintEverything;
            if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
                // Signal a refresh if a transaction modified the window state,
                // a new buffer was latched, or if HWC has requested a full
                // repaint
                //内部调用是 handleMessageRefresh()
                signalRefresh();
            }
            break;
        }
        case MessageQueue::REFRESH: {
            
            handleMessageRefresh();
            break;
        }
    }
}

最终,通过层层调用,终于切换到了SF的 onMessageReceived()方法,在这里会进行图形合成输出。

看看 handleMessageRefresh()

3.10 图形合成输出 SF.handleMessageRefresh()

void SurfaceFlinger::handleMessageRefresh() {
    ATRACE_CALL();

    mRefreshPending = false;

    const bool repaintEverything = mRepaintEverything.exchange(false);
    // 合成前
    preComposition();
    rebuildLayerStacks();
    calculateWorkingSet();
    for (const auto& [token, display] : mDisplays) {
        // 
        beginFrame(display);
        // 
        prepareFrame(display);
        
        doDebugFlashRegions(display, repaintEverything);
        //开始合成
        doComposition(display, repaintEverything);
    }

    logLayerStats();

    postFrame();
    // 合成后
    postComposition();

    mHadClientComposition = false;
    mHadDeviceComposition = false;
    for (const auto& [token, displayDevice] : mDisplays) {
        auto display = displayDevice->getCompositionDisplay();
        const auto displayId = display->getId();
        mHadClientComposition =
                mHadClientComposition || getHwComposer().hasClientComposition(displayId);
        mHadDeviceComposition =
                mHadDeviceComposition || getHwComposer().hasDeviceComposition(displayId);
    }

    mVsyncModulator.onRefreshed(mHadClientComposition);

    mLayersWithQueuedFrames.clear();
}

至此,SF分阶段开始执行图层合成工作,具体工作后续分析。

四、总结

回顾 SurfaceFlinger 的启动过程,主要做了如下工作:

  1. 实例化 SurfaceFlinger对象,在主线程创建looper消息机制。赋值 mMessageQueue、mConmpositionEnginer等成员

  2. 调用SF.init()方法:

    • 创建Scheduler 调度对象,内部创建 DispVysnc、EventControlThread、scheduler::IdleTimer触摸事件计时器等对象。
    • 创建app、sf两个EventThread线程,前者用来绘制、后者用来合成layer。
    • 创建HWComposer对象,负责vsync信号的产生(由硬件或者软件线程模拟。注册callback到HWComposer,产生信号后,回调到SF,完成图层合成的工作。
    • 此外,针对app EVenThread延时源信号,Choreographer会监听 app EVenThread延时源信号。收到vsync后,开始三大流程的绘制(measure/layout/draw)
  3. 注册名字为 SurfaceFlinger的服务到SM,提供给应用层使用。

  4. 调用SF.run()方法,开始等待mMessageQueue中事件的到来。

4.1 涉及到的线程

  1. SF的主线程,收到信号开始合成展示
  2. app、sf的 EventThread: sf会把vsync信号分发到 SF主线程。app则是分发到应用层。
  3. DispSync线程:会把vsync信号分发到 app和sf线程
  4. EventControlThread线程 用来控制HWC硬件是否产生vsync信号

五、参考

gityuan.com/2017/02/11/…

ljd1996.github.io/2020/11/02/…