Merge "Fix VD animator not being properly resumed" into nyc-mr1-dev

This commit is contained in:
Doris Liu
2016-07-20 23:10:52 +00:00
committed by Android (Google) Code Review

View File

@@ -188,7 +188,7 @@ public:
virtual void prepareTree(TreeInfo& info) override {
info.errorHandler = this;
for (auto& anim : mVectorDrawableAnimators) {
for (auto& anim : mRunningVDAnimators) {
// Assume that the property change in VD from the animators will not be consumed. Mark
// otherwise if the VDs are found in the display list tree. For VDs that are not in
// the display list tree, we stop providing animation pulses by 1) removing them from
@@ -196,6 +196,11 @@ public:
// listeners can receive the corresponding callbacks.
anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
}
if (info.mode == TreeInfo::MODE_FULL) {
for (auto &anim : mPausedVDAnimators) {
anim->getVectorDrawable()->setPropertyChangeWillBeConsumed(false);
}
}
// TODO: This is hacky
info.windowInsetLeft = -stagingProperties().getLeft();
info.windowInsetTop = -stagingProperties().getTop();
@@ -206,17 +211,33 @@ public:
info.windowInsetTop = 0;
info.errorHandler = nullptr;
for (auto it = mVectorDrawableAnimators.begin(); it != mVectorDrawableAnimators.end();) {
for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
if (!(*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
// Vector Drawable is not in the display list, we should remove this animator from
// the list and post a delayed message to end the animator.
// the list, put it in the paused list, and post a delayed message to end the
// animator.
detachVectorDrawableAnimator(it->get());
it = mVectorDrawableAnimators.erase(it);
mPausedVDAnimators.insert(*it);
it = mRunningVDAnimators.erase(it);
} else {
++it;
it++;
}
}
info.out.hasAnimations |= !mVectorDrawableAnimators.empty();
if (info.mode == TreeInfo::MODE_FULL) {
// Check whether any paused animator's target is back in Display List. If so, put the
// animator back in the running list.
for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
if ((*it)->getVectorDrawable()->getPropertyChangeWillBeConsumed()) {
mRunningVDAnimators.insert(*it);
it = mPausedVDAnimators.erase(it);
} else {
it++;
}
}
}
info.out.hasAnimations |= !mRunningVDAnimators.empty();
}
void sendMessage(const sp<MessageHandler>& handler) {
@@ -232,17 +253,18 @@ public:
}
void attachPendingVectorDrawableAnimators() {
mVectorDrawableAnimators.insert(mPendingVectorDrawableAnimators.begin(),
mRunningVDAnimators.insert(mPendingVectorDrawableAnimators.begin(),
mPendingVectorDrawableAnimators.end());
mPendingVectorDrawableAnimators.clear();
}
void detachAnimators() {
// Remove animators from the list and post a delayed message in future to end the animator
for (auto& anim : mVectorDrawableAnimators) {
for (auto& anim : mRunningVDAnimators) {
detachVectorDrawableAnimator(anim.get());
}
mVectorDrawableAnimators.clear();
mRunningVDAnimators.clear();
mPausedVDAnimators.clear();
}
void doAttachAnimatingNodes(AnimationContext* context) {
@@ -253,18 +275,48 @@ public:
mPendingAnimatingRenderNodes.clear();
}
void runVectorDrawableAnimators(AnimationContext* context) {
for (auto it = mVectorDrawableAnimators.begin(); it != mVectorDrawableAnimators.end();) {
void runVectorDrawableAnimators(AnimationContext* context, TreeInfo::TraversalMode mode) {
for (auto it = mRunningVDAnimators.begin(); it != mRunningVDAnimators.end();) {
if ((*it)->animate(*context)) {
it = mVectorDrawableAnimators.erase(it);
it = mRunningVDAnimators.erase(it);
} else {
++it;
it++;
}
}
if (mode == TreeInfo::MODE_FULL) {
// During full sync we also need to pulse paused animators, in case their targets
// have been added back to the display list. All the animators that passed the
// scheduled finish time will be removed from the paused list.
for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
if ((*it)->animate(*context)) {
// Animator has finished, remove from the list.
it = mPausedVDAnimators.erase(it);
} else {
it++;
}
}
}
}
void trimPausedVDAnimators(AnimationContext* context) {
// Trim paused vector drawable animator list.
for (auto it = mPausedVDAnimators.begin(); it != mPausedVDAnimators.end();) {
// Remove paused VD animator if no one else is referencing it. Note that animators that
// have passed scheduled finish time are removed from list when they are being pulsed
// before prepare tree.
// TODO: this is a bit hacky, need to figure out a better way to track when the paused
// animators should be freed.
if ((*it)->getStrongCount() == 1) {
it = mPausedVDAnimators.erase(it);
} else {
it++;
}
}
}
void pushStagingVectorDrawableAnimators(AnimationContext* context) {
for (auto& anim : mVectorDrawableAnimators) {
for (auto& anim : mRunningVDAnimators) {
anim->pushStaging(*context);
}
}
@@ -286,7 +338,15 @@ private:
JavaVM* mVm;
std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
std::set< sp<PropertyValuesAnimatorSet> > mPendingVectorDrawableAnimators;
std::set< sp<PropertyValuesAnimatorSet> > mVectorDrawableAnimators;
std::set< sp<PropertyValuesAnimatorSet> > mRunningVDAnimators;
// mPausedVDAnimators stores a list of animators that have not yet passed the finish time, but
// their VectorDrawable targets are no longer in the DisplayList. We skip these animators when
// render thread runs animators independent of UI thread (i.e. RT_ONLY mode). These animators
// need to be re-activated once their VD target is added back into DisplayList. Since that could
// only happen when we do a full sync, we need to make sure to pulse these paused animators at
// full sync. If any animator's VD target is found in DisplayList during a full sync, we move
// the animator back to the running list.
std::set< sp<PropertyValuesAnimatorSet> > mPausedVDAnimators;
void detachVectorDrawableAnimator(PropertyValuesAnimatorSet* anim) {
if (anim->isInfinite() || !anim->isRunning()) {
// Do not need to post anything if the animation is infinite (i.e. no meaningful
@@ -336,13 +396,20 @@ public:
if (mode == TreeInfo::MODE_FULL) {
mRootNode->pushStagingVectorDrawableAnimators(this);
}
mRootNode->runVectorDrawableAnimators(this);
mRootNode->runVectorDrawableAnimators(this, mode);
}
// Runs any animations still left in mCurrentFrameAnimations
virtual void runRemainingAnimations(TreeInfo& info) {
AnimationContext::runRemainingAnimations(info);
postOnFinishedEvents();
if (info.mode == TreeInfo::MODE_FULL) {
// Trim paused VD animators at full sync, so that when Java loses reference to an
// animator, we know we won't be requested to animate it any more, then we remove such
// animators from the paused list so they can be properly freed. We also remove the
// animators from paused list when the time elapsed since start has exceeded duration.
mRootNode->trimPausedVDAnimators(this);
}
}
virtual void detachAnimators() override {