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*/@UnsupportedAppUsagepublic 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 listComposerState 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和heightnotifyReparentedSurfaces();  // 调用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 callbacksfor (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// statefor (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 noneif (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 pendingauto itr = mTransactionQueues.find(applyToken);// if this is an animation frame, wait until prior animation frame has// been applied by SFif (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 nowif (!(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 flagif (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 transactionsetTransactionFlags(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 indicationsif (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 controlmTransactionCompletedThread.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 layersif (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 stateconst 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 stateconst 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// setTransactionCompletedListenerreturn 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/38182305mCurrentState.active_legacy.transform.set(x, y);mCurrentState.modified = true;setTransactionFlags(eTransactionNeeded);return true;
}

就这样完成了对Layer位置的改变。

SurfaceFlinger中Layer的修改 - 安卓R相关推荐

  1. 录屏流程 - 安卓R

    根据安卓实现录屏app可知,安卓录屏时要创建一个VirtualDisplay.本文介绍安卓录屏的底层原理. 从frameworks/base/media/java/android/media/proj ...

  2. Android中SlidingDrawer介绍【安卓进化三十四】

    Android中SlidingDrawer介绍[安卓进化三十四] 安卓中1.5后加入了SlidingDrawer[隐藏式抽屉],设计原理在你的UI布局有限的情况下,放不下太多的控件的时候,可以考虑用这 ...

  3. 修改安卓默认的系统button样式,以及其它系统控件的默认样式

    先介绍下修改原理:首先打开位于android.widget包下面的Button.java文件,这里有一句关键的代码如下: public Button(Context context, Attribut ...

  4. 【Android 逆向】修改 Android 系统文件 ( Android 逆向中需要经常修改的文件和目录 | 在 root 后的设备中获取 / 目录的 rw 权限后注意事项 )

    文章目录 一.Android 逆向中需要经常修改的文件和目录 二.在 root 后的设备中获取 / 目录的 rw 权限后注意事项 1.不要随意执行 wipe 命令 2.不要随意执行 rm 命令 一.A ...

  5. android陀螺仪测试工具,修改安卓陀螺仪和加速度计的sensor抽象层HAL

    项目具体需求 硬件平台:全志A31 SOC,512RAM,2G ROM: 软件平台:android 4.4xx 内核版本:linux3.4.xx 1.打开内核选项: Devices Drivers H ...

  6. android layout(l, t, r, b);,服务器里的a,t,l,r,b是什么意思? Android编程中关于layout(l,t,r,b)函数的问题...

    导航:网站首页 > 服务器里的a,t,l,r,b是什么意思? Android编程中关于layout(l,t,r,b)函数的问题 服务器里的a,t,l,r,b是什么意思? Android编程中关于 ...

  7. 计算机普通用户禁止修改c盘,保护C盘数据win7中设置禁止修改C盘文件的方法

    我们在win7电脑的使用中一般电脑中的C盘都是安装的就是我们所说的系统盘,那对于C盘的话是最好不要保存其他的文件和安装软件的,那有小伙伴害怕电脑中的还在那更要文件被别人修改的情况,想要直接设置禁止修改 ...

  8. git 中 A C D M R T U X 分别解释

    git 中 A C D M R T U X 分别解释 ​ A: 你本地新增的文件(服务器上没有). C: 文件的一个新拷贝.D: 你本地删除的文件(服务器上还在).M: 文件的内容或者mode被修改了 ...

  9. android自动改,【玩机组ROM修改教程】自己修改安卓ROM 刷机包教程

    本帖最后由 威风凛凛77 于 2018-5-4 18:02 编辑 偉鎽凛凛头衔01.gif (279.94 KB, 下载次数: 85) 2018-5-4 12:41 上传 [玩机组ROM修改教程]自己 ...

最新文章

  1. osmnx 应用 可视化两张图异同的点和边
  2. 一个简单问题引发对IEnumerable和IQueryable的思考
  3. dazhilu飞鸽传书 2013 官方网站
  4. Python3十大经典错误及解决办法
  5. matlab 限幅,限幅是什么意思
  6. stream 定长循环_Java8之Stream流代替For循环操作
  7. 既然现在处理器性能过剩,为什么PC用起来不流畅?
  8. centos升级默认node版本
  9. 都是以父元素的width为参照物的
  10. 复制百度文库的文字加什么后缀_下载百度文库文档 怎么快速提取百度文库中可以完整阅读的文档...
  11. java乘法代码_java九九乘法表代码
  12. 上海驾驶证满6年换证
  13. 使用Git管理多媒体文件
  14. icloud 如何同步_如何使用iCloud同步联系人,提醒等
  15. 学霸,顾名思义,就是成绩非常好
  16. 《异常检测——从经典算法到深度学习》15 通过无监督和主动学习进行实用的白盒异常检测
  17. FFMPEG音频视频开发: 开发本地视频播放器(单线程解码)
  18. python pymysql cursors_怎么Pythonpymysql.cursors从mysql存储过程获取INOUT返回结果
  19. HDU 1265 浮点数
  20. 数据保护:UPS不间断电源初步使用

热门文章

  1. c++ 多态 学习总结3 虚析构和纯虚析构
  2. Bootstrap笔记(十一) 表格篇
  3. eve正在跃迁服务器维护,【终极跃迁测试】新伊甸常见问题答疑
  4. Python-with open() as f的用法
  5. 三种价差交易,你知道几个?
  6. Mvp-10隔膜泵串口编程
  7. 看完当幸福来敲门的随想
  8. 夏普为何会错失高通3月29日的第二轮投资
  9. Unexpected Exception caught setting ‘xx‘ on ‘xxx‘
  10. 2017年11月学习心得报告