Android 14 - 绘制体系 - VSync(1)

整体框架

VsyncConfiguration一些基本参数配置比如PhaseOffsetsWorkDuration

Scheduler:作为SF生成和派发VSync的整体调度器,主要面向SurfaceFlinger提供VSync相关接口。Scheduler包含对所有屏幕的VSync的控制。本身MessageQueue子类

RefreshRateSelector每个Display屏幕对应一个RefreshRateSelector用于基于屏幕支持的刷新率范围,选择一个合适Refresh RateFrame Rate传递VSyncSchedule作为软件VSync生成重要因素

VsyncScheduleVsync生成的调度器。每个屏幕对应一个VsyncSchedule。包含一个Tracker(VSyncPredictor)、一个Dispatch(VSyncDispatchTimerQueue)、一个Controller(VSyncReactor)。一方面对接硬件VSync信号开关一方面对接软件VSync计算输出

VSyncPredictor 在VsyncSchedule语境中一个Tracker负责综合各方因素根据算法由硬件VSync计算出软件VSync周期工具类

VSyncDispatchTimerQueue在VsyncSchedule语境中一个Dispather负责VSync分发使用者

VSyncCallbackRegistration代表一个VSync使用者的注册比如常见的针对上层应用的VSYNC-app、针对SurfaceFlinger合成的VSYNC-sf对应一个VSyncCallbackRegistration另外客户端还有一个VSYNC-appSf

EventThread处理客户端应用VSYNC的一个独立线程。期内维护一个不断请求VSYNC的死循环。比如VSYNC-app,一方面通过VSyncCallbackRegistration申请一次VSYNC另一方VSYNC生成通过ConnectionVSYNC发送给DisplayEventReceiver也就是VSYNC的终端接收者。一般情况两个EventThread一个是针对客户端应用侧VSYNC-app另一个客户端使用SF同步信号VSYNC-appSf

DisplayEventReceiver通过socket机制提供了一SF客户端应用传递VSYNC通道服务端EventThread通过DisplayEventReceiver发送VSYNC事件客户端Choreographer通过DisplayEventReceiver接收到VSYNC下发ViewRootImp驱动下一次绘制渲染

Android 13以后VSYNC架构变化之一是给SF使用的VSYNC-sf信号通过EventThread维护而是直接Schedule维护。供客户端应用使用的VSYN-app仍然EventThread维护另外新增一个VSYN-appSf信号也是EventThread维护主要作用如果客户端使用SF同步信号可以切换VSYNC-appSf这个信号Android 13之前这个机制通过VSYNC-sf实现Android 13SF专门使用VSYNC-sfEventThread剥离出来直接Schedule维护VSYN-appSf专门针对客户端

关键参数

探索VSync机制需要一些关键参数概念有所了解dumpsys SurfaceFlinger入手

屏幕刷新率

ColorMode设备支持ColorMode可根据系统设置应用自身设定的颜色模式最终决定使用那个ColorMode

deviceProductInfo: 屏幕设备信息manufacturerPnpId=QCMPlug and Play即插即用设备唯一识别码

activeMode:当前使用帧率模式

displayModes:当前屏幕支持帧率模式打印信息支持60Hz90Hz两种帧率

displayManagerPolicy当前采用帧率管理策略primaryRanges代表选取帧率通常采纳范围,如果用户通过setFrameRate手动指定一个帧率,其可能超出primaryRanges的范围;appRequestRanges代表用户可以指定帧率范围最终帧率可能超过primaryRanges但绝不会超过appRequestRanges

主要组件的初始化

SurfaceFlinger的初始化

SurfaceFlinger启动源于SystemServer执行main_surfaceflinger.cppmain方法

int main(int, char**) {
    ...
    sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
    ...
    flinger->init();
    ...
}

surfaceflinger::createSurfaceFlinger()实现platform/frameworks/native/services/surfaceflinger/SurfaceFlingerFactory.cpp

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

    return sp<SurfaceFlinger>::make(factory);
}

随后调用SurfaceFlingerinit方法

platform/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
    ...
    sp<const DisplayDevice> display;
    if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) {
        const auto& displays = mCurrentState.displays;

        const auto& token = displays.keyAt(*indexOpt);
        const auto& state = displays.valueAt(*indexOpt);

        processDisplayAdded(token, state);
        mDrawingState.displays.add(token, state);

        display = getDefaultDisplayDeviceLocked();
    }
    ...
    initScheduler(display);
    ...
}

构建RefreshRateSelector

上面的代码中调用了processDisplayAdded添加主屏幕,后续挂载一个新屏幕也会走此流程:

void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
                                         const DisplayDeviceState& state) {
     ...
     auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state,
                                                 displaySurface, producer);
     ...
 }
 
 sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const wp<IBinder>& displayToken,
        std::shared_ptr<compositionengine::Display> compositionDisplay,
        const DisplayDeviceState& state,
        const sp<compositionengine::DisplaySurface>& displaySurface,
        const sp<IGraphicBufferProducer>& producer) {
        ...
         creationArgs.refreshRateSelector =
                mPhysicalDisplays.get(physical->id)
                        .transform(&PhysicalDisplay::snapshotRef)
                        .transform([&](const display::DisplaySnapshot& snapshot) {
                            return std::make_shared<
                                    scheduler::RefreshRateSelector>(snapshot.displayModes(),
                                                                    creationArgs.activeModeId,
                                                                    config);
                        })
                        .value_or(nullptr);
        ...
        sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
 
 }
                                             

上面每个Display构建一个refreshRateSelectorRefreshRateSelector

初始化Scheduler

VSync相关初始化都在initScheduler

void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
    const auto activeMode = display->refreshRateSelector().getActiveMode();
    const Fps activeRefreshRate = activeMode.fps;
    // 创建配置
    mVsyncConfiguration = getFactory().createVsyncConfiguration(activeRefreshRate);
    // 创建Scheduler
    mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
                                             static_cast<ISchedulerCallback&>(*this), features,
                                             std::move(modulatorPtr));
    // 注册屏幕每个屏幕构建一个VsyncSchedule对象
    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
    mScheduler->startTimers();
    // 创建VSYNC-app对应EventThread
    mAppConnectionHandle =
		mScheduler->createEventThread(Scheduler::Cycle::Render,
									  mFrameTimeline->getTokenManager(),
									  /* workDuration */ configs.late.appWorkDuration,
									  /* readyDuration */ configs.late.sfWorkDuration);
    // 创建VSYNC-appSf对应的EventThread
mSfConnectionHandle =
		mScheduler->createEventThread(Scheduler::Cycle::LastComposite,
									  mFrameTimeline->getTokenManager(),
									  /* workDuration */ activeRefreshRate.getPeriod(),
									  /* readyDuration */ configs.late.sfWorkDuration);
    // 创建VSYNC-sf对应调度器
    mScheduler->initVsync(mScheduler->getVsyncSchedule()->getDispatch(),
                          *mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);
      ...
}

VsyncSchedule创建Scheduler::registerDisplay

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

void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
    auto schedulePtr = std::make_shared<VsyncSchedule>(displayId, mFeatures,
                                                       [this](PhysicalDisplayId id, bool enable) {
                                                           onHardwareVsyncRequest(id, enable);
                                                       });

    registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr));
}

VsyncSchedule构造函数初始化

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

VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features,
                             RequestHardwareVsync requestHardwareVsync)
      : mId(id),
        mRequestHardwareVsync(std::move(requestHardwareVsync)),
        mTracker(createTracker(id)),
        mDispatch(createDispatch(mTracker)),
        mController(createController(id, *mTracker, features)),
        mTracer(features.test(Feature::kTracePredictedVsync)
                        ? std::make_unique<PredictedVsyncTracer>(mDispatch)
                        : nullptr) {}

VsyncSchedule构造几个重要组件

VsyncSchedule::VsyncSchedule(PhysicalDisplayId id, FeatureFlags features,
                             RequestHardwareVsync requestHardwareVsync)
      : mId(id),
        mRequestHardwareVsync(std::move(requestHardwareVsync)),
        mTracker(createTracker(id)),
        mDispatch(createDispatch(mTracker)),
        mController(createController(id, *mTracker, features)),
        mTracer(features.test(Feature::kTracePredictedVsync)
                        ? std::make_unique<PredictedVsyncTracer>(mDispatch)
                        : nullptr) {}

其中mTracker本质上VSyncPredictor

VsyncSchedule::TrackerPtr VsyncSchedule::createTracker(PhysicalDisplayId id) {
    // TODO(b/144707443): Tune constants.
    constexpr nsecs_t kInitialPeriod = (60_Hz).getPeriodNsecs();
    constexpr size_t kHistorySize = 20;
    constexpr size_t kMinSamplesForPrediction = 6;
    constexpr uint32_t kDiscardOutlierPercent = 20;

    return std::make_unique<VSyncPredictor>(id, kInitialPeriod, kHistorySize,
                                            kMinSamplesForPrediction, kDiscardOutlierPercent);
}

mDispatch本质上VSyncDispatchTimerQueue

VsyncSchedule::DispatchPtr VsyncSchedule::createDispatch(TrackerPtr tracker) {
    using namespace std::chrono_literals;

    // TODO(b/144707443): Tune constants.
    constexpr std::chrono::nanoseconds kGroupDispatchWithin = 500us;
    constexpr std::chrono::nanoseconds kSnapToSameVsyncWithin = 3ms;

    return std::make_unique<VSyncDispatchTimerQueue>(std::make_unique<Timer>(), std::move(tracker),
                                                     kGroupDispatchWithin.count(),
                                                     kSnapToSameVsyncWithin.count());
}

mController本质上VSyncReactor

VsyncSchedule::ControllerPtr VsyncSchedule::createController(PhysicalDisplayId id,
                                                             VsyncTracker& tracker,
                                                             FeatureFlags features) {
    // TODO(b/144707443): Tune constants.
    constexpr size_t kMaxPendingFences = 20;
    const bool hasKernelIdleTimer = features.test(Feature::kKernelIdleTimer);

    auto reactor = std::make_unique<VSyncReactor>(id, std::make_unique<SystemClock>(), tracker,
                                                  kMaxPendingFences, hasKernelIdleTimer);

    reactor->setIgnorePresentFences(!features.test(Feature::kPresentFences));
    return reactor;
}

VSYNC-appVSYNC-appSf这两个信号是在EventThread维护看下createEventThread

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

ConnectionHandle Scheduler::createEventThread(Cycle cycle,
                                              frametimeline::TokenManager* tokenManager,
                                              std::chrono::nanoseconds workDuration,
                                              std::chrono::nanoseconds readyDuration) {
  // 根据cycle参数不同选择app还是appSf
    auto eventThread = std::make_unique<impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
                                                           getVsyncSchedule(), tokenManager,
                                                           makeThrottleVsyncCallback(),
                                                           makeGetVsyncPeriodFunction(),
                                                           workDuration, readyDuration);

    auto& handle = cycle == Cycle::Render ? mAppConnectionHandle : mSfConnectionHandle;
    // 创建Connection
    handle = createConnection(std::move(eventThread));
    return handle;
}

EventThread构造函数

EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule,
                         android::frametimeline::TokenManager* tokenManager,
                         ThrottleVsyncCallback throttleVsyncCallback,
                         GetVsyncPeriodFunction getVsyncPeriodFunction,
                         std::chrono::nanoseconds workDuration,
                         std::chrono::nanoseconds readyDuration)
      : mThreadName(name),
      // ATRACE名称
        mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0),
        // VSYNC计算时使用的偏移量
        mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
        // VSYNC计算时使用的偏移量
        mReadyDuration(readyDuration),
        mVsyncSchedule(std::move(vsyncSchedule)),
        // 一个VSYNC请求者的具体处理
        mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback()/*VSync生成后的回调函数*/, name),
        mTokenManager(tokenManager),
        mThrottleVsyncCallback(std::move(throttleVsyncCallback)),
        mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)) {
    LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction == nullptr,
            "getVsyncPeriodFunction must not be null");

    mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
        std::unique_lock<std::mutex> lock(mMutex);
        threadMain(lock);
    });

上面方法通过createConnection创建VSync事件派发通道

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

ConnectionHandle Scheduler::createConnection(std::unique_ptr<EventThread> eventThread) {
    const ConnectionHandle handle = ConnectionHandle{mNextConnectionHandleId++};
    ALOGV("Creating a connection handle with ID %" PRIuPTR, handle.id);

    auto connection = createConnectionInternal(eventThread.get());

    std::lock_guard<std::mutex> lock(mConnectionsLock);
    mConnections.emplace(handle, Connection{connection, std::move(eventThread)});
    return handle;
}

sp<EventThreadConnection> Scheduler::createConnectionInternal(
        EventThread* eventThread, EventRegistrationFlags eventRegistration,
        const sp<IBinder>& layerHandle) {
    int32_t layerId = static_cast<int32_t>(LayerHandle::getLayerId(layerHandle));
    auto connection = eventThread->createEventConnection([&] { resync(); }, eventRegistration);
    mLayerHistory.attachChoreographer(layerId, connection);
    return connection;
}

最终是由EventThread创建Connection:

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

sp<EventThreadConnection> EventThread::createEventConnection(
        ResyncCallback resyncCallback, EventRegistrationFlags eventRegistration) const {
    return sp<EventThreadConnection>::make(const_cast<EventThread*>(this),
                                           IPCThreadState::self()->getCallingUid(),
                                           std::move(resyncCallback), eventRegistration);
}

VSYNC-app的请求流程

VSYNC-appEventThread维护VSYNC-app触发多种因素包括新屏幕挂载客户端主动请求EVentThread线程内部自发

EventThread内部自发为例

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()) {
            event = mPendingEvents.front();
            mPendingEvents.pop_front();

            if (event->header.type == 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();
                }
            }
        }

        bool vsyncRequested = false;

        // Find connections that should consume this event.
        auto it = mDisplayEventConnections.begin();
        while (it != mDisplayEventConnections.end()) {
            if (const auto connection = it->promote()) {
                if (event && shouldConsumeEvent(*event, connection)) {
                    consumers.push_back(connection);
                }

                vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;

                ++it;
            } else {
                it = mDisplayEventConnections.erase(it);
            }
        }

        if (!consumers.empty()) {
            dispatchEvent(*event, consumers);
            consumers.clear();
        }

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

        if (mState == State::VSync) {
            const auto scheduleResult =
                    mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
                                                 .readyDuration = mReadyDuration.count(),
                                                 .earliestVsync = mLastVsyncCallbackTime.ns()});
            LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback");
        } else {
            mVsyncRegistration.cancel();
        }

        if (!mPendingEvents.empty()) {
            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 std::chrono::nanoseconds timeout =
                    mState == State::SyntheticVSync ? 16ms : 1000ms;
            if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
                if (mState == State::VSync) {
                    ALOGW("Faking VSYNC due to driver stall for thread %s", mThreadName);
                }

                LOG_FATAL_IF(!mVSyncState);
                const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
                const auto deadlineTimestamp = now + timeout.count();
                const auto expectedVSyncTime = deadlineTimestamp + timeout.count();
                mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now,
                                                   ++mVSyncState->count, expectedVSyncTime,
                                                   deadlineTimestamp));
            }
        }
    }
    // cancel any pending vsync event before exiting
    mVsyncRegistration.cancel();
}

触发VSYNC请求

const auto scheduleResult =

mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),

.readyDuration = mReadyDuration.count(),

.earliestVsync = mLastVsyncCallbackTime.ns()});

LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback");

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

ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
    if (!mToken) {
        return std::nullopt;
    }
    return mDispatch->schedule(*mToken, scheduleTiming);
}

mDispatchVSyncDispatchTimerQueue同一个文件

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

ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token,
                                                 ScheduleTiming scheduleTiming) {
    std::lock_guard lock(mMutex);
    return scheduleLocked(token, scheduleTiming);
}

ScheduleResult VSyncDispatchTimerQueue::scheduleLocked(CallbackToken token,
                                                       ScheduleTiming scheduleTiming) {
    auto it = mCallbacks.find(token);
    if (it == mCallbacks.end()) {
        return {};
    }
    auto& callback = it->second;
    auto const now = mTimeKeeper->now();

    /* If the timer thread will run soon, we'll apply this work update via the callback
     * timer recalculation to avoid cancelling a callback that is about to fire. */
    auto const rearmImminent = now > mIntendedWakeupTime;
    if (CC_UNLIKELY(rearmImminent)) {
        callback->addPendingWorkloadUpdate(scheduleTiming);
        return getExpectedCallbackTime(*mTracker, now, scheduleTiming);
    }

    const ScheduleResult result = callback->schedule(scheduleTiming, *mTracker, now);
    if (!result.has_value()) {
        return {};
    }

    if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack) {
        rearmTimerSkippingUpdateFor(now, it);
    }

    return result;
}

这里callbackVSyncDispatchTimerQueueEntry具体实现VSyncDispatchTimerQueue.cpp文件

ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
                                                      VSyncTracker& tracker, nsecs_t now) {
    auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(
            std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration));
    auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;

    bool const wouldSkipAVsyncTarget =
            mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance));
    bool const wouldSkipAWakeup =
            mArmedInfo && ((nextWakeupTime > (mArmedInfo->mActualWakeupTime + mMinVsyncDistance)));
    if (wouldSkipAVsyncTarget && wouldSkipAWakeup) {
        return getExpectedCallbackTime(nextVsyncTime, timing);
    }

    nextVsyncTime = adjustVsyncIfNeeded(tracker, nextVsyncTime);
    nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;

    auto const nextReadyTime = nextVsyncTime - timing.readyDuration;
    mScheduleTiming = timing;
    mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime};
    return getExpectedCallbackTime(nextVsyncTime, timing);
}

这里就是计算下一次VSync的地方了。tracker就是VSyncPredictor计算VSync核心

上面VSyncDispatchTimerQueue::scheduleLockedschedule计算时间调用

rearmTimerSkippingUpdateForrearmTimerSkippingUpdateFor设置一个Alarm定时执行VSync回调

void VSyncDispatchTimerQueue::rearmTimerSkippingUpdateFor(
        nsecs_t now, CallbackMap::iterator const& skipUpdateIt) {
        ...
        setTimer(*min, now);
        ...
}

void VSyncDispatchTimerQueue::setTimer(nsecs_t targetTime, nsecs_t /*now*/) {
    mIntendedWakeupTime = targetTime;
    mTimeKeeper->alarmAt(std::bind(&VSyncDispatchTimerQueue::timerCallback, this),
                         mIntendedWakeupTime);
    mLastTimerSchedule = mTimeKeeper->now();
}

这里timerCallbackEventThread这个方法

scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() {
    return [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
        onVsync(vsyncTime, wakeupTime, readyTime);
    };
}

void EventThread::onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
    std::lock_guard<std::mutex> lock(mMutex);
    mLastVsyncCallbackTime = TimePoint::fromNs(vsyncTime);

    LOG_FATAL_IF(!mVSyncState);
    mVsyncTracer = (mVsyncTracer + 1) % 2;
    mPendingEvents.push_back(makeVSync(mVSyncState->displayId, wakeupTime, ++mVSyncState->count,
                                       vsyncTime, readyTime));
    mCondition.notify_all();
}

Vsync信号将会封装Event放入mPendingEvents

VSYNC-app的分发过程

之前threadMain方法代码

if (!mPendingEvents.empty()) {
            event = mPendingEvents.front();
            mPendingEvents.pop_front();

            if (event->header.type == 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();
                }
            }
        }
...
if (!consumers.empty()) {
    dispatchEvent(*event, consumers);
    consumers.clear();
}

void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
                                const DisplayEventConsumers& consumers) {
    for (const auto& consumer : consumers) {
        DisplayEventReceiver::Event copy = event;
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
            const int64_t frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
            copy.vsync.vsyncData.frameInterval = frameInterval;
            generateFrameTimeline(copy.vsync.vsyncData, frameInterval, copy.header.timestamp,
                                  event.vsync.vsyncData.preferredExpectedPresentationTime(),
                                  event.vsync.vsyncData.preferredDeadlineTimestamp());
        }
        switch (consumer->postEvent(copy)) {
            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);
        }
    }
}

这里consumerEventThreadConnection

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

status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
    constexpr auto toStatus = [](ssize_t size) {
        return size < 0 ? status_t(size) : status_t(NO_ERROR);
    };

    if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE ||
        event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
        mPendingEvents.emplace_back(event);
        if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
            return status_t(NO_ERROR);
        }

        auto size = DisplayEventReceiver::sendEvents(&mChannel, mPendingEvents.data(),
                                                     mPendingEvents.size());
        mPendingEvents.clear();
        return toStatus(size);
    }

    auto size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
    return toStatus(size);
}

DisplayEventReceiver::sendEvents最终客户端

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

BitTube通过socket事件分发客户端的Choreographer

VSYNC-sf的请求和分发

VSYNC-sf触发SurfaceFlinger::initScheduler调用MessageQueue::initVsync

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

void MessageQueue::initVsync(std::shared_ptr<scheduler::VSyncDispatch> dispatch,
                             frametimeline::TokenManager& tokenManager,
                             std::chrono::nanoseconds workDuration) {
    std::unique_ptr<scheduler::VSyncCallbackRegistration> oldRegistration;
    {
        std::lock_guard lock(mVsync.mutex);
        mVsync.workDuration = workDuration;
        mVsync.tokenManager = &tokenManager;
        oldRegistration = onNewVsyncScheduleLocked(std::move(dispatch));
    }

    // See comments in onNewVsyncSchedule. Today, oldRegistration should be
    // empty, but nothing prevents us from calling initVsync multiple times, so
    // go ahead and destruct it outside the lock for safety.
    oldRegistration.reset();
}

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

std::unique_ptr<scheduler::VSyncCallbackRegistration> MessageQueue::onNewVsyncScheduleLocked(
        std::shared_ptr<scheduler::VSyncDispatch> dispatch) {
    const bool reschedule = mVsync.registration &&
            mVsync.registration->cancel() == scheduler::CancelResult::Cancelled;
    auto oldRegistration = std::move(mVsync.registration);
    mVsync.registration = std::make_unique<
            scheduler::VSyncCallbackRegistration>(std::move(dispatch),
                                                  std::bind(&MessageQueue::vsyncCallback, this,
                                                            std::placeholders::_1,
                                                            std::placeholders::_2,
                                                            std::placeholders::_3),
                                                  "sf");
    if (reschedule) {
        mVsync.scheduledFrameTime =
                mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
                                               .readyDuration = 0,
                                               .earliestVsync = mVsync.lastCallbackTime.ns()});
    }
    return oldRegistration;
}

可以看到这里VSYNC信号命名“sf”mVsync.registration->schedule此处调用VSync生成过程前面VSync-app相同。但这里回调函数vsyncCallback

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

void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) {
    ATRACE_CALL();
    // Trace VSYNC-sf
    mVsync.value = (mVsync.value + 1) % 2;

    const auto expectedVsyncTime = TimePoint::fromNs(vsyncTime);
    {
        std::lock_guard lock(mVsync.mutex);
        mVsync.lastCallbackTime = expectedVsyncTime;
        mVsync.scheduledFrameTime.reset();
    }

    const auto vsyncId = VsyncId{mVsync.tokenManager->generateTokenForPredictions(
            {targetWakeupTime, readyTime, vsyncTime})};

    mHandler->dispatchFrame(vsyncId, expectedVsyncTime);
}

MessageQueue本身一个消息队列实现这里看到收到VSync回调,通过mHandler->dispatchFrame抛到队列最终执行

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

void MessageQueue::Handler::handleMessage(const Message&) {
    mFramePending.store(false);
    mQueue.onFrameSignal(mQueue.mCompositor, mVsyncId, mExpectedVsyncTime);
}

最后回调

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

void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
                              TimePoint expectedVsyncTime) {
          ...
          if (!compositor.commit(pacesetterId, targets)) return;
          ...
          const auto resultsPerDisplay = compositor.composite(pacesetterId, targeters);
  }

这里的compositor是SurfaceFlinger。接下来就是由SF进行合成工作

  • 25
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值