Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 481e96e0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Clean up around transaction commit"

parents 31e76ed9 9e168db5
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -725,14 +725,14 @@ void Layer::commitTransaction(State&) {
    mDrawingState.bufferlessSurfaceFramesTX.clear();
}

uint32_t Layer::getTransactionFlags(uint32_t flags) {
    auto ret = mTransactionFlags & flags;
    mTransactionFlags &= ~flags;
    return ret;
uint32_t Layer::clearTransactionFlags(uint32_t mask) {
    const auto flags = mTransactionFlags & mask;
    mTransactionFlags &= ~mask;
    return flags;
}

uint32_t Layer::setTransactionFlags(uint32_t flags) {
    return mTransactionFlags |= flags;
void Layer::setTransactionFlags(uint32_t mask) {
    mTransactionFlags |= mask;
}

bool Layer::setPosition(float x, float y) {
+6 −2
Original line number Diff line number Diff line
@@ -640,8 +640,12 @@ public:
    bool isLegacyDataSpace() const;

    uint32_t getTransactionFlags() const { return mTransactionFlags; }
    uint32_t getTransactionFlags(uint32_t flags);
    uint32_t setTransactionFlags(uint32_t flags);

    // Sets the masked bits.
    void setTransactionFlags(uint32_t mask);

    // Clears and returns the masked bits.
    uint32_t clearTransactionFlags(uint32_t mask);

    FloatRect getBounds(const Region& activeTransparentRegion) const;
    FloatRect getBounds() const;
+46 −59
Original line number Diff line number Diff line
@@ -1962,7 +1962,7 @@ void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncT

        mFrameTimeline->setSfWakeUp(vsyncId, frameStart, Fps::fromPeriodNsecs(stats.vsyncPeriod));

        refreshNeeded |= handleMessageTransaction();
        refreshNeeded |= flushAndCommitTransactions();
        refreshNeeded |= handleMessageInvalidate();

        if (tracePreComposition) {
@@ -2007,25 +2007,23 @@ void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncT
    notifyRegionSamplingThread();
}

bool SurfaceFlinger::handleMessageTransaction() {
bool SurfaceFlinger::flushAndCommitTransactions() {
    ATRACE_CALL();

    if (getTransactionFlags(eTransactionFlushNeeded)) {
    if (clearTransactionFlags(eTransactionFlushNeeded)) {
        flushTransactionQueues();
    }
    uint32_t transactionFlags = peekTransactionFlags();
    bool runHandleTransaction =
            ((transactionFlags & (~eTransactionFlushNeeded)) != 0) || mForceTraversal;

    if (runHandleTransaction) {
        handleTransaction(eTransactionMask);
    const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || mForceTraversal;
    if (shouldCommit) {
        commitTransactions();
    }

    if (transactionFlushNeeded()) {
        setTransactionFlags(eTransactionFlushNeeded);
    }

    return runHandleTransaction;
    return shouldCommit;
}

void SurfaceFlinger::onMessageRefresh() {
@@ -2451,29 +2449,26 @@ void SurfaceFlinger::postFrame() {
    }
}

void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) {
void SurfaceFlinger::commitTransactions() {
    ATRACE_CALL();

    // here we keep a copy of the drawing state (that is the state that's
    // going to be overwritten by handleTransactionLocked()) outside of
    // mStateLock so that the side-effects of the State assignment
    // don't happen with mStateLock held (which can cause deadlocks).
    // Keep a copy of the drawing state (that is going to be overwritten
    // by commitTransactionsLocked) outside of mStateLock so that the side
    // effects of the State assignment don't happen with mStateLock held,
    // which can cause deadlocks.
    State drawingState(mDrawingState);

    Mutex::Autolock _l(mStateLock);
    Mutex::Autolock lock(mStateLock);
    mDebugInTransaction = systemTime();

    // Here we're guaranteed that some transaction flags are set
    // so we can call handleTransactionLocked() unconditionally.
    // We call getTransactionFlags(), which will also clear the flags,
    // with mStateLock held to guarantee that mCurrentState won't change
    // until the transaction is committed.
    // so we can call commitTransactionsLocked unconditionally.
    // We clear the flags with mStateLock held to guarantee that
    // mCurrentState won't change until the transaction is committed.
    modulateVsync(&VsyncModulator::onTransactionCommit);
    transactionFlags = getTransactionFlags(eTransactionMask);
    handleTransactionLocked(transactionFlags);
    commitTransactionsLocked(clearTransactionFlags(eTransactionMask));

    mDebugInTransaction = 0;
    // here the transaction has been committed
}

void SurfaceFlinger::loadDisplayModes(PhysicalDisplayId displayId, DisplayModes& outModes,
@@ -2927,8 +2922,8 @@ void SurfaceFlinger::processDisplayChangesLocked() {
    mDrawingState.displays = mCurrentState.displays;
}

void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) {
    // Commit display transactions
void SurfaceFlinger::commitTransactionsLocked(uint32_t transactionFlags) {
    // Commit display transactions.
    const bool displayTransactionNeeded = transactionFlags & eDisplayTransactionNeeded;
    if (displayTransactionNeeded) {
        processDisplayChangesLocked();
@@ -2942,7 +2937,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) {
        mSomeChildrenChanged = false;
    }

    // Update transform hint
    // Update transform hint.
    if (transactionFlags & (eTransformHintUpdateNeeded | eDisplayTransactionNeeded)) {
        // Layers and/or displays have changed, so update the transform hint for each layer.
        //
@@ -2995,10 +2990,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) {
        });
    }

    /*
     * Perform our own transaction if needed
     */

    if (mLayersAdded) {
        mLayersAdded = false;
        // Layers have been added.
@@ -3020,7 +3011,9 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) {
        });
    }

    commitTransaction();
    doCommitTransactions();
    signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
    mAnimTransactionPending = false;
}

void SurfaceFlinger::updateInputFlinger() {
@@ -3169,14 +3162,9 @@ void SurfaceFlinger::setVsyncConfig(const VsyncModulator::VsyncConfig& config,
    mEventQueue->setDuration(config.sfWorkDuration);
}

void SurfaceFlinger::commitTransaction() {
void SurfaceFlinger::doCommitTransactions() {
    ATRACE_CALL();
    commitTransactionLocked();
    signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
    mAnimTransactionPending = false;
}

void SurfaceFlinger::commitTransactionLocked() {
    if (!mLayersPendingRemoval.isEmpty()) {
        // Notify removed layers now that they can't be drawn from
        for (const auto& l : mLayersPendingRemoval) {
@@ -3220,11 +3208,10 @@ void SurfaceFlinger::commitTransactionLocked() {
void SurfaceFlinger::commitOffscreenLayers() {
    for (Layer* offscreenLayer : mOffscreenLayers) {
        offscreenLayer->traverse(LayerVector::StateSet::Drawing, [](Layer* layer) {
            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
            if (!trFlags) return;

            if (layer->clearTransactionFlags(eTransactionNeeded)) {
                layer->doTransaction(0);
                layer->commitChildList();
            }
        });
    }
}
@@ -3260,12 +3247,12 @@ bool SurfaceFlinger::handlePageFlip() {
    // Display is now waiting on Layer 1's frame, which is behind layer 0's
    // second frame. But layer 0's second frame could be waiting on display.
    mDrawingState.traverse([&](Layer* layer) {
         uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
         if (trFlags || mForceTransactionDisplayChange) {
        if (layer->clearTransactionFlags(eTransactionNeeded) || mForceTransactionDisplayChange) {
            const uint32_t flags = layer->doTransaction(0);
             if (flags & Layer::eVisibleRegion)
            if (flags & Layer::eVisibleRegion) {
                mVisibleRegionsDirty = true;
            }
        }

        if (layer->hasReadyFrame()) {
            frameQueued = true;
@@ -3374,23 +3361,23 @@ void SurfaceFlinger::removeGraphicBufferProducerAsync(const wp<IBinder>& binder)
    }));
}

uint32_t SurfaceFlinger::peekTransactionFlags() {
uint32_t SurfaceFlinger::getTransactionFlags() const {
    return mTransactionFlags;
}

uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags) {
    return mTransactionFlags.fetch_and(~flags) & flags;
uint32_t SurfaceFlinger::clearTransactionFlags(uint32_t mask) {
    return mTransactionFlags.fetch_and(~mask) & mask;
}

uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
    return setTransactionFlags(flags, TransactionSchedule::Late);
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t mask) {
    return setTransactionFlags(mask, TransactionSchedule::Late);
}

uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, TransactionSchedule schedule,
                                             const sp<IBinder>& token) {
    uint32_t old = mTransactionFlags.fetch_or(flags);
    modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, token);
    if ((old & flags) == 0) scheduleInvalidate(FrameHint::kActive);
uint32_t SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
                                             const sp<IBinder>& applyToken) {
    const uint32_t old = mTransactionFlags.fetch_or(mask);
    modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
    if ((old & mask) == 0) scheduleInvalidate(FrameHint::kActive);
    return old;
}

+17 −12
Original line number Diff line number Diff line
@@ -352,7 +352,6 @@ protected:
            uint32_t permissions,
            std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks)
            REQUIRES(mStateLock);
    virtual void commitTransactionLocked();

    // Used internally by computeLayerBounds() to gets the clip rectangle to use for the
    // root layers on a particular display in layer-coordinate space. The
@@ -804,8 +803,12 @@ private:
    // incoming transactions
    void onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncTime);

    // Returns whether the transaction actually modified any state
    bool handleMessageTransaction();
    // Returns whether transactions were committed.
    bool flushAndCommitTransactions() EXCLUDES(mStateLock);

    void commitTransactions() EXCLUDES(mStateLock);
    void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
    void doCommitTransactions() REQUIRES(mStateLock);

    // Handle the REFRESH message queue event, sending the current frame down to RenderEngine and
    // the Composer HAL for presentation
@@ -814,9 +817,6 @@ private:
    // Returns whether a new buffer has been latched (see handlePageFlip())
    bool handleMessageInvalidate();

    void handleTransaction(uint32_t transactionFlags);
    void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);

    void updateInputFlinger();
    void notifyWindowInfos();
    void commitInputWindowCommands() REQUIRES(mStateLock);
@@ -848,18 +848,23 @@ private:
    void flushTransactionQueues();
    // Returns true if there is at least one transaction that needs to be flushed
    bool transactionFlushNeeded();
    uint32_t getTransactionFlags(uint32_t flags);
    uint32_t peekTransactionFlags();
    // Can only be called from the main thread or with mStateLock held
    uint32_t setTransactionFlags(uint32_t flags);

    uint32_t getTransactionFlags() const;

    // Sets the masked bits, and returns the old flags.
    uint32_t setTransactionFlags(uint32_t mask);

    // Clears and returns the masked bits.
    uint32_t clearTransactionFlags(uint32_t mask);

    // Indicate SF should call doTraversal on layers, but don't trigger a wakeup! We use this cases
    // where there are still pending transactions but we know they won't be ready until a frame
    // arrives from a different layer. So we need to ensure we performTransaction from invalidate
    // but there is no need to try and wake up immediately to do it. Rather we rely on
    // onFrameAvailable or another layer update to wake us up.
    void setTraversalNeeded();
    uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule, const sp<IBinder>& = {});
    void commitTransaction() REQUIRES(mStateLock);
    uint32_t setTransactionFlags(uint32_t mask, TransactionSchedule,
                                 const sp<IBinder>& applyToken = {});
    void commitOffscreenLayers();
    bool transactionIsReadyToBeApplied(
            const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime,
+2 −2
Original line number Diff line number Diff line
@@ -70,10 +70,10 @@ cc_test {
        "MessageQueueTest.cpp",
        "SurfaceFlinger_CreateDisplayTest.cpp",
        "SurfaceFlinger_DestroyDisplayTest.cpp",
        "SurfaceFlinger_DisplayTransactionCommitTest.cpp",
        "SurfaceFlinger_GetDisplayNativePrimariesTest.cpp",
        "SurfaceFlinger_HandleTransactionLockedTest.cpp",
        "SurfaceFlinger_NotifyPowerBoostTest.cpp",
        "SurfaceFlinger_HotplugTest.cpp",
        "SurfaceFlinger_NotifyPowerBoostTest.cpp",
        "SurfaceFlinger_OnInitializeDisplaysTest.cpp",
        "SurfaceFlinger_SetDisplayStateTest.cpp",
        "SurfaceFlinger_SetPowerModeInternalTest.cpp",
Loading