summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorvollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-07 18:59:31 +0000
committervollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-07 18:59:31 +0000
commite4cbcc77d2e11a060e1232dcf60ad647a4d4dfb5 (patch)
tree75475f509107dc5f4f3f581c9daa3569c92ef9af /ui
parentc92649a420f92b60b3d7343cf542a80eb79f7fc7 (diff)
downloadchromium_src-e4cbcc77d2e11a060e1232dcf60ad647a4d4dfb5.zip
chromium_src-e4cbcc77d2e11a060e1232dcf60ad647a4d4dfb5.tar.gz
chromium_src-e4cbcc77d2e11a060e1232dcf60ad647a4d4dfb5.tar.bz2
Add support for different tween types in ui::Layer animations
Also includes code for cutting down on the number of draws requested during animations. BUG=None TEST=None Review URL: http://codereview.chromium.org/9599003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125419 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/compositor/layer_animation_element.cc27
-rw-r--r--ui/gfx/compositor/layer_animation_element.h11
-rw-r--r--ui/gfx/compositor/layer_animation_sequence.cc21
-rw-r--r--ui/gfx/compositor/layer_animation_sequence.h3
-rw-r--r--ui/gfx/compositor/layer_animator.cc40
-rw-r--r--ui/gfx/compositor/layer_animator.h14
-rw-r--r--ui/gfx/compositor/scoped_layer_animation_settings.cc24
-rw-r--r--ui/gfx/compositor/scoped_layer_animation_settings.h12
-rw-r--r--ui/gfx/compositor/screen_rotation.cc6
-rw-r--r--ui/gfx/compositor/screen_rotation.h4
10 files changed, 119 insertions, 43 deletions
diff --git a/ui/gfx/compositor/layer_animation_element.cc b/ui/gfx/compositor/layer_animation_element.cc
index 330e7e8..ec8d8d4bf 100644
--- a/ui/gfx/compositor/layer_animation_element.cc
+++ b/ui/gfx/compositor/layer_animation_element.cc
@@ -22,8 +22,10 @@ class Pause : public LayerAnimationElement {
private:
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE {}
- virtual void OnProgress(double t,
- LayerAnimationDelegate* delegate) OVERRIDE {}
+ virtual bool OnProgress(double t,
+ LayerAnimationDelegate* delegate) OVERRIDE {
+ return false;
+ }
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {}
virtual void OnAbort() OVERRIDE {}
@@ -45,9 +47,10 @@ class TransformTransition : public LayerAnimationElement {
start_ = delegate->GetTransformForAnimation();
}
- virtual void OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
+ virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetTransformFromAnimation(
Tween::ValueBetween(t, start_, target_));
+ return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
@@ -84,8 +87,9 @@ class BoundsTransition : public LayerAnimationElement {
start_ = delegate->GetBoundsForAnimation();
}
- virtual void OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
+ virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetBoundsFromAnimation(Tween::ValueBetween(t, start_, target_));
+ return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
@@ -123,8 +127,9 @@ class OpacityTransition : public LayerAnimationElement {
start_ = delegate->GetOpacityForAnimation();
}
- virtual void OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
+ virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetOpacityFromAnimation(Tween::ValueBetween(t, start_, target_));
+ return true;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
@@ -162,8 +167,9 @@ class VisibilityTransition : public LayerAnimationElement {
start_ = delegate->GetVisibilityForAnimation();
}
- virtual void OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
+ virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) OVERRIDE {
delegate->SetVisibilityFromAnimation(t == 1.0 ? target_ : start_);
+ return t == 1.0;
}
virtual void OnGetTarget(TargetValue* target) const OVERRIDE {
@@ -209,19 +215,20 @@ LayerAnimationElement::LayerAnimationElement(
base::TimeDelta duration)
: first_frame_(true),
properties_(properties),
- duration_(duration) {
+ duration_(duration),
+ tween_type_(Tween::LINEAR) {
}
LayerAnimationElement::~LayerAnimationElement() {
}
-void LayerAnimationElement::Progress(double t,
+bool LayerAnimationElement::Progress(double t,
LayerAnimationDelegate* delegate) {
if (first_frame_)
OnStart(delegate);
- OnProgress(t, delegate);
- delegate->ScheduleDrawForAnimation();
+ bool need_draw = OnProgress(Tween::CalculateValue(tween_type_, t), delegate);
first_frame_ = t == 1.0;
+ return need_draw;
}
void LayerAnimationElement::GetTargetValue(TargetValue* target) const {
diff --git a/ui/gfx/compositor/layer_animation_element.h b/ui/gfx/compositor/layer_animation_element.h
index 2867dee..ae023dc 100644
--- a/ui/gfx/compositor/layer_animation_element.h
+++ b/ui/gfx/compositor/layer_animation_element.h
@@ -9,6 +9,7 @@
#include <set>
#include "base/time.h"
+#include "ui/base/animation/tween.h"
#include "ui/gfx/compositor/compositor_export.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/transform.h"
@@ -80,8 +81,8 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
// Updates the delegate to the appropriate value for |t|, which is in the
// range [0, 1] (0 for initial, and 1 for final). If the animation is not
// aborted, it is guaranteed that Progress will eventually be called with
- // t = 1.0.
- void Progress(double t, LayerAnimationDelegate* delegate);
+ // t = 1.0. Returns true if a redraw is required.
+ bool Progress(double t, LayerAnimationDelegate* delegate);
// Called if the animation is not allowed to complete. This may be called
// before OnStarted or Progress.
@@ -96,11 +97,14 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
// The duration of the animation
base::TimeDelta duration() const { return duration_; }
+ Tween::Type tween_type() const { return tween_type_; }
+ void set_tween_type(Tween::Type tween_type) { tween_type_ = tween_type;}
+
protected:
// Called once each time the animation element is run before any call to
// OnProgress.
virtual void OnStart(LayerAnimationDelegate* delegate) = 0;
- virtual void OnProgress(double t, LayerAnimationDelegate* delegate) = 0;
+ virtual bool OnProgress(double t, LayerAnimationDelegate* delegate) = 0;
virtual void OnGetTarget(TargetValue* target) const = 0;
virtual void OnAbort() = 0;
@@ -108,6 +112,7 @@ class COMPOSITOR_EXPORT LayerAnimationElement {
bool first_frame_;
const AnimatableProperties properties_;
const base::TimeDelta duration_;
+ Tween::Type tween_type_;
DISALLOW_COPY_AND_ASSIGN(LayerAnimationElement);
};
diff --git a/ui/gfx/compositor/layer_animation_sequence.cc b/ui/gfx/compositor/layer_animation_sequence.cc
index 6111823..aff8e8c 100644
--- a/ui/gfx/compositor/layer_animation_sequence.cc
+++ b/ui/gfx/compositor/layer_animation_sequence.cc
@@ -31,27 +31,29 @@ LayerAnimationSequence::~LayerAnimationSequence() {
DetachedFromSequence(this, true));
}
-void LayerAnimationSequence::Progress(base::TimeDelta elapsed,
+bool LayerAnimationSequence::Progress(base::TimeDelta elapsed,
LayerAnimationDelegate* delegate) {
+ bool redraw_required = false;
+
if (elements_.empty())
- return;
+ return redraw_required;
if (is_cyclic_ && duration_ > base::TimeDelta()) {
// If delta = elapsed - last_start_ is huge, we can skip ahead by complete
// loops to save time.
base::TimeDelta delta = elapsed - last_start_;
int64 k = delta.ToInternalValue() / duration_.ToInternalValue() - 1;
- if (k > 0) {
- last_start_ += base::TimeDelta::FromInternalValue(
- k * duration_.ToInternalValue());
- }
+
+ last_start_ += base::TimeDelta::FromInternalValue(
+ k * duration_.ToInternalValue());
}
size_t current_index = last_element_ % elements_.size();
while ((is_cyclic_ || last_element_ < elements_.size()) &&
(last_start_ + elements_[current_index]->duration() < elapsed)) {
// Let the element we're passing finish.
- elements_[current_index]->Progress(1.0, delegate);
+ if (elements_[current_index]->Progress(1.0, delegate))
+ redraw_required = true;
last_start_ += elements_[current_index]->duration();
++last_element_;
current_index = last_element_ % elements_.size();
@@ -63,7 +65,8 @@ void LayerAnimationSequence::Progress(base::TimeDelta elapsed,
t = (elapsed - last_start_).InMillisecondsF() /
elements_[current_index]->duration().InMillisecondsF();
}
- elements_[current_index]->Progress(t, delegate);
+ if (elements_[current_index]->Progress(t, delegate))
+ redraw_required = true;
}
if (!is_cyclic_ && elapsed == duration_) {
@@ -71,6 +74,8 @@ void LayerAnimationSequence::Progress(base::TimeDelta elapsed,
last_start_ = base::TimeDelta::FromMilliseconds(0);
NotifyEnded();
}
+
+ return redraw_required;
}
void LayerAnimationSequence::GetTargetValue(
diff --git a/ui/gfx/compositor/layer_animation_sequence.h b/ui/gfx/compositor/layer_animation_sequence.h
index 2fad33d..dc85721 100644
--- a/ui/gfx/compositor/layer_animation_sequence.h
+++ b/ui/gfx/compositor/layer_animation_sequence.h
@@ -38,7 +38,8 @@ class COMPOSITOR_EXPORT LayerAnimationSequence {
// Updates the delegate to the appropriate value for |elapsed|, which is in
// the range [0, Duration()]. If the animation is not aborted, it is
// guaranteed that Animate will be called with elapsed = Duration().
- void Progress(base::TimeDelta elapsed, LayerAnimationDelegate* delegate);
+ // Returns true if a redraw is required.
+ bool Progress(base::TimeDelta elapsed, LayerAnimationDelegate* delegate);
// Sets the target value to the value that would have been set had
// the sequence completed. Does nothing if the sequence is cyclic.
diff --git a/ui/gfx/compositor/layer_animator.cc b/ui/gfx/compositor/layer_animator.cc
index 9d6fa14..d442dd6 100644
--- a/ui/gfx/compositor/layer_animator.cc
+++ b/ui/gfx/compositor/layer_animator.cc
@@ -34,6 +34,7 @@ LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
: delegate_(NULL),
preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
transition_duration_(transition_duration),
+ tween_type_(Tween::LINEAR),
is_started_(false),
disable_timer_for_test_(false) {
}
@@ -61,9 +62,10 @@ void LayerAnimator::SetTransform(const Transform& transform) {
base::TimeDelta duration = transition_duration_;
if (disable_animations_for_test_)
duration = base::TimeDelta();
- StartAnimation(new LayerAnimationSequence(
- LayerAnimationElement::CreateTransformElement(
- transform, duration)));
+ scoped_ptr<LayerAnimationElement> element(
+ LayerAnimationElement::CreateTransformElement(transform, duration));
+ element->set_tween_type(tween_type_);
+ StartAnimation(new LayerAnimationSequence(element.release()));
}
Transform LayerAnimator::GetTargetTransform() const {
@@ -76,9 +78,10 @@ void LayerAnimator::SetBounds(const gfx::Rect& bounds) {
base::TimeDelta duration = transition_duration_;
if (disable_animations_for_test_)
duration = base::TimeDelta();
- StartAnimation(new LayerAnimationSequence(
- LayerAnimationElement::CreateBoundsElement(
- bounds, duration)));
+ scoped_ptr<LayerAnimationElement> element(
+ LayerAnimationElement::CreateBoundsElement(bounds, duration));
+ element->set_tween_type(tween_type_);
+ StartAnimation(new LayerAnimationSequence(element.release()));
}
gfx::Rect LayerAnimator::GetTargetBounds() const {
@@ -91,9 +94,10 @@ void LayerAnimator::SetOpacity(float opacity) {
base::TimeDelta duration = transition_duration_;
if (disable_animations_for_test_)
duration = base::TimeDelta();
- StartAnimation(new LayerAnimationSequence(
- LayerAnimationElement::CreateOpacityElement(
- opacity, duration)));
+ scoped_ptr<LayerAnimationElement> element(
+ LayerAnimationElement::CreateOpacityElement(opacity, duration));
+ element->set_tween_type(tween_type_);
+ StartAnimation(new LayerAnimationSequence(element.release()));
}
float LayerAnimator::GetTargetOpacity() const {
@@ -106,6 +110,8 @@ void LayerAnimator::SetVisibility(bool visibility) {
base::TimeDelta duration = transition_duration_;
if (disable_animations_for_test_)
duration = base::TimeDelta();
+
+ // Tween type doesn't matter for visibility.
StartAnimation(new LayerAnimationSequence(
LayerAnimationElement::CreateVisibilityElement(
visibility, duration)));
@@ -174,10 +180,9 @@ void LayerAnimator::ScheduleTogether(
// Scheduling a zero duration pause that affects all the animated properties
// will prevent any of the sequences from animating until there are no
// running animations that affect any of these properties.
- ScheduleAnimation(
- new LayerAnimationSequence(
- LayerAnimationElement::CreatePauseElement(animated_properties,
- base::TimeDelta())));
+ ScheduleAnimation(new LayerAnimationSequence(
+ LayerAnimationElement::CreatePauseElement(animated_properties,
+ base::TimeDelta())));
// These animations (provided they don't animate any common properties) will
// now animate together if trivially scheduled.
@@ -232,20 +237,27 @@ void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
// LayerAnimator private -------------------------------------------------------
void LayerAnimator::Step(base::TimeTicks now) {
+ TRACE_EVENT0("ui", "LayerAnimator::Step");
+
last_step_time_ = now;
// We need to make a copy of the running animations because progressing them
// and finishing them may indirectly affect the collection of running
// animations.
RunningAnimations running_animations_copy = running_animations_;
+ bool needs_redraw = false;
for (size_t i = 0; i < running_animations_copy.size(); ++i) {
base::TimeDelta delta = now - running_animations_copy[i].start_time;
if (delta >= running_animations_copy[i].sequence->duration() &&
!running_animations_copy[i].sequence->is_cyclic()) {
FinishAnimation(running_animations_copy[i].sequence);
} else {
- running_animations_copy[i].sequence->Progress(delta, delegate());
+ if (running_animations_copy[i].sequence->Progress(delta, delegate()))
+ needs_redraw = true;
}
}
+
+ if (needs_redraw)
+ delegate()->ScheduleDrawForAnimation();
}
void LayerAnimator::SetStartTime(base::TimeTicks start_time) {
diff --git a/ui/gfx/compositor/layer_animator.h b/ui/gfx/compositor/layer_animator.h
index f40786d..67874b3 100644
--- a/ui/gfx/compositor/layer_animator.h
+++ b/ui/gfx/compositor/layer_animator.h
@@ -15,6 +15,7 @@
#include "base/observer_list.h"
#include "base/time.h"
#include "ui/base/animation/animation_container_element.h"
+#include "ui/base/animation/tween.h"
#include "ui/gfx/compositor/compositor_export.h"
#include "ui/gfx/compositor/layer_animation_element.h"
@@ -81,6 +82,10 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
preemption_strategy_ = strategy;
}
+ PreemptionStrategy preemption_strategy() const {
+ return preemption_strategy_;
+ }
+
// Start an animation sequence. If an animation for the same property is in
// progress, it needs to be interrupted with the new animation. The animator
// takes ownership of this animation sequence.
@@ -119,6 +124,12 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
void AddObserver(LayerAnimationObserver* observer);
void RemoveObserver(LayerAnimationObserver* observer);
+ // This determines how implicit animations will be tweened. This has no
+ // effect on animations that are explicitly started or scheduled. The default
+ // is Tween::LINEAR.
+ void set_tween_type(Tween::Type tween_type) { tween_type_ = tween_type; }
+ Tween::Type tween_type() const { return tween_type_; }
+
// For testing purposes only.
void set_disable_timer_for_test(bool disable_timer) {
disable_timer_for_test_ = disable_timer;
@@ -234,6 +245,9 @@ class COMPOSITOR_EXPORT LayerAnimator : public AnimationContainerElement {
// The default length of animations.
base::TimeDelta transition_duration_;
+ // The default tween type for implicit transitions
+ Tween::Type tween_type_;
+
// Used for coordinating the starting of animations.
base::TimeTicks last_step_time_;
diff --git a/ui/gfx/compositor/scoped_layer_animation_settings.cc b/ui/gfx/compositor/scoped_layer_animation_settings.cc
index 78fb067..9897949 100644
--- a/ui/gfx/compositor/scoped_layer_animation_settings.cc
+++ b/ui/gfx/compositor/scoped_layer_animation_settings.cc
@@ -19,12 +19,16 @@ namespace ui {
ScopedLayerAnimationSettings::ScopedLayerAnimationSettings(
LayerAnimator* animator)
: animator_(animator),
- old_transition_duration_(animator->transition_duration_) {
+ old_transition_duration_(animator->transition_duration_),
+ old_tween_type_(animator->tween_type()),
+ old_preemption_strategy_(animator->preemption_strategy()) {
SetTransitionDuration(kDefaultTransitionDuration);
}
ScopedLayerAnimationSettings::~ScopedLayerAnimationSettings() {
animator_->transition_duration_ = old_transition_duration_;
+ animator_->set_tween_type(old_tween_type_);
+ animator_->set_preemption_strategy(old_preemption_strategy_);
for (std::set<ImplicitAnimationObserver*>::const_iterator i =
observers_.begin(); i != observers_.end(); ++i) {
@@ -48,5 +52,23 @@ base::TimeDelta ScopedLayerAnimationSettings::GetTransitionDuration() const {
return animator_->transition_duration_;
}
+void ScopedLayerAnimationSettings::SetTweenType(Tween::Type tween_type) {
+ animator_->set_tween_type(tween_type);
+}
+
+Tween::Type ScopedLayerAnimationSettings::GetTweenType() const {
+ return animator_->tween_type();
+}
+
+void ScopedLayerAnimationSettings::SetPreemptionStrategy(
+ LayerAnimator::PreemptionStrategy strategy) {
+ animator_->set_preemption_strategy(strategy);
+}
+
+LayerAnimator::PreemptionStrategy
+ScopedLayerAnimationSettings::GetPreemptionStrategy() const {
+ return animator_->preemption_strategy();
+}
+
} // namespace ui
diff --git a/ui/gfx/compositor/scoped_layer_animation_settings.h b/ui/gfx/compositor/scoped_layer_animation_settings.h
index 94e5a4e..61c2b37 100644
--- a/ui/gfx/compositor/scoped_layer_animation_settings.h
+++ b/ui/gfx/compositor/scoped_layer_animation_settings.h
@@ -10,12 +10,13 @@
#include "base/time.h"
+#include "ui/base/animation/tween.h"
#include "ui/gfx/compositor/compositor_export.h"
+#include "ui/gfx/compositor/layer_animator.h"
namespace ui {
class ImplicitAnimationObserver;
-class LayerAnimator;
class LayerAnimationObserver;
// Scoped settings allow you to temporarily change the animator's settings and
@@ -28,12 +29,21 @@ class COMPOSITOR_EXPORT ScopedLayerAnimationSettings {
virtual ~ScopedLayerAnimationSettings();
void AddObserver(ImplicitAnimationObserver* observer);
+
void SetTransitionDuration(base::TimeDelta duration);
base::TimeDelta GetTransitionDuration() const;
+ void SetTweenType(Tween::Type tween_type);
+ Tween::Type GetTweenType() const;
+
+ void SetPreemptionStrategy(LayerAnimator::PreemptionStrategy strategy);
+ LayerAnimator::PreemptionStrategy GetPreemptionStrategy() const;
+
private:
LayerAnimator* animator_;
base::TimeDelta old_transition_duration_;
+ Tween::Type old_tween_type_;
+ LayerAnimator::PreemptionStrategy old_preemption_strategy_;
std::set<ImplicitAnimationObserver*> observers_;
DISALLOW_COPY_AND_ASSIGN(ScopedLayerAnimationSettings);
diff --git a/ui/gfx/compositor/screen_rotation.cc b/ui/gfx/compositor/screen_rotation.cc
index df399e2..5669856 100644
--- a/ui/gfx/compositor/screen_rotation.cc
+++ b/ui/gfx/compositor/screen_rotation.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -95,10 +95,10 @@ void ScreenRotation::OnStart(LayerAnimationDelegate* delegate) {
interpolated_transform_->SetChild(rotation.release());
}
-void ScreenRotation::OnProgress(double t,
+bool ScreenRotation::OnProgress(double t,
LayerAnimationDelegate* delegate) {
delegate->SetTransformFromAnimation(interpolated_transform_->Interpolate(t));
- delegate->ScheduleDrawForAnimation();
+ return true;
}
void ScreenRotation::OnGetTarget(TargetValue* target) const {
diff --git a/ui/gfx/compositor/screen_rotation.h b/ui/gfx/compositor/screen_rotation.h
index 1d95a5d..315b981 100644
--- a/ui/gfx/compositor/screen_rotation.h
+++ b/ui/gfx/compositor/screen_rotation.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -31,7 +31,7 @@ class COMPOSITOR_EXPORT ScreenRotation : public LayerAnimationElement {
private:
// Implementation of LayerAnimationDelegate
virtual void OnStart(LayerAnimationDelegate* delegate) OVERRIDE;
- virtual void OnProgress(double t,
+ virtual bool OnProgress(double t,
LayerAnimationDelegate* delegate) OVERRIDE;
virtual void OnGetTarget(TargetValue* target) const OVERRIDE;
virtual void OnAbort() OVERRIDE;