欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > Android12 显示框架之Transaction----server端

Android12 显示框架之Transaction----server端

2024/10/24 11:12:43 来源:https://blog.csdn.net/yzq_yezhiqiang/article/details/141347891  浏览:    关键词:Android12 显示框架之Transaction----server端

目录: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 pendingauto itr = mPendingTransactionQueues.find(state.applyToken);// if this is an animation frame, wait until prior animation frame has// been applied by SFif (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 lockstd::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.cppvoid 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 nowif (!(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.cppvoid 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 fromfor (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 statemCurrentState.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的情况去考虑具体的合成及送显情形了。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com