Loading core/java/android/view/RenderNode.java +4 −0 Original line number Diff line number Diff line Loading @@ -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!"); Loading graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +6 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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 Loading libs/hwui/Animator.cpp +33 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ namespace uirenderer { BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) : mTarget(nullptr) , mStagingTarget(nullptr) , mFinalValue(finalValue) , mDeltaValue(0) , mFromValue(0) Loading Loading @@ -82,7 +83,7 @@ void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) { } void BaseRenderNodeAnimator::attach(RenderNode* target) { mTarget = target; mStagingTarget = target; onAttached(); } Loading Loading @@ -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)); } Loading Loading @@ -195,6 +205,7 @@ void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) { } } } onPushStaging(); } void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) { Loading Loading @@ -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; } } Loading libs/hwui/Animator.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -197,6 +201,8 @@ private: const PropertyAccessors* mPropertyAccess; static const PropertyAccessors PROPERTY_ACCESSOR_LUT[]; bool mShouldSyncPropertyFields = false; bool mShouldUpdateStagingProperties = false; }; class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator { Loading libs/hwui/AnimatorManager.cpp +25 −17 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); } Loading @@ -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) Loading Loading @@ -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 Loading
core/java/android/view/RenderNode.java +4 −0 Original line number Diff line number Diff line Loading @@ -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!"); Loading
graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +6 −11 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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 Loading
libs/hwui/Animator.cpp +33 −4 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ namespace uirenderer { BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) : mTarget(nullptr) , mStagingTarget(nullptr) , mFinalValue(finalValue) , mDeltaValue(0) , mFromValue(0) Loading Loading @@ -82,7 +83,7 @@ void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) { } void BaseRenderNodeAnimator::attach(RenderNode* target) { mTarget = target; mStagingTarget = target; onAttached(); } Loading Loading @@ -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)); } Loading Loading @@ -195,6 +205,7 @@ void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) { } } } onPushStaging(); } void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) { Loading Loading @@ -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; } } Loading
libs/hwui/Animator.h +6 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -197,6 +201,8 @@ private: const PropertyAccessors* mPropertyAccess; static const PropertyAccessors PROPERTY_ACCESSOR_LUT[]; bool mShouldSyncPropertyFields = false; bool mShouldUpdateStagingProperties = false; }; class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator { Loading
libs/hwui/AnimatorManager.cpp +25 −17 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); } Loading @@ -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) Loading Loading @@ -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