diff options
-rw-r--r-- | core/java/android/view/RenderNode.java | 4 | ||||
-rw-r--r-- | graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java | 17 | ||||
-rw-r--r-- | libs/hwui/Animator.cpp | 37 | ||||
-rw-r--r-- | libs/hwui/Animator.h | 6 | ||||
-rw-r--r-- | libs/hwui/AnimatorManager.cpp | 42 | ||||
-rw-r--r-- | libs/hwui/AnimatorManager.h | 7 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 6 |
8 files changed, 37 insertions, 86 deletions
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index a4cb7035f2f9..7017ff5a3fa0 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -775,10 +775,6 @@ 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!"); diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 77748a8b12ea..99bc306821ef 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -778,6 +778,7 @@ 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; @@ -1047,13 +1048,16 @@ 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) { - final RenderNode target = mLastSeenTarget.get(); - if (target != null && target.isAttached()) { - target.addAnimator(this); - return true; - } + if (mLastSeenTarget != null && mLastSeenTarget.get() != null) { + setTarget(mLastSeenTarget.get()); + return true; } return false; } @@ -1151,6 +1155,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { if (mListener != null) { mListener.onAnimationEnd(null); } + mTarget = null; } // onFinished: should be called from native diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index 294edb6ecd46..372bcb3b2375 100644 --- a/libs/hwui/Animator.cpp +++ b/libs/hwui/Animator.cpp @@ -33,7 +33,6 @@ namespace uirenderer { BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) : mTarget(nullptr) - , mStagingTarget(nullptr) , mFinalValue(finalValue) , mDeltaValue(0) , mFromValue(0) @@ -83,7 +82,7 @@ void BaseRenderNodeAnimator::setStartDelay(nsecs_t startDelay) { } void BaseRenderNodeAnimator::attach(RenderNode* target) { - mStagingTarget = target; + mTarget = target; onAttached(); } @@ -146,15 +145,6 @@ 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)); } @@ -205,7 +195,6 @@ void BaseRenderNodeAnimator::pushStaging(AnimationContext& context) { } } } - onPushStaging(); } void BaseRenderNodeAnimator::transitionToRunning(AnimationContext& context) { @@ -320,36 +309,18 @@ RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float fi void RenderPropertyAnimator::onAttached() { if (!mHasStartValue - && mStagingTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) { - setStartValue((mStagingTarget->stagingProperties().*mPropertyAccess->getter)()); + && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) { + setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)()); } } void RenderPropertyAnimator::onStagingPlayStateChanged() { if (mStagingPlayState == PlayState::Running) { - 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; - } + (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue()); } 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; } } diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h index fdae0f32d4e6..fcbc11b0306c 100644 --- a/libs/hwui/Animator.h +++ b/libs/hwui/Animator.h @@ -85,7 +85,6 @@ 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 @@ -124,10 +123,8 @@ protected: virtual void onStagingPlayStateChanged() {} virtual void onPlayTimeChanged(nsecs_t playTime) {} - virtual void onPushStaging() {} RenderNode* mTarget; - RenderNode* mStagingTarget; float mFinalValue; float mDeltaValue; @@ -191,7 +188,6 @@ 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); @@ -201,8 +197,6 @@ private: const PropertyAccessors* mPropertyAccess; static const PropertyAccessors PROPERTY_ACCESSOR_LUT[]; - bool mShouldSyncPropertyFields = false; - bool mShouldUpdateStagingProperties = false; }; class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator { diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp index 2198fcc95fe5..2b49b4743d89 100644 --- a/libs/hwui/AnimatorManager.cpp +++ b/libs/hwui/AnimatorManager.cpp @@ -42,23 +42,7 @@ 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) { @@ -74,12 +58,21 @@ 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; + } - // 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)); + 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); } + animator->attach(&mParent); + mAnimators.push_back(std::move(animator)); } mNewAnimators.clear(); } @@ -88,11 +81,6 @@ 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) @@ -166,6 +154,10 @@ 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) {} diff --git a/libs/hwui/AnimatorManager.h b/libs/hwui/AnimatorManager.h index 61f6179d217c..c24ef47a4644 100644 --- a/libs/hwui/AnimatorManager.h +++ b/libs/hwui/AnimatorManager.h @@ -39,13 +39,11 @@ public: ~AnimatorManager(); void addAnimator(const sp<BaseRenderNodeAnimator>& animator); - void removeAnimator(const sp<BaseRenderNodeAnimator>& animator); void setAnimationHandle(AnimationHandle* handle); bool hasAnimationHandle() { return mAnimationHandle; } void pushStaging(); - void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator); // Returns the combined dirty mask of all animators run uint32_t animate(TreeInfo& info); @@ -64,10 +62,15 @@ public: private: uint32_t animateCommon(TreeInfo& info); + // This would remove the animator from mAnimators list. It should only be called during + // push staging. + void removeActiveAnimator(const sp<BaseRenderNodeAnimator>& animator); + RenderNode& mParent; AnimationHandle* mAnimationHandle; // To improve the efficiency of resizing & removing from the vector + // use manual ref counting instead of sp<>. std::vector< sp<BaseRenderNodeAnimator> > mNewAnimators; std::vector< sp<BaseRenderNodeAnimator> > mAnimators; }; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 9ac76a4339e1..bade216b3b21 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -218,10 +218,6 @@ void RenderNode::addAnimator(const sp<BaseRenderNodeAnimator>& animator) { mAnimatorManager.addAnimator(animator); } -void RenderNode::removeAnimator(const sp<BaseRenderNodeAnimator>& animator) { - mAnimatorManager.removeAnimator(animator); -} - void RenderNode::damageSelf(TreeInfo& info) { if (isRenderable()) { if (properties().getClipDamageToBounds()) { diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index e0376450178f..f248de54acba 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -187,12 +187,6 @@ public: // UI thread only! ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator); - void removeAnimator(const sp<BaseRenderNodeAnimator>& animator); - - // This can only happen during pushStaging() - void onAnimatorTargetChanged(BaseRenderNodeAnimator* animator) { - mAnimatorManager.onAnimatorTargetChanged(animator); - } AnimatorManager& animators() { return mAnimatorManager; } |