Index: ui/compositor/layer_animation_element.cc |
diff --git a/ui/compositor/layer_animation_element.cc b/ui/compositor/layer_animation_element.cc |
index 6c9aa3954405ce8182119b5bfe5cc67abe0aeb48..1d633bac80d158765d18de3612d13b94b7b262c7 100644 |
--- a/ui/compositor/layer_animation_element.cc |
+++ b/ui/compositor/layer_animation_element.cc |
@@ -5,7 +5,10 @@ |
#include "ui/compositor/layer_animation_element.h" |
#include "base/compiler_specific.h" |
+#include "cc/animation.h" |
+#include "cc/animation_id_provider.h" |
#include "ui/base/animation/tween.h" |
+#include "ui/compositor/float_animation_curve_adapter.h" |
#include "ui/compositor/layer_animation_delegate.h" |
#include "ui/compositor/layer_animator.h" |
#include "ui/gfx/interpolated_transform.h" |
@@ -29,7 +32,7 @@ class Pause : public LayerAnimationElement { |
return false; |
} |
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
DISALLOW_COPY_AND_ASSIGN(Pause); |
}; |
@@ -59,7 +62,7 @@ class TransformTransition : public LayerAnimationElement { |
target->transform = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -99,7 +102,7 @@ class InterpolatedTransformTransition : public LayerAnimationElement { |
target->transform = interpolated_transform_->Interpolate(1.0f); |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -137,7 +140,7 @@ class BoundsTransition : public LayerAnimationElement { |
target->bounds = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -177,7 +180,7 @@ class OpacityTransition : public LayerAnimationElement { |
target->opacity = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -217,7 +220,7 @@ class VisibilityTransition : public LayerAnimationElement { |
target->visibility = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -258,7 +261,7 @@ class BrightnessTransition : public LayerAnimationElement { |
target->brightness = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -299,7 +302,7 @@ class GrayscaleTransition : public LayerAnimationElement { |
target->grayscale = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -352,7 +355,7 @@ class ColorTransition : public LayerAnimationElement { |
target->color = target_; |
} |
- virtual void OnAbort() OVERRIDE {} |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE {} |
private: |
static AnimatableProperties GetProperties() { |
@@ -367,6 +370,110 @@ class ColorTransition : public LayerAnimationElement { |
DISALLOW_COPY_AND_ASSIGN(ColorTransition); |
}; |
+// ThreadedLayerAnimationElement ----------------------------------------------- |
+ |
+class ThreadedLayerAnimationElement : public LayerAnimationElement { |
+ public: |
+ ThreadedLayerAnimationElement(const AnimatableProperties& properties, |
+ base::TimeDelta duration) |
+ : LayerAnimationElement(properties, duration) { |
+ } |
+ virtual ~ThreadedLayerAnimationElement() {} |
+ |
+ bool IsThreaded() const { |
+ return (duration() != base::TimeDelta()); |
+ } |
+ |
+ protected: |
+ virtual bool OnProgress(double t, |
+ LayerAnimationDelegate* delegate) OVERRIDE { |
+ if (t < 1.0) |
+ return false; |
+ |
+ if (animation_id()) { |
+ delegate->RemoveThreadedAnimation(animation_id()); |
+ set_animation_id(0); |
+ } |
+ |
+ OnEnd(delegate); |
+ return true; |
+ } |
+ |
+ virtual void OnAbort(LayerAnimationDelegate* delegate) OVERRIDE { |
+ if (delegate && animation_id()) |
+ delegate->RemoveThreadedAnimation(animation_id()); |
+ } |
+ |
+ virtual void RequestEffectiveStart( |
+ LayerAnimationDelegate* delegate) OVERRIDE { |
+ DCHECK(animation_group_id()); |
+ set_animation_id(cc::AnimationIdProvider::NextAnimationId()); |
+ set_effective_start_time(base::TimeTicks()); |
+ scoped_ptr<cc::Animation> animation = CreateCCAnimation(); |
+ animation->setNeedsSynchronizedStartTime(true); |
+ delegate->AddThreadedAnimation(animation.Pass()); |
+ } |
+ |
+ virtual void OnEnd(LayerAnimationDelegate* delegate) = 0; |
+ |
+ virtual scoped_ptr<cc::Animation> CreateCCAnimation() = 0; |
+ |
+ private: |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ThreadedLayerAnimationElement); |
+}; |
+ |
+// ThreadedOpacityTransition --------------------------------------------------- |
+ |
+class ThreadedOpacityTransition : public ThreadedLayerAnimationElement { |
+ public: |
+ ThreadedOpacityTransition(float target, base::TimeDelta duration) |
+ : ThreadedLayerAnimationElement(GetProperties(), duration), |
+ start_(0.0f), |
+ target_(target) { |
+ } |
+ virtual ~ThreadedOpacityTransition() {} |
+ |
+ protected: |
+ virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE { |
+ start_ = delegate->GetOpacityForAnimation(); |
+ } |
+ |
+ virtual void OnEnd(LayerAnimationDelegate* delegate) OVERRIDE { |
+ delegate->SetOpacityFromAnimation(target_); |
+ } |
+ |
+ virtual scoped_ptr<cc::Animation> CreateCCAnimation() OVERRIDE { |
+ scoped_ptr<cc::AnimationCurve> animation_curve( |
+ new FloatAnimationCurveAdapter(tween_type(), |
+ start_, |
+ target_, |
+ duration())); |
+ scoped_ptr<cc::Animation> animation( |
+ cc::Animation::create(animation_curve.Pass(), |
+ animation_id(), |
+ animation_group_id(), |
+ cc::Animation::Opacity)); |
+ return animation.Pass(); |
+ } |
+ |
+ virtual void OnGetTarget(TargetValue* target) const OVERRIDE { |
+ target->opacity = target_; |
+ } |
+ |
+ private: |
+ static AnimatableProperties GetProperties() { |
+ AnimatableProperties properties; |
+ properties.insert(LayerAnimationElement::OPACITY); |
+ return properties; |
+ } |
+ |
+ float start_; |
+ const float target_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ThreadedOpacityTransition); |
+}; |
+ |
} // namespace |
// LayerAnimationElement::TargetValue ------------------------------------------ |
@@ -399,31 +506,74 @@ LayerAnimationElement::LayerAnimationElement( |
: first_frame_(true), |
properties_(properties), |
duration_(GetEffectiveDuration(duration)), |
- tween_type_(Tween::LINEAR) { |
+ tween_type_(Tween::LINEAR), |
+ animation_id_(0), |
+ animation_group_id_(0) { |
} |
LayerAnimationElement::~LayerAnimationElement() { |
} |
+void LayerAnimationElement::ProgressToEffectiveStart( |
+ LayerAnimationDelegate* delegate) { |
+ DCHECK(first_frame_); |
+ if (!IsThreaded()) |
+ return; |
+ |
+ OnStart(delegate); |
+ RequestEffectiveStart(delegate); |
+ first_frame_ = false; |
+} |
+ |
bool LayerAnimationElement::Progress(base::TimeTicks now, |
LayerAnimationDelegate* delegate) { |
- DCHECK(start_time_ != base::TimeTicks()); |
- base::TimeDelta elapsed = now - start_time_; |
+ DCHECK(requested_start_time_ != base::TimeTicks()); |
if (first_frame_) |
OnStart(delegate); |
+ |
+ bool need_draw; |
double t = 1.0; |
+ |
+ if (first_frame_ && (now - requested_start_time_ >= duration_)) { |
+ // This can be finished immediately, without waiting for an effective start. |
+ need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate); |
Ian Vollick
2013/01/25 15:11:47
I think you can just call OnProgress(t, delegate)
ajuma
2013/01/29 18:31:23
Done.
|
+ return need_draw; |
+ } |
+ |
+ if (first_frame_) { |
+ RequestEffectiveStart(delegate); |
Ian Vollick
2013/01/25 15:11:47
Just double checking -- it's not possible to call
ajuma
2013/01/29 18:31:23
Right, calling Progress before ProgressToEffective
|
+ first_frame_ = false; |
+ } |
+ |
+ if (effective_start_time_ == base::TimeTicks()) { |
+ // This hasn't actually started yet. |
+ need_draw = false; |
+ return need_draw; |
+ } |
+ |
+ base::TimeDelta elapsed = now - effective_start_time_; |
if ((duration_ > base::TimeDelta()) && (elapsed < duration_)) |
t = elapsed.InMillisecondsF() / duration_.InMillisecondsF(); |
- bool need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate); |
+ need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate); |
first_frame_ = t == 1.0; |
return need_draw; |
} |
bool LayerAnimationElement::IsFinished(base::TimeTicks time, |
base::TimeDelta* total_duration) { |
- base::TimeDelta elapsed = time - start_time_; |
- if (elapsed >= duration_) { |
- *total_duration = duration_; |
+ // If an effective start has been requested but the effective start time |
+ // hasn't yet been set, the animation is not finished, regardless of the |
+ // value of |time|. |
+ if (!first_frame_ && (effective_start_time_ == base::TimeTicks())) |
+ return false; |
+ |
+ base::TimeDelta queueing_delay; |
+ if (!first_frame_) |
+ queueing_delay = effective_start_time_ - requested_start_time_; |
+ |
+ base::TimeDelta elapsed = time - requested_start_time_; |
+ if (elapsed >= duration_ + queueing_delay) { |
+ *total_duration = duration_ + queueing_delay; |
return true; |
} |
return false; |
@@ -441,9 +591,34 @@ void LayerAnimationElement::GetTargetValue(TargetValue* target) const { |
OnGetTarget(target); |
} |
-void LayerAnimationElement::Abort() { |
+bool LayerAnimationElement::IsThreaded() const { |
+ return false; |
+} |
+ |
+void LayerAnimationElement::Abort(LayerAnimationDelegate* delegate) { |
first_frame_ = true; |
- OnAbort(); |
+ OnAbort(delegate); |
+} |
+ |
+void LayerAnimationElement::RequestEffectiveStart( |
+ LayerAnimationDelegate* delegate) { |
+ DCHECK(requested_start_time_ != base::TimeTicks()); |
+ effective_start_time_ = requested_start_time_; |
+} |
+ |
+// static |
+LayerAnimationElement::AnimatableProperty |
+LayerAnimationElement::ToAnimatableProperty( |
+ cc::Animation::TargetProperty property) { |
+ switch (property) { |
+ case cc::Animation::Transform: |
+ return TRANSFORM; |
+ case cc::Animation::Opacity: |
+ return OPACITY; |
+ default: |
+ NOTREACHED(); |
+ return AnimatableProperty(); |
+ } |
} |
// static |
@@ -484,7 +659,7 @@ LayerAnimationElement* LayerAnimationElement::CreateBoundsElement( |
LayerAnimationElement* LayerAnimationElement::CreateOpacityElement( |
float opacity, |
base::TimeDelta duration) { |
- return new OpacityTransition(opacity, duration); |
+ return new ThreadedOpacityTransition(opacity, duration); |
} |
// static |