Merge "Revert "Check RenderNode's owning view before attaching animators"" into nyc-dev
This commit is contained in:
@@ -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!");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 new animators that are not already in the mAnimators list
|
||||
for (auto& anim : mNewAnimators) {
|
||||
if (anim->target() != &mParent) {
|
||||
mAnimators.push_back(std::move(anim));
|
||||
// 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);
|
||||
}
|
||||
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) {}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user