目录:Android显示终极宝典
上篇讲完了在client端Transaction的内容,最后调用setTransactionState()把所有的参数都交给了surfaceflinger,那么任务就交给server来完成了。本节我们一起接着看看下面的内容。
setTransactionState()
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
status_t SurfaceFlinger::setTransactionState(
const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
ATRACE_CALL();
uint32_t permissions =
callingThreadHasUnscopedSurfaceFlingerAccess() ? Permission::ACCESS_SURFACE_FLINGER : 0;
// Avoid checking for rotation permissions if the caller already has ACCESS_SURFACE_FLINGER
// permissions.
if ((permissions & Permission::ACCESS_SURFACE_FLINGER) ||
callingThreadHasRotateSurfaceFlingerAccess()) {
permissions |= Permission::ROTATE_SURFACE_FLINGER;
}
if (!(permissions & Permission::ACCESS_SURFACE_FLINGER) &&
(flags & (eEarlyWakeupStart | eEarlyWakeupEnd))) {
ALOGE("Only WindowManager is allowed to use eEarlyWakeup[Start|End] flags");
flags &= ~(eEarlyWakeupStart | eEarlyWakeupEnd);
}
const int64_t postTime = systemTime();
IPCThreadState* ipc = IPCThreadState::self();
const int originPid = ipc->getCallingPid();
const int originUid = ipc->getCallingUid();
TransactionState state{frameTimelineInfo, states,
displays, flags,
applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp,
uncacheBuffer, postTime,
permissions, hasListenerCallbacks,
listenerCallbacks, originPid,
originUid, transactionId};
// Check for incoming buffer updates and increment the pending buffer count.
state.traverseStatesWithBuffers([&](const layer_state_t& state) {
mBufferCountTracker.increment(state.surface->localBinder());
});
queueTransaction(state);
// Check the pending state to make sure the transaction is synchronous.
if (state.transactionCommittedSignal) {
waitForSynchronousTransaction(*state.transactionCommittedSignal);
}
return NO_ERROR;
}
这段代码主要看queueTransaction(),其他内容大概知道怎么回事就可以了。client传进来的参数会和其他临时创建的变量一起被构建成一个TransactionState,将其送入queueTransaction()基于此来执行后续流程。
queueTransaction()
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::queueTransaction(TransactionState& state) {
Mutex::Autolock _l(mQueueLock);
// If its TransactionQueue already has a pending TransactionState or if it is pending
auto itr = mPendingTransactionQueues.find(state.applyToken);
// if this is an animation frame, wait until prior animation frame has
// been applied by SF
if (state.flags & eAnimation) {
while (itr != mPendingTransactionQueues.end()) {
status_t err = mTransactionQueueCV.waitRelative(mQueueLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
ALOGW_IF(err == TIMED_OUT,
"setTransactionState timed out "
"waiting for animation frame to apply");
break;
}
itr = mPendingTransactionQueues.find(state.applyToken);
}
}
// Generate a CountDownLatch pending state if this is a synchronous transaction.
if ((state.flags & eSynchronous) || state.inputWindowCommands.syncInputWindows) {
state.transactionCommittedSignal = std::make_shared<CountDownLatch>(
(state.inputWindowCommands.syncInputWindows
? (CountDownLatch::eSyncInputWindows | CountDownLatch::eSyncTransaction)
: CountDownLatch::eSyncTransaction));
}
mTransactionQueue.emplace(state);
ATRACE_INT("TransactionQueue", mTransactionQueue.size());
const auto schedule = [](uint32_t flags) {
if (flags & eEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;
if (flags & eEarlyWakeupStart) return TransactionSchedule::EarlyStart;
return TransactionSchedule::Late;
}(state.flags);
setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken);
}
这段代码主要看三点:
- mTransactionQueue.emplace(state):将state存储起来,后面在另一个线程处理。
- 获取schedule值:这个一般情况比如本地播放等结果为TransactionSchedule::Late,EarlyStart和EarlyEnd则是WMS在切换窗口时设置,这里不考虑这种特殊case。
- setTransactionFlags():根据flags及mTransactionFlags旧值决定本次是否发起invalidate消息。该函数内的modulateVsync()在当前内容中暂时不关心。
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::signalTransaction() {
mScheduler->resetIdleTimer();
mPowerAdvisor.notifyDisplayUpdateImminent();
mEventQueue->invalidate();
}
假设本次执行signalTransaction(),跑完mEventQueue->invalidate()之后,后面的执行流程是个什么样子呢?简单画图会比较直白方便大家理解一些:
具体代码大家可以依据图中连线上的接口名称去看code,这里简单描述下过程:signalTransaction()执行之后,代码逻辑会经有MessageQueue+VSyncDispatch+Timer这三者,最终把Transaction需要处理的信息送达surfaceflinger主线程进行处理。
handleMessageTransaction()
接下来直接看handleMessageTransaction():
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
bool SurfaceFlinger::handleMessageTransaction() {
ATRACE_CALL();
if (getTransactionFlags(eTransactionFlushNeeded)) {
flushTransactionQueues();
}
uint32_t transactionFlags = peekTransactionFlags();
bool runHandleTransaction =
((transactionFlags & (~eTransactionFlushNeeded)) != 0) || mForceTraversal;
if (runHandleTransaction) {
handleTransaction(eTransactionMask);
}
if (transactionFlushNeeded()) {
setTransactionFlags(eTransactionFlushNeeded);
}
return runHandleTransaction;
}
这里注意getTransactionFlags()函数传入的eTransactionFlushNeeded,也就是说之前必须设置过eTransactionFlushNeeded标志位才会真正的执行flushTransactionQueues(),执行完以后还要清除掉mTransactionFlags中的eTransactionFlushNeeded标志位。
flushTransactionQueues()
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::flushTransactionQueues() {
// to prevent onHandleDestroyed from being called while the lock is held,
// we must keep a copy of the transactions (specifically the composer
// states) around outside the scope of the lock
std::vector<const TransactionState> transactions;
// Layer handles that have transactions with buffers that are ready to be applied.
std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>> bufferLayersReadyToPresent;
{
Mutex::Autolock _l(mStateLock);
{
Mutex::Autolock _l(mQueueLock);
// Collect transactions from pending transaction queue.
auto it = mPendingTransactionQueues.begin();
while (it != mPendingTransactionQueues.end()) {
auto& [applyToken, transactionQueue] = *it;
while (!transactionQueue.empty()) {
auto& transaction = transactionQueue.front();
if (!transactionIsReadyToBeApplied(transaction.frameTimelineInfo,
transaction.isAutoTimestamp,
transaction.desiredPresentTime,
transaction.originUid, transaction.states,
bufferLayersReadyToPresent)) {
setTransactionFlags(eTransactionFlushNeeded);
break;
}
transaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
bufferLayersReadyToPresent.insert(state.surface);
});
transactions.emplace_back(std::move(transaction));
transactionQueue.pop();
}
if (transactionQueue.empty()) {
it = mPendingTransactionQueues.erase(it);
mTransactionQueueCV.broadcast();
} else {
it = std::next(it, 1);
}
}
// Collect transactions from current transaction queue or queue to pending transactions.
// Case 1: push to pending when transactionIsReadyToBeApplied is false.
// Case 2: push to pending when there exist a pending queue.
// Case 3: others are ready to apply.
while (!mTransactionQueue.empty()) {
auto& transaction = mTransactionQueue.front();
bool pendingTransactions = mPendingTransactionQueues.find(transaction.applyToken) !=
mPendingTransactionQueues.end();
if (pendingTransactions ||
!transactionIsReadyToBeApplied(transaction.frameTimelineInfo,
transaction.isAutoTimestamp,
transaction.desiredPresentTime,
transaction.originUid, transaction.states,
bufferLayersReadyToPresent)) {
mPendingTransactionQueues[transaction.applyToken].push(std::move(transaction));
} else {
transaction.traverseStatesWithBuffers([&](const layer_state_t& state) {
bufferLayersReadyToPresent.insert(state.surface);
});
transactions.emplace_back(std::move(transaction));
}
mTransactionQueue.pop();
ATRACE_INT("TransactionQueue", mTransactionQueue.size());
}
}
// Now apply all transactions.
for (const auto& transaction : transactions) {
applyTransactionState(transaction.frameTimelineInfo, transaction.states,
transaction.displays, transaction.flags,
transaction.inputWindowCommands, transaction.desiredPresentTime,
transaction.isAutoTimestamp, transaction.buffer,
transaction.postTime, transaction.permissions,
transaction.hasListenerCallbacks, transaction.listenerCallbacks,
transaction.originPid, transaction.originUid, transaction.id);
if (transaction.transactionCommittedSignal) {
mTransactionCommittedSignals.emplace_back(
std::move(transaction.transactionCommittedSignal));
}
}
}
}
第一个while循环检查mPendingTransactionQueues中的transaction是否已经准备好被apply,如果是则记录到临时transactions的vector中,否则重新设置eTransactionFlushNeeded。
第二个while循环则是对queueTransaction()中新添加的mTransactionQueue遍历检查是否可以被apply,如果可以则将其移入transactions中,否则放入mPendingTransactionQueues中。
mTransactionQueue数量的变化过程可以在perfetto中直观的看到,它在哪个阶段增加的哪个阶段消耗的一目了然:
两个循环中都使用到了transactionIsReadyToBeApplied()方法来辅助判断是否能被apply,该函数的主体功能就是:通过检查期望显示的时间戳、vsync时间戳是否与帧率同步、acquireFence是否已signaled以及buffer的状态来判断当前事务是否已经准备好。
最后一个for循环则是对上面收集到的transactions开始进行apply。
applyTransactionState()
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelineInfo,
const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
const int64_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& uncacheBuffer,
const int64_t postTime, uint32_t permissions,
bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks,
int originPid, int originUid, uint64_t transactionId) {
uint32_t transactionFlags = 0;
for (const DisplayState& display : displays) {
transactionFlags |= setDisplayStateLocked(display);
}
// start and end registration for listeners w/ no surface so they can get their callback. Note
// that listeners with SurfaceControls will start registration during setClientStateLocked
// below.
for (const auto& listener : listenerCallbacks) {
mTransactionCallbackInvoker.startRegistration(listener);
mTransactionCallbackInvoker.endRegistration(listener);
}
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash> listenerCallbacksWithSurfaces;
uint32_t clientStateFlags = 0;
for (const ComposerState& state : states) {
clientStateFlags |=
setClientStateLocked(frameTimelineInfo, state, desiredPresentTime, isAutoTimestamp,
postTime, permissions, listenerCallbacksWithSurfaces);
if ((flags & eAnimation) && state.state.surface) {
if (const auto layer = fromHandle(state.state.surface).promote(); layer) {
mScheduler->recordLayerHistory(layer.get(),
isAutoTimestamp ? 0 : desiredPresentTime,
LayerHistory::LayerUpdateType::AnimationTX);
}
}
}
for (const auto& listenerCallback : listenerCallbacksWithSurfaces) {
mTransactionCallbackInvoker.endRegistration(listenerCallback);
}
// If the state doesn't require a traversal and there are callbacks, send them now
if (!(clientStateFlags & eTraversalNeeded) && hasListenerCallbacks) {
mTransactionCallbackInvoker.sendCallbacks();
}
transactionFlags |= clientStateFlags;
if (permissions & Permission::ACCESS_SURFACE_FLINGER) {
transactionFlags |= addInputWindowCommands(inputWindowCommands);
} else if (!inputWindowCommands.empty()) {
ALOGE("Only privileged callers are allowed to send input commands.");
}
if (uncacheBuffer.isValid()) {
ClientCache::getInstance().erase(uncacheBuffer);
}
// If a synchronous transaction is explicitly requested without any changes, force a transaction
// anyway. This can be used as a flush mechanism for previous async transactions.
// Empty animation transaction can be used to simulate back-pressure, so also force a
// transaction for empty animation transactions.
if (transactionFlags == 0 &&
((flags & eSynchronous) || (flags & eAnimation))) {
transactionFlags = eTransactionNeeded;
}
if (transactionFlags) {
if (mInterceptor->isEnabled()) {
mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags,
originPid, originUid, transactionId);
}
// We are on the main thread, we are about to preform a traversal. Clear the traversal bit
// so we don't have to wake up again next frame to preform an unnecessary traversal.
if (transactionFlags & eTraversalNeeded) {
transactionFlags = transactionFlags & (~eTraversalNeeded);
mForceTraversal = true;
}
if (transactionFlags) {
setTransactionFlags(transactionFlags);
}
if (flags & eAnimation) {
mAnimTransactionPending = true;
}
}
}
第一个for循环暂时不用关注,因为一般情况下transaction不会去设置DisplayState。
第二个for循环也不用看,传进来为空。实际的ListenerCallbacks保存在ComposerState的state.listeners中。
第三个for循环才是重点内容:setClientStateLocked()
setClientStateLocked()
这个函数很长很长,这里不贴代码了。主要做了如下的工作:
- 提取并设置回调机制的必要步骤。
- 获取handle对应的layer,根据client设置的layer_state_t信息去填充layer的mDrawingState变量,关于layerstack的信息保存在surfaceflinger的mCurrentState中。
- 根据listener构建CallbackHandle并将它们保存到mDrawingState.callbackHandles以及TransactionCallbackInvoker的mPendingTransactions中。
剩下来的内容都是围绕transactionFlags的标志来决定是否在主线程再发起setTransactionFlags()。
到此,flushTransactionQueues()执行完毕。
handleTransaction()
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) {
ATRACE_CALL();
// here we keep a copy of the drawing state (that is the state that's
// going to be overwritten by handleTransactionLocked()) outside of
// mStateLock so that the side-effects of the State assignment
// don't happen with mStateLock held (which can cause deadlocks).
State drawingState(mDrawingState);
Mutex::Autolock _l(mStateLock);
mDebugInTransaction = systemTime();
// Here we're guaranteed that some transaction flags are set
// so we can call handleTransactionLocked() unconditionally.
// We call getTransactionFlags(), which will also clear the flags,
// with mStateLock held to guarantee that mCurrentState won't change
// until the transaction is committed.
modulateVsync(&VsyncModulator::onTransactionCommit);
transactionFlags = getTransactionFlags(eTransactionMask);
handleTransactionLocked(transactionFlags);
mDebugInTransaction = 0;
// here the transaction has been committed
}
这里会先做一个动作,把mTransactionFlags给清零。然后再进行handleTransactionLocked():
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) {
//省略
commitTransaction();
}
这里主要看下commitTransaction()这个函数:
//frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::commitTransaction() {
ATRACE_CALL();
commitTransactionLocked();
signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
mAnimTransactionPending = false;
}
void SurfaceFlinger::commitTransactionLocked() {
if (!mLayersPendingRemoval.isEmpty()) {
// Notify removed layers now that they can't be drawn from
for (const auto& l : mLayersPendingRemoval) {
recordBufferingStats(l->getName(), l->getOccupancyHistory(true));
// Ensure any buffers set to display on any children are released.
if (l->isRemovedFromCurrentState()) {
l->latchAndReleaseBuffer();
}
// If the layer has been removed and has no parent, then it will not be reachable
// when traversing layers on screen. Add the layer to the offscreenLayers set to
// ensure we can copy its current to drawing state.
if (!l->getParent()) {
mOffscreenLayers.emplace(l.get());
}
}
mLayersPendingRemoval.clear();
}
// If this transaction is part of a window animation then the next frame
// we composite should be considered an animation as well.
mAnimCompositionPending = mAnimTransactionPending;
mDrawingState = mCurrentState;
// clear the "changed" flags in current state
mCurrentState.colorMatrixChanged = false;
if (mVisibleRegionsDirty) {
for (const auto& rootLayer : mDrawingState.layersSortedByZ) {
rootLayer->commitChildList();
}
}
commitOffscreenLayers();
if (mNumClones > 0) {
mDrawingState.traverse([&](Layer* layer) { layer->updateMirrorInfo(); });
}
}
这段代码的核心内容是更新绘制状态mCurrentState->mDrawingState,并根据脏区域标记的情况来遍历所有图层提交子图层列表。其他内容则是对已被移除图层的一些处理工作,且将必要的图层加入offscreen layers,然后遍历并处理所有的offscreen layers。
code走到这里,client端传递过来的Transaction的内容在server端已经基本被处理完了,后面的内容则是surfaceflinger根据各个layer的情况去考虑具体的合成及送显情形了。