0 前言
在Android图形框架之SurfaceControl 构建过程分析一文中,我们了解到了创建一个SurfaceControl的过程,其实这个过程创建了一个Surface以及一个Layer。接下来将根据SurfaceControl构建事务对象并提交。本文将分析下面这段代码:
cpp
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControl, std::numeric_limits<int32_t>::max())
.show(surfaceControl)
.setBackgroundColor(surfaceControl, half3{0, 0, 0}, 1.0f, ui::Dataspace::UNKNOWN) // black background
.setAlpha(surfaceControl, 1.0f)
.setLayerStack(surfaceControl, ui::LayerStack::fromValue(mLayerStack))
.apply();
1 Transaction类
SurfaceComposerClient::Transaction{}
表示创建了一个Transaction对象。SurfaceComposerClient::Transaction类是Android操作系统中用于管理SurfaceControl的类。它提供了一系列的函数来设置SurfaceControl的各种属性,并将这些更改作为事务对象提交给SurfaceFlinger。下面是它的部分定义代码:
cpp
class Transaction : public Parcelable {
private:
static sp<IBinder> sApplyToken;
void releaseBufferIfOverwriting(const layer_state_t& state);
static void mergeFrameTimelineInfo(FrameTimelineInfo& t, const FrameTimelineInfo& other);
static void clearFrameTimelineInfo(FrameTimelineInfo& t);
public:
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
void clear();
Transaction& setLayer(const sp<SurfaceControl>& sc,
int32_t z);
Transaction& show(const sp<SurfaceControl>& sc);
Transaction& setBackgroundColor(const sp<SurfaceControl>& sc, const half3& color,
float alpha, ui::Dataspace dataspace);
Transaction& setAlpha(const sp<SurfaceControl>& sc,
float alpha);
Transaction& setLayerStack(const sp<SurfaceControl>&, ui::LayerStack);
status_t apply(bool synchronous = false, bool oneWay = false);
...
从类的定义可以看到,Transaction继承了Parcelable接口,这意味着它可以被序列化和反序列化,方便进行跨进程通信。
2 setLayer函数
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;
}
setLayer函数主要完成两个功能:一是调用getLayerState获取Layer的state,二是设置Layer的z值。
我们先来看看getLayerState函数的具体实现:
cpp
layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) {
auto handle = sc->getLayerStateHandle();
if (mComposerStates.count(handle) == 0) {
// we don't have it, add an initialized layer_state to our list
ComposerState s;
s.state.surface = handle;
s.state.layerId = sc->getLayerId();
mComposerStates[handle] = s;
}
return &(mComposerStates[handle].state);
}
getLayerState函数首先会通过getLayerStateHandle方法拿到该Layer的stateHandle,实际上就是一个sp<IBinder>
。如果它不在mComposerStates里面,则根据stateHandle和LayerId来构建一个新的ComposerState。mComposerStates的定义是std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates
,一个sp对应一个ComposerState。最后返回ComposerState类的内部变量state(layer_state_t结构体)。
拿到该Layer的state后,再设置layer_state_t
结构体中的 what
字段的 eLayerChanged
标志位,以及清除 what
字段的 eRelativeLayerChanged
标志位。最后设置z值,它用来表示Surface的层级,z越大表示Surface越靠上层。我们在引言中的代码将z设为最大值,说明该Layer会堆叠显示在最上层。
cpp
s->what |= layer_state_t::eLayerChanged;
s->what &= ~layer_state_t::eRelativeLayerChanged;
s->z = z;
3 show函数
cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
const sp<SurfaceControl>& sc) {
return setFlags(sc, 0, layer_state_t::eLayerHidden);
}
show方法内部调用了setFlags函数,该函数用于清除eLayerHidden标志位,目的是让Surface状态改为显示而不是隐藏。看一看setFlags函数的具体实现:
cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
const sp<SurfaceControl>& sc, uint32_t flags,
uint32_t mask) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
(mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
(mask & layer_state_t::eEnableBackpressure) ||
(mask & layer_state_t::eIgnoreDestinationFrame) ||
(mask & layer_state_t::eLayerIsDisplayDecoration) ||
(mask & layer_state_t::eLayerIsRefreshRateIndicator)) {
s->what |= layer_state_t::eFlagsChanged;
}
// 清除mask标志位,即eLayerHidden。
s->flags &= ~mask;
// 由于flags为0,所以这里并没有改变flag
s->flags |= (flags & mask);
// 更新mask
s->mask |= mask;
registerSurfaceControlForCallback(sc);
return *this;
}
上面的代码实际上就是用于设置标志位的,由于我们设置的flags=0,而mask=layer_state_t::eLayerHidden,所以调用该方法会清除eLayerHidden标志位。因此达到将Surface显示(show)出来的目的。
4 setBackgroundColor函数
cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundColor(
const sp<SurfaceControl>& sc, const half3& color, float alpha, ui::Dataspace dataspace) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eBackgroundColorChanged;
s->bgColor.rgb = color; // rbg颜色
s->bgColor.a = alpha; // 透明度
s->bgColorDataspace = dataspace; // 颜色空间
registerSurfaceControlForCallback(sc);
return *this;
}
setBackgroundColor
方法,主要用于设置一个 SurfaceControl
对象的背景色。它通过操作 layer_state_t
结构体的成员,修改背景颜色相关的状态。
5 setAlpha函数
cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha(
const sp<SurfaceControl>& sc, float alpha) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
if (alpha < 0.0f || alpha > 1.0f) {
ALOGE("SurfaceComposerClient::Transaction::setAlpha: invalid alpha %f, clamping", alpha);
}
s->what |= layer_state_t::eAlphaChanged;
s->color.a = std::clamp(alpha, 0.f, 1.f);
registerSurfaceControlForCallback(sc);
return *this;
}
setAlpha
主要用于修改 SurfaceControl
对象的透明度,确保 alpha
值在有效范围内,并通过设置标志位 eAlphaChanged
通知系统进行透明度更新。
setBackgroundColor
方法里面可以对背景的透明度进行设置,而这里设置的是整个Surface的透明度(包括背景和内容)。这是有区别的。
6 setLayerStack函数
cpp
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayerStack(
const sp<SurfaceControl>& sc, ui::LayerStack layerStack) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::eLayerStackChanged;
s->layerStack = layerStack;
registerSurfaceControlForCallback(sc);
return *this;
}
这个方法就是用于设置LayerStack属性。这里简单讲述一下LayerStack的作用:
- Layer顺序的控制: LayerStack控制Layer在整个渲染系统中的显示顺序。较高的LayerStack值通常代表较"前"显示的Layer,而较低的LayerStack值则代表较"后"的Layer。
- 多显示设备支持 : LayerStack在多显示设备系统中尤为重要。例如,一个设备可能连接多个显示屏,每个显示屏可能有不同的LayerStack。在这种情况下,每个显示设备可能有独立的LayerStack,用来控制各自显示的Layer顺序。不同显示设备之间的Layer层级关系可以通过不同的LayerStack值来区分。
7 apply函数
这段代码是 SurfaceComposerClient::Transaction::apply
方法的实现,它是 Android 图形系统中应用事务的核心函数之一。该方法负责将所有挂起的图层操作应用到显示系统中,并最终通知 SurfaceFlinger
执行这些图层更改。此过程包括缓存图层状态、设置显示状态、同步回调等操作。
cpp
status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {
if (mStatus != NO_ERROR) {
return mStatus;
}
// 创建同步回调
std::shared_ptr<SyncCallback> syncCallback = std::make_shared<SyncCallback>();
if (synchronous) {
syncCallback->init();
addTransactionCommittedCallback(SyncCallback::getCallback(syncCallback),
/*callbackContext=*/nullptr);
}
// 准备监听器回调
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` 来缓存所有需要更新的图层缓冲区。
cacheBuffers();
// 准备 ComposerState 和 DisplayState
Vector<ComposerState> composerStates;
Vector<DisplayState> displayStates;
uint32_t flags = 0;
for (auto const& kv : mComposerStates) {
composerStates.add(kv.second);
}
displayStates = std::move(mDisplayStates);
// 设置事务标志
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
if (oneWay) {
if (synchronous) {
ALOGE("Transaction attempted to set synchronous and one way at the same time"
" this is an invalid request. Synchronous will win for safety");
} else {
flags |= ISurfaceComposer::eOneWay;
}
}
// 处理早期唤醒标志
if (mEarlyWakeupStart && !mEarlyWakeupEnd) {
flags |= ISurfaceComposer::eEarlyWakeupStart;
}
if (mEarlyWakeupEnd && !mEarlyWakeupStart) {
flags |= ISurfaceComposer::eEarlyWakeupEnd;
}
// 获取 applyToken
sp<IBinder> applyToken = mApplyToken ? mApplyToken : sApplyToken;
// 提交事务到 SurfaceFlinger
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId,
mMergedTransactionIds);
// 生成新事务ID并清理当前状态
mId = generateId();
clear();
// 如果是同步事务则等待
if (synchronous) {
syncCallback->wait();
}
mStatus = NO_ERROR;
return NO_ERROR;
}