SurfaceFlinger 合成
简介
本节会来介绍SurfaceFlinger的核心函数:合成,这个也是SurfaceFLinger最重要的功能之一。
前面我们介绍过应用的窗口怎么把图元Buffer,窗口属性传递给SurfaceFlinger,而SurfaceFlinger就是要讲这些信息整合在一起,然后讲各个应用的窗口全部都合成一个,最后送到drm驱动中去显示。
这个过程有大量计算机图像绘制使用的变量,还有一些gles的使用,有的我们会简单提一下,不关心的可以跳过这些,看一下总体的流程。
接下来,我们就接着VSync信号那章3.8节,SurfaceFlinger收到VSync信号后开始学习。
SurfaceFlinger 处理VSync信号
这里compositor就是SurfaceFlinger
void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
TimePoint expectedVsyncTime) {
const TimePoint frameTime = SchedulerClock::now();
// 做合成的一些预处理,判断flag决策是否需要合成,详见1.1
if (!compositor.commit(frameTime, vsyncId, expectedVsyncTime)) {
return;
}
// 触发合成。详见2.1
compositor.composite(frameTime, vsyncId);
compositor.sample();
}
SurfaceFlinger::commit
1.1 SurfaceFlinger::commit
数据预处理,判断是否需要进行合成。
bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime)
FTL_FAKE_GUARD(kMainThreadContext) {
// 这里expectedVsyncTime一般是未来的时间,而frameTime之前传的是now
// 如果expectedVsyncTime > frameTime,一般是正常情况,直接使用expectedVsyncTime作为预期时间,否则一般是帧延迟了,重新算一个VSync时间。
const TimePoint lastScheduledPresentTime = mScheduledPresentTime;
mScheduledPresentTime = expectedVsyncTime;
mExpectedPresentTime = expectedVsyncTime >= frameTime ? expectedVsyncTime
: calculateExpectedPresentTime(frameTime);
const Period vsyncPeriod = mScheduler->getVsyncSchedule()->period();
// 获取上一帧合成的fence,每次提交合成后会存一个fence到mPreviousPresentFences数组变量里。
const FenceTimePtr& previousPresentFence = getPreviousPresentFence(frameTime, vsyncPeriod);
// backpressure propagation模式下,Fence没有好,我们可以适当延迟等待,而不是直接放弃当前帧
const int graceTimeForPresentFenceMs = static_cast<int>(
mBackpressureGpuComposition || !mCompositionCoverage.test(CompositionCoverage::Gpu));
// isFencePending会调用fence wait判断上一帧合成是否完成。
// 之前提过,fence是跨越设备的锁,我们在上一次合成中只是向gpu或者hwc发送了指令,通过fence可以确定他们是否完成了任务
// 之前,如果上一帧fence还没有释放,这里会返回false
const TracedOrdinal<bool> framePending = {"PrevFramePending",
isFencePending(previousPresentFence,
graceTimeForPresentFenceMs)};
// 这里的逻辑是同于统计丢帧
const nsecs_t frameMissedSlop = vsyncPeriod.ns() / 2;
const nsecs_t previousPresentTime = previousPresentFence->getSignalTime();
// 如果上一帧fence还没释放,或者上一次完成的时间远大于上一次VSync预期的时间,我们都认为是丢帧了。
const TracedOrdinal<bool> frameMissed = {"PrevFrameMissed",
framePending ||
(previousPresentTime >= 0 &&
(lastScheduledPresentTime.ns() <
previousPresentTime - frameMissedSlop))};
// 是否是hwc合成丢帧
const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
frameMissed &&
mCompositionCoverage.test(
CompositionCoverage::Hwc)};
// 是否是SurfaceFlinger丢帧
const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
frameMissed &&
mCompositionCoverage.test(
CompositionCoverage::Gpu)};
// 根据前面的判断加一下计数
if (frameMissed) {
mFrameMissedCount++;
mTimeStats->incrementMissedFrames();
}
if (hwcFrameMissed) {
mHwcFrameMissedCount++;
}
if (gpuFrameMissed) {
mGpuFrameMissedCount++;
}
if (mTracingEnabledChanged) {
mLayerTracingEnabled = mLayerTracing.isEnabled();
mTracingEnabledChanged = false;
}
// 如果是需要更新刷新率模式,上一次合成没完成,就直接等下一个VSync再处理。
if (mSetActiveModePending) {
if (framePending) {
mScheduler->scheduleFrame();
return false;
}
// 更新刷新率模式
mSetActiveModePending = false;
{
Mutex::Autolock lock(mStateLock);
updateInternalStateWithChangedMode();
}
}
// backpressure propagation前面已经有延迟依旧没有完成,那只能请求下一帧VSync再进行合成。
if (framePending) {
if (mBackpressureGpuComposition || (hwcFrameMissed && !gpuFrameMissed)) {
scheduleCommit(FrameHint::kNone);
return false;
}
}
// 。。。每次commit和composite都会通过PowerAdvisor记录一些时间信息,应该是用作功耗统计使用
// 开发者模式里显示刷新率的逻辑
if (mRefreshRateOverlaySpinner) {
Mutex::Autolock lock(mStateLock);
if (const auto display = getDefaultDisplayDeviceLocked()) {
display->animateRefreshRateOverlay();
}
}
// 判断是否需要composite
bool mustComposite = mMustComposite.exchange(false);
{
mFrameTimeline->setSfWakeUp(vsyncId.value, frameTime.ns(),
Fps::fromPeriodNsecs(vsyncPeriod.ns()));
// 检测Flag来决定是否需要调用flushLifecycleUpdates
// 在Transaction的章节里我们提过,当通过binder把Transaction传给SurfaceFlinger后,SurfaceFlinger会封装参数后放入一个队列中
// flushLifecycleUpdates就是去处理队列的时机
// 主要是将ready的TransactionState和之前收到请求需要添加以及销毁窗口的信息都封装到Update对象内,详见1.2
const bool flushTransactions = clearTransactionFlags(eTransactionFlushNeeded);
frontend::Update updates;
if (flushTransactions) {
updates = flushLifecycleUpdates();
//。。。tracing
}
bool transactionsAreEmpty;
// mLegacyFrontEndEnabled和mLayerLifecycleManagerEnabled只有一个为ture,应该是两套算法逻辑,会根据一个系统属性来决定,都是更新layer中的Snapshot的
// 因为我看我的手机的属性应该是走的mLegacyFrontEndEnabled true的逻辑,我们这里就看这条线,详见1.3
if (mLegacyFrontEndEnabled) {
mustComposite |= updateLayerSnapshotsLegacy(vsyncId, updates, flushTransactions,
transactionsAreEmpty);
}
if (mLayerLifecycleManagerEnabled) {
mustComposite |=
updateLayerSnapshots(vsyncId, updates, flushTransactions, transactionsAreEmpty);
}
if (transactionFlushNeeded()) {
setTransactionFlags(eTransactionFlushNeeded);
}
// 回调通知,在releasePendingBuffer时候,会addCallbackHandles,然后这里会回调client侧,然后client进行BufferRelease
if (transactionsAreEmpty) {
mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
} else {
mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
}
}
// 处理刷新率更新
{
Mutex::Autolock lock(mStateLock);
mScheduler->chooseRefreshRateForContent();
setActiveModeInHwcIfNeeded();
}
updateCursorAsync();
// 更新inputFlinger focused窗口
updateInputFlinger(vsyncId, frameTime);
// 。。。
persistDisplayBrightness(mustComposite);
// 返回是否需要合成
return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}
1.2 SurfaceFlinger::flushLifecycleUpdates
这里其实没有真的去处理这些TransactionState,只是将已经处于Ready状态的Transaction都存到update.transactions里
同时会讲之前存在mNewLayers,mCreatedLayers里需要添加或者mDestroyedHandles需要删除的窗口也封装到update里。
这样窗口的变化信息都在update里了。
frontend::Update SurfaceFlinger::flushLifecycleUpdates() {
frontend::Update update;
// 处理之前setTransactionState放入队列的任务
// 会把所有Ready状态到TransactionState返回回来,然后存在update.transactions,详见1.2.1
update.transactions = mTransactionHandler.flushTransactions();
{
// 当client侧通过binder请求SurfaceFlinger,SurfaceFlinger会将参数放到mNewLayers,mCreatedLayers里,这个在SurfaceFlinger binder框架2.2节提到过
// 这里会把参数都提取出来,全部都放到Update里面
std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
update.layerCreatedStates = std::move(mCreatedLayers);
mCreatedLayers.clear();
update.newLayers = std::move(mNewLayers);
mNewLayers.clear();
update.layerCreationArgs = std::move(mNewLayerArgs);
mNewLayerArgs.clear();
update.destroyedHandles = std::move(mDestroyedHandles);
mDestroyedHandles.clear();
}
return update;
}
1.2.1 TransactionHandler::flushTransactions
这里mLocklessTransactionQueue是之前Transaction章节提到的SurfaceFlinger通过queueTransaction放入队列的TransactionState对象。
这里把队列的对象都取出来,存到mPendingTransactionQueues这个map里,这个map的key是窗口的token,value是TransactionState队列。
然后循环调用flushPendingTransactionQueues,flushPendingTransactionQueues本身就会遍历所有的TransactionState,这里之所以还要加一个循环是因为有屏障逻辑。
在acquireNextBufferLocked的时候如果没有立刻将Transaction传给SurfaceFlinger的情况,就会设置一个barrier,表示新的这个Transaction的处理必须要依赖上一个Transaction的完成。
所以这里flushPendingTransactionQueues即使遍历了所有的窗口,也不一定能一次性完成,需要到没有更多可以处理的TransactionState才算完成。
所有Ready的TransactionState在flushPendingTransactionQueues过程中都会被存储到transactions中最后作为返回值返回。
std::vector<TransactionState> TransactionHandler::flushTransactions() {
while (!mLocklessTransactionQueue.isEmpty()) {
// 之前讲Transaction到章节最后我们提到,Transaction里面的内容被封装成TransactionState,通过queueTransaction放到队列中
// 就是放在了mLocklessTransactionQueue中
// 这里取出来的就是TransactionState
auto maybeTransaction = mLocklessTransactionQueue.pop();
// 过滤异常的State
if (!maybeTransaction.has_value()) {
break;
}
auto transaction = maybeTransaction.value();
// 把有效都TransactionState放到mPendingTransactionQueues中。
// mPendingTransactionQueues是一个map,key是窗口token,value是TransactionState队列,
mPendingTransactionQueues[transaction.applyToken].emplace(std::move(transaction));
}
std::vector<TransactionState> transactions;
TransactionFlushState flushState;
flushState.queueProcessTime = systemTime();
// 循环执行flushPendingTransactionQueues,这里需要循环的原因上面已经说了,主要是处理有barrier的Transaction。
int lastTransactionsPendingBarrier = 0;
int transactionsPendingBarrier = 0;
do {
// 这里比较两次flushPendingTransactionQueues后由于barrier未就绪的Transaction个数,如果一样说明不需要再继续执行flushPendingTransactionQueues
lastTransactionsPendingBarrier = transactionsPendingBarrier;
// 会把所有ready状态的TransactionState存储到transactions,详见1.2.2
transactionsPendingBarrier = flushPendingTransactionQueues(transactions, flushState);
} while (lastTransactionsPendingBarrier != transactionsPendingBarrier);
applyUnsignaledBufferTransaction(transactions, flushState);
mPendingTransactionCount.fetch_sub(transactions.size());
ATRACE_INT("TransactionQueue", static_cast<int>(mPendingTransactionCount.load()));
return transactions;
}
1.2.2 TransactionHandler::flushPendingTransactionQueues
通过applyFilters逐个判断TrasactionState是否ready,主要是判断两个点:
1.时间, 通过SurfaceFlinger::transactionReadyTimelineCheck判断
2.barrier是否就绪,通过SurfaceFlinger::transactionReadyBufferCheck判断
这里就不详细看了,感兴趣可以自己去看下。把ready的TransactionState都存储到transactions里。
int TransactionHandler::flushPendingTransactionQueues
(std::vector<TransactionState>& transactions,
TransactionFlushState& flushState) {
int transactionsPendingBarrier = 0;
// 遍历所有TransactionState
auto it = mPendingTransactionQueues.begin();
while (it != mPendingTransactionQueues.end()) {
auto& [applyToken, queue] = *it;
while (!queue.empty()) {
auto& transaction = queue.front();
flushState.transaction = &transaction;
// 判断Transaction当前是否ready,比如有barrier的,依赖的前置Transaction是否已经执行了
// 或者是期望的时间还没有到
auto ready = applyFilters(flushState);
if (ready == TransactionReadiness::NotReadyBarrier) {
// 统计barrier没有就绪的个数,如果两次循环执行flushPendingTransactionQueues这个数量未改变,就不用再继续循环了,需要等下一帧再处理
transactionsPendingBarrier++;
break;
} else if (ready == TransactionReadiness::NotReady) {
break;
} else if (ready == TransactionReadiness::NotReadyUnsignaled) {
flushState.queueWithUnsignaledBuffer = applyToken;
break;
}
// 走到这的Transaction就是已经处于ready状态了,详见1.2.3
popTransactionFromPending(transactions, flushState, queue);
}
if (queue.empty()) {
it = mPendingTransactionQueues.erase(it);
} else {
it = std::next(it, 1);
}
}
// 返回由于barrier未就绪导致未处理的Transcaion个数
return transactionsPendingBarrier;
}
1.2.3 TransactionHandler::popTransactionFromPending
将TransactionState加到transactions队列里,然后如果有必要就更新了flushState.bufferLayersReadyToPresent里面窗口对应的frameNumber。
void TransactionHandler::popTransactionFromPending(std::vector<TransactionState>& transactions,
TransactionFlushState& flushState,
std::queue<TransactionState>& queue) {
auto& transaction = queue.front();
// Transaction is ready move it from the pending queue.
flushState.firstTransaction = false;
removeFromStalledTransactions(transaction.id);
// 将TransactionState加到transactions队列里。
transactions.emplace_back(std::move(transaction));
queue.pop();
auto& readyToApplyTransaction = transactions.back();
readyToApplyTransaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
const bool frameNumberChanged =
state.bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
// bufferLayersReadyToPresent是一个map,key是窗口的handle,value是帧号。
if (frameNumberChanged) {
flushState.bufferLayersReadyToPresent.emplace_or_replace(state.surface.get(),
state.bufferData->frameNumber);
} else {
flushState.bufferLayersReadyToPresent
.emplace_or_replace(state.surface.get(), std::numeric_limits<uint64_t>::max());
}
});
}
1.3 SurfaceFlinger::updateLayerSnapshotsLegacy
这个方法是commit的关键方法,会调用commitCreatedLayers处理添加layer的请求
调用applyTransactions处理通过Transactions请求layer的属性变化
通过调用commitTransactions,处理一些存储在pengding变量里的layer增删操作旋转等,还会将我们前面存储在临时变量的属性(比如mCurrentState)同步到当前使用的属性中去(比如mDrawingState)
最终还调用了latchBuffers去获取了所有新的buffer(如果layer有内容更新则需要获取新buffer),存到BufferInfo中。
bool SurfaceFlinger::updateLayerSnapshotsLegacy(VsyncId vsyncId, frontend::Update& update,
bool transactionsFlushed,