基础概念梳理
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();
}
}
-
requestLayout();/invalidate()//触发视图更新
-
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier(); 添加消息屏障,,阻塞住所有同步消息,此刻主线程添加的所有消息都无法执行,只能执行异步任务
-
注册异步消息 但是会后执行 mChoreographer.postCallback( Choreog rapher.CALLBACK_TRAVERSAL, mTraversalRunnable, null); 将要执行的数据传入编舞者,mTraversalRunnable做了三件事 设置
mTraversalScheduled标识位为false。移除
同步屏障。执行
performTraversals方法,开始绘制 -
scheduleFrameLocked(now); //向fr层注册VSync信号
-
当底层产生一个VSync信号时,会发送给编舞者的DisplayEventReceiver,给到Choreographer
-
Choreographer收到该信号,开始执行 FrameDisplayEventReceiver->onVsync () 发送消息到主线程(FrameHandler) 执行FrameDisplayEventReceiver里的run方法,执行doFrame,