目录:Android显示终极宝典
在前面的章节中,应用通过createSurface()在surfaceflinger中创建了一层layer,紧接着要做的事情就是对这个layer设置一些属性(或者叫状态),常设置的属性有位置、大小、z-order等等。那么,client端是如何设置到surfaceflinger中的呢?Android12引入了Transaction机制来传递这些属性到surfaceflinger对应的layer中。
画个简图如下:
本节先从client端开始看,client端主要看三个内容:
- layer_state_t
- registerSurfaceControlForCallback()
- apply()
这三个内容是Transaction的核心,我们逐一来看一下。
layer_state_t
Transaction中还有一类直接针对display设置状态的接口,这里我们就不看了,主要看下layer的内容。
Transaction所有针对layer的接口的共性目的都是在设置layer_state_t这个结构体,对应到surfaceflinger中,则是将所设置的属性保存到layer的mDrawingState中。
//frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
const sp<SurfaceControl>& sc, int32_t z) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eLayerChanged;
s->what &= ~layer_state_t::eRelativeLayerChanged;
s->z = z;
registerSurfaceControlForCallback(sc);
return *this;
}
另外一点,从代码中可以看到,大部分接口都会去调用registerSurfaceControlForCallback()这个接口,这个接口看似代码量很少,但是由其牵扯出的逻辑还是比较复杂的,需要一点一点展开来看一看吧。
registerSurfaceControlForCallback()
//frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback(
const sp<SurfaceControl>& sc) {
auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()];
callbackInfo.surfaceControls.insert(sc);
TransactionCompletedListener::getInstance()
->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds);
}
看代码可以得到的信息有:只要只调用了这个接口,那么mListenerCallbacks就会有值,且将SurfaceControl保存到其CalllbackInfo的SurfaceControls成员中。
然后进程中还创建了一个TransactionCompletedListener单例,后面会传递给surfaceflinger,而surfaceflinger在处理完transaction后则会回调这个listener。
接着看下addSurfaceControlToCallbacks():
//frameworks/native/libs/gui/SurfaceComposerClient.cpp
void TransactionCompletedListener::addSurfaceControlToCallbacks(
const sp<SurfaceControl>& surfaceControl,
const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds) {
std::lock_guard<std::mutex> lock(mMutex);
for (auto callbackId : callbackIds) {
mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct,
std::forward_as_tuple(
surfaceControl->getHandle()),
std::forward_as_tuple(surfaceControl));
}
}
这个函数的目的是依据registerSurfaceControlForCallback()传进来的SurfaceControl和callbackIds用来构建出listener内部成员mCallbacks的value(callbackTranslation)中的surfaceControls。但是,一般情况下传进来的callbackIds是空值,所以addSurfaceControlToCallbacks()在一般情况下什么也不会做。只有等到addTransactionCallback()被调用后,callbackIds中才有值,在此后addSurfaceControlToCallbacks()才会做有意义的事情。
接着看看addTransactionCallback():
//frameworks/native/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::addTransactionCallback(
TransactionCompletedCallbackTakesContext callback, void* callbackContext,
CallbackId::Type callbackType) {
auto listener = TransactionCompletedListener::getInstance();
auto callbackWithContext = std::bind(callback, callbackContext, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3);
const auto& surfaceControls =
mListenerCallbacks[TransactionCompletedListener::getIInstance()].surfaceControls;
CallbackId callbackId =
listener->addCallbackFunction(callbackWithContext, surfaceControls, callbackType);
mListenerCallbacks[TransactionCompletedListener::getIInstance()].callbackIds.emplace(
callbackId);
return *this;
}
先不急着分析它内部的代码,先来看看这个函数被谁调用。搜索code发现它会被addTransactionCompletedCallback()和addTransactionCommittedCallback()调用,而:
- addTransactionCommittedCallback()会被CTS测试code调用。
- addTransactionCompletedCallback()会被BLASTBufferQueue和CTS测试code调用。
BLASTBufferQueue会在processNextBufferLocked()的时候将transactionCallbackThunk()注册传递给addTransactionCompletedCallback()函数。第一个参数就是transactionCallbackThunk(),第二个参数是BLASTBufferQueue的this指针,第三个参数是CallbackId::Type::ON_COMPLETE。
现在正式来看addTransactionCallback()的代码做的事情:
- 首先,它会将传进来的callback重新打包成callbackWithContext;
- 再者,获取Transaction的mListenerCallbacks内部保存的surfaceControls;
- 然后,调用addCallbackFunction()将构建的callbackWithContext和获取到的surfaceControls分别保存到CallbackTranslation中并且返回一个callbackId;
- 最后,将上面返回的callbackId保存到Transaction的mListenerCallbacks的CallbackInfo的callbackIds成员中。
到这里,registerSurfaceControlForCallback()就结束了,它的主要作用是将BLASTBufferQueue和TransactionCompletedListener联系起来。TransactionCompletedListener是基于binder实现的,它被传递给surfaceflinger,完成传递步骤则是在apply()方法内了。
apply()
//frameworks/native/libs/gui/SurfaceComposerClient.cpp
status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
if (mStatus != NO_ERROR) {
return mStatus;
}
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
bool hasListenerCallbacks = !mListenerCallbacks.empty();
std::vector<ListenerCallbacks> listenerCallbacks;
// For every listener with registered callbacks
for (const auto& [listener, callbackInfo] : mListenerCallbacks) {
auto& [callbackIds, surfaceControls] = callbackInfo;
if (callbackIds.empty()) {
continue;
}
if (surfaceControls.empty()) {
listenerCallbacks.emplace_back(IInterface::asBinder(listener), std::move(callbackIds));
} else {
// If the listener has any SurfaceControls set on this Transaction update the surface
// state
for (const auto& surfaceControl : surfaceControls) {
layer_state_t* s = getLayerState(surfaceControl);
if (!s) {
ALOGE("failed to get layer state");
continue;
}
std::vector<CallbackId> callbacks(callbackIds.begin(), callbackIds.end());
s->what |= layer_state_t::eHasListenerCallbacksChanged;
s->listeners.emplace_back(IInterface::asBinder(listener), callbacks);
}
}
}
cacheBuffers();
Vector<ComposerState> composerStates;
Vector<DisplayState> displayStates;
uint32_t flags = 0;
mForceSynchronous |= synchronous;
for (auto const& kv : mComposerStates){
composerStates.add(kv.second);
}
displayStates = std::move(mDisplayStates);
if (mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous;
}
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
// If both mEarlyWakeupStart and mEarlyWakeupEnd are set
// it is equivalent for none
if (mEarlyWakeupStart && !mEarlyWakeupEnd) {
flags |= ISurfaceComposer::eEarlyWakeupStart;
}
if (mEarlyWakeupEnd && !mEarlyWakeupStart) {
flags |= ISurfaceComposer::eEarlyWakeupEnd;
}
sp<IBinder> applyToken = mApplyToken
? mApplyToken
: IInterface::asBinder(TransactionCompletedListener::getIInstance());
sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
hasListenerCallbacks, listenerCallbacks, mId);
mId = generateId();
// Clear the current states and flags
clear();
mStatus = NO_ERROR;
return NO_ERROR;
}
apply()一般不会传入参数,所以通常它的参数固定为false。
第一个for循环的作用很单纯,就是将transaction中保存的listener存入Surfacecontrol对应layer_state_t(即listeners成员)中去。
cacheBuffers()实际上是做了一个策略,如果这个surface是带buffer的,那么会在transaction内部创建一个BufferCache保存buffer的mId,并且后面随transaction一起传递的也是这个mId(保存在cachedBuffer.id成员中)。
接下来是对flags的设定:eSynchronous的值由apply()的参数和setDisplayProjection()接口来决定,一般情况不会设定。eAnimation、eEarlyWakeupStart和eEarlyWakeupEnd都是由WMS来设定的,在WMS处理窗口动画效果的时候会去设置。
然后调用surfaceflinger的setTransactionState()接口,将应用设置的所有信息传递给它,传递的最后一个参数是一个自增的mId,可以通过这个id值来快速确认client和server直接的调用对应关系。
最后,调用clear()清理掉该transaction涉及到传递的所有成员变量的值。也就是说一个进程在apply()完以后要重新使用这个transaction,则必须重新设置layer_state_t(和DisplayState)。
到此,client端的Transaction就讲完了,后面继续学习下surfaceflinger端是如何处理transaction的。
TransactionCompletedListener
这里简单描述下TransactionCompletedListener是如何被回调的。
surfaceflinger端这里不讲,这里直接掐头去尾直接讲和本节相关的。在setClientStateLocked()函数中会调用TransactionCallbackInvoker的startRegistration()方法将listener保存到mCompletedTransactions中。然后在surfaceflinger处理完transaction后会在handleMessageInvalidate()中调用TransactionCallbackInvoker的sendCallbacks()去回调TransactionCompletedListener的onTransactionCompleted()函数。接着回调callbackFunction(),一路回调到BLASTBufferQueue再到JAVA层。
总结
Transaction的作用是提供给应用统一设置所有需要设置的layer或者display的状态值,以原子操作的形式发送给surfacefinger进行处理,如果应用设置了回调,那么surfacefinger在处理完transaction后会将消息回调到上层。