summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/RenderNode.java4
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java17
-rw-r--r--libs/hwui/Animator.cpp37
-rw-r--r--libs/hwui/Animator.h6
-rw-r--r--libs/hwui/AnimatorManager.cpp42
-rw-r--r--libs/hwui/AnimatorManager.h7
-rw-r--r--libs/hwui/RenderNode.cpp4
-rw-r--r--libs/hwui/RenderNode.h6
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; }