diff options
author | vollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-07 18:59:31 +0000 |
---|---|---|
committer | vollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-07 18:59:31 +0000 |
commit | e4cbcc77d2e11a060e1232dcf60ad647a4d4dfb5 (patch) | |
tree | 75475f509107dc5f4f3f581c9daa3569c92ef9af /ui | |
parent | c92649a420f92b60b3d7343cf542a80eb79f7fc7 (diff) | |
download | chromium_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.cc | 27 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_animation_element.h | 11 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_animation_sequence.cc | 21 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_animation_sequence.h | 3 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_animator.cc | 40 | ||||
-rw-r--r-- | ui/gfx/compositor/layer_animator.h | 14 | ||||
-rw-r--r-- | ui/gfx/compositor/scoped_layer_animation_settings.cc | 24 | ||||
-rw-r--r-- | ui/gfx/compositor/scoped_layer_animation_settings.h | 12 | ||||
-rw-r--r-- | ui/gfx/compositor/screen_rotation.cc | 6 | ||||
-rw-r--r-- | ui/gfx/compositor/screen_rotation.h | 4 |
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; |