SurfaceControl的内部类Transaction
根据SurfaceFlinger中Layer的创建流程,一般在app中创建Surface,SurfaceFlinger中有一个Layer与之对应,通过BufferQueue机制将app的Surface图像传给SurfaceFlinger的Layer进行SurfaceFlinger中Layer的合成并显示到屏幕上。而SurfaceControl是对Surface包装,如果希望修改Surface对应的Layer的状态例如位置、大小等,则可以使用SurfaceControl的内部静态类Transaction实现,示例代码如下:
// val sc: SurfaceControl
SurfaceControl.Transaction().apply { // 创建SurfaceControl.Transaction对象
setPosition(sc, x, y) // 设置某个SurfaceControl的位置
setAlpha(sc, alpha) // 设置某个SurfaceControl的透明度
show(sc) // 设置某个SurfaceControl显示
apply() // 提交之前的设置
}
首先创建SurfaceControl.Transaction对象,然后调用一些set方法设置某个SurfaceControl的状态,最后调用apply方法提交状态设置。
那么我们从Transaction的setPosition来看其是怎么实现的(frameworks/base/core/java/android/view/SurfaceControl.java):
/**
* @hide
*/
@UnsupportedAppUsage
public Transaction setPosition(SurfaceControl sc, float x, float y) {
checkPreconditions(sc);
nativeSetPosition(mNativeObject, sc.mNativeObject, x, y);
return this;
}
直接调用了frameworks/base/core/jni/android_view_SurfaceControl.cpp的nativeSetPosition方法:
static void nativeSetPosition(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject, jfloat x, jfloat y) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
transaction->setPosition(ctrl, x, y);
}
还原了native的Transaction对象和SurfaceControl对象,其中Transaction是SurfaceComposerClient的内部类,调用了transaction的setPosition方法(frameworks/native/libs/gui/SurfaceComposerClient.cpp):
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition(
const sp<SurfaceControl>& sc, float x, float y) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
return *this;
}
s->what |= layer_state_t::ePositionChanged;
s->x = x;
s->y = y;
registerSurfaceControlForCallback(sc);
return *this;
}
在layer_state_t对象中保存了x和y的值,并对位置的改变记录在了what中,那么继续看Transaction的getLayerState方法是怎么拿到layer_state_t对象的(frameworks/native/libs/gui/include/gui/SurfaceComposerClient.h和cpp):
class Transaction : public Parcelable {
protected:
std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates;
......
layer_state_t* getLayerState(const sp<SurfaceControl>& sc) {
return getLayerState(sc->getHandle());
}
......
}
layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<IBinder>& handle) {
if (mComposerStates.count(handle) == 0) {
// we don't have it, add an initialized layer_state to our list
ComposerState s;
s.state.surface = handle;
mComposerStates[handle] = s;
}
return &(mComposerStates[handle].state);
}
mComposerStates的key是SurfaceControl的mHandle,值是ComposerState对象,其有layer_state_t类型的成员遍历state,这里面存放了what、x、y等一些状态变量。
因此根据对Transaction的setPosition方法分析得知,Transaction将每个SurfaceControl设置的状态保存在其相应native对象的mComposerStates成员变量中。
接下来分析Transaction的apply方法(frameworks/base/core/java/android/view/SurfaceControl.java):
/**
* Apply the transaction, clearing it's state, and making it usable
* as a new transaction.
*/
public void apply() {
apply(false);
}
/**
* Jankier version of apply. Avoid use (b/28068298).
* @hide
*/
public void apply(boolean sync) {
applyResizedSurfaces(); // 直接改变SurfaceControl的with和height
notifyReparentedSurfaces(); // 调用OnReparentListener的onReparent方法
nativeApplyTransaction(mNativeObject, sync);
}
调用了frameworks/base/core/jni/android_view_SurfaceControl.cpp的nativeApplyTransaction方法:
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
transaction->apply(sync);
}
进而调用了SurfaceComposerClient::Transaction的apply方法:
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);
}
}
}
mListenerCallbacks.clear();
cacheBuffers();
Vector<ComposerState> composerStates;
Vector<DisplayState> displayStates;
uint32_t flags = 0;
mForceSynchronous |= synchronous;
for (auto const& kv : mComposerStates){
composerStates.add(kv.second);
}
mComposerStates.clear();
displayStates = mDisplayStates;
mDisplayStates.clear();
if (mForceSynchronous) {
flags |= ISurfaceComposer::eSynchronous;
}
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
if (mEarlyWakeup) {
flags |= ISurfaceComposer::eEarlyWakeup;
}
// If both mExplicitEarlyWakeupStart and mExplicitEarlyWakeupEnd are set
// it is equivalent for none
if (mExplicitEarlyWakeupStart && !mExplicitEarlyWakeupEnd) {
flags |= ISurfaceComposer::eExplicitEarlyWakeupStart;
}
if (mExplicitEarlyWakeupEnd && !mExplicitEarlyWakeupStart) {
flags |= ISurfaceComposer::eExplicitEarlyWakeupEnd;
}
mForceSynchronous = false;
mAnimation = false;
mEarlyWakeup = false;
mExplicitEarlyWakeupStart = false;
mExplicitEarlyWakeupEnd = false;
sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
sf->setTransactionState(composerStates, displayStates, flags, applyToken, mInputWindowCommands,
mDesiredPresentTime,
{} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
hasListenerCallbacks, listenerCallbacks);
mInputWindowCommands.clear();
mStatus = NO_ERROR;
return NO_ERROR;
}
通过binder调用了SurfaceFlinger的setTransactionState方法,并将composerStates的值传了过去。
SurfaceFlinger处理Transaction流程
继续看frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp的setTransactionState方法:
void SurfaceFlinger::setTransactionState(
const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags,
const sp<IBinder>& applyToken, const InputWindowCommands& inputWindowCommands,
int64_t desiredPresentTime, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks) {
ATRACE_CALL();
const int64_t postTime = systemTime();
bool privileged = callingThreadHasUnscopedSurfaceFlingerAccess();
Mutex::Autolock _l(mStateLock);
// If its TransactionQueue already has a pending TransactionState or if it is pending
auto itr = mTransactionQueues.find(applyToken);
// if this is an animation frame, wait until prior animation frame has
// been applied by SF
if (flags & eAnimation) {
while (itr != mTransactionQueues.end()) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
ALOGW_IF(err == TIMED_OUT,
"setTransactionState timed out "
"waiting for animation frame to apply");
break;
}
itr = mTransactionQueues.find(applyToken);
}
}
const bool pendingTransactions = itr != mTransactionQueues.end();
// Expected present time is computed and cached on invalidate, so it may be stale.
if (!pendingTransactions) {
mExpectedPresentTime = calculateExpectedPresentTime(systemTime());
}
if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) {
mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
uncacheBuffer, postTime, privileged,
hasListenerCallbacks, listenerCallbacks);
setTransactionFlags(eTransactionFlushNeeded);
return;
}
applyTransactionState(states, displays, flags, inputWindowCommands, desiredPresentTime,
uncacheBuffer, postTime, privileged, hasListenerCallbacks,
listenerCallbacks);
}
调用了SurfaceFlinger的applyTransactionState方法:
void SurfaceFlinger::applyTransactionState(
const Vector<ComposerState>& states, const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
const client_cache_t& uncacheBuffer, const int64_t postTime, bool privileged,
bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
bool isMainThread) {
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
// For window updates that are part of an animation we must wait for
// previous animation "frames" to be handled.
while (!isMainThread && mAnimTransactionPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
// caller after a few seconds.
ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out "
"waiting for previous animation frame");
mAnimTransactionPending = false;
break;
}
}
}
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) {
mTransactionCompletedThread.startRegistration(listener);
mTransactionCompletedThread.endRegistration(listener);
}
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash> listenerCallbacksWithSurfaces;
uint32_t clientStateFlags = 0;
for (const ComposerState& state : states) {
clientStateFlags |= setClientStateLocked(state, desiredPresentTime, postTime, privileged,
listenerCallbacksWithSurfaces);
if ((flags & eAnimation) && state.state.surface) {
if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
mScheduler->recordLayerHistory(layer.get(), desiredPresentTime,
LayerHistory::LayerUpdateType::AnimationTX);
}
}
}
for (const auto& listenerCallback : listenerCallbacksWithSurfaces) {
mTransactionCompletedThread.endRegistration(listenerCallback);
}
// If the state doesn't require a traversal and there are callbacks, send them now
if (!(clientStateFlags & eTraversalNeeded) && hasListenerCallbacks) {
mTransactionCompletedThread.sendCallbacks();
}
transactionFlags |= clientStateFlags;
transactionFlags |= addInputWindowCommands(inputWindowCommands);
if (uncacheBuffer.isValid()) {
ClientCache::getInstance().erase(uncacheBuffer);
getRenderEngine().unbindExternalTextureBuffer(uncacheBuffer.id);
}
// 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 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 uneeded traversal.
if (isMainThread && (transactionFlags & eTraversalNeeded)) {
transactionFlags = transactionFlags & (~eTraversalNeeded);
mForceTraversal = true;
}
const auto transactionStart = [](uint32_t flags) {
if (flags & eEarlyWakeup) {
return Scheduler::TransactionStart::Early;
}
if (flags & eExplicitEarlyWakeupEnd) {
return Scheduler::TransactionStart::EarlyEnd;
}
if (flags & eExplicitEarlyWakeupStart) {
return Scheduler::TransactionStart::EarlyStart;
}
return Scheduler::TransactionStart::Normal;
}(flags);
if (transactionFlags) {
if (mInterceptor->isEnabled()) {
mInterceptor->saveTransaction(states, mCurrentState.displays, displays, flags);
}
// TODO(b/159125966): Remove eEarlyWakeup completly as no client should use this flag
if (flags & eEarlyWakeup) {
ALOGW("eEarlyWakeup is deprecated. Use eExplicitEarlyWakeup[Start|End]");
}
if (!privileged && (flags & (eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd))) {
ALOGE("Only WindowManager is allowed to use eExplicitEarlyWakeup[Start|End] flags");
flags &= ~(eExplicitEarlyWakeupStart | eExplicitEarlyWakeupEnd);
}
// this triggers the transaction
setTransactionFlags(transactionFlags, transactionStart);
if (flags & eAnimation) {
mAnimTransactionPending = true;
}
// if this is a synchronous transaction, wait for it to take effect
// before returning.
const bool synchronous = flags & eSynchronous;
const bool syncInput = inputWindowCommands.syncInputWindows;
if (!synchronous && !syncInput) {
return;
}
if (synchronous) {
mTransactionPending = true;
}
if (syncInput) {
mPendingSyncInputWindows = true;
}
// applyTransactionState can be called by either the main SF thread or by
// another process through setTransactionState. While a given process may wish
// to wait on synchronous transactions, the main SF thread should never
// be blocked. Therefore, we only wait if isMainThread is false.
while (!isMainThread && (mTransactionPending || mPendingSyncInputWindows)) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
// just in case something goes wrong in SF, return to the
// called after a few seconds.
ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
mTransactionPending = false;
mPendingSyncInputWindows = false;
break;
}
}
} else {
// even if a transaction is not needed, we need to update VsyncModulator
// about explicit early indications
if (transactionStart == Scheduler::TransactionStart::EarlyStart ||
transactionStart == Scheduler::TransactionStart::EarlyEnd) {
mVSyncModulator->setTransactionStart(transactionStart);
}
}
}
其中调用了SurfaceFlinger的setClientStateLocked方法:
uint32_t SurfaceFlinger::setClientStateLocked(
const ComposerState& composerState, int64_t desiredPresentTime, int64_t postTime,
bool privileged,
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks) {
const layer_state_t& s = composerState.state;
for (auto& listener : s.listeners) {
// note that startRegistration will not re-register if the listener has
// already be registered for a prior surface control
mTransactionCompletedThread.startRegistration(listener);
listenerCallbacks.insert(listener);
}
sp<Layer> layer = nullptr;
if (s.surface) {
layer = fromHandleLocked(s.surface).promote();
} else {
// The client may provide us a null handle. Treat it as if the layer was removed.
ALOGW("Attempt to set client state with a null layer handle");
}
if (layer == nullptr) {
for (auto& [listener, callbackIds] : s.listeners) {
mTransactionCompletedThread.registerUnpresentedCallbackHandle(
new CallbackHandle(listener, callbackIds, s.surface));
}
return 0;
}
uint32_t flags = 0;
const uint64_t what = s.what;
// If we are deferring transaction, make sure to push the pending state, as otherwise the
// pending state will also be deferred.
if (what & layer_state_t::eDeferTransaction_legacy) {
layer->pushPendingState();
}
// Only set by BLAST adapter layers
if (what & layer_state_t::eProducerDisconnect) {
layer->onDisconnect();
}
if (what & layer_state_t::ePositionChanged) {
if (layer->setPosition(s.x, s.y)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eLayerChanged) {
// NOTE: index needs to be calculated before we update the state
const auto& p = layer->getParent();
if (p == nullptr) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setLayer(s.z) && idx >= 0) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
} else {
if (p->setChildLayer(layer, s.z)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
}
if (what & layer_state_t::eRelativeLayerChanged) {
// NOTE: index needs to be calculated before we update the state
const auto& p = layer->getParent();
if (p == nullptr) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
if (layer->setRelativeLayer(s.relativeLayerHandle, s.z) && idx >= 0) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded|eTraversalNeeded;
}
} else {
if (p->setChildRelativeLayer(layer, s.relativeLayerHandle, s.z)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
}
if (what & layer_state_t::eSizeChanged) {
if (layer->setSize(s.w, s.h)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eAlphaChanged) {
if (layer->setAlpha(s.alpha))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eColorChanged) {
if (layer->setColor(s.color))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eColorTransformChanged) {
if (layer->setColorTransform(s.colorTransform)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eBackgroundColorChanged) {
if (layer->setBackgroundColor(s.color, s.bgColorAlpha, s.bgColorDataspace)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eMatrixChanged) {
// TODO: b/109894387
//
// SurfaceFlinger's renderer is not prepared to handle cropping in the face of arbitrary
// rotation. To see the problem observe that if we have a square parent, and a child
// of the same size, then we rotate the child 45 degrees around it's center, the child
// must now be cropped to a non rectangular 8 sided region.
//
// Of course we can fix this in the future. For now, we are lucky, SurfaceControl is
// private API, and the WindowManager only uses rotation in one case, which is on a top
// level layer in which cropping is not an issue.
//
// However given that abuse of rotation matrices could lead to surfaces extending outside
// of cropped areas, we need to prevent non-root clients without permission ACCESS_SURFACE_FLINGER
// (a.k.a. everyone except WindowManager and tests) from setting non rectangle preserving
// transformations.
if (layer->setMatrix(s.matrix, privileged))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eTransparentRegionChanged) {
if (layer->setTransparentRegionHint(s.transparentRegion))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eFlagsChanged) {
if (layer->setFlags(s.flags, s.mask))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eCropChanged_legacy) {
if (layer->setCrop_legacy(s.crop_legacy)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eCornerRadiusChanged) {
if (layer->setCornerRadius(s.cornerRadius))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eBackgroundBlurRadiusChanged && !mDisableBlurs && mSupportsBlur) {
if (layer->setBackgroundBlurRadius(s.backgroundBlurRadius)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eLayerStackChanged) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
// We only allow setting layer stacks for top level layers,
// everything else inherits layer stack from its parent.
if (layer->hasParent()) {
ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
layer->getDebugName());
} else if (idx < 0) {
ALOGE("Attempt to set layer stack on layer without parent (%s) that "
"that also does not appear in the top level layer list. Something"
" has gone wrong.",
layer->getDebugName());
} else if (layer->setLayerStack(s.layerStack)) {
mCurrentState.layersSortedByZ.removeAt(idx);
mCurrentState.layersSortedByZ.add(layer);
// we need traversal (state changed)
// AND transaction (list changed)
flags |= eTransactionNeeded | eTraversalNeeded | eTransformHintUpdateNeeded;
}
}
if (what & layer_state_t::eDeferTransaction_legacy) {
if (s.barrierHandle_legacy != nullptr) {
layer->deferTransactionUntil_legacy(s.barrierHandle_legacy, s.frameNumber_legacy);
} else if (s.barrierGbp_legacy != nullptr) {
const sp<IGraphicBufferProducer>& gbp = s.barrierGbp_legacy;
if (authenticateSurfaceTextureLocked(gbp)) {
const auto& otherLayer =
(static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
layer->deferTransactionUntil_legacy(otherLayer, s.frameNumber_legacy);
} else {
ALOGE("Attempt to defer transaction to to an"
" unrecognized GraphicBufferProducer");
}
}
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
if (what & layer_state_t::eReparentChildren) {
if (layer->reparentChildren(s.reparentHandle)) {
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
if (what & layer_state_t::eDetachChildren) {
layer->detachChildren();
}
if (what & layer_state_t::eOverrideScalingModeChanged) {
layer->setOverrideScalingMode(s.overrideScalingMode);
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
if (what & layer_state_t::eTransformChanged) {
if (layer->setTransform(s.transform)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eTransformToDisplayInverseChanged) {
if (layer->setTransformToDisplayInverse(s.transformToDisplayInverse))
flags |= eTraversalNeeded;
}
if (what & layer_state_t::eCropChanged) {
if (layer->setCrop(s.crop)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eFrameChanged) {
if (layer->setFrame(s.frame)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eAcquireFenceChanged) {
if (layer->setAcquireFence(s.acquireFence)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eDataspaceChanged) {
if (layer->setDataspace(s.dataspace)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eHdrMetadataChanged) {
if (layer->setHdrMetadata(s.hdrMetadata)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eSurfaceDamageRegionChanged) {
if (layer->setSurfaceDamageRegion(s.surfaceDamageRegion)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eApiChanged) {
if (layer->setApi(s.api)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eSidebandStreamChanged) {
if (layer->setSidebandStream(s.sidebandStream)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eInputInfoChanged) {
if (privileged) {
layer->setInputInfo(s.inputInfo);
flags |= eTraversalNeeded;
} else {
ALOGE("Attempt to update InputWindowInfo without permission ACCESS_SURFACE_FLINGER");
}
}
if (what & layer_state_t::eMetadataChanged) {
if (layer->setMetadata(s.metadata)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eColorSpaceAgnosticChanged) {
if (layer->setColorSpaceAgnostic(s.colorSpaceAgnostic)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eShadowRadiusChanged) {
if (layer->setShadowRadius(s.shadowRadius)) flags |= eTraversalNeeded;
}
if (what & layer_state_t::eFrameRateSelectionPriority) {
if (privileged && layer->setFrameRateSelectionPriority(s.frameRateSelectionPriority)) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eFrameRateChanged) {
if (ValidateFrameRate(s.frameRate, s.frameRateCompatibility,
"SurfaceFlinger::setClientStateLocked") &&
layer->setFrameRate(Layer::FrameRate(s.frameRate,
Layer::FrameRate::convertCompatibility(
s.frameRateCompatibility)))) {
flags |= eTraversalNeeded;
}
}
if (what & layer_state_t::eFixedTransformHintChanged) {
if (layer->setFixedTransformHint(s.fixedTransformHint)) {
flags |= eTraversalNeeded | eTransformHintUpdateNeeded;
}
}
// This has to happen after we reparent children because when we reparent to null we remove
// child layers from current state and remove its relative z. If the children are reparented in
// the same transaction, then we have to make sure we reparent the children first so we do not
// lose its relative z order.
if (what & layer_state_t::eReparent) {
bool hadParent = layer->hasParent();
if (layer->reparent(s.parentHandleForChild)) {
if (!hadParent) {
mCurrentState.layersSortedByZ.remove(layer);
}
flags |= eTransactionNeeded | eTraversalNeeded;
}
}
std::vector<sp<CallbackHandle>> callbackHandles;
if ((what & layer_state_t::eHasListenerCallbacksChanged) && (!s.listeners.empty())) {
for (auto& [listener, callbackIds] : s.listeners) {
callbackHandles.emplace_back(new CallbackHandle(listener, callbackIds, s.surface));
}
}
bool bufferChanged = what & layer_state_t::eBufferChanged;
bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
sp<GraphicBuffer> buffer;
if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
buffer = s.buffer;
bool success = ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
if (success) {
getRenderEngine().cacheExternalTextureBuffer(s.buffer);
success = ClientCache::getInstance()
.registerErasedRecipient(s.cachedBuffer,
wp<ClientCache::ErasedRecipient>(this));
if (!success) {
getRenderEngine().unbindExternalTextureBuffer(s.buffer->getId());
}
}
} else if (cacheIdChanged) {
buffer = ClientCache::getInstance().get(s.cachedBuffer);
} else if (bufferChanged) {
buffer = s.buffer;
}
if (buffer) {
if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime,
s.cachedBuffer)) {
flags |= eTraversalNeeded;
}
}
if (layer->setTransactionCompletedListeners(callbackHandles)) flags |= eTraversalNeeded;
// Do not put anything that updates layer state or modifies flags after
// setTransactionCompletedListener
return flags;
}
首先根据s.surface(之前SurfaceControl的mHandle)获取对应的layer,然后在判断what & layer_state_t::ePositionChanged不为0,则调用了frameworks/native/services/surfaceflinger/Layer.cpp的setPosition方法:
bool Layer::setPosition(float x, float y) {
if (mCurrentState.requested_legacy.transform.tx() == x &&
mCurrentState.requested_legacy.transform.ty() == y)
return false;
mCurrentState.sequence++;
// We update the requested and active position simultaneously because
// we want to apply the position portion of the transform matrix immediately,
// but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
mCurrentState.requested_legacy.transform.set(x, y);
// Here we directly update the active state
// unlike other setters, because we store it within
// the transform, but use different latching rules.
// b/38182305
mCurrentState.active_legacy.transform.set(x, y);
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
}
就这样完成了对Layer位置的改变。
1万+

被折叠的 条评论
为什么被折叠?



