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

Commit 529efdf6 authored by Jamie Gennis's avatar Jamie Gennis Committed by The Android Automerger
Browse files

SurfaceFlinger: add animation transactions

This change adds a transaction flag for WindowManager to indicate that a
transaction is being used to animate windows around the screen.  SurfaceFlinger
will not allow more than one of these transactions to be outstanding at a time
to prevent the animation "frames" from being dropped.

Bug: 7353840
Change-Id: I6488a6e0e1ed13d27356d2203c9dc766dc6b1759
parent eec9e645
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ public:
    // flags for setTransactionState()
    // flags for setTransactionState()
    enum {
    enum {
        eSynchronous = 0x01,
        eSynchronous = 0x01,
        eAnimation   = 0x02,
    };
    };


    enum {
    enum {
+4 −1
Original line number Original line Diff line number Diff line
@@ -105,6 +105,9 @@ public:
    //! Close a composer transaction on all active SurfaceComposerClients.
    //! Close a composer transaction on all active SurfaceComposerClients.
    static void closeGlobalTransaction(bool synchronous = false);
    static void closeGlobalTransaction(bool synchronous = false);


    //! Flag the currently open transaction as an animation transaction.
    static void setAnimationTransaction();

    status_t    hide(SurfaceID id);
    status_t    hide(SurfaceID id);
    status_t    show(SurfaceID id);
    status_t    show(SurfaceID id);
    status_t    setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
    status_t    setFlags(SurfaceID id, uint32_t flags, uint32_t mask);
+22 −1
Original line number Original line Diff line number Diff line
@@ -115,12 +115,15 @@ class Composer : public Singleton<Composer>
    SortedVector<ComposerState> mComposerStates;
    SortedVector<ComposerState> mComposerStates;
    SortedVector<DisplayState > mDisplayStates;
    SortedVector<DisplayState > mDisplayStates;
    uint32_t                    mForceSynchronous;
    uint32_t                    mForceSynchronous;
    bool                        mAnimation;


    Composer() : Singleton<Composer>(),
    Composer() : Singleton<Composer>(),
        mForceSynchronous(0)
        mForceSynchronous(0),
        mAnimation(false)
    { }
    { }


    void closeGlobalTransactionImpl(bool synchronous);
    void closeGlobalTransactionImpl(bool synchronous);
    void setAnimationTransactionImpl();


    layer_state_t* getLayerStateLocked(
    layer_state_t* getLayerStateLocked(
            const sp<SurfaceComposerClient>& client, SurfaceID id);
            const sp<SurfaceComposerClient>& client, SurfaceID id);
@@ -159,6 +162,10 @@ public:
            const Rect& layerStackRect,
            const Rect& layerStackRect,
            const Rect& displayRect);
            const Rect& displayRect);


    static void setAnimationTransaction() {
        Composer::getInstance().setAnimationTransactionImpl();
    }

    static void closeGlobalTransaction(bool synchronous) {
    static void closeGlobalTransaction(bool synchronous) {
        Composer::getInstance().closeGlobalTransactionImpl(synchronous);
        Composer::getInstance().closeGlobalTransactionImpl(synchronous);
    }
    }
@@ -194,12 +201,22 @@ void Composer::closeGlobalTransactionImpl(bool synchronous) {
        if (synchronous || mForceSynchronous) {
        if (synchronous || mForceSynchronous) {
            flags |= ISurfaceComposer::eSynchronous;
            flags |= ISurfaceComposer::eSynchronous;
        }
        }
        if (mAnimation) {
            flags |= ISurfaceComposer::eAnimation;
        }

        mForceSynchronous = false;
        mForceSynchronous = false;
        mAnimation = false;
    }
    }


   sm->setTransactionState(transaction, displayTransaction, flags);
   sm->setTransactionState(transaction, displayTransaction, flags);
}
}


void Composer::setAnimationTransactionImpl() {
    Mutex::Autolock _l(mLock);
    mAnimation = true;
}

layer_state_t* Composer::getLayerStateLocked(
layer_state_t* Composer::getLayerStateLocked(
        const sp<SurfaceComposerClient>& client, SurfaceID id) {
        const sp<SurfaceComposerClient>& client, SurfaceID id) {


@@ -471,6 +488,10 @@ void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) {
    Composer::closeGlobalTransaction(synchronous);
    Composer::closeGlobalTransaction(synchronous);
}
}


void SurfaceComposerClient::setAnimationTransaction() {
    Composer::setAnimationTransaction();
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) {
status_t SurfaceComposerClient::setCrop(SurfaceID id, const Rect& crop) {
+26 −6
Original line number Original line Diff line number Diff line
@@ -86,7 +86,8 @@ const String16 sDump("android.permission.DUMP");
SurfaceFlinger::SurfaceFlinger()
SurfaceFlinger::SurfaceFlinger()
    :   BnSurfaceComposer(), Thread(false),
    :   BnSurfaceComposer(), Thread(false),
        mTransactionFlags(0),
        mTransactionFlags(0),
        mTransationPending(false),
        mTransactionPending(false),
        mAnimTransactionPending(false),
        mLayersRemoved(false),
        mLayersRemoved(false),
        mRepaintEverything(0),
        mRepaintEverything(0),
        mBootTime(systemTime()),
        mBootTime(systemTime()),
@@ -1264,7 +1265,8 @@ void SurfaceFlinger::commitTransaction()
    }
    }


    mDrawingState = mCurrentState;
    mDrawingState = mCurrentState;
    mTransationPending = false;
    mTransactionPending = false;
    mAnimTransactionPending = false;
    mTransactionCV.broadcast();
    mTransactionCV.broadcast();
}
}


@@ -1665,6 +1667,21 @@ void SurfaceFlinger::setTransactionState(
    Mutex::Autolock _l(mStateLock);
    Mutex::Autolock _l(mStateLock);
    uint32_t transactionFlags = 0;
    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 (mAnimTransactionPending) {
            status_t err = mTransactionCV.waitRelative(mStateLock, 500 * 1000);
            if (CC_UNLIKELY(err != NO_ERROR)) {
                // just in case something goes wrong in SF, return to the
                // caller after a few hundred microseconds.
                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
                mAnimTransactionPending = false;
                break;
            }
        }
    }

    size_t count = displays.size();
    size_t count = displays.size();
    for (size_t i=0 ; i<count ; i++) {
    for (size_t i=0 ; i<count ; i++) {
        const DisplayState& s(displays[i]);
        const DisplayState& s(displays[i]);
@@ -1685,15 +1702,18 @@ void SurfaceFlinger::setTransactionState(
        // if this is a synchronous transaction, wait for it to take effect
        // if this is a synchronous transaction, wait for it to take effect
        // before returning.
        // before returning.
        if (flags & eSynchronous) {
        if (flags & eSynchronous) {
            mTransationPending = true;
            mTransactionPending = true;
        }
        if (flags & eAnimation) {
            mAnimTransactionPending = true;
        }
        }
        while (mTransationPending) {
        while (mTransactionPending) {
            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
            if (CC_UNLIKELY(err != NO_ERROR)) {
            if (CC_UNLIKELY(err != NO_ERROR)) {
                // just in case something goes wrong in SF, return to the
                // just in case something goes wrong in SF, return to the
                // called after a few seconds.
                // called after a few seconds.
                ALOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
                ALOGW_IF(err == TIMED_OUT, "setTransactionState timed out!");
                mTransationPending = false;
                mTransactionPending = false;
                break;
                break;
            }
            }
        }
        }
+2 −1
Original line number Original line Diff line number Diff line
@@ -398,7 +398,8 @@ private:
    volatile int32_t mTransactionFlags;
    volatile int32_t mTransactionFlags;
    Condition mTransactionCV;
    Condition mTransactionCV;
    SortedVector<sp<LayerBase> > mLayerPurgatory;
    SortedVector<sp<LayerBase> > mLayerPurgatory;
    bool mTransationPending;
    bool mTransactionPending;
    bool mAnimTransactionPending;
    Vector<sp<LayerBase> > mLayersPendingRemoval;
    Vector<sp<LayerBase> > mLayersPendingRemoval;


    // protected by mStateLock (but we could use another lock)
    // protected by mStateLock (but we could use another lock)