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

Commit 51060f3f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Switch to callback animation"

parents cde76928 ce637139
Loading
Loading
Loading
Loading
+40 −11
Original line number Original line Diff line number Diff line
@@ -168,7 +168,7 @@ void MouseCursorController::fade(PointerControllerInterface::Transition transiti
        updatePointerLocked();
        updatePointerLocked();
    } else {
    } else {
        mLocked.pointerFadeDirection = -1;
        mLocked.pointerFadeDirection = -1;
        mContext.startAnimation();
        startAnimationLocked();
    }
    }
}
}


@@ -185,7 +185,7 @@ void MouseCursorController::unfade(PointerControllerInterface::Transition transi
        updatePointerLocked();
        updatePointerLocked();
    } else {
    } else {
        mLocked.pointerFadeDirection = 1;
        mLocked.pointerFadeDirection = 1;
        mContext.startAnimation();
        startAnimationLocked();
    }
    }
}
}


@@ -312,10 +312,9 @@ void MouseCursorController::setCustomPointerIcon(const SpriteIcon& icon) {
    updatePointerLocked();
    updatePointerLocked();
}
}


bool MouseCursorController::doFadingAnimation(nsecs_t timestamp, bool keepAnimating) {
bool MouseCursorController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
    nsecs_t frameDelay = timestamp - mContext.getAnimationTime();
    nsecs_t frameDelay = timestamp - mContext.getAnimationTime();

    bool keepAnimating = false;
    std::scoped_lock lock(mLock);


    // Animate pointer fade.
    // Animate pointer fade.
    if (mLocked.pointerFadeDirection < 0) {
    if (mLocked.pointerFadeDirection < 0) {
@@ -337,13 +336,10 @@ bool MouseCursorController::doFadingAnimation(nsecs_t timestamp, bool keepAnimat
        }
        }
        updatePointerLocked();
        updatePointerLocked();
    }
    }

    return keepAnimating;
    return keepAnimating;
}
}


bool MouseCursorController::doBitmapAnimation(nsecs_t timestamp) {
bool MouseCursorController::doBitmapAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) {
    std::scoped_lock lock(mLock);

    std::map<int32_t, PointerAnimation>::const_iterator iter =
    std::map<int32_t, PointerAnimation>::const_iterator iter =
            mLocked.animationResources.find(mLocked.requestedPointerType);
            mLocked.animationResources.find(mLocked.requestedPointerType);
    if (iter == mLocked.animationResources.end()) {
    if (iter == mLocked.animationResources.end()) {
@@ -364,7 +360,6 @@ bool MouseCursorController::doBitmapAnimation(nsecs_t timestamp) {


        spriteController->closeTransaction();
        spriteController->closeTransaction();
    }
    }

    // Keep animating.
    // Keep animating.
    return true;
    return true;
}
}
@@ -399,7 +394,7 @@ void MouseCursorController::updatePointerLocked() REQUIRES(mLock) {
                if (anim_iter != mLocked.animationResources.end()) {
                if (anim_iter != mLocked.animationResources.end()) {
                    mLocked.animationFrameIndex = 0;
                    mLocked.animationFrameIndex = 0;
                    mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
                    mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC);
                    mContext.startAnimation();
                    startAnimationLocked();
                }
                }
                mLocked.pointerSprite->setIcon(iter->second);
                mLocked.pointerSprite->setIcon(iter->second);
            } else {
            } else {
@@ -457,4 +452,38 @@ bool MouseCursorController::resourcesLoaded() {
    return mLocked.resourcesLoaded;
    return mLocked.resourcesLoaded;
}
}


bool MouseCursorController::doAnimations(nsecs_t timestamp) {
    std::scoped_lock lock(mLock);
    bool keepFading = doFadingAnimationLocked(timestamp);
    bool keepBitmap = doBitmapAnimationLocked(timestamp);
    bool keepAnimating = keepFading || keepBitmap;
    if (!keepAnimating) {
        /*
         * We know that this callback will be removed before another
         * is added. mLock in PointerAnimator will not be released
         * until after this is removed, and adding another callback
         * requires that lock. Thus it's safe to set mLocked.animating
         * here.
         */
        mLocked.animating = false;
    }
    return keepAnimating;
}

void MouseCursorController::startAnimationLocked() REQUIRES(mLock) {
    using namespace std::placeholders;

    if (mLocked.animating) {
        return;
    }
    mLocked.animating = true;

    std::function<bool(nsecs_t)> func = std::bind(&MouseCursorController::doAnimations, this, _1);
    /*
     * Using -1 for displayId here to avoid removing the callback
     * if a TouchSpotController with the same display is removed.
     */
    mContext.addAnimationCallback(-1, func);
}

} // namespace android
} // namespace android
+9 −2
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@
#include <utils/Looper.h>
#include <utils/Looper.h>
#include <utils/RefBase.h>
#include <utils/RefBase.h>


#include <functional>
#include <map>
#include <map>
#include <memory>
#include <memory>
#include <vector>
#include <vector>
@@ -61,8 +62,7 @@ public:
    void getAdditionalMouseResources();
    void getAdditionalMouseResources();
    bool isViewportValid();
    bool isViewportValid();


    bool doBitmapAnimation(nsecs_t timestamp);
    bool doAnimations(nsecs_t timestamp);
    bool doFadingAnimation(nsecs_t timestamp, bool keepAnimating);


    bool resourcesLoaded();
    bool resourcesLoaded();


@@ -96,6 +96,8 @@ private:


        int32_t buttonState;
        int32_t buttonState;


        bool animating{false};

    } mLocked GUARDED_BY(mLock);
    } mLocked GUARDED_BY(mLock);


    bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
    bool getBoundsLocked(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const;
@@ -104,6 +106,11 @@ private:
    void updatePointerLocked();
    void updatePointerLocked();


    void loadResourcesLocked(bool getAdditionalMouseResources);
    void loadResourcesLocked(bool getAdditionalMouseResources);

    bool doBitmapAnimationLocked(nsecs_t timestamp);
    bool doFadingAnimationLocked(nsecs_t timestamp);

    void startAnimationLocked();
};
};


} // namespace android
} // namespace android
+5 −19
Original line number Original line Diff line number Diff line
@@ -57,7 +57,6 @@ std::shared_ptr<PointerController> PointerController::create(


    controller->mContext.setHandlerController(controller);
    controller->mContext.setHandlerController(controller);
    controller->mContext.setCallbackController(controller);
    controller->mContext.setCallbackController(controller);
    controller->mContext.initializeDisplayEventReceiver();
    return controller;
    return controller;
}
}


@@ -189,24 +188,6 @@ void PointerController::setCustomPointerIcon(const SpriteIcon& icon) {
    mCursorController.setCustomPointerIcon(icon);
    mCursorController.setCustomPointerIcon(icon);
}
}


void PointerController::doAnimate(nsecs_t timestamp) {
    std::scoped_lock lock(mLock);

    mContext.setAnimationPending(false);

    bool keepFading = false;
    keepFading = mCursorController.doFadingAnimation(timestamp, keepFading);

    for (auto& [displayID, spotController] : mLocked.spotControllers) {
        keepFading = spotController.doFadingAnimation(timestamp, keepFading);
    }

    bool keepBitmapFlipping = mCursorController.doBitmapAnimation(timestamp);
    if (keepFading || keepBitmapFlipping) {
        mContext.startAnimation();
    }
}

void PointerController::doInactivityTimeout() {
void PointerController::doInactivityTimeout() {
    fade(Transition::GRADUAL);
    fade(Transition::GRADUAL);
}
}
@@ -221,6 +202,11 @@ void PointerController::onDisplayViewportsUpdated(std::vector<DisplayViewport>&
    for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
    for (auto it = mLocked.spotControllers.begin(); it != mLocked.spotControllers.end();) {
        int32_t displayID = it->first;
        int32_t displayID = it->first;
        if (!displayIdSet.count(displayID)) {
        if (!displayIdSet.count(displayID)) {
            /*
             * Ensures that an in-progress animation won't dereference
             * a null pointer to TouchSpotController.
             */
            mContext.removeAnimationCallback(displayID);
            it = mLocked.spotControllers.erase(it);
            it = mLocked.spotControllers.erase(it);
        } else {
        } else {
            ++it;
            ++it;
+0 −1
Original line number Original line Diff line number Diff line
@@ -70,7 +70,6 @@ public:
    void setCustomPointerIcon(const SpriteIcon& icon);
    void setCustomPointerIcon(const SpriteIcon& icon);
    void setInactivityTimeout(InactivityTimeout inactivityTimeout);
    void setInactivityTimeout(InactivityTimeout inactivityTimeout);
    void doInactivityTimeout();
    void doInactivityTimeout();
    void doAnimate(nsecs_t timestamp);
    void reloadPointerResources();
    void reloadPointerResources();
    void onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports);
    void onDisplayViewportsUpdated(std::vector<DisplayViewport>& viewports);


+92 −43
Original line number Original line Diff line number Diff line
@@ -38,10 +38,10 @@ PointerControllerContext::PointerControllerContext(
        mSpriteController(spriteController),
        mSpriteController(spriteController),
        mHandler(new MessageHandler()),
        mHandler(new MessageHandler()),
        mCallback(new LooperCallback()),
        mCallback(new LooperCallback()),
        mController(controller) {
        mController(controller),
        mAnimator(*this) {
    std::scoped_lock lock(mLock);
    std::scoped_lock lock(mLock);
    mLocked.inactivityTimeout = InactivityTimeout::NORMAL;
    mLocked.inactivityTimeout = InactivityTimeout::NORMAL;
    mLocked.animationPending = false;
}
}


PointerControllerContext::~PointerControllerContext() {
PointerControllerContext::~PointerControllerContext() {
@@ -57,15 +57,6 @@ void PointerControllerContext::setInactivityTimeout(InactivityTimeout inactivity
    }
    }
}
}


void PointerControllerContext::startAnimation() {
    std::scoped_lock lock(mLock);
    if (!mLocked.animationPending) {
        mLocked.animationPending = true;
        mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
        mDisplayEventReceiver.requestNextVsync();
    }
}

void PointerControllerContext::resetInactivityTimeout() {
void PointerControllerContext::resetInactivityTimeout() {
    std::scoped_lock lock(mLock);
    std::scoped_lock lock(mLock);
    resetInactivityTimeoutLocked();
    resetInactivityTimeoutLocked();
@@ -85,14 +76,8 @@ void PointerControllerContext::removeInactivityTimeout() {
    mLooper->removeMessages(mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
    mLooper->removeMessages(mHandler, MessageHandler::MSG_INACTIVITY_TIMEOUT);
}
}


void PointerControllerContext::setAnimationPending(bool animationPending) {
nsecs_t PointerControllerContext::getAnimationTime() REQUIRES(mAnimator.mLock) {
    std::scoped_lock lock(mLock);
    return mAnimator.getAnimationTimeLocked();
    mLocked.animationPending = animationPending;
}

nsecs_t PointerControllerContext::getAnimationTime() {
    std::scoped_lock lock(mLock);
    return mLocked.animationTime;
}
}


void PointerControllerContext::setHandlerController(std::shared_ptr<PointerController> controller) {
void PointerControllerContext::setHandlerController(std::shared_ptr<PointerController> controller) {
@@ -112,31 +97,8 @@ sp<SpriteController> PointerControllerContext::getSpriteController() {
    return mSpriteController;
    return mSpriteController;
}
}


void PointerControllerContext::initializeDisplayEventReceiver() {
    if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
        mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK, Looper::EVENT_INPUT,
                       mCallback, nullptr);
    } else {
        ALOGE("Failed to initialize DisplayEventReceiver.");
    }
}

void PointerControllerContext::handleDisplayEvents() {
void PointerControllerContext::handleDisplayEvents() {
    bool gotVsync = false;
    mAnimator.handleVsyncEvents();
    ssize_t n;
    nsecs_t timestamp;
    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
    while ((n = mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
        for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
            if (buf[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                timestamp = buf[i].header.timestamp;
                gotVsync = true;
            }
        }
    }
    if (gotVsync) {
        mController.doAnimate(timestamp);
    }
}
}


void PointerControllerContext::MessageHandler::handleMessage(const Message& message) {
void PointerControllerContext::MessageHandler::handleMessage(const Message& message) {
@@ -176,4 +138,91 @@ int PointerControllerContext::LooperCallback::handleEvent(int /* fd */, int even
    return 1; // keep the callback
    return 1; // keep the callback
}
}


void PointerControllerContext::addAnimationCallback(int32_t displayId,
                                                    std::function<bool(nsecs_t)> callback) {
    mAnimator.addCallback(displayId, callback);
}

void PointerControllerContext::removeAnimationCallback(int32_t displayId) {
    mAnimator.removeCallback(displayId);
}

PointerControllerContext::PointerAnimator::PointerAnimator(PointerControllerContext& context)
      : mContext(context) {
    initializeDisplayEventReceiver();
}

void PointerControllerContext::PointerAnimator::initializeDisplayEventReceiver() {
    if (mDisplayEventReceiver.initCheck() == NO_ERROR) {
        mContext.mLooper->addFd(mDisplayEventReceiver.getFd(), Looper::POLL_CALLBACK,
                                Looper::EVENT_INPUT, mContext.mCallback, nullptr);
    } else {
        ALOGE("Failed to initialize DisplayEventReceiver.");
    }
}

void PointerControllerContext::PointerAnimator::addCallback(int32_t displayId,
                                                            std::function<bool(nsecs_t)> callback) {
    std::scoped_lock lock(mLock);
    mLocked.callbacks[displayId] = callback;
    startAnimationLocked();
}

void PointerControllerContext::PointerAnimator::removeCallback(int32_t displayId) {
    std::scoped_lock lock(mLock);
    auto it = mLocked.callbacks.find(displayId);
    if (it == mLocked.callbacks.end()) {
        return;
    }
    mLocked.callbacks.erase(it);
}

void PointerControllerContext::PointerAnimator::handleVsyncEvents() {
    bool gotVsync = false;
    ssize_t n;
    nsecs_t timestamp;
    DisplayEventReceiver::Event buf[EVENT_BUFFER_SIZE];
    while ((n = mDisplayEventReceiver.getEvents(buf, EVENT_BUFFER_SIZE)) > 0) {
        for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
            if (buf[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                timestamp = buf[i].header.timestamp;
                gotVsync = true;
            }
        }
    }
    if (gotVsync) {
        std::scoped_lock lock(mLock);
        mLocked.animationPending = false;
        handleCallbacksLocked(timestamp);
    }
}

nsecs_t PointerControllerContext::PointerAnimator::getAnimationTimeLocked() REQUIRES(mLock) {
    return mLocked.animationTime;
}

void PointerControllerContext::PointerAnimator::startAnimationLocked() REQUIRES(mLock) {
    if (!mLocked.animationPending) {
        mLocked.animationPending = true;
        mLocked.animationTime = systemTime(SYSTEM_TIME_MONOTONIC);
        mDisplayEventReceiver.requestNextVsync();
    }
}

void PointerControllerContext::PointerAnimator::handleCallbacksLocked(nsecs_t timestamp)
        REQUIRES(mLock) {
    for (auto it = mLocked.callbacks.begin(); it != mLocked.callbacks.end();) {
        bool keepCallback = it->second(timestamp);
        if (!keepCallback) {
            it = mLocked.callbacks.erase(it);
        } else {
            ++it;
        }
    }

    if (!mLocked.callbacks.empty()) {
        startAnimationLocked();
    }
}

} // namespace android
} // namespace android
Loading