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

Commit d50e741e authored by Valerie Hau's avatar Valerie Hau
Browse files

Do not set eTraversalNeeded w/out wake up

Multiple layers may set eTraversalNeeded during Layer->doTransaction.
If a prior layer doesn't wish to wake up SF, setting eTraversalNeeded
may block a later layer from triggering a wake-up.  Set
force transaction instead to trigger doTransaction at a later
time.

Bug: 158409746
Test: build, boot, manual, SurfaceFlinger_test,
libsurfaceflinger_unittest

Change-Id: I6a43eb53323073361c5b1ebe87e4ceb8a6d3f120
parent c8cdfef8
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -866,13 +866,12 @@ bool Layer::applyPendingStates(State* stateToCommit) {
    }

    // If we still have pending updates, we need to ensure SurfaceFlinger
    // will keep calling doTransaction, and so we set the transaction flags.
    // will keep calling doTransaction, and so we force a traversal.
    // However, our pending states won't clear until a frame is available,
    // and so there is no need to specifically trigger a wakeup. Rather
    // we set the flags and wait for something else to wake us up.
    // and so there is no need to specifically trigger a wakeup.
    if (!mPendingStates.empty()) {
        setTransactionFlags(eTransactionNeeded);
        mFlinger->setTransactionFlagsNoWake(eTraversalNeeded);
        mFlinger->setTraversalNeeded();
    }

    mCurrentState.modified = false;
+5 −5
Original line number Diff line number Diff line
@@ -2764,7 +2764,8 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
     * (perform the transaction for each of them if needed)
     */

    if ((transactionFlags & eTraversalNeeded) || mTraversalNeededMainThread) {
    if ((transactionFlags & eTraversalNeeded) || mForceTraversal) {
        mForceTraversal = false;
        mCurrentState.traverse([&](Layer* layer) {
            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
            if (!trFlags) return;
@@ -2777,7 +2778,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
                mInputInfoChanged = true;
            }
        });
        mTraversalNeededMainThread = false;
    }

    /*
@@ -3248,8 +3248,8 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags,
    return old;
}

uint32_t SurfaceFlinger::setTransactionFlagsNoWake(uint32_t flags) {
    return mTransactionFlags.fetch_or(flags);
void SurfaceFlinger::setTraversalNeeded() {
    mForceTraversal = true;
}

bool SurfaceFlinger::flushTransactionQueues() {
@@ -3449,7 +3449,7 @@ void SurfaceFlinger::applyTransactionState(
    // so we don't have to wake up again next frame to preform an uneeded traversal.
    if (isMainThread && (transactionFlags & eTraversalNeeded)) {
        transactionFlags = transactionFlags & (~eTraversalNeeded);
        mTraversalNeededMainThread = true;
        mForceTraversal = true;
    }

    if (transactionFlags) {
+5 −5
Original line number Diff line number Diff line
@@ -628,12 +628,12 @@ private:
    uint32_t peekTransactionFlags();
    // Can only be called from the main thread or with mStateLock held
    uint32_t setTransactionFlags(uint32_t flags);
    // Set the transaction flags, 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
    // 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 to wake us up.
    uint32_t setTransactionFlagsNoWake(uint32_t flags);
    // onFrameAvailable or another layer update to wake us up.
    void setTraversalNeeded();
    uint32_t setTransactionFlags(uint32_t flags, Scheduler::TransactionStart transactionStart);
    void commitTransaction() REQUIRES(mStateLock);
    void commitOffscreenLayers();
@@ -1001,7 +1001,7 @@ private:
    bool mTransactionPending = false;
    bool mAnimTransactionPending = false;
    SortedVector<sp<Layer>> mLayersPendingRemoval;
    bool mTraversalNeededMainThread = false;
    bool mForceTraversal = false;

    // global color transform states
    Daltonizer mDaltonizer;