使用SurfaceComposerClient::createSurface创建SurfaceControl之后,SurfaceControl可以创建Surface用于绘制。
但是如果想要配置Surface的zorder,位置等属性怎么办呢?
在 SurfaceComposerClient::Transaction中提供了各中配置属性的方法
SurfaceComposerClient::Transaction::setXXX()
比如在《02 最简单的SurfaceFlinger应用程序》里配置了zorder为最大,显示位置设置在屏幕的中间,把当前层设置为可见等。
SurfaceComposerClient::Transaction{}
.setLayer(surfaceControl, std::numeric_limits<int32_t>::max())
.setPosition(surfaceControl, (displayMode.resolution.getWidth() - 200) / 2,
(displayMode.resolution.getHeight() - 200) / 2)
.show(surfaceControl)
.apply();
以setLayer为例看下其内部是如果工作的。
setLayer
1. 首先获取LayerSate;其实是ComposerState中的layer_state_t;如果在mComposerStates里找不到就创建一个,找到就直接返回。
2. 修改state里的值
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
const sp<SurfaceControl>& sc, int32_t z) {
layer_state_t* s = getLayerState(sc);
s->what |= layer_state_t::eLayerChanged;
s->what &= ~layer_state_t::eRelativeLayerChanged;
s->z = z;
}
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);
}
sp<IBinder> SurfaceControl::getLayerStateHandle() const
{
return mHandle;
}
setPosition
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition(
const sp<SurfaceControl>& sc, float x, float y) {
layer_state_t* s = getLayerState(sc);
s->what |= layer_state_t::ePositionChanged;
s->x = x;
s->y = y;
return *this;
}
show
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::show(
const sp<SurfaceControl>& sc) {
return setFlags(sc, 0, layer_state_t::eLayerHidden);
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags(
const sp<SurfaceControl>& sc, uint32_t flags,
uint32_t mask) {
layer_state_t* s = getLayerState(sc);
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)) {
s->what |= layer_state_t::eFlagsChanged;
}
s->flags &= ~mask;
s->flags |= (flags & mask);
s->mask |= mask;
return *this;
}
别的设置属性的实现基本都差不多,不再一一阐述。
apply
设置完一堆参数之后,什么时候生效呢?答案是执行apply
apply作用:
- 把配置好layer参数的mComposerStates,放入composerStates
- mDisplayStates放入displayStates
- 调用sf->setTransactionState提交事务
status_t SurfaceComposerClient::Transaction::apply(bool synchronous) {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
Vector<ComposerState> composerStates;
Vector<DisplayState> displayStates;
for (auto const& kv : mComposerStates){
composerStates.add(kv.second);
}
displayStates = std::move(mDisplayStates);
sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
hasListenerCallbacks, listenerCallbacks, mId);
}
会调用到SurfaceFlinger的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) {
TransactionState state{frameTimelineInfo, states,
displays, flags,
applyToken, inputWindowCommands,
desiredPresentTime, isAutoTimestamp,
uncacheBuffer, postTime,
permissions, hasListenerCallbacks,
listenerCallbacks, originPid,
originUid, transactionId};
queueTransaction(state);
}
void SurfaceFlinger::queueTransaction(TransactionState& state) {
mTransactionQueue.emplace(state);
setTransactionFlags(eTransactionFlushNeeded, schedule, state.applyToken);
}
setTransactionState
主要作用:
1. 用传进来的参数创建一个TransactionState
2. 用queueTransaction,将创建的state 放入mTransactionQueue队列,设置eTransactionFlushNeeded 标志;等待下一个vsync来之后来取。
画个图总结一下:
- 从代码看每个surfacecontrol只会有一个ComposerState
- 不执行apply,以上设置的参数均不会生效
- 每次apply都会创建一个TransactionState添加到SurfaceFlinger的mTransactionQueue
现在SurfaceFliger拿到了layer的所有信息,后就可以根据这些信息来进行合成刷新了。
创作不易,欢迎点赞评论。