Android Framework之Vsync

313 阅读5分钟

基础概念梳理

Vsync作用

  • SurfaceFlinger处理前后缓冲区的切换
  • 上层Choreographer接收处理

卡顿

因为上层UI比较复杂,在下一次信号来临的时候,来不及绘制完成,只能继续使用上一次的画面,也就出现了所谓的卡顿

SurfaceFlinger大体流程

SurfaceFlinger 实现了ComposerCallback 接口,所以在初始化以后可以会回调onComposerHalHotplug,在该方法里

if (std::this_thread::get_id() == mMainThreadId) {
    processDisplayHotplugEventsLocked();//主线程去处理
}
​
-->  {
  //初始化scheduler
   if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
                    initScheduler(state);
                }
}
​
-->initScheduler()
  --> 创建mScheduler
     -->Scheduler构造函数 创建 VsyncSchedule
        -->引出 createVSyncDispatch ()创建的分发 
  -->createConnection() //创建 app和appsf链接
     -->创建vsyncSource 和EventTheread 
        -->eventTheread将创建的vsyncSource 传入自己构造函数 添加callBack
        -->EventThread.cpp的 onVSyncEvent()方法 放入mPendingEvents 在threadMain方法中处理
  --> mEventQueue->initVsync()//添加回调 和mScheduler 的dispatch 绑定
 
  
 -------- -------- -------- -------- -------- -------- -------- -------- --------
  接收消息的Event地方有两个MessageQueue.cpp 中的vsyncCallback 和EventThread.onSyncEvent
  需要的时候再继续进一步深入处理,所以到这里我们可以知道当Vsync信号发送过来的时候,MessageQueue开始处理驱动SF处理图片
  
void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {
    if (mScheduler) {
      
        return;
    }
    const auto displayId = displayState.physical->id;
    scheduler::RefreshRateConfigs::Config config =
            {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),
             .frameRateMultipleThreshold =
                     base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)};
    mRefreshRateConfigs =
            std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
                                                            displayState.physical->activeMode
                                                                    ->getId(),
                                                            config);
    const auto currRefreshRate = displayState.physical->activeMode->getFps();
    mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,
                                                                      hal::PowerMode::OFF);
​
    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
    mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());
​
    // 创建mScheduler 在SurfaceFlingerDefaultFactoty上
    mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
    const auto configs = mVsyncConfiguration->getCurrentConfigs();
    const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
  //注册 app 和appSf
    mAppConnectionHandle =
            mScheduler->createConnection("app", mFrameTimeline->getTokenManager(),
                                         /*workDuration=*/configs.late.appWorkDuration,
                                         /*readyDuration=*/configs.late.sfWorkDuration,
                                         impl::EventThread::InterceptVSyncsCallback());
    mSfConnectionHandle =
            mScheduler->createConnection("appSf", mFrameTimeline->getTokenManager(),
                                         /*workDuration=*/std::chrono::nanoseconds(vsyncPeriod),
                                         /*readyDuration=*/configs.late.sfWorkDuration,
                                         [this](nsecs_t timestamp) {
                                             mInterceptor->saveVSyncEvent(timestamp);
                                         });
​
  //EventQueue 添加回调 SF
    mEventQueue->initVsync(mScheduler->getVsyncDispatch(), *mFrameTimeline->getTokenManager(),
                           configs.late.sfWorkDuration);
​
    mRegionSamplingThread =
            new RegionSamplingThread(*this, RegionSamplingThread::EnvironmentTimingTunables());
    mFpsReporter = new FpsReporter(*mFrameTimeline, *this);
    
    mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, displayId,
                                            displayState.physical->activeMode->getId(),
                                            vsyncPeriod);
    static auto ignorePresentFences =
            base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false);
    mScheduler->setIgnorePresentFences(
            ignorePresentFences ||
            getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE));
}

-->VsyncSchedule.cpp-->SurfaceFlingerDefaultFactory.cpp-->createScheduler()

std::unique_ptr<Scheduler> DefaultFactory::createScheduler(
        const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback) {
    return std::make_unique<Scheduler>(configs, callback);//将sf传进Shceduler的构造函数 依次调用构造函数
}

Scheduler.cpp 构造函数

​
Scheduler::Scheduler(const scheduler::RefreshRateConfigs& configs, ISchedulerCallback& callback,
                     Options options)
      : Scheduler(createVsyncSchedule(options.supportKernelTimer), configs, callback,
                  createLayerHistory(configs), options) {}
-->createVsyncSchedule(options.supportKernelTimer)//调用到该方法 进行了初始化 在其中初始化了Vsync信号产生  分发相关类对象和运行逻辑

--->VsyncSchedule-->引出如下

  • VSyncTracker
  • VSyncReactor
  • VSyncDispatch
struct VsyncSchedule {
    std::unique_ptr<scheduler::VsyncController> controller;
    std::unique_ptr<scheduler::VSyncTracker> tracker;
    std::unique_ptr<scheduler::VSyncDispatch> dispatch;
};
Scheduler::VsyncSchedule Scheduler::createVsyncSchedule(bool supportKernelTimer) {
    auto clock = std::make_unique<scheduler::SystemClock>();//clock
    auto tracker = createVSyncTracker();//创建VsyncTracker对象
    auto dispatch = createVSyncDispatch(*tracker);;//创建VsyncDispatchr对象
    constexpr size_t pendingFenceLimit = 20;
  //创建 VSyncReactor
    auto controller =
            std::make_unique<scheduler::VSyncReactor>(std::move(clock), *tracker, pendingFenceLimit,                                               supportKernelTimer);
    return {std::move(controller), std::move(tracker), std::move(dispatch)};//封装在一个VsyncScheduler struct里 引出VsyncSchedule
}
std::unique_ptr<scheduler::VSyncTracker> createVSyncTracker() {
    // TODO(b/144707443): Tune constants.
    constexpr int kDefaultRate = 60;
    constexpr auto initialPeriod = std::chrono::duration<nsecs_t, std::ratio<1, kDefaultRate>>(1);
    constexpr nsecs_t idealPeriod =
            std::chrono::duration_cast<std::chrono::nanoseconds>(initialPeriod).count();
    constexpr size_t vsyncTimestampHistorySize = 20;
    constexpr size_t minimumSamplesForPrediction = 6;///模拟Vsync最少采样个数
    constexpr uint32_t discardOutlierPercent = 20;
    return std::make_unique<scheduler::VSyncPredictor>(idealPeriod, vsyncTimestampHistorySize,
                                                       minimumSamplesForPrediction,
                                                       discardOutlierPercent);
}
//创建VSyncDispatch  该类主要负责注册监听事件的对象,等Vsync信号一来就回调回去,相当于观察者
//目录 /frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatch.h
std::unique_ptr<scheduler::VSyncDispatch> createVSyncDispatch(scheduler::VSyncTracker& tracker) {
    // TODO(b/144707443): Tune constants.
    constexpr std::chrono::nanoseconds vsyncMoveThreshold = 3ms;
    constexpr std::chrono::nanoseconds timerSlack = 500us;
    return std::make_unique<
            scheduler::VSyncDispatchTimerQueue>(std::make_unique<scheduler::Timer>(), tracker,
                                                timerSlack.count(), vsyncMoveThreshold.count());
}

createConnection()

Scheduler.cpp
Scheduler::ConnectionHandle Scheduler::createConnection(
        const char* connectionName, frametimeline::TokenManager* tokenManager,
        std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration,
        impl::EventThread::InterceptVSyncsCallback interceptCallback) {
  //创建一个vsyncSource
    auto vsyncSource = makePrimaryDispSyncSource(connectionName, workDuration, readyDuration);
    auto throttleVsync = makeThrottleVsyncCallback();
    auto getVsyncPeriod = makeGetVsyncPeriodFunction();
  //创建一个eventThread
    auto eventThread = std::make_unique<impl::EventThread>(std::move(vsyncSource), tokenManager,
                                                           std::move(interceptCallback),
                                                           std::move(throttleVsync),
                                                           std::move(getVsyncPeriod));
    return createConnection(std::move(eventThread));
}
------->
​
Scheduler::ConnectionHandle Scheduler::createConnection(std::unique_ptr<EventThread> eventThread) {
    //创建一个handle
    const ConnectionHandle handle = ConnectionHandle{mNextConnectionHandleId++};
  
    auto connection = createConnectionInternal(eventThread.get());
​
    std::lock_guard<std::mutex> lock(mConnectionsLock);
  //将key-value 存在map里 
    mConnections.emplace(handle, Connection{connection, std::move(eventThread)});
  //就创建了一个handle 存入map 将handle 返回去
    return handle;
}
​
----->
sp<EventThreadConnection> Scheduler::createConnectionInternal(
        EventThread* eventThread, ISurfaceComposer::EventRegistrationFlags eventRegistration) {
    return eventThread->createEventConnection([&] { resync(); }, eventRegistration);
}
​
​

DispSyncSource.cpp

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

DispSyncSource::DispSyncSource(scheduler::VSyncDispatch& vSyncDispatch,
                               std::chrono::nanoseconds workDuration,
                               std::chrono::nanoseconds readyDuration, bool traceVsync,
                               const char* name)
      : mName(name),
        mValue(base::StringPrintf("VSYNC-%s", name), 0),
        mTraceVsync(traceVsync),
        mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
        mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
        mReadyDuration(readyDuration) {
          //绑定回调callback
     
    mCallbackRepeater =
            std::make_unique<CallbackRepeater>(vSyncDispatch,
                                               std::bind(&DispSyncSource::onVsyncCallback, this,
                                                         std::placeholders::_1,
                                                         std::placeholders::_2,
                                                         std::placeholders::_3),
                                               name, workDuration, readyDuration,
                                               std::chrono::steady_clock::now().time_since_epoch());
}
​
  VSyncCallbackRegistration mRegistration GUARDED_BY(mMutex);

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

VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncDispatch& dispatch,
                                                     VSyncDispatch::Callback const& callbackFn,
                                                     std::string const& callbackName)
      : mDispatch(dispatch),
        mToken(dispatch.registerCallback(callbackFn, callbackName)),
        mValidToken(true) {}
​
​
​
---->
VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
        Callback const& callbackFn, std::string callbackName) {
    std::lock_guard lock(mMutex);
  //mCallbacks-->指向DispSyncSource
    return CallbackToken{
            mCallbacks
                    .emplace(++mCallbackToken,
                             std::make_shared<VSyncDispatchTimerQueueEntry>(callbackName,
                                                                            callbackFn,
                                                                            mMinVsyncDistance))
                    .first->first};
}

Choreographer大体流程

Choreographer的构造函数中 有一个 mDisplayEventReceiver  是负责接收Vsync信号的接收器
mDisplayEventReceiver的构造函数有nativeInit()方法
  调用到android_view_DisplayEventReceiver的nativeInit()
  还有一个 mCallbackQueues 负责维护关心刷新的对象 包含 ViewRootImp,TextView ,ValueAniator等
​
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj,
                        jint vsyncSource, jint eventRegistration) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }
​
    sp<NativeDisplayEventReceiver> receiver =
            new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,
                                           eventRegistration);
    status_t status = receiver->initialize();
    if (status) {
        String8 message;
        message.appendFormat("Failed to initialize display event receiver.  status=%d", status);
        jniThrowRuntimeException(env, message.string());
        return 0;
    }
​
    receiver->incStrong(gDisplayEventReceiverClassInfo.clazz); // retain a reference for the object
    return reinterpret_cast<jlong>(receiver.get());
}

总结基础路程

资料

developer.aliyun.com/article/921…

ViewRootImp

void scheduleTraversals() {
    if (!mTraversalScheduled) {
        mTraversalScheduled = true;
        mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
        mChoreographer.postCallback(
                Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        notifyRendererOfFramePending();
        pokeDrawLockIfNeeded();
    }
}
  1. requestLayout();/invalidate()//触发视图更新

  2. mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); 添加消息屏障,,阻塞住所有同步消息,此刻主线程添加的所有消息都无法执行,只能执行异步任务

  3. 注册异步消息 但是会后执行 mChoreographer.postCallback( Choreog rapher.CALLBACK_TRAVERSAL, mTraversalRunnable, null); 将要执行的数据传入编舞者,mTraversalRunnable做了三件事 设置mTraversalScheduled标识位为false。

    移除同步屏障

    执行performTraversals方法,开始绘制

  4. scheduleFrameLocked(now); //向fr层注册VSync信号

  5. 当底层产生一个VSync信号时,会发送给编舞者的DisplayEventReceiver,给到Choreographer

  6. Choreographer收到该信号,开始执行 FrameDisplayEventReceiver->onVsync () 发送消息到主线程(FrameHandler) 执行FrameDisplayEventReceiver里的run方法,执行doFrame,