276 lines
8.4 KiB
C++
276 lines
8.4 KiB
C++
/*
|
|
* Copyright (C) 2014 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef ANIMATOR_H
|
|
#define ANIMATOR_H
|
|
|
|
#include "CanvasProperty.h"
|
|
|
|
#include <cutils/compiler.h>
|
|
#include <utils/RefBase.h>
|
|
#include <utils/StrongPointer.h>
|
|
#include <utils/Timers.h>
|
|
#include <memory>
|
|
|
|
#include "utils/Macros.h"
|
|
|
|
#include <vector>
|
|
|
|
namespace android {
|
|
namespace uirenderer {
|
|
|
|
class AnimationContext;
|
|
class BaseRenderNodeAnimator;
|
|
class Interpolator;
|
|
class RenderNode;
|
|
class RenderProperties;
|
|
|
|
class AnimationListener : public VirtualLightRefBase {
|
|
public:
|
|
virtual void onAnimationFinished(BaseRenderNodeAnimator*) = 0;
|
|
|
|
protected:
|
|
virtual ~AnimationListener() {}
|
|
};
|
|
|
|
enum class RepeatMode {
|
|
// These are the same values as the RESTART and REVERSE in ValueAnimator.java.
|
|
Restart = 1,
|
|
Reverse = 2
|
|
};
|
|
|
|
class BaseRenderNodeAnimator : public VirtualLightRefBase {
|
|
PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator);
|
|
|
|
public:
|
|
void setStartValue(float value);
|
|
void setInterpolator(Interpolator* interpolator);
|
|
void setDuration(nsecs_t durationInMs);
|
|
nsecs_t duration() { return mDuration; }
|
|
void setStartDelay(nsecs_t startDelayInMs);
|
|
nsecs_t startDelay() { return mStartDelay; }
|
|
void setListener(AnimationListener* listener) { mListener = listener; }
|
|
AnimationListener* listener() { return mListener.get(); }
|
|
void setAllowRunningAsync(bool mayRunAsync) { mMayRunAsync = mayRunAsync; }
|
|
bool mayRunAsync() { return mMayRunAsync; }
|
|
void start();
|
|
virtual void reset();
|
|
void reverse();
|
|
// Terminates the animation at its current progress.
|
|
void cancel();
|
|
|
|
// Terminates the animation and skip to the end of the animation.
|
|
virtual void end();
|
|
|
|
void attach(RenderNode* target);
|
|
virtual void onAttached() {}
|
|
void detach() { mTarget = nullptr; }
|
|
void pushStaging(AnimationContext& context);
|
|
bool animate(AnimationContext& context);
|
|
|
|
// Returns the remaining time in ms for the animation. Note this should only be called during
|
|
// an animation on RenderThread.
|
|
nsecs_t getRemainingPlayTime();
|
|
|
|
bool isRunning() {
|
|
return mPlayState == PlayState::Running || mPlayState == PlayState::Reversing;
|
|
}
|
|
bool isFinished() { return mPlayState == PlayState::Finished; }
|
|
float finalValue() { return mFinalValue; }
|
|
|
|
virtual uint32_t dirtyMask() = 0;
|
|
|
|
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
|
|
// thread and Render Thread animation state, respectively.
|
|
// From the UI thread, mStagingPlayState transition looks like
|
|
// NotStarted -> Running/Reversing -> Finished
|
|
// ^ |
|
|
// | |
|
|
// ----------------------
|
|
// Note: For mStagingState, the Finished state (optional) is only set when the animation is
|
|
// terminated by user.
|
|
//
|
|
// On Render Thread, mPlayState transition:
|
|
// NotStart -> Running/Reversing-> Finished
|
|
// ^ |
|
|
// | |
|
|
// ------------------
|
|
// Note that if the animation is in Running/Reversing state, calling start or reverse again
|
|
// would do nothing if the animation has the same play direction as the request; otherwise,
|
|
// the animation would start from where it is and change direction (i.e. Reversing <-> Running)
|
|
|
|
enum class PlayState {
|
|
NotStarted,
|
|
Running,
|
|
Reversing,
|
|
Finished,
|
|
};
|
|
|
|
explicit BaseRenderNodeAnimator(float finalValue);
|
|
virtual ~BaseRenderNodeAnimator();
|
|
|
|
virtual float getValue(RenderNode* target) const = 0;
|
|
virtual void setValue(RenderNode* target, float value) = 0;
|
|
|
|
void callOnFinishedListener(AnimationContext& context);
|
|
|
|
virtual void onStagingPlayStateChanged() {}
|
|
virtual void onPlayTimeChanged(nsecs_t playTime) {}
|
|
virtual void onPushStaging() {}
|
|
|
|
RenderNode* mTarget;
|
|
RenderNode* mStagingTarget;
|
|
|
|
float mFinalValue;
|
|
float mDeltaValue;
|
|
float mFromValue;
|
|
|
|
std::unique_ptr<Interpolator> mInterpolator;
|
|
PlayState mStagingPlayState;
|
|
PlayState mPlayState;
|
|
bool mHasStartValue;
|
|
nsecs_t mStartTime;
|
|
nsecs_t mDuration;
|
|
nsecs_t mStartDelay;
|
|
bool mMayRunAsync;
|
|
// Play Time tracks the progress of animation, it should always be [0, mDuration], 0 being
|
|
// the beginning of the animation, will reach mDuration at the end of an animation.
|
|
nsecs_t mPlayTime;
|
|
|
|
sp<AnimationListener> mListener;
|
|
|
|
private:
|
|
enum class Request { Start, Reverse, Reset, Cancel, End };
|
|
|
|
// Defines different actions upon finish.
|
|
enum class Action {
|
|
// For animations that got canceled or finished normally. no more action needs to be done.
|
|
None,
|
|
// For animations that get reset, the reset will happen in the next animation pulse.
|
|
Reset,
|
|
// For animations being ended, in the next animation pulse the animation will skip to end.
|
|
End
|
|
};
|
|
|
|
inline void checkMutable();
|
|
virtual void transitionToRunning(AnimationContext& context);
|
|
void doSetStartValue(float value);
|
|
bool updatePlayTime(nsecs_t playTime);
|
|
void resolveStagingRequest(Request request);
|
|
|
|
std::vector<Request> mStagingRequests;
|
|
Action mPendingActionUponFinish = Action::None;
|
|
};
|
|
|
|
class RenderPropertyAnimator : public BaseRenderNodeAnimator {
|
|
public:
|
|
enum RenderProperty {
|
|
TRANSLATION_X = 0,
|
|
TRANSLATION_Y,
|
|
TRANSLATION_Z,
|
|
SCALE_X,
|
|
SCALE_Y,
|
|
ROTATION,
|
|
ROTATION_X,
|
|
ROTATION_Y,
|
|
X,
|
|
Y,
|
|
Z,
|
|
ALPHA,
|
|
};
|
|
|
|
RenderPropertyAnimator(RenderProperty property, float finalValue);
|
|
|
|
virtual uint32_t dirtyMask();
|
|
|
|
protected:
|
|
virtual float getValue(RenderNode* target) const override;
|
|
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);
|
|
typedef float (RenderProperties::*GetFloatProperty)() const;
|
|
|
|
struct PropertyAccessors;
|
|
const PropertyAccessors* mPropertyAccess;
|
|
|
|
static const PropertyAccessors PROPERTY_ACCESSOR_LUT[];
|
|
bool mShouldSyncPropertyFields = false;
|
|
bool mShouldUpdateStagingProperties = false;
|
|
};
|
|
|
|
class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator {
|
|
public:
|
|
CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property,
|
|
float finalValue);
|
|
|
|
virtual uint32_t dirtyMask();
|
|
|
|
protected:
|
|
virtual float getValue(RenderNode* target) const override;
|
|
virtual void setValue(RenderNode* target, float value) override;
|
|
|
|
private:
|
|
sp<CanvasPropertyPrimitive> mProperty;
|
|
};
|
|
|
|
class CanvasPropertyPaintAnimator : public BaseRenderNodeAnimator {
|
|
public:
|
|
enum PaintField {
|
|
STROKE_WIDTH = 0,
|
|
ALPHA,
|
|
};
|
|
|
|
CanvasPropertyPaintAnimator(CanvasPropertyPaint* property, PaintField field,
|
|
float finalValue);
|
|
|
|
virtual uint32_t dirtyMask();
|
|
|
|
protected:
|
|
virtual float getValue(RenderNode* target) const override;
|
|
virtual void setValue(RenderNode* target, float value) override;
|
|
|
|
private:
|
|
sp<CanvasPropertyPaint> mProperty;
|
|
PaintField mField;
|
|
};
|
|
|
|
class RevealAnimator : public BaseRenderNodeAnimator {
|
|
public:
|
|
RevealAnimator(int centerX, int centerY, float startValue, float finalValue);
|
|
|
|
virtual uint32_t dirtyMask();
|
|
|
|
protected:
|
|
virtual float getValue(RenderNode* target) const override;
|
|
virtual void setValue(RenderNode* target, float value) override;
|
|
|
|
private:
|
|
int mCenterX, mCenterY;
|
|
};
|
|
|
|
} /* namespace uirenderer */
|
|
} /* namespace android */
|
|
|
|
#endif /* ANIMATOR_H */
|