Fixes to startDelay
Bug: 15991758
Don't update the UI thread with final value until after
startDelay
Change-Id: Ie8bffb5a3ace353ec1d82943a4efcbd01c42c28f
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index 4a8c122..f3ef48b 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -32,7 +32,8 @@
************************************************************/
BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue)
- : mFinalValue(finalValue)
+ : mTarget(NULL)
+ , mFinalValue(finalValue)
, mDeltaValue(0)
, mFromValue(0)
, mInterpolator(0)
@@ -81,9 +82,14 @@
mStartDelay = startDelay;
}
-void BaseRenderNodeAnimator::pushStaging(RenderNode* target, TreeInfo& info) {
+void BaseRenderNodeAnimator::attach(RenderNode* target) {
+ mTarget = target;
+ onAttached();
+}
+
+void BaseRenderNodeAnimator::pushStaging(TreeInfo& info) {
if (!mHasStartValue) {
- doSetStartValue(getValue(target));
+ doSetStartValue(getValue(mTarget));
}
if (mStagingPlayState > mPlayState) {
mPlayState = mStagingPlayState;
@@ -109,20 +115,25 @@
}
// No interpolator was set, use the default
if (!mInterpolator) {
- setInterpolator(Interpolator::createDefaultInterpolator());
+ mInterpolator = Interpolator::createDefaultInterpolator();
}
if (mDuration < 0 || mDuration > 50000) {
ALOGW("Your duration is strange and confusing: %" PRId64, mDuration);
}
}
-bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) {
+bool BaseRenderNodeAnimator::animate(TreeInfo& info) {
if (mPlayState < RUNNING) {
return false;
}
+ // If BaseRenderNodeAnimator is handling the delay (not typical), then
+ // because the staging properties reflect the final value, we always need
+ // to call setValue even if the animation isn't yet running or is still
+ // being delayed as we need to override the staging value
if (mStartTime > info.frameTimeMs) {
info.out.hasAnimations |= true;
+ setValue(mTarget, mFromValue);
return false;
}
@@ -136,7 +147,7 @@
}
fraction = mInterpolator->interpolate(fraction);
- setValue(target, mFromValue + (mDeltaValue * fraction));
+ setValue(mTarget, mFromValue + (mDeltaValue * fraction));
if (mPlayState == FINISHED) {
callOnFinishedListener(info);
@@ -188,12 +199,17 @@
, mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) {
}
-void RenderPropertyAnimator::onAttached(RenderNode* target) {
+void RenderPropertyAnimator::onAttached() {
if (!mHasStartValue
- && target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
- setStartValue((target->stagingProperties().*mPropertyAccess->getter)());
+ && mTarget->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) {
+ setStartValue((mTarget->stagingProperties().*mPropertyAccess->getter)());
}
- (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+}
+
+void RenderPropertyAnimator::onStagingPlayStateChanged() {
+ if (mStagingPlayState == RUNNING) {
+ (mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+ }
}
uint32_t RenderPropertyAnimator::dirtyMask() {
diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h
index a981b5a..0dda23f 100644
--- a/libs/hwui/Animator.h
+++ b/libs/hwui/Animator.h
@@ -50,12 +50,14 @@
ANDROID_API void setListener(AnimationListener* listener) {
mListener = listener;
}
- ANDROID_API void start() { mStagingPlayState = RUNNING; }
- ANDROID_API void cancel() { mStagingPlayState = FINISHED; }
+ ANDROID_API void start() { mStagingPlayState = RUNNING; onStagingPlayStateChanged(); }
+ ANDROID_API void cancel() { mStagingPlayState = FINISHED; onStagingPlayStateChanged(); }
- virtual void onAttached(RenderNode* target) {}
- virtual void pushStaging(RenderNode* target, TreeInfo& info);
- bool animate(RenderNode* target, TreeInfo& info);
+ void attach(RenderNode* target);
+ virtual void onAttached() {}
+ void detach() { mTarget = 0; }
+ void pushStaging(TreeInfo& info);
+ bool animate(TreeInfo& info);
bool isFinished() { return mPlayState == FINISHED; }
float finalValue() { return mFinalValue; }
@@ -68,15 +70,20 @@
virtual float getValue(RenderNode* target) const = 0;
virtual void setValue(RenderNode* target, float value) = 0;
+ RenderNode* target() { return mTarget; }
void callOnFinishedListener(TreeInfo& info);
+ virtual void onStagingPlayStateChanged() {}
+
enum PlayState {
NOT_STARTED,
RUNNING,
FINISHED,
};
+ RenderNode* mTarget;
+
float mFinalValue;
float mDeltaValue;
float mFromValue;
@@ -92,9 +99,9 @@
sp<AnimationListener> mListener;
private:
- void doSetStartValue(float value);
inline void checkMutable();
- void transitionToRunning(TreeInfo& info);
+ virtual void transitionToRunning(TreeInfo& info);
+ void doSetStartValue(float value);
};
class RenderPropertyAnimator : public BaseRenderNodeAnimator {
@@ -116,13 +123,13 @@
ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue);
- virtual void onAttached(RenderNode* target);
-
ANDROID_API virtual uint32_t dirtyMask();
protected:
virtual float getValue(RenderNode* target) const;
virtual void setValue(RenderNode* target, float value);
+ virtual void onAttached();
+ virtual void onStagingPlayStateChanged();
private:
typedef bool (RenderProperties::*SetFloatProperty)(float value);
diff --git a/libs/hwui/AnimatorManager.cpp b/libs/hwui/AnimatorManager.cpp
index 6a10cf8..27b0893 100644
--- a/libs/hwui/AnimatorManager.cpp
+++ b/libs/hwui/AnimatorManager.cpp
@@ -25,6 +25,7 @@
using namespace std;
static void unref(BaseRenderNodeAnimator* animator) {
+ animator->detach();
animator->decStrong(0);
}
@@ -39,7 +40,7 @@
void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) {
animator->incStrong(0);
- animator->onAttached(&mParent);
+ animator->attach(&mParent);
mNewAnimators.push_back(animator.get());
}
@@ -58,7 +59,7 @@
move_all(mNewAnimators, mAnimators);
}
for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) {
- (*it)->pushStaging(&mParent, info);
+ (*it)->pushStaging(info);
}
}
@@ -68,7 +69,7 @@
: mTarget(target), mInfo(info) {}
bool operator() (BaseRenderNodeAnimator* animator) {
- bool remove = animator->animate(&mTarget, mInfo);
+ bool remove = animator->animate(mInfo);
if (remove) {
animator->decStrong(0);
}