Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Unified Diff: ui/compositor/layer_animation_element.cc

Issue 11896017: Thread ui opacity animations (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Correctly deal with sequences meant to start together Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698