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

This commit is contained in:
Doris Liu
2016-02-19 22:45:14 +00:00
committed by Android (Google) Code Review
8 changed files with 86 additions and 37 deletions

View File

@@ -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!");

View File

@@ -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,16 +1047,13 @@ 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());
return true;
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

View File

@@ -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;
}
}

View File

@@ -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 {

View File

@@ -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) {}

View File

@@ -39,11 +39,13 @@ 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);
@@ -62,15 +64,10 @@ 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;
};

View File

@@ -218,6 +218,10 @@ 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()) {

View File

@@ -187,6 +187,12 @@ 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; }