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

Commit e87a74e1 authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Revert "Revert "Check RenderNode's owning view before attaching animators""" into nyc-dev

parents 0a1cdee3 8b083206
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -775,6 +775,10 @@ public class RenderNode {
        mOwningView.mAttachInfo.mViewRootImpl.registerAnimatingRenderNode(this);
    }

    public boolean isAttached() {
        return mOwningView != null && mOwningView.mAttachInfo != null;
    }

    public void addAnimator(AnimatedVectorDrawable.VectorDrawableAnimator animatorSet) {
        if (mOwningView == null || mOwningView.mAttachInfo == null) {
            throw new IllegalStateException("Cannot start this animator on a detached view!");
+6 −11
Original line number Diff line number Diff line
@@ -778,7 +778,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
        private boolean mShouldIgnoreInvalidAnim;
        // TODO: Consider using NativeAllocationRegistery to track native allocation
        private final VirtualRefBasePtr mSetRefBasePtr;
        private WeakReference<RenderNode> mTarget = null;
        private WeakReference<RenderNode> mLastSeenTarget = null;
        private int mLastListenerId = 0;
        private int mPendingAnimationAction = NONE;
@@ -1048,17 +1047,14 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
            }
        }

        private boolean setTarget(RenderNode node) {
            node.addAnimator(this);
            mTarget = new WeakReference<RenderNode>(node);
            return true;
        }

        private boolean useLastSeenTarget() {
            if (mLastSeenTarget != null && mLastSeenTarget.get() != null) {
                setTarget(mLastSeenTarget.get());
            if (mLastSeenTarget != null) {
                final RenderNode target = mLastSeenTarget.get();
                if (target != null && target.isAttached()) {
                    target.addAnimator(this);
                    return true;
                }
            }
            return false;
        }

@@ -1155,7 +1151,6 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
            if (mListener != null) {
                mListener.onAnimationEnd(null);
            }
            mTarget = null;
        }

        // onFinished: should be called from native
+33 −4
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ namespace uirenderer {

BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
        : mTarget(nullptr)
        , mStagingTarget(nullptr)
        , mFinalValue(finalValue)
        , mDeltaValue(0)
        , mFromValue(0)
@@ -82,7 +83,7 @@ void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) {
}

void BaseRenderNodeAnimator::attach(RenderNode* target) {
    mTarget = target;
    mStagingTarget = target;
    onAttached();
}

@@ -145,6 +146,15 @@ void BaseRenderNodeAnimator::resolveStagingRequest(Request request) {
}

void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) {
    if (mStagingTarget) {
        RenderNode* oldTarget = mTarget;
        mTarget = mStagingTarget;
        mStagingTarget = nullptr;
        if (oldTarget && oldTarget != mTarget) {
            oldTarget->onAnimatorTargetChanged(this);
        }
    }

    if (!mHasStartValue) {
        doSetStartValue(getValue(mTarget));
    }
@@ -195,6 +205,7 @@ void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) {
            }
        }
    }
    onPushStaging();
}

void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) {
@@ -309,18 +320,36 @@ RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float fi

void RenderPropertyAnimator::onAttached() {
    if (!mHasStartValue
            && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
        setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
            && mStagingTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
        setStartValue((mStagingTarget->stagingProperties().*mPropertyAccess->getter)());
    }
}

void RenderPropertyAnimator::onStagingPlayStateChanged() {
    if (mStagingPlayState == PlayState::Running) {
        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
        if (mStagingTarget) {
            (mStagingTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
        } else {
            // In the case of start delay where stagingTarget has been sync'ed over and null'ed
            // we delay the properties update to push staging.
            mShouldUpdateStagingProperties = true;
        }
    } else if (mStagingPlayState == PlayState::Finished) {
        // We're being canceled, so make sure that whatever values the UI thread
        // is observing for us is pushed over
        mShouldSyncPropertyFields = true;
    }
}

void RenderPropertyAnimator::onPushStaging() {
    if (mShouldUpdateStagingProperties) {
        (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
        mShouldUpdateStagingProperties = false;
    }

    if (mShouldSyncPropertyFields) {
        mTarget->setPropertyFieldsDirty(dirtyMask());
        mShouldSyncPropertyFields = false;
    }
}

+6 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ public:

    void forceEndNow(AnimationContext& context);
    RenderNode* target() { return mTarget; }
    RenderNode* stagingTarget() { return mStagingTarget; }

protected:
    // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI
@@ -123,8 +124,10 @@ protected:

    virtual void onStagingPlayStateChanged() {}
    virtual void onPlayTimeChanged(nsecs_t playTime) {}
    virtual void onPushStaging() {}

    RenderNode* mTarget;
    RenderNode* mStagingTarget;

    float mFinalValue;
    float mDeltaValue;
@@ -188,6 +191,7 @@ protected:
    virtual void setValue(RenderNode* target, float value) override;
    virtual void onAttached() override;
    virtual void onStagingPlayStateChanged() override;
    virtual void onPushStaging() override;

private:
    typedef bool (RenderProperties::*SetFloatProperty)(float value);
@@ -197,6 +201,8 @@ private:
    const PropertyAccessors* mPropertyAccess;

    static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
    bool mShouldSyncPropertyFields = false;
    bool mShouldUpdateStagingProperties = false;
};

class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
+25 −17
Original line number Diff line number Diff line
@@ -42,7 +42,23 @@ AnimatorManager::~AnimatorManager() {
}

void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
    RenderNode* stagingTarget = animator->stagingTarget();
    if (stagingTarget == &mParent) {
        return;
    }
    mNewAnimators.emplace_back(animator.get());
    // If the animator is already attached to other RenderNode, remove it from that RenderNode's
    // new animator list. This ensures one animator only ends up in one newAnimatorList during one
    // frame, even when it's added multiple times to multiple targets.
    if (stagingTarget) {
        stagingTarget->removeAnimator(animator);
    }
    animator->attach(&mParent);
}

void AnimatorManager::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) {
    mNewAnimators.erase(std::remove(mNewAnimators.begin(), mNewAnimators.end(), animator),
            mNewAnimators.end());
}

void AnimatorManager::setAnimationHandle(AnimationHandle* handle) {
@@ -58,21 +74,12 @@ void AnimatorManager::pushStaging() {
        LOG_ALWAYS_FATAL_IF(!mAnimationHandle,
                "Trying to start new animators on %p (%s) without an animation handle!",
                &mParent, mParent.getName());
        // Only add animators that are not already in the on-going animator list.
        for (auto& animator : mNewAnimators) {
            RenderNode* targetRenderNode = animator->target();
            if (targetRenderNode == &mParent) {
                // Animator already in the animator list: skip adding again
                continue;
            }

            if (targetRenderNode){
                // If the animator is already in another RenderNode's animator list, remove animator from
                // that list and add animator to current RenderNode's list.
                targetRenderNode->animators().removeActiveAnimator(animator);
        // Only add new animators that are not already in the mAnimators list
        for (auto& anim : mNewAnimators) {
            if (anim->target() != &mParent) {
                mAnimators.push_back(std::move(anim));
            }
            animator->attach(&mParent);
            mAnimators.push_back(std::move(animator));
        }
        mNewAnimators.clear();
    }
@@ -81,6 +88,11 @@ void AnimatorManager::pushStaging() {
    }
}

void AnimatorManager::onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) {
    LOG_ALWAYS_FATAL_IF(animator->target() == &mParent, "Target has not been changed");
    mAnimators.erase(std::remove(mAnimators.begin(), mAnimators.end(), animator), mAnimators.end());
}

class AnimateFunctor {
public:
    AnimateFunctor(TreeInfo& info, AnimationContext& context)
@@ -154,10 +166,6 @@ void AnimatorManager::endAllStagingAnimators() {
    mNewAnimators.clear();
}

void AnimatorManager::removeActiveAnimator(const sp<BaseRenderNodeAnimator>& animator) {
    std::remove(mAnimators.begin(), mAnimators.end(), animator);
}

class EndActiveAnimatorsFunctor {
public:
    EndActiveAnimatorsFunctor(AnimationContext& context) : mContext(context) {}
Loading