上一篇文章介绍了 onFrameAvailable() 函数的流程,最终回调到了 BLASTBufferQueue 中,这里测处理跟 Android 老版本还是有区别的,在 BLASTBufferQueue 中通过提交事务的方式通知 SurfaceFlinger 进行更新,而不是老版本中的直接调用 SurfaceFlinger 中的对应函数。这里我们就来看一下 提交事务的通知流程。
一、提交事务
上一篇文章中的 t->setApplyToken(mApplyToken).apply() 其实调用的就是 SurfaceComposerClient 中的 apply() 函数。
1、SurfaceComposerClient.cpp
源码位置:/frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {……// 获取 SurfaceComposer 服务sp<ISurfaceComposer> sf(ComposerService::getComposerService());bool hasListenerCallbacks = !mListenerCallbacks.empty();std::vector<ListenerCallbacks> listenerCallbacks;// 处理监听器回调for (const auto& [listener, callbackInfo] : mListenerCallbacks) {auto& [callbackIds, surfaceControls] = callbackInfo;……if (surfaceControls.empty()) {listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));} else {// 如果侦听器在此事务上设置了任何surfacecontrol,则更新Surface状态for (const auto& surfaceControl : surfaceControls) {layer_state_t* s = getLayerState(surfaceControl);……std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end());s->what |= layer_state_t::eHasListenerCallbacksChanged;s->listeners.emplace_back(IInterface::asBinder(listener), callbacks);}}}……// 提交事务sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,hasListenerCallbacks, listenerCallbacks, mId);……
}
该方法是 SurfaceFlinger 客户端与服务端通信的关键部分,用于提交所有待处理的层和显示更改。通过这个方法,客户端可以控制层的显示属性、动画、同步模式以及监听器回调等,确保所有更改被原子性地应用到系统中。
2、SurfaceFlinger.cpp
源码位置:/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
setTransactionState
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) {……IPCThreadState* ipc = IPCThreadState::self();const int originPid = ipc->getCallingPid();const int originUid = ipc->getCallingUid();// 记录事务状态。创建一个 TransactionState 结构体,封装了事务的所有必要信息TransactionState state{frameTimelineInfo, states,displays, flags,applyToken, inputWindowCommands,desiredPresentTime, isAutoTimestamp,uncacheBuffer, postTime,permissions, hasListenerCallbacks,listenerCallbacks, originPid,originUid, transactionId};……if (mTransactionTracing) {mTransactionTracing->addQueuedTransaction(state);}// 将事务加入队列,准备处理。queueTransaction(state);// 检查挂起状态以确保事务是同步的.if (state.transactionCommittedSignal) {waitForSynchronousTransaction(*state.transactionCommittedSignal);}return NO_ERROR;
}
该方法是 SurfaceFlinger 服务端处理来自客户端事务请求的关键入口点。它不仅处理事务数据,还执行必要的权限检查,确保只有授权的客户端才能执行特定的操作。此外,它还支持事务的同步和异步执行,以及事务的追踪,这对于系统稳定性和性能优化至关重要。
queueTransaction
void SurfaceFlinger::queueTransaction(TransactionState& state) {state.queueTime = systemTime();Mutex::Autolock lock(mQueueLock);……// 加入事务队列mTransactionQueue.emplace_back(state);ATRACE_INT("TransactionQueue", mTransactionQueue.size());// 根据事务的标志位(state.flags)调用schedule lambda函数,确定事务的调度策略const auto schedule = [](uint32_t flags) {if (flags & eEarlyWakeupEnd) return TransactionSchedule::EarlyEnd;if (flags & eEarlyWakeupStart) return TransactionSchedule::EarlyStart;return TransactionSchedule::Late;}(state.flags);const auto frameHint = state.isFrameActive() ? FrameHint::kActive : FrameHint::kNone;// 设置事务标志setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken, frameHint);
}
该方法是 SurfaceFlinger 处理事务队列的核心部分,它不仅负责将事务加入队列,还根据事务的特性和需求调整了事务的调度策略,确保了事务能够按照预期的顺序和优先级得到处理。通过这种方式,SurfaceFlinger 能够有效地管理多个并发事务,保证系统的响应性和稳定性。
3、Scheduler
源码位置:/frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
schedule
// 在主线程上调度异步或同步任务
template <typename F, typename T = std::invoke_result_t<F>>
[[nodiscard]] std::future<T> schedule(F&& f) {// 创建Taskauto [task, future] = makeTask(std::move(f));// 接收一个任务对象,并将其发送到消息队列中postMessage(std::move(task));return std::move(future);
}
该函数允许用户以一种简洁的方式异步执行代码,并通过 std::future 管理异步操作的结果。这种设计模式在多线程编程中非常常见,尤其是在需要处理大量异步事件和任务的场景中。这里调用了 makeTask() 创建任务并将其发送到消息队列中。
Scheduler
源码位置:/frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features): impl::MessageQueue(compositor), mFeatures(features), mSchedulerCallback(callback) {}
可以看到 Scheduler 继承 MessageQueue,所以上面调用的是 MessageQueue 中的 makeTask() 函数。
4、MessageQueue
源码位置:/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h
makeTask
template <typename F>
inline auto makeTask(F&& f) {sp<Task<F>> task = new Task<F>(std::move(f));return std::make_pair(task, task->mTask.get_future());
}
这里将一个可调用对象 f 封装成一个可以异步执行的任务,并返回一个包含任务对象和一个 std::future 对象的 std::pair。
template <typename F>
class Task : public MessageHandler {template <typename G>friend auto makeTask(G&&);explicit Task(F&& f) : mTask(std::move(f)) {}void handleMessage(const Message&) override { mTask(); }using T = std::invoke_result_t<F>;std::packaged_task<T()> mTask;
};
这里可以看到上面的任务消息最终会在 handleMessage() 函数中进行处理。即 Scheduler.cpp 的 handleMessage() 函数中。
handleMessage
源码位置:/frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
MessageQueue::MessageQueue(ICompositor& compositor): MessageQueue(compositor, sp<Handler>::make(*this)) {}void MessageQueue::Handler::handleMessage(const Message&) {// 更新帧待处理状态mFramePending.store(false);const nsecs_t frameTime = systemTime();auto& compositor = mQueue.mCompositor;// 提交当前帧if (!compositor.commit(frameTime, mVsyncId, mExpectedVsyncTime)) {return;}// 合成帧compositor.composite(frameTime, mVsyncId);// 采样compositor.sample();
}
该方法的流程反映了典型的帧渲染管线的一部分,包括帧提交、合成和采样等关键步骤。这些操作通常在接收到 VSync 信号或其他触发消息时执行,确保了屏幕内容的及时更新和渲染效率。而这里的 ICompositor 是 SurfaceFlinger 在初始化 Scheduler 时传进来的参数。
5、SurfaceFlinger.cpp
initScheduler
void SurfaceFlinger::initScheduler(const sp<DisplayDevice>& display) {mScheduler = std::make_unique<scheduler::Scheduler>(static_cast<ICompositor&>(*this),static_cast<ISchedulerCallback&>(*this), features);{auto configs = display->holdRefreshRateConfigs();……mScheduler->createVsyncSchedule(features);mScheduler->setRefreshRateConfigs(std::move(configs));}setVsyncEnabled(false);mScheduler->startTimers();……
}
所以上面的 compositor.XXX() 调用的是 SurfaceFlinger 总的对应方法,这就与 SurfaceFlinger 核心类建立了连接。