SurfaceFlinger中Layer的修改 - 安卓R

部署运行你感兴趣的模型镜像

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位置的改变。

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>我们正在分析SurfaceFlinger的`run`函数的初始化和执行流程。根据之前提供的崩溃日志,我们可以看到崩溃发生在`Scheduler::run`函数中(backtrace中的第#08帧)。因此,我们将重点分析`Scheduler::run`方法及其在SurfaceFlinger中的作用。 ### 一、SurfaceFlinger中`run`函数的背景 在Android显示系统中,`SurfaceFlinger`作为系统服务运行,负责接收所有窗口的图形数据,进行合成,并将结果发送到显示设备。`Scheduler`是SurfaceFlinger中负责调度合成的核心模块,其`run`方法是主循环的入口。 ### 二、`Scheduler::run`的初始化流程 1. **创建消息队列** SurfaceFlinger在初始化过程中会创建`MessageQueue`对象,该队列用于处理来自`EventThread`(VSync信号源)的事件: ```cpp // SurfaceFlinger.cpp void SurfaceFlinger::init() { // ... 其他初始化 mScheduler = std::make_unique<scheduler::Scheduler>(...); mEventQueue = std::make_unique<impl::MessageQueue>(); // 将Scheduler与MessageQueue关联 mScheduler->setEventQueue(mEventQueue.get()); } ``` 2. **启动调度线程** 在`SurfaceFlinger`主函数中,通过调用`Scheduler::run`启动调度循环: ```cpp // main_surfaceflinger.cpp int main(int, char**) { // ... 初始化 flinger->run(); // 内部调用Scheduler::run() return 0; } ``` 实际执行的是`Scheduler::run`方法,该方法会进入一个无限循环,等待和处理消息。 ### 三、`Scheduler::run`的执行流程 `Scheduler::run`方法的核心是一个消息循环,其处理流程如下: 1. **等待消息** 通过`MessageQueue::waitMessage()`阻塞等待新消息(主要是VSync信号触发的合成事件): ```cpp // Scheduler.cpp void Scheduler::run() { while (true) { auto message = mMessageQueue->waitMessage(); // 阻塞等待 if (message.type == MessageQueue::REFRESH) { onFrameSignal(...); // 处理合成帧 } } } ``` 2. **处理VSync信号** 当`EventThread`分发VSync信号时,会向`MessageQueue`推送`REFRESH`消息: ```cpp // MessageQueue.cpp void MessageQueue::Handler::dispatchRefresh() { mQueue.mHandler->handleMessage(Message(MessageQueue::REFRESH)); } ``` 3. **执行合成操作** `Scheduler`收到`REFRESH`消息后,调用`onFrameSignal`方法,最终触发`SurfaceFlinger::composite`: ```cpp // Scheduler.cpp void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId, TimePoint expectedVsyncTime) { compositor.composite(vsyncId, expectedVsyncTime); // 调用SurfaceFlinger的composite } ``` 4. **合成流程** `SurfaceFlinger::composite`执行以下关键步骤: - **准备帧**:收集所有图层的状态和缓冲区。 - **调用HWC**:通过`HWComposer`进行硬件合成或回退到GPU合成。 - **提交帧**:将最终帧提交给显示设备。 $$ \text{Frame}_{n} = \text{HWC} \left( \bigoplus_{i=1}^{k} \text{Layer}_{i} \right) $$ ### 四、关键对象交互 ```mermaid sequenceDiagram participant EventThread as VSync事件线程 participant MessageQueue as 消息队列 participant Scheduler as 调度器(Scheduler) participant SF as SurfaceFlinger EventThread->>MessageQueue: VSync信号到达 MessageQueue->>Scheduler: 发送REFRESH消息 Scheduler->>SF: 调用composite() SF->>SF: 合成所有图层 SF->>HWComposer: 提交帧 ``` ### 五、崩溃日志分析 在用户提供的崩溃日志中,崩溃发生在`Scheduler::run`的调用栈中(#08帧),具体是在等待消息后执行到`onFrameSignal`的过程中。崩溃点位于`FrameTargeter::setPresentFence`(#00帧),这通常与显示设备的栅栏(Fence)同步异常有关。可能的原因包括: - 无效的栅栏指针(如已关闭的文件描述符) - 硬件合成器(HWC)驱动异常 --- ### 六、调试建议 1. **检查HWC状态** 通过`dumpsys SurfaceFlinger`查看`HWComposer`是否报告错误: ``` HWComposer state: Display 0: ERROR (timeout) ``` 2. **启用详细日志** 在`SurfaceFlinger`启动参数中添加`-v`选项: ```bash setprop debug.sf.log_redirector stdout ``` 3. **捕获崩溃现场** 使用`gdb`附加到`surfaceflinger`进程,在崩溃时检查寄存器`r0`的值(`0xb7b7b7bb`)是否为无效地址。 --- §§相关问题§§ 1. SurfaceFlinger如何处理多显示器的合成调度? 2. VSync信号的分发机制在Android 12及更高版本中有哪些变化? 3. 如何调试`HWComposer`的硬件合成失败问题? 4. `MessageQueue`在SurfaceFlinger中如何避免消息积压?</think>### SurfaceFlinger中`run`函数的初始化和执行流程 `run()`函数是SurfaceFlinger的主事件循环核心,负责协调整个显示合成流程。以下是其完整的初始化和执行流程(基于Android U代码分析): #### 一、初始化阶段 1. **主线程启动** 在`main()`函数中完成基础初始化后,调用`Scheduler::run()`启动主循环: ```cpp // main_surfaceflinger.cpp int main() { sp<SurfaceFlinger> flinger = new SurfaceFlinger(); flinger->init(); // 初始化HWC、EventThread等 flinger->run(); // 进入主循环 } ``` 2. **消息队列创建** 在`SurfaceFlinger`构造函数中创建消息队列: ```cpp // SurfaceFlinger.cpp SurfaceFlinger::SurfaceFlinger() { mEventQueue = std::make_unique<impl::MessageQueue>(); mScheduler = std::make_unique<Scheduler>(mEventQueue.get()); } ``` 3. **VSync信号源配置** 通过`EventThread`建立VSync监听: ```mermaid sequenceDiagram HWComposer->>+EventThread: VSync信号 EventThread->>+MessageQueue: VSync消息 MessageQueue->>+Scheduler: 唤醒处理 ``` #### 二、`run()`核心执行流程 ```cpp // Scheduler.cpp void Scheduler::run() { while (true) { auto message = mMessageQueue->waitMessage(); // 阻塞等待消息 switch (message.type) { case MessageQueue::REFRESH: onFrameSignal(message.compositor, message.vsyncId, message.timestamp); break; case MessageQueue::INVALIDATE: // 处理图层更新 break; } } } ``` #### 三、关键处理流程解析 1. **帧信号处理** (`onFrameSignal`) - 调用`SurfaceFlinger::composite()`进行合成 - 通过`FrameTargeter`设置显示栅栏: ```cpp // FrameTargeter.cpp void FrameTargeter::setPresentFence(sp<Fence> fence) { mPresentFence = fence; // 此处是崩溃点 } ``` 2. **合成引擎工作流** $$ \text{Frame}_{n} = \sum_{i=1}^{k} \text{Layer}_i \oplus \text{HWC}_\text{strategy} $$ - 收集所有可见图层 - 通过`HWComposer`生成合成策略 - 提交到显示驱动 3. **同步机制** - 使用`Fence`同步GPU/显示操作 - 通过`BufferQueue`管理缓冲区生命周期: ```cpp // BufferQueueProducer.cpp status_t dequeueBuffer(int* slot, sp<Fence>* fence) { // 确保缓冲区可用 } ``` #### 四、崩溃点分析 在您提供的日志中: ``` #00 pc 004710a8 /system/bin/surfaceflinger (FrameTargeter::setPresentFence(...)+72) ``` 表明在设置显示栅栏时发生`SIGBUS`总线错误。可能原因: 1. **内存对齐问题**:指针`0xb7b7b7bb`不符合ARM对齐要求 2. **栅栏对象失效**:`sp<Fence>`指向已释放内存 3. **并发修改**:多个线程同时操作`FrameTargeter` #### 五、性能优化机制 1. **动态调度策略** 根据负载切换合成模式: ```cpp if (layers > MAX_OVERLAY) { useGpuComposition(); // 回退到GPU合成 } else { useHwcComposition(); // 硬件合成 } ``` 2. **VSync自适应** 根据帧率需求动态调整`EventThread`的分发策略 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SSSxCCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值