diff options
author | John Reck <jreck@google.com> | 2014-05-14 16:34:14 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-05-15 08:53:39 -0700 |
commit | ff941dcd815021bb20d6504eb486acb1e50592c3 (patch) | |
tree | 1d417ed425ed1c08598689f302b31e23d73036f2 /libs | |
parent | 951ecb77c5dfe69a4d19d26429286111333ab123 (diff) | |
download | frameworks_base-ff941dcd815021bb20d6504eb486acb1e50592c3.zip frameworks_base-ff941dcd815021bb20d6504eb486acb1e50592c3.tar.gz frameworks_base-ff941dcd815021bb20d6504eb486acb1e50592c3.tar.bz2 |
Animator start value...
Change-Id: Ifd35ed95a28c625086d7fa97764fe63ab4a997f1
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Animator.cpp | 145 | ||||
-rw-r--r-- | libs/hwui/Animator.h | 102 | ||||
-rw-r--r-- | libs/hwui/RenderNode.cpp | 34 | ||||
-rw-r--r-- | libs/hwui/RenderNode.h | 28 | ||||
-rw-r--r-- | libs/hwui/TreeInfo.h | 4 |
5 files changed, 155 insertions, 158 deletions
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp index a033f86..83eedfb 100644 --- a/libs/hwui/Animator.cpp +++ b/libs/hwui/Animator.cpp @@ -27,31 +27,48 @@ namespace android { namespace uirenderer { /************************************************************ - * Base animator + * BaseRenderNodeAnimator ************************************************************/ -BaseAnimator::BaseAnimator() - : mInterpolator(0) - , mPlayState(PENDING) +BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) + : mFinalValue(finalValue) + , mDeltaValue(0) + , mFromValue(0) + , mInterpolator(0) + , mPlayState(NEEDS_START) , mStartTime(0) - , mDuration(300) { - + , mDuration(300){ } -BaseAnimator::~BaseAnimator() { +BaseRenderNodeAnimator::~BaseRenderNodeAnimator() { setInterpolator(NULL); } -void BaseAnimator::setInterpolator(Interpolator* interpolator) { +void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) { delete mInterpolator; mInterpolator = interpolator; } -void BaseAnimator::setDuration(nsecs_t duration) { +void BaseRenderNodeAnimator::setDuration(nsecs_t duration) { mDuration = duration; } -bool BaseAnimator::animateFrame(TreeInfo& info) { +void BaseRenderNodeAnimator::setStartValue(float value) { + LOG_ALWAYS_FATAL_IF(mPlayState != NEEDS_START, + "Cannot set the start value after the animator has started!"); + mFromValue = value; + mDeltaValue = (mFinalValue - mFromValue); + mPlayState = PENDING; +} + +void BaseRenderNodeAnimator::setupStartValueIfNecessary(RenderNode* target, TreeInfo& info) { + if (mPlayState == NEEDS_START) { + setStartValue(getValue(target)); + mPlayState = PENDING; + } +} + +bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) { if (mPlayState == PENDING) { mPlayState = RUNNING; mStartTime = info.frameTimeMs; @@ -59,7 +76,6 @@ bool BaseAnimator::animateFrame(TreeInfo& info) { if (!mInterpolator) { setInterpolator(Interpolator::createDefaultInterpolator()); } - onAnimationStarted(); } float fraction = 1.0f; @@ -71,17 +87,16 @@ bool BaseAnimator::animateFrame(TreeInfo& info) { } } fraction = mInterpolator->interpolate(fraction); - onAnimationUpdated(fraction); + setValue(target, mFromValue + (mDeltaValue * fraction)); if (mPlayState == FINISHED) { - onAnimationFinished(); callOnFinishedListener(info); return true; } return false; } -void BaseAnimator::callOnFinishedListener(TreeInfo& info) { +void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) { if (mListener.get()) { if (!info.animationHook) { mListener->onAnimationFinished(this); @@ -92,70 +107,49 @@ void BaseAnimator::callOnFinishedListener(TreeInfo& info) { } /************************************************************ - * BaseRenderNodeAnimator - ************************************************************/ - -BaseRenderNodeAnimator::BaseRenderNodeAnimator( - BaseRenderNodeAnimator::DeltaValueType deltaType, float delta) - : mTarget(0) - , mDeltaValueType(deltaType) - , mDeltaValue(delta) - , mFromValue(-1) { -} - -bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) { - mTarget = target; - bool finished = animateFrame(info); - mTarget = NULL; - return finished; -} - -void BaseRenderNodeAnimator::onAnimationStarted() { - mFromValue = getValue(); - - if (mDeltaValueType == BaseRenderNodeAnimator::ABSOLUTE) { - mDeltaValue = (mDeltaValue - mFromValue); - mDeltaValueType = BaseRenderNodeAnimator::DELTA; - } -} - -void BaseRenderNodeAnimator::onAnimationUpdated(float fraction) { - float value = mFromValue + (mDeltaValue * fraction); - setValue(value); -} - -/************************************************************ * RenderPropertyAnimator ************************************************************/ +struct RenderPropertyAnimator::PropertyAccessors { + RenderNode::DirtyPropertyMask dirtyMask; + GetFloatProperty getter; + SetFloatProperty setter; +}; + // Maps RenderProperty enum to accessors const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = { - {&RenderProperties::getTranslationX, &RenderProperties::setTranslationX }, - {&RenderProperties::getTranslationY, &RenderProperties::setTranslationY }, - {&RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ }, - {&RenderProperties::getScaleX, &RenderProperties::setScaleX }, - {&RenderProperties::getScaleY, &RenderProperties::setScaleY }, - {&RenderProperties::getRotation, &RenderProperties::setRotation }, - {&RenderProperties::getRotationX, &RenderProperties::setRotationX }, - {&RenderProperties::getRotationY, &RenderProperties::setRotationY }, - {&RenderProperties::getX, &RenderProperties::setX }, - {&RenderProperties::getY, &RenderProperties::setY }, - {&RenderProperties::getZ, &RenderProperties::setZ }, - {&RenderProperties::getAlpha, &RenderProperties::setAlpha }, + {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX }, + {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY }, + {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ }, + {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX }, + {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY }, + {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation }, + {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX }, + {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY }, + {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX }, + {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY }, + {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ }, + {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha }, }; -RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, - DeltaValueType deltaType, float deltaValue) - : BaseRenderNodeAnimator(deltaType, deltaValue) - , mPropertyAccess(PROPERTY_ACCESSOR_LUT[property]) { +RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue) + : BaseRenderNodeAnimator(finalValue) + , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) { +} + +void RenderPropertyAnimator::onAttached(RenderNode* target) { + if (target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) { + setStartValue((target->stagingProperties().*mPropertyAccess->getter)()); + } + (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue()); } -float RenderPropertyAnimator::getValue() const { - return (target()->animatorProperties().*mPropertyAccess.getter)(); +float RenderPropertyAnimator::getValue(RenderNode* target) const { + return (target->properties().*mPropertyAccess->getter)(); } -void RenderPropertyAnimator::setValue(float value) { - (target()->animatorProperties().*mPropertyAccess.setter)(value); +void RenderPropertyAnimator::setValue(RenderNode* target, float value) { + (target->animatorProperties().*mPropertyAccess->setter)(value); } /************************************************************ @@ -163,16 +157,16 @@ void RenderPropertyAnimator::setValue(float value) { ************************************************************/ CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator( - CanvasPropertyPrimitive* property, DeltaValueType deltaType, float deltaValue) - : BaseRenderNodeAnimator(deltaType, deltaValue) + CanvasPropertyPrimitive* property, float finalValue) + : BaseRenderNodeAnimator(finalValue) , mProperty(property) { } -float CanvasPropertyPrimitiveAnimator::getValue() const { +float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const { return mProperty->value; } -void CanvasPropertyPrimitiveAnimator::setValue(float value) { +void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) { mProperty->value = value; } @@ -181,14 +175,13 @@ void CanvasPropertyPrimitiveAnimator::setValue(float value) { ************************************************************/ CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator( - CanvasPropertyPaint* property, PaintField field, - DeltaValueType deltaType, float deltaValue) - : BaseRenderNodeAnimator(deltaType, deltaValue) + CanvasPropertyPaint* property, PaintField field, float finalValue) + : BaseRenderNodeAnimator(finalValue) , mProperty(property) , mField(field) { } -float CanvasPropertyPaintAnimator::getValue() const { +float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const { switch (mField) { case STROKE_WIDTH: return mProperty->value.getStrokeWidth(); @@ -204,7 +197,7 @@ static uint8_t to_uint8(float value) { return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c ); } -void CanvasPropertyPaintAnimator::setValue(float value) { +void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) { switch (mField) { case STROKE_WIDTH: mProperty->value.setStrokeWidth(value); diff --git a/libs/hwui/Animator.h b/libs/hwui/Animator.h index 52a1807..fe88cbf 100644 --- a/libs/hwui/Animator.h +++ b/libs/hwui/Animator.h @@ -33,16 +33,14 @@ class RenderProperties; class AnimationListener : public VirtualLightRefBase { public: - ANDROID_API virtual void onAnimationFinished(BaseAnimator*) = 0; + ANDROID_API virtual void onAnimationFinished(BaseRenderNodeAnimator*) = 0; protected: ANDROID_API virtual ~AnimationListener() {} }; -// Helper class to contain generic animator helpers -class BaseAnimator : public VirtualLightRefBase { - PREVENT_COPY_AND_ASSIGN(BaseAnimator); +class BaseRenderNodeAnimator : public VirtualLightRefBase { + PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator); public: - ANDROID_API void setInterpolator(Interpolator* interpolator); ANDROID_API void setDuration(nsecs_t durationInMs); ANDROID_API nsecs_t duration() { return mDuration; } @@ -50,31 +48,38 @@ public: mListener = listener; } + ANDROID_API virtual void onAttached(RenderNode* target) {} + + // Guaranteed to happen before the staging push + void setupStartValueIfNecessary(RenderNode* target, TreeInfo& info); + + bool animate(RenderNode* target, TreeInfo& info); + bool isFinished() { return mPlayState == FINISHED; } + float finalValue() { return mFinalValue; } protected: - BaseAnimator(); - virtual ~BaseAnimator(); - - // This is the main animation entrypoint that subclasses should call - // to generate the onAnimation* lifecycle events - // Returns true if the animation has finished, false otherwise - bool animateFrame(TreeInfo& info); + BaseRenderNodeAnimator(float finalValue); + virtual ~BaseRenderNodeAnimator(); - // Called when PlayState switches from PENDING to RUNNING - virtual void onAnimationStarted() {} - virtual void onAnimationUpdated(float fraction) = 0; - virtual void onAnimationFinished() {} + void setStartValue(float value); + virtual float getValue(RenderNode* target) const = 0; + virtual void setValue(RenderNode* target, float value) = 0; private: void callOnFinishedListener(TreeInfo& info); enum PlayState { + NEEDS_START, PENDING, RUNNING, FINISHED, }; + float mFinalValue; + float mDeltaValue; + float mFromValue; + Interpolator* mInterpolator; PlayState mPlayState; long mStartTime; @@ -83,42 +88,6 @@ private: sp<AnimationListener> mListener; }; -class BaseRenderNodeAnimator : public BaseAnimator { -public: - // Since the UI thread doesn't necessarily know what the current values - // actually are and thus can't do the calculations, this is used to inform - // the animator how to lazy-resolve the input value - enum DeltaValueType { - // The delta value represents an absolute value endpoint - // mDeltaValue needs to be recalculated to be mDelta = (mDelta - fromValue) - // in onAnimationStarted() - ABSOLUTE = 0, - // The final value represents an offset from the current value - // No recalculation is needed - DELTA, - }; - - bool animate(RenderNode* target, TreeInfo& info); - -protected: - BaseRenderNodeAnimator(DeltaValueType deltaType, float deltaValue); - - RenderNode* target() const { return mTarget; } - virtual float getValue() const = 0; - virtual void setValue(float value) = 0; - -private: - virtual void onAnimationStarted(); - virtual void onAnimationUpdated(float fraction); - - // mTarget is only valid inside animate() - RenderNode* mTarget; - - BaseRenderNodeAnimator::DeltaValueType mDeltaValueType; - float mDeltaValue; - float mFromValue; -}; - class RenderPropertyAnimator : public BaseRenderNodeAnimator { public: enum RenderProperty { @@ -136,23 +105,20 @@ public: ALPHA, }; - ANDROID_API RenderPropertyAnimator(RenderProperty property, - DeltaValueType deltaType, float deltaValue); + ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue); + + ANDROID_API virtual void onAttached(RenderNode* target); protected: - ANDROID_API virtual float getValue() const; - ANDROID_API virtual void setValue(float value); + virtual float getValue(RenderNode* target) const; + virtual void setValue(RenderNode* target, float value); private: typedef void (RenderProperties::*SetFloatProperty)(float value); typedef float (RenderProperties::*GetFloatProperty)() const; - struct PropertyAccessors { - GetFloatProperty getter; - SetFloatProperty setter; - }; - - PropertyAccessors mPropertyAccess; + struct PropertyAccessors; + const PropertyAccessors* mPropertyAccess; static const PropertyAccessors PROPERTY_ACCESSOR_LUT[]; }; @@ -160,10 +126,10 @@ private: class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator { public: ANDROID_API CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property, - DeltaValueType deltaType, float deltaValue); + float finalValue); protected: - ANDROID_API virtual float getValue() const; - ANDROID_API virtual void setValue(float value); + virtual float getValue(RenderNode* target) const; + virtual void setValue(RenderNode* target, float value); private: sp<CanvasPropertyPrimitive> mProperty; }; @@ -176,10 +142,10 @@ public: }; ANDROID_API CanvasPropertyPaintAnimator(CanvasPropertyPaint* property, - PaintField field, DeltaValueType deltaType, float deltaValue); + PaintField field, float finalValue); protected: - ANDROID_API virtual float getValue() const; - ANDROID_API virtual void setValue(float value); + virtual float getValue(RenderNode* target) const; + virtual void setValue(RenderNode* target, float value); private: sp<CanvasPropertyPaint> mProperty; PaintField mField; diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index fba482d..d4ff4a3 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -53,7 +53,7 @@ void RenderNode::outputLogBuffer(int fd) { } RenderNode::RenderNode() - : mNeedsPropertiesSync(false) + : mDirtyPropertyFields(0) , mNeedsDisplayListDataSync(false) , mDisplayListData(0) , mStagingDisplayListData(0) @@ -109,23 +109,37 @@ void RenderNode::prepareTreeImpl(TreeInfo& info) { prepareSubTree(info, mDisplayListData); } -static bool is_finished(const sp<BaseRenderNodeAnimator>& animator) { - return animator->isFinished(); -} +class PushAnimatorsFunctor { +public: + PushAnimatorsFunctor(RenderNode* target, TreeInfo& info) + : mTarget(target), mInfo(info) {} -void RenderNode::pushStagingChanges(TreeInfo& info) { - if (mNeedsPropertiesSync) { - mNeedsPropertiesSync = false; - mProperties = mStagingProperties; + bool operator() (const sp<BaseRenderNodeAnimator>& animator) { + animator->setupStartValueIfNecessary(mTarget, mInfo); + return animator->isFinished(); } +private: + RenderNode* mTarget; + TreeInfo& mInfo; +}; + +void RenderNode::pushStagingChanges(TreeInfo& info) { + // Push the animators first so that setupStartValueIfNecessary() is called + // before properties() is trampled by stagingProperties(), as they are + // required by some animators. if (mNeedsAnimatorsSync) { mAnimators.resize(mStagingAnimators.size()); std::vector< sp<BaseRenderNodeAnimator> >::iterator it; + PushAnimatorsFunctor functor(this, info); // hint: this means copy_if_not() it = std::remove_copy_if(mStagingAnimators.begin(), mStagingAnimators.end(), - mAnimators.begin(), is_finished); + mAnimators.begin(), functor); mAnimators.resize(std::distance(mAnimators.begin(), it)); } + if (mDirtyPropertyFields) { + mDirtyPropertyFields = 0; + mProperties = mStagingProperties; + } if (mNeedsDisplayListDataSync) { mNeedsDisplayListDataSync = false; // Do a push pass on the old tree to handle freeing DisplayListData @@ -144,7 +158,7 @@ public: AnimateFunctor(RenderNode* target, TreeInfo& info) : mTarget(target), mInfo(info) {} - bool operator() (sp<BaseRenderNodeAnimator>& animator) { + bool operator() (const sp<BaseRenderNodeAnimator>& animator) { return animator->animate(mTarget, mInfo); } private: diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h index bc62ee1..1811a7b 100644 --- a/libs/hwui/RenderNode.h +++ b/libs/hwui/RenderNode.h @@ -82,6 +82,22 @@ class DrawDisplayListOp; */ class RenderNode : public VirtualLightRefBase { public: + enum DirtyPropertyMask { + GENERIC = 1 << 1, + TRANSLATION_X = 1 << 2, + TRANSLATION_Y = 1 << 3, + TRANSLATION_Z = 1 << 4, + SCALE_X = 1 << 5, + SCALE_Y = 1 << 6, + ROTATION = 1 << 7, + ROTATION_X = 1 << 8, + ROTATION_Y = 1 << 9, + X = 1 << 10, + Y = 1 << 11, + Z = 1 << 12, + ALPHA = 1 << 13, + }; + ANDROID_API RenderNode(); ANDROID_API virtual ~RenderNode(); @@ -123,6 +139,14 @@ public: } } + bool isPropertyFieldDirty(DirtyPropertyMask field) const { + return mDirtyPropertyFields & field; + } + + void setPropertyFieldsDirty(uint32_t fields) { + mDirtyPropertyFields |= fields; + } + const RenderProperties& properties() { return mProperties; } @@ -136,7 +160,6 @@ public: } RenderProperties& mutateStagingProperties() { - mNeedsPropertiesSync = true; return mStagingProperties; } @@ -152,6 +175,7 @@ public: // UI thread only! ANDROID_API void addAnimator(const sp<BaseRenderNodeAnimator>& animator) { + animator->onAttached(this); mStagingAnimators.insert(animator); mNeedsAnimatorsSync = true; } @@ -227,7 +251,7 @@ private: String8 mName; - bool mNeedsPropertiesSync; + uint32_t mDirtyPropertyFields; RenderProperties mProperties; RenderProperties mStagingProperties; diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h index fc5994c..d4a23b8 100644 --- a/libs/hwui/TreeInfo.h +++ b/libs/hwui/TreeInfo.h @@ -21,12 +21,12 @@ namespace android { namespace uirenderer { -class BaseAnimator; +class BaseRenderNodeAnimator; class AnimationListener; class AnimationHook { public: - virtual void callOnFinished(BaseAnimator* animator, AnimationListener* listener) = 0; + virtual void callOnFinished(BaseRenderNodeAnimator* animator, AnimationListener* listener) = 0; protected: ~AnimationHook() {} }; |