diff options
author | vollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 07:37:08 +0000 |
---|---|---|
committer | vollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 07:37:08 +0000 |
commit | 0a9fd4dd4f05423a83479ace4d2b2469eced588e (patch) | |
tree | bf8de741db7e373a398bde755180b926b608c51d /cc | |
parent | 3d871d9695ec44bf3b5cabd09549bd2c1f999eb5 (diff) | |
download | chromium_src-0a9fd4dd4f05423a83479ace4d2b2469eced588e.zip chromium_src-0a9fd4dd4f05423a83479ace4d2b2469eced588e.tar.gz chromium_src-0a9fd4dd4f05423a83479ace4d2b2469eced588e.tar.bz2 |
With this patch we accomplish the following:
1. layer animation controllers are ref counted (so they can be shared by the two impl trees)
2. the layer tree hosts now own a list of active animation controllers. This allows for a couple of nice things
__a. Ticking the animation controllers no longer requires a tree walk
__b. We will be able to support ticking of animation controllers for layers that are not yet added to the layer tree. (Support coming in a future patch).
3. animation controllers register and unregister themselves from their respective layer tree host's list when they have an animation to tick.
BUG=162111
Review URL: https://chromiumcodereview.appspot.com/11348256
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171714 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/animation_registrar.h | 35 | ||||
-rw-r--r-- | cc/cc.gyp | 1 | ||||
-rw-r--r-- | cc/layer.cc | 74 | ||||
-rw-r--r-- | cc/layer.h | 22 | ||||
-rw-r--r-- | cc/layer_animation_controller.cc | 87 | ||||
-rw-r--r-- | cc/layer_animation_controller.h | 54 | ||||
-rw-r--r-- | cc/layer_animation_controller_unittest.cc | 191 | ||||
-rw-r--r-- | cc/layer_impl.cc | 48 | ||||
-rw-r--r-- | cc/layer_impl.h | 17 | ||||
-rw-r--r-- | cc/layer_tree_host.cc | 67 | ||||
-rw-r--r-- | cc/layer_tree_host.h | 28 | ||||
-rw-r--r-- | cc/layer_tree_host_common_unittest.cc | 26 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.cc | 79 | ||||
-rw-r--r-- | cc/layer_tree_host_impl.h | 21 | ||||
-rw-r--r-- | cc/proxy.h | 2 | ||||
-rw-r--r-- | cc/single_thread_proxy.cc | 4 | ||||
-rw-r--r-- | cc/single_thread_proxy.h | 1 | ||||
-rw-r--r-- | cc/test/animation_test_common.cc | 34 | ||||
-rw-r--r-- | cc/test/animation_test_common.h | 17 | ||||
-rw-r--r-- | cc/test/fake_proxy.h | 1 | ||||
-rw-r--r-- | cc/test/layer_tree_test_common.cc | 28 | ||||
-rw-r--r-- | cc/test/layer_tree_test_common.h | 1 | ||||
-rw-r--r-- | cc/thread_proxy.h | 1 | ||||
-rw-r--r-- | cc/tree_synchronizer_unittest.cc | 16 |
24 files changed, 420 insertions, 435 deletions
diff --git a/cc/animation_registrar.h b/cc/animation_registrar.h new file mode 100644 index 0000000..5cce4e9 --- /dev/null +++ b/cc/animation_registrar.h @@ -0,0 +1,35 @@ +// Copyright 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. + +#ifndef CC_ANIMATION_REGISTRAR_H_ +#define CC_ANIMATION_REGISTRAR_H_ + +namespace cc { + +class LayerAnimationController; + +// TODO(vollick): we need to rename: +// AnimationRegistrar -> AnimationController +// LayerAnimationController -> LayerAnimator +class CC_EXPORT AnimationRegistrar { + public: + // Registers the given animation controller as active. An active animation + // controller is one that has a running animation that needs to be ticked. + virtual void DidActivateAnimationController(LayerAnimationController*) = 0; + + // Unregisters the given animation controller. When this happens, the + // animation controller will no longer be ticked (since it's not active). It + // is not an error to call this function with a deactivated controller. + virtual void DidDeactivateAnimationController(LayerAnimationController*) = 0; + + // Registers the given controller as alive. + virtual void RegisterAnimationController(LayerAnimationController*) = 0; + + // Unregisters the given controller as alive. + virtual void UnregisterAnimationController(LayerAnimationController*) = 0; +}; + +} // namespace cc + +#endif // CC_ANIMATION_REGISTRAR_H_ @@ -10,6 +10,7 @@ 'animation_curve.cc', 'animation_curve.h', 'animation_events.h', + 'animation_registrar.h', 'append_quads_data.h', 'bitmap_content_layer_updater.cc', 'bitmap_content_layer_updater.h', diff --git a/cc/layer.cc b/cc/layer.cc index 57d1c17..42247fd 100644 --- a/cc/layer.cc +++ b/cc/layer.cc @@ -32,7 +32,7 @@ Layer::Layer() , m_layerId(s_nextLayerId++) , m_parent(0) , m_layerTreeHost(0) - , m_layerAnimationController(LayerAnimationController::create(this)) + , m_layerAnimationController(LayerAnimationController::create()) , m_scrollable(false) , m_shouldScrollOnMainThread(false) , m_haveWheelEventHandlers(false) @@ -40,7 +40,6 @@ Layer::Layer() , m_touchEventHandlerRegionChanged(false) , m_anchorPoint(0.5, 0.5) , m_backgroundColor(0) - , m_opacity(1.0) , m_anchorPointZ(0) , m_isContainerForFixedPositionLayers(false) , m_fixedToContainerLayer(false) @@ -64,6 +63,7 @@ Layer::Layer() s_nextLayerId = 1; m_layerId = s_nextLayerId++; } + m_layerAnimationController->setId(m_layerId); } Layer::~Layer() @@ -96,9 +96,7 @@ void Layer::setLayerTreeHost(LayerTreeHost* host) if (m_replicaLayer) m_replicaLayer->setLayerTreeHost(host); - // If this layer already has active animations, the host needs to be notified. - if (host && m_layerAnimationController->hasActiveAnimation()) - host->didAddAnimation(); + m_layerAnimationController->setAnimationRegistrar(host); } void Layer::setNeedsCommit() @@ -353,12 +351,16 @@ bool Layer::needsDisplay() const void Layer::setOpacity(float opacity) { - if (m_opacity == opacity) + if (!m_layerAnimationController->setOpacity(opacity)) return; - m_opacity = opacity; setNeedsCommit(); } +float Layer::opacity() const +{ + return m_layerAnimationController->opacity(); +} + bool Layer::opacityIsAnimating() const { return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity); @@ -390,12 +392,16 @@ void Layer::setSublayerTransform(const gfx::Transform& sublayerTransform) void Layer::setTransform(const gfx::Transform& transform) { - if (m_transform == transform) + if (!m_layerAnimationController->setTransform(transform)) return; - m_transform = transform; setNeedsCommit(); } +const gfx::Transform& Layer::transform() const +{ + return m_layerAnimationController->transform(); +} + bool Layer::transformIsAnimating() const { return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform); @@ -578,8 +584,6 @@ void Layer::pushPropertiesTo(LayerImpl* layer) m_touchEventHandlerRegionChanged = false; } layer->setContentsOpaque(m_contentsOpaque); - if (!opacityIsAnimating()) - layer->setOpacity(m_opacity); layer->setPosition(m_position); layer->setIsContainerForFixedPositionLayers(m_isContainerForFixedPositionLayers); layer->setFixedToContainerLayer(m_fixedToContainerLayer); @@ -588,8 +592,6 @@ void Layer::pushPropertiesTo(LayerImpl* layer) layer->setScrollOffset(m_scrollOffset); layer->setMaxScrollOffset(m_maxScrollOffset); layer->setSublayerTransform(m_sublayerTransform); - if (!transformIsAnimating()) - layer->setTransform(m_transform); // If the main thread commits multiple times before the impl thread actually draws, then damage tracking // will become incorrect if we simply clobber the updateRect here. The LayerImpl's updateRect needs to @@ -713,32 +715,6 @@ int Layer::id() const return m_layerId; } -float Layer::opacity() const -{ - return m_opacity; -} - -void Layer::setOpacityFromAnimation(float opacity) -{ - // This is called due to an ongoing accelerated animation. Since this animation is - // also being run on the impl thread, there is no need to request a commit to push - // this value over, so set the value directly rather than calling setOpacity. - m_opacity = opacity; -} - -const gfx::Transform& Layer::transform() const -{ - return m_transform; -} - -void Layer::setTransformFromAnimation(const gfx::Transform& transform) -{ - // This is called due to an ongoing accelerated animation. Since this animation is - // also being run on the impl thread, there is no need to request a commit to push - // this value over, so set this value directly rather than calling setTransform. - m_transform = transform; -} - bool Layer::addAnimation(scoped_ptr <ActiveAnimation> animation) { // WebCore currently assumes that accelerated animations will start soon @@ -758,10 +734,7 @@ bool Layer::addAnimation(scoped_ptr <ActiveAnimation> animation) #endif m_layerAnimationController->addAnimation(animation.Pass()); - if (m_layerTreeHost) { - m_layerTreeHost->didAddAnimation(); setNeedsCommit(); - } return true; } @@ -789,21 +762,24 @@ void Layer::resumeAnimations(double monotonicTime) setNeedsCommit(); } -void Layer::setLayerAnimationController(scoped_ptr<LayerAnimationController> layerAnimationController) +void Layer::setLayerAnimationController(scoped_refptr<LayerAnimationController> layerAnimationController) { - m_layerAnimationController = layerAnimationController.Pass(); + m_layerAnimationController = layerAnimationController; if (m_layerAnimationController) { - m_layerAnimationController->setClient(this); + m_layerAnimationController->setId(id()); m_layerAnimationController->setForceSync(); } setNeedsCommit(); } -scoped_ptr<LayerAnimationController> Layer::releaseLayerAnimationController() +scoped_refptr<LayerAnimationController> Layer::releaseLayerAnimationController() { - scoped_ptr<LayerAnimationController> toReturn = m_layerAnimationController.Pass(); - m_layerAnimationController = LayerAnimationController::create(this); - return toReturn.Pass(); + scoped_refptr<LayerAnimationController> toReturn = m_layerAnimationController; + m_layerAnimationController = LayerAnimationController::create(); + m_layerAnimationController->setId(id()); + m_layerAnimationController->setTransform(toReturn->transform()); + m_layerAnimationController->setOpacity(toReturn->opacity()); + return toReturn; } bool Layer::hasActiveAnimation() const @@ -43,21 +43,13 @@ struct RenderingStats; // Base class for composited layers. Special layer types are derived from // this class. -class CC_EXPORT Layer : public base::RefCounted<Layer>, public LayerAnimationControllerClient { +class CC_EXPORT Layer : public base::RefCounted<Layer> { public: typedef std::vector<scoped_refptr<Layer> > LayerList; static scoped_refptr<Layer> create(); - // LayerAnimationControllerClient implementation - virtual int id() const OVERRIDE; - virtual void setOpacityFromAnimation(float) OVERRIDE; - virtual float opacity() const OVERRIDE; - virtual void setTransformFromAnimation(const gfx::Transform&) OVERRIDE; - // A layer's transform operates layer space. That is, entirely in logical, - // non-page-scaled pixels (that is, they have page zoom baked in, but not page scale). - // The root layer is a special case -- it operates in physical pixels. - virtual const gfx::Transform& transform() const OVERRIDE; + int id() const; Layer* rootLayer(); Layer* parent() { return m_parent; } @@ -98,6 +90,7 @@ public: virtual bool needsDisplay() const; void setOpacity(float); + float opacity() const; bool opacityIsAnimating() const; void setFilters(const WebKit::WebFilterOperations&); @@ -127,6 +120,7 @@ public: const gfx::Transform& sublayerTransform() const { return m_sublayerTransform; } void setTransform(const gfx::Transform&); + const gfx::Transform& transform() const; bool transformIsAnimating() const; DrawProperties<Layer, RenderSurface>& drawProperties() { return m_drawProperties; } @@ -266,8 +260,8 @@ public: void resumeAnimations(double monotonicTime); LayerAnimationController* layerAnimationController() { return m_layerAnimationController.get(); } - void setLayerAnimationController(scoped_ptr<LayerAnimationController>); - scoped_ptr<LayerAnimationController> releaseLayerAnimationController(); + void setLayerAnimationController(scoped_refptr<LayerAnimationController>); + scoped_refptr<LayerAnimationController> releaseLayerAnimationController(); void setLayerAnimationDelegate(WebKit::WebAnimationDelegate* layerAnimationDelegate) { m_layerAnimationDelegate = layerAnimationDelegate; } @@ -333,7 +327,7 @@ private: // updated via setLayerTreeHost() if a layer moves between trees. LayerTreeHost* m_layerTreeHost; - scoped_ptr<LayerAnimationController> m_layerAnimationController; + scoped_refptr<LayerAnimationController> m_layerAnimationController; // Layer properties. gfx::Size m_bounds; @@ -351,7 +345,6 @@ private: gfx::PointF m_anchorPoint; SkColor m_backgroundColor; std::string m_debugName; - float m_opacity; skia::RefPtr<SkImageFilter> m_filter; WebKit::WebFilterOperations m_filters; WebKit::WebFilterOperations m_backgroundFilters; @@ -368,7 +361,6 @@ private: bool m_drawCheckerboardForMissingTiles; bool m_forceRenderSurface; - gfx::Transform m_transform; gfx::Transform m_sublayerTransform; // Replica layer used for reflections. diff --git a/cc/layer_animation_controller.cc b/cc/layer_animation_controller.cc index 805f8fc..e337395 100644 --- a/cc/layer_animation_controller.cc +++ b/cc/layer_animation_controller.cc @@ -5,24 +5,29 @@ #include "cc/layer_animation_controller.h" #include "cc/active_animation.h" +#include "cc/animation_registrar.h" #include "cc/keyframed_animation_curve.h" #include "ui/gfx/transform.h" namespace cc { -LayerAnimationController::LayerAnimationController(LayerAnimationControllerClient* client) +LayerAnimationController::LayerAnimationController() : m_forceSync(false) - , m_client(client) + , m_id(-1) + , m_opacity(1.0) + , m_registrar(0) { } LayerAnimationController::~LayerAnimationController() { + if (m_registrar) + m_registrar->DidDeactivateAnimationController(this); } -scoped_ptr<LayerAnimationController> LayerAnimationController::create(LayerAnimationControllerClient* client) +scoped_refptr<LayerAnimationController> LayerAnimationController::create() { - return make_scoped_ptr(new LayerAnimationController(client)); + return make_scoped_refptr(new LayerAnimationController()); } void LayerAnimationController::pauseAnimation(int animationId, double timeOffset) @@ -41,6 +46,7 @@ void LayerAnimationController::removeAnimation(int animationId) else i++; } + updateRegistration(); } void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::TargetProperty targetProperty) @@ -51,6 +57,7 @@ void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation: else i++; } + updateRegistration(); } // According to render layer backing, these are for testing only. @@ -75,6 +82,12 @@ void LayerAnimationController::resumeAnimations(double monotonicTime) // are kept in sync. void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl) { + if (!isAnimatingProperty(ActiveAnimation::Opacity)) + controllerImpl->m_opacity = m_opacity; + + if (!isAnimatingProperty(ActiveAnimation::Transform)) + controllerImpl->m_transform = m_transform; + if (m_forceSync) { replaceImplThreadAnimations(controllerImpl); m_forceSync = false; @@ -100,11 +113,14 @@ void LayerAnimationController::animate(double monotonicTime, AnimationEventsVect tickAnimations(monotonicTime); markAnimationsForDeletion(monotonicTime, events); startAnimationsWaitingForTargetAvailability(monotonicTime, events); + + updateRegistration(); } void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation) { m_activeAnimations.append(animation.Pass()); + updateRegistration(); } ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const @@ -154,9 +170,40 @@ void LayerAnimationController::notifyAnimationStarted(const AnimationEvent& even } } -void LayerAnimationController::setClient(LayerAnimationControllerClient* client) +void LayerAnimationController::setAnimationRegistrar(AnimationRegistrar* registrar) +{ + if (m_registrar == registrar) + return; + + if (m_registrar) + m_registrar->UnregisterAnimationController(this); + + m_registrar = registrar; + if (m_registrar) + m_registrar->RegisterAnimationController(this); + + updateRegistration(); +} + +void LayerAnimationController::setId(int id) +{ + m_id = id; +} + +bool LayerAnimationController::setOpacity(float opacity) { - m_client = client; + if (m_opacity == opacity || isAnimatingProperty(ActiveAnimation::Opacity)) + return false; + m_opacity = opacity; + return true; +} + +bool LayerAnimationController::setTransform(const gfx::Transform& transform) +{ + if (m_transform == transform || isAnimatingProperty(ActiveAnimation::Transform)) + return false; + m_transform = transform; + return true; } void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const @@ -214,7 +261,7 @@ void LayerAnimationController::startAnimationsWaitingForNextTick(double monotoni if (!m_activeAnimations[i]->hasSetStartTime()) m_activeAnimations[i]->setStartTime(monotonicTime); if (events) - events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); + events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); } } } @@ -225,7 +272,7 @@ void LayerAnimationController::startAnimationsWaitingForStartTime(double monoton if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) { m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime); if (events) - events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); + events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); } } } @@ -264,7 +311,7 @@ void LayerAnimationController::startAnimationsWaitingForTargetAvailability(doubl if (!m_activeAnimations[i]->hasSetStartTime()) m_activeAnimations[i]->setStartTime(monotonicTime); if (events) - events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); + events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) { if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) { m_activeAnimations[j]->setRunState(ActiveAnimation::Running, monotonicTime); @@ -320,7 +367,7 @@ void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, A for (size_t j = i; j < m_activeAnimations.size(); j++) { if (groupId == m_activeAnimations[j]->group()) { if (events) - events->push_back(AnimationEvent(AnimationEvent::Finished, m_client->id(), m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime)); + events->push_back(AnimationEvent(AnimationEvent::Finished, m_id, m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime)); m_activeAnimations[j]->setRunState(ActiveAnimation::WaitingForDeletion, monotonicTime); } } @@ -358,7 +405,7 @@ void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationControl void LayerAnimationController::tickAnimations(double monotonicTime) { - for (size_t i = 0; i < m_activeAnimations.size(); ++i) { + for (size_t i = 0; i < m_activeAnimations.size(); ++i) { if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Paused) { double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime); @@ -371,21 +418,17 @@ void LayerAnimationController::tickAnimations(double monotonicTime) case ActiveAnimation::Transform: { const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve(); - const gfx::Transform matrix = transformAnimationCurve->getValue(trimmed).toTransform(); + m_transform = transformAnimationCurve->getValue(trimmed).toTransform(); if (m_activeAnimations[i]->isFinishedAt(monotonicTime)) m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime); - - m_client->setTransformFromAnimation(matrix); break; } case ActiveAnimation::Opacity: { const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve(); - const float opacity = floatAnimationCurve->getValue(trimmed); + m_opacity = floatAnimationCurve->getValue(trimmed); if (m_activeAnimations[i]->isFinishedAt(monotonicTime)) m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime); - - m_client->setOpacityFromAnimation(opacity); break; } @@ -397,4 +440,14 @@ void LayerAnimationController::tickAnimations(double monotonicTime) } } +void LayerAnimationController::updateRegistration() +{ + if (m_registrar) { + if (hasActiveAnimation()) + m_registrar->DidActivateAnimationController(this); + else + m_registrar->DidDeactivateAnimationController(this); + } +} + } // namespace cc diff --git a/cc/layer_animation_controller.h b/cc/layer_animation_controller.h index be55afe..f4fd9b8 100644 --- a/cc/layer_animation_controller.h +++ b/cc/layer_animation_controller.h @@ -7,10 +7,13 @@ #include "base/basictypes.h" #include "base/hash_tables.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/time.h" #include "cc/animation_events.h" #include "cc/cc_export.h" #include "cc/scoped_ptr_vector.h" +#include "ui/gfx/transform.h" namespace gfx { class Transform; @@ -19,24 +22,13 @@ class Transform; namespace cc { class Animation; +class AnimationRegistrar; class KeyframeValueList; -class CC_EXPORT LayerAnimationControllerClient { +class CC_EXPORT LayerAnimationController + : public base::RefCounted<LayerAnimationController> { public: - virtual ~LayerAnimationControllerClient() { } - - virtual int id() const = 0; - virtual void setOpacityFromAnimation(float) = 0; - virtual float opacity() const = 0; - virtual void setTransformFromAnimation(const gfx::Transform&) = 0; - virtual const gfx::Transform& transform() const = 0; -}; - -class CC_EXPORT LayerAnimationController { -public: - static scoped_ptr<LayerAnimationController> create(LayerAnimationControllerClient*); - - virtual ~LayerAnimationController(); + static scoped_refptr<LayerAnimationController> create(); // These methods are virtual for testing. virtual void addAnimation(scoped_ptr<ActiveAnimation>); @@ -75,10 +67,30 @@ public: // thread, all animations will be transferred. void setForceSync() { m_forceSync = true; } - void setClient(LayerAnimationControllerClient*); + void setAnimationRegistrar(AnimationRegistrar*); + void setId(int id); + + // Gets the last animated opacity value. + float opacity() const { return m_opacity; } + + // Sets the opacity. Returns true if this call actually updates the opacity. + // This can return false if either the new opacity matches the old, or if + // the property is currently animating. + bool setOpacity(float opacity); + + // Gets the last animate transform value. + const gfx::Transform& transform() const { return m_transform; } + + // Sets the transform. Returns true if this call actually updates the + // transform. This can return false if either the new transform matches the + // old or if the property is currently animating. + bool setTransform(const gfx::Transform& transform); protected: - explicit LayerAnimationController(LayerAnimationControllerClient*); + friend class base::RefCounted<LayerAnimationController>; + + LayerAnimationController(); + virtual ~LayerAnimationController(); private: typedef base::hash_set<int> TargetProperties; @@ -97,10 +109,16 @@ private: void tickAnimations(double monotonicTime); + void updateRegistration(); + // If this is true, we force a sync to the impl thread. bool m_forceSync; - LayerAnimationControllerClient* m_client; + float m_opacity; + gfx::Transform m_transform; + + AnimationRegistrar* m_registrar; + int m_id; ScopedPtrVector<ActiveAnimation> m_activeAnimations; DISALLOW_COPY_AND_ASSIGN(LayerAnimationController); diff --git a/cc/layer_animation_controller_unittest.cc b/cc/layer_animation_controller_unittest.cc index 29b6e6e..0310663 100644 --- a/cc/layer_animation_controller_unittest.cc +++ b/cc/layer_animation_controller_unittest.cc @@ -28,10 +28,8 @@ scoped_ptr<ActiveAnimation> createActiveAnimation(scoped_ptr<AnimationCurve> cur TEST(LayerAnimationControllerTest, syncNewAnimation) { - FakeLayerAnimationControllerClient dummyImpl; - scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); @@ -47,10 +45,8 @@ TEST(LayerAnimationControllerTest, syncNewAnimation) // thread, we must be sure to respect the synchronized start time. TEST(LayerAnimationControllerTest, doNotClobberStartTimes) { - FakeLayerAnimationControllerClient dummyImpl; - scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); @@ -76,10 +72,8 @@ TEST(LayerAnimationControllerTest, doNotClobberStartTimes) TEST(LayerAnimationControllerTest, syncPauseAndResume) { - FakeLayerAnimationControllerClient dummyImpl; - scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); @@ -116,10 +110,8 @@ TEST(LayerAnimationControllerTest, syncPauseAndResume) TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation) { - FakeLayerAnimationControllerClient dummyImpl; - scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); @@ -149,18 +141,16 @@ TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation) TEST(LayerAnimationControllerTest, TrivialTransition) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); controller->addAnimation(toAdd.Pass()); controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1, events.get()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -168,9 +158,7 @@ TEST(LayerAnimationControllerTest, TrivialTransition) TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfTheyWaitLongerToStartThanTheirDuration) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); toAdd->setNeedsSynchronizedStartTime(true); @@ -179,18 +167,18 @@ TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfThe controller->addAnimation(toAdd.Pass()); controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(2, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); // Send the synchronized start time. controller->notifyAnimationStarted(AnimationEvent(AnimationEvent::Started, 0, 1, ActiveAnimation::Opacity, 2)); controller->animate(5, events.get()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -198,21 +186,19 @@ TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfThe TEST(LayerAnimationControllerTest, TrivialQueuing) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 1, 0.5)).PassAs<AnimationCurve>(), 2, ActiveAnimation::Opacity)); controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); controller->animate(2, events.get()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -220,13 +206,12 @@ TEST(LayerAnimationControllerTest, TrivialQueuing) TEST(LayerAnimationControllerTest, Interrupt) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); + controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 1, 0.5)).PassAs<AnimationCurve>(), 2, ActiveAnimation::Opacity)); toAdd->setRunState(ActiveAnimation::WaitingForNextTick, 0); @@ -236,9 +221,9 @@ TEST(LayerAnimationControllerTest, Interrupt) // this call to animate. controller->animate(0.5, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); controller->animate(1.5, events.get()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -246,24 +231,23 @@ TEST(LayerAnimationControllerTest, Interrupt) TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); + controller->setOpacity(0); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Transform)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), 2, ActiveAnimation::Transform)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 2, ActiveAnimation::Opacity)); controller->animate(0, events.get()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); EXPECT_TRUE(controller->hasActiveAnimation()); controller->animate(1, events.get()); // Should not have started the float transition yet. EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); // The float animation should have started at time 1 and should be done. controller->animate(2, events.get()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -273,9 +257,7 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked) TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(2)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Transform)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); @@ -284,18 +266,18 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting) // Animations with id 1 should both start now. controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); // The opacity animation should have finished at time 1, but the group // of animations with id 1 don't finish until time 2 because of the length // of the transform animation. controller->animate(2, events.get()); // Should not have started the float transition yet. EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); // The second opacity animation should start at time 2 and should be done by time 3 controller->animate(3, events.get()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -303,10 +285,9 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting) TEST(LayerAnimationControllerTest, ScheduleAnimation) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); + controller->setOpacity(0); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); toAdd->setRunState(ActiveAnimation::WaitingForStartTime, 0); toAdd->setStartTime(1); @@ -314,12 +295,12 @@ TEST(LayerAnimationControllerTest, ScheduleAnimation) controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(2, events.get()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -327,9 +308,7 @@ TEST(LayerAnimationControllerTest, ScheduleAnimation) TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); @@ -341,15 +320,15 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation) // First 2s opacity transition should start immediately. controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(0.5, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.25, dummy.opacity()); + EXPECT_EQ(0.25, controller->opacity()); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); controller->animate(2, events.get()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -358,9 +337,7 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation) TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationWithAnimInQueue) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); @@ -374,19 +351,19 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationW // First 2s opacity transition should start immediately. controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(0.5, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.25, dummy.opacity()); + EXPECT_EQ(0.25, controller->opacity()); EXPECT_TRUE(controller->hasActiveAnimation()); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); controller->animate(3, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(4, events.get()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); EXPECT_FALSE(controller->hasActiveAnimation()); } @@ -394,9 +371,7 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationW TEST(LayerAnimationControllerTest, TrivialLooping) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); toAdd->setIterations(3); @@ -404,35 +379,33 @@ TEST(LayerAnimationControllerTest, TrivialLooping) controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1.25, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.25, dummy.opacity()); + EXPECT_EQ(0.25, controller->opacity()); controller->animate(1.75, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); controller->animate(2.25, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.25, dummy.opacity()); + EXPECT_EQ(0.25, controller->opacity()); controller->animate(2.75, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); controller->animate(3, events.get()); EXPECT_FALSE(controller->hasActiveAnimation()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); // Just be extra sure. controller->animate(4, events.get()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); } // Test that an infinitely looping animation does indeed go until aborted. TEST(LayerAnimationControllerTest, InfiniteLooping) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); const int id = 1; scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity)); @@ -441,69 +414,65 @@ TEST(LayerAnimationControllerTest, InfiniteLooping) controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1.25, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.25, dummy.opacity()); + EXPECT_EQ(0.25, controller->opacity()); controller->animate(1.75, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); controller->animate(1073741824.25, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.25, dummy.opacity()); + EXPECT_EQ(0.25, controller->opacity()); controller->animate(1073741824.75, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Aborted, 0.75); EXPECT_FALSE(controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); } // Test that pausing and resuming work as expected. TEST(LayerAnimationControllerTest, PauseResume) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); const int id = 1; controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity)); controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(0.5, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Paused, 0.5); controller->animate(1024, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Running, 1024); controller->animate(1024.25, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); controller->animate(1024.5, events.get()); EXPECT_FALSE(controller->hasActiveAnimation()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); } TEST(LayerAnimationControllerTest, AbortAGroupedAnimation) { scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); const int id = 1; controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Transform)); @@ -512,29 +481,25 @@ TEST(LayerAnimationControllerTest, AbortAGroupedAnimation) controller->animate(0, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0, dummy.opacity()); + EXPECT_EQ(0, controller->opacity()); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(0.5, dummy.opacity()); + EXPECT_EQ(0.5, controller->opacity()); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Aborted, 1); controller->animate(1, events.get()); EXPECT_TRUE(controller->hasActiveAnimation()); - EXPECT_EQ(1, dummy.opacity()); + EXPECT_EQ(1, controller->opacity()); controller->animate(2, events.get()); EXPECT_TRUE(!controller->hasActiveAnimation()); - EXPECT_EQ(0.75, dummy.opacity()); + EXPECT_EQ(0.75, controller->opacity()); } TEST(LayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded) { - FakeLayerAnimationControllerClient dummyImpl; - scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl)); - scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); - FakeLayerAnimationControllerClient dummy; - scoped_ptr<LayerAnimationController> controller( - LayerAnimationController::create(&dummy)); + scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); + scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 0, ActiveAnimation::Opacity)); toAdd->setNeedsSynchronizedStartTime(true); diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc index 2b78195..c9c41c1 100644 --- a/cc/layer_impl.cc +++ b/cc/layer_impl.cc @@ -37,7 +37,6 @@ LayerImpl::LayerImpl(int id) , m_layerSurfacePropertyChanged(false) , m_masksToBounds(false) , m_contentsOpaque(false) - , m_opacity(1.0) , m_preserves3D(false) , m_useParentBackfaceVisibility(false) , m_drawCheckerboardForMissingTiles(false) @@ -50,9 +49,10 @@ LayerImpl::LayerImpl(int id) #ifndef NDEBUG , m_betweenWillDrawAndDidDraw(false) #endif - , m_layerAnimationController(LayerAnimationController::create(this)) + , m_layerAnimationController(LayerAnimationController::create()) { DCHECK(m_layerId > 0); + m_layerAnimationController->setId(m_layerId); } LayerImpl::~LayerImpl() @@ -115,6 +115,12 @@ int LayerImpl::descendantsDrawContent() return result; } +void LayerImpl::setLayerTreeHostImpl(LayerTreeHostImpl* hostImpl) +{ + m_layerTreeHostImpl = hostImpl; + m_layerAnimationController->setAnimationRegistrar(hostImpl); +} + scoped_ptr<SharedQuadState> LayerImpl::createSharedQuadState() const { scoped_ptr<SharedQuadState> state = SharedQuadState::Create(); @@ -415,26 +421,6 @@ int LayerImpl::id() const return m_layerId; } -float LayerImpl::opacity() const -{ - return m_opacity; -} - -void LayerImpl::setOpacityFromAnimation(float opacity) -{ - setOpacity(opacity); -} - -const gfx::Transform& LayerImpl::transform() const -{ - return m_transform; -} - -void LayerImpl::setTransformFromAnimation(const gfx::Transform& transform) -{ - setTransform(transform); -} - void LayerImpl::setBounds(const gfx::Size& bounds) { if (m_bounds == bounds) @@ -557,13 +543,16 @@ void LayerImpl::setContentsOpaque(bool opaque) void LayerImpl::setOpacity(float opacity) { - if (m_opacity == opacity) + if (!m_layerAnimationController->setOpacity(opacity)) return; - - m_opacity = opacity; m_layerSurfacePropertyChanged = true; } +float LayerImpl::opacity() const +{ + return m_layerAnimationController->opacity(); +} + bool LayerImpl::opacityIsAnimating() const { return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity); @@ -599,13 +588,16 @@ void LayerImpl::setSublayerTransform(const gfx::Transform& sublayerTransform) void LayerImpl::setTransform(const gfx::Transform& transform) { - if (m_transform == transform) + if (!m_layerAnimationController->setTransform(transform)) return; - - m_transform = transform; m_layerSurfacePropertyChanged = true; } +const gfx::Transform& LayerImpl::transform() const +{ + return m_layerAnimationController->transform(); +} + bool LayerImpl::transformIsAnimating() const { return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform); diff --git a/cc/layer_impl.h b/cc/layer_impl.h index b92862e..76a3e38 100644 --- a/cc/layer_impl.h +++ b/cc/layer_impl.h @@ -38,7 +38,7 @@ class Layer; struct AppendQuadsData; -class CC_EXPORT LayerImpl : public LayerAnimationControllerClient { +class CC_EXPORT LayerImpl { public: typedef ScopedPtrVector<LayerImpl> LayerList; @@ -49,12 +49,7 @@ public: virtual ~LayerImpl(); - // LayerAnimationControllerClient implementation. - virtual int id() const OVERRIDE; - virtual void setOpacityFromAnimation(float) OVERRIDE; - virtual float opacity() const OVERRIDE; - virtual void setTransformFromAnimation(const gfx::Transform&) OVERRIDE; - virtual const gfx::Transform& transform() const OVERRIDE; + int id() const; // Tree structure. LayerImpl* parent() { return m_parent; } @@ -77,7 +72,7 @@ public: bool replicaHasMask() const { return m_replicaLayer && (m_maskLayer || m_replicaLayer->m_maskLayer); } LayerTreeHostImpl* layerTreeHostImpl() const { return m_layerTreeHostImpl; } - void setLayerTreeHostImpl(LayerTreeHostImpl* hostImpl) { m_layerTreeHostImpl = hostImpl; } + void setLayerTreeHostImpl(LayerTreeHostImpl* hostImpl); scoped_ptr<SharedQuadState> createSharedQuadState() const; // willDraw must be called before appendQuads. If willDraw is called, @@ -131,6 +126,7 @@ public: bool contentsOpaque() const { return m_contentsOpaque; } void setOpacity(float); + float opacity() const; bool opacityIsAnimating() const; void setPosition(const gfx::PointF&); @@ -239,6 +235,7 @@ public: void setDoubleSided(bool); void setTransform(const gfx::Transform&); + const gfx::Transform& transform() const; bool transformIsAnimating() const; const gfx::RectF& updateRect() const { return m_updateRect; } @@ -343,13 +340,11 @@ private: bool m_masksToBounds; bool m_contentsOpaque; - float m_opacity; gfx::PointF m_position; bool m_preserves3D; bool m_useParentBackfaceVisibility; bool m_drawCheckerboardForMissingTiles; gfx::Transform m_sublayerTransform; - gfx::Transform m_transform; bool m_useLCDText; bool m_drawsContent; @@ -386,7 +381,7 @@ private: gfx::RectF m_updateRect; // Manages animations for this layer. - scoped_ptr<LayerAnimationController> m_layerAnimationController; + scoped_refptr<LayerAnimationController> m_layerAnimationController; // Manages scrollbars for this layer scoped_ptr<ScrollbarAnimationController> m_scrollbarAnimationController; diff --git a/cc/layer_tree_host.cc b/cc/layer_tree_host.cc index ec16740..00a7b68 100644 --- a/cc/layer_tree_host.cc +++ b/cc/layer_tree_host.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/debug/trace_event.h" #include "base/message_loop.h" +#include "base/stl_util.h" #include "base/string_number_conversions.h" #include "cc/font_atlas.h" #include "cc/heads_up_display_layer.h" @@ -177,7 +178,6 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::create(LayerTreeHostClient* client, con LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings) : m_animating(false) - , m_needsAnimateLayers(false) , m_needsFullTreeSync(true) , m_client(client) , m_commitNumber(0) @@ -235,6 +235,9 @@ LayerTreeHost::~LayerTreeHost() RateLimiterMap::iterator it = m_rateLimiters.begin(); if (it != m_rateLimiters.end()) it->second->stop(); + + if (m_rootLayer) + m_rootLayer = 0; } void LayerTreeHost::setSurfaceReady() @@ -387,11 +390,6 @@ void LayerTreeHost::finishCommitOnImplThread(LayerTreeHostImpl* hostImpl) else hostImpl->activeTree()->set_hud_layer(0); - // We may have added an animation during the tree sync. This will cause both layer tree hosts - // to visit their controllers. - if (rootLayer() && m_needsAnimateLayers) - hostImpl->setNeedsAnimateLayers(); - hostImpl->activeTree()->set_source_frame_number(commitNumber()); hostImpl->setViewportSize(layoutViewportSize(), deviceViewportSize()); hostImpl->setDeviceScaleFactor(deviceScaleFactor()); @@ -525,12 +523,6 @@ void LayerTreeHost::setAnimationEvents(scoped_ptr<AnimationEventsVector> events, setAnimationEventsRecursive(*events.get(), m_rootLayer.get(), wallClockTime); } -void LayerTreeHost::didAddAnimation() -{ - m_needsAnimateLayers = true; - m_proxy->didAddAnimation(); -} - void LayerTreeHost::setRootLayer(scoped_refptr<Layer> rootLayer) { if (m_rootLayer == rootLayer) @@ -933,33 +925,16 @@ void LayerTreeHost::setDeviceScaleFactor(float deviceScaleFactor) void LayerTreeHost::animateLayers(base::TimeTicks time) { - if (!m_settings.acceleratedAnimationEnabled || !m_needsAnimateLayers) + if (!m_settings.acceleratedAnimationEnabled || m_activeAnimationControllers.empty()) return; TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); - m_needsAnimateLayers = animateLayersRecursive(m_rootLayer.get(), time); -} -bool LayerTreeHost::animateLayersRecursive(Layer* current, base::TimeTicks time) -{ - if (!current) - return false; - - bool subtreeNeedsAnimateLayers = false; - LayerAnimationController* currentController = current->layerAnimationController(); double monotonicTime = (time - base::TimeTicks()).InSecondsF(); - currentController->animate(monotonicTime, 0); - - // If the current controller still has an active animation, we must continue animating layers. - if (currentController->hasActiveAnimation()) - subtreeNeedsAnimateLayers = true; - for (size_t i = 0; i < current->children().size(); ++i) { - if (animateLayersRecursive(current->children()[i].get(), time)) - subtreeNeedsAnimateLayers = true; - } - - return subtreeNeedsAnimateLayers; + AnimationControllerSet copy = m_activeAnimationControllers; + for (AnimationControllerSet::iterator iter = copy.begin(); iter != copy.end(); ++iter) + (*iter)->animate(monotonicTime, 0); } void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& events, Layer* layer, base::Time wallClockTime) @@ -980,4 +955,30 @@ void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& eve setAnimationEventsRecursive(events, layer->children()[childIndex].get(), wallClockTime); } +void LayerTreeHost::DidActivateAnimationController(LayerAnimationController* controller) { + // Controllers register themselves when they have new animations. We need + // to commit in this case. + setNeedsCommit(); + m_activeAnimationControllers.insert(controller); +} + +void LayerTreeHost::DidDeactivateAnimationController(LayerAnimationController* controller) { + if (ContainsKey(m_activeAnimationControllers, controller)) + m_activeAnimationControllers.erase(controller); +} + +void LayerTreeHost::RegisterAnimationController(LayerAnimationController* controller) { +#if !defined(NDEBUG) + m_allAnimationControllers.insert(controller); +#endif +} + +void LayerTreeHost::UnregisterAnimationController(LayerAnimationController* controller) { +#if !defined(NDEBUG) + if (ContainsKey(m_allAnimationControllers, controller)) + m_allAnimationControllers.erase(controller); +#endif + DidDeactivateAnimationController(controller); +} + } // namespace cc diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h index 4423082..21af798 100644 --- a/cc/layer_tree_host.h +++ b/cc/layer_tree_host.h @@ -14,6 +14,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "cc/animation_events.h" +#include "cc/animation_registrar.h" #include "cc/cc_export.h" #include "cc/layer_tree_host_client.h" #include "cc/layer_tree_host_common.h" @@ -36,6 +37,15 @@ struct hash<WebKit::WebGraphicsContext3D*> { } }; } // namespace BASE_HASH_NAMESPACE + +namespace BASE_HASH_NAMESPACE { +template<> +struct hash<cc::LayerAnimationController*> { + size_t operator()(cc::LayerAnimationController* ptr) const { + return hash<size_t>()(reinterpret_cast<size_t>(ptr)); + } +}; +} // namespace BASE_HASH_NAMESPACE #endif // COMPILER namespace cc { @@ -113,7 +123,8 @@ struct CC_EXPORT RendererCapabilities { int maxTextureSize; }; -class CC_EXPORT LayerTreeHost : public RateLimiterClient { +class CC_EXPORT LayerTreeHost : public RateLimiterClient, + public AnimationRegistrar { public: static scoped_ptr<LayerTreeHost> create(LayerTreeHostClient*, const LayerTreeSettings&, scoped_ptr<Thread> implThread); virtual ~LayerTreeHost(); @@ -190,7 +201,6 @@ public: bool commitRequested() const; void setAnimationEvents(scoped_ptr<AnimationEventsVector>, base::Time wallClockTime); - virtual void didAddAnimation(); Layer* rootLayer() { return m_rootLayer.get(); } const Layer* rootLayer() const { return m_rootLayer.get(); } @@ -248,8 +258,15 @@ protected: bool initialize(scoped_ptr<Thread> implThread); bool initializeForTesting(scoped_ptr<Proxy> proxyForTesting); + // AnimationRegistar implementation. + virtual void DidActivateAnimationController(LayerAnimationController*) OVERRIDE; + virtual void DidDeactivateAnimationController(LayerAnimationController*) OVERRIDE; + virtual void RegisterAnimationController(LayerAnimationController*) OVERRIDE; + virtual void UnregisterAnimationController(LayerAnimationController*) OVERRIDE; + private: typedef std::vector<scoped_refptr<Layer> > LayerList; + typedef base::hash_set<LayerAnimationController*> AnimationControllerSet; bool initializeProxy(scoped_ptr<Proxy> proxy); void initializeRenderer(); @@ -271,7 +288,6 @@ private: void setAnimationEventsRecursive(const AnimationEventsVector&, Layer*, base::Time wallClockTime); bool m_animating; - bool m_needsAnimateLayers; bool m_needsFullTreeSync; base::CancelableClosure m_prepaintCallback; @@ -318,6 +334,12 @@ private: static bool s_needsFilterContext; + AnimationControllerSet m_activeAnimationControllers; + +#if !defined(NDEBUG) + AnimationControllerSet m_allAnimationControllers; +#endif + DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); }; diff --git a/cc/layer_tree_host_common_unittest.cc b/cc/layer_tree_host_common_unittest.cc index d9c97a2..d343c78 100644 --- a/cc/layer_tree_host_common_unittest.cc +++ b/cc/layer_tree_host_common_unittest.cc @@ -1680,24 +1680,11 @@ TEST(LayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy) renderSurface1->setForceRenderSurface(true); renderSurface2->setForceRenderSurface(true); - // Put an animated opacity on the render surface. - addOpacityTransitionToController(*renderSurface1->layerAnimationController(), 10, 1, 0, false); - - // Also put an animated opacity on a layer without descendants. - addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController(), 10, 1, 0, false); - gfx::Transform layerTransform; layerTransform.Translate(1, 1); gfx::Transform sublayerTransform; sublayerTransform.Scale3d(10, 1, 1); - // Put a transform animation on the render surface. - addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0); - - // Also put transform animations on grandChildOfRoot, and grandChildOfRS2 - addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0); - addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(), 10, 30, 0); - setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false); setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false); setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false); @@ -1708,6 +1695,19 @@ TEST(LayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy) setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false); setLayerPropertiesForTesting(grandChildOfRS2.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false); + // Put an animated opacity on the render surface. + addOpacityTransitionToController(*renderSurface1->layerAnimationController(), 10, 1, 0, false); + + // Also put an animated opacity on a layer without descendants. + addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController(), 10, 1, 0, false); + + // Put a transform animation on the render surface. + addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0); + + // Also put transform animations on grandChildOfRoot, and grandChildOfRS2 + addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0); + addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(), 10, 30, 0); + executeCalculateDrawProperties(parent.get()); // Only layers that are associated with render surfaces should have an actual renderSurface() value. diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc index 7298c49..f006620 100644 --- a/cc/layer_tree_host_impl.cc +++ b/cc/layer_tree_host_impl.cc @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/debug/trace_event.h" +#include "base/stl_util.h" #include "cc/append_quads_data.h" #include "cc/damage_tracker.h" #include "cc/debug_rect_history.h" @@ -215,7 +216,6 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre PriorityCalculator::allowNothingCutoff()) , m_backgroundColor(0) , m_hasTransparentBackground(false) - , m_needsAnimateLayers(false) , m_pinchGestureActive(false) , m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread())) , m_debugRectHistory(DebugRectHistory::create()) @@ -236,8 +236,13 @@ LayerTreeHostImpl::~LayerTreeHostImpl() DCHECK(m_proxy->isImplThread()); TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); - if (rootLayer()) + if (rootLayer()) { clearRenderSurfaces(); + // The layer trees must be destroyed before the layer tree host. We've + // made a contract with our animation controllers that the registrar + // will outlive them, and we must make good. + m_activeTree.reset(); + } } void LayerTreeHostImpl::beginCommit() @@ -584,35 +589,6 @@ bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame) return drawFrame; } -void LayerTreeHostImpl::animateLayersRecursive(LayerImpl* current, base::TimeTicks monotonicTime, base::Time wallClockTime, AnimationEventsVector* events, bool& didAnimate, bool& needsAnimateLayers) -{ - bool subtreeNeedsAnimateLayers = false; - - LayerAnimationController* currentController = current->layerAnimationController(); - - bool hadActiveAnimation = currentController->hasActiveAnimation(); - double monotonicTimeSeconds = (monotonicTime - base::TimeTicks()).InSecondsF(); - currentController->animate(monotonicTimeSeconds, events); - bool startedAnimation = events->size() > 0; - - // We animated if we either ticked a running animation, or started a new animation. - if (hadActiveAnimation || startedAnimation) - didAnimate = true; - - // If the current controller still has an active animation, we must continue animating layers. - if (currentController->hasActiveAnimation()) - subtreeNeedsAnimateLayers = true; - - for (size_t i = 0; i < current->children().size(); ++i) { - bool childNeedsAnimateLayers = false; - animateLayersRecursive(current->children()[i], monotonicTime, wallClockTime, events, didAnimate, childNeedsAnimateLayers); - if (childNeedsAnimateLayers) - subtreeNeedsAnimateLayers = true; - } - - needsAnimateLayers = subtreeNeedsAnimateLayers; -} - void LayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled) { // Lazily create the timeSource adapter so that we can vary the interval for testing. @@ -955,7 +931,7 @@ void LayerTreeHostImpl::setVisible(bool visible) m_renderer->setVisible(visible); - setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers); + setBackgroundTickingEnabled(!m_visible && !m_activeAnimationControllers.empty()); } bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface) @@ -1508,23 +1484,23 @@ void LayerTreeHostImpl::animatePageScale(base::TimeTicks time) void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime) { - if (!m_settings.acceleratedAnimationEnabled || !m_needsAnimateLayers || !rootLayer()) + if (!m_settings.acceleratedAnimationEnabled || m_activeAnimationControllers.empty() || !rootLayer()) return; TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); - scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); + double monotonicSeconds = (monotonicTime - base::TimeTicks()).InSecondsF(); - bool didAnimate = false; - animateLayersRecursive(rootLayer(), monotonicTime, wallClockTime, events.get(), didAnimate, m_needsAnimateLayers); + scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); + AnimationControllerSet copy = m_activeAnimationControllers; + for (AnimationControllerSet::iterator iter = copy.begin(); iter != copy.end(); ++iter) + (*iter)->animate(monotonicSeconds, events.get()); if (!events->empty()) m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime); - if (didAnimate) - m_client->setNeedsRedrawOnImplThread(); - - setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers); + m_client->setNeedsRedrawOnImplThread(); + setBackgroundTickingEnabled(!m_visible && !m_activeAnimationControllers.empty()); } base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const @@ -1614,4 +1590,27 @@ void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeT animateScrollbarsRecursive(layer->children()[i], time); } +void LayerTreeHostImpl::DidActivateAnimationController(LayerAnimationController* controller) { + m_activeAnimationControllers.insert(controller); +} + +void LayerTreeHostImpl::DidDeactivateAnimationController(LayerAnimationController* controller) { + if (ContainsKey(m_activeAnimationControllers, controller)) + m_activeAnimationControllers.erase(controller); +} + +void LayerTreeHostImpl::RegisterAnimationController(LayerAnimationController* controller) { +#if !defined(NDEBUG) + m_allAnimationControllers.insert(controller); +#endif +} + +void LayerTreeHostImpl::UnregisterAnimationController(LayerAnimationController* controller) { +#if !defined(NDEBUG) + if (ContainsKey(m_allAnimationControllers, controller)) + m_allAnimationControllers.erase(controller); +#endif + DidDeactivateAnimationController(controller); +} + } // namespace cc diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h index 4bbce14..f9059a4 100644 --- a/cc/layer_tree_host_impl.h +++ b/cc/layer_tree_host_impl.h @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/time.h" #include "cc/animation_events.h" +#include "cc/animation_registrar.h" #include "cc/cc_export.h" #include "cc/input_handler.h" #include "cc/layer_tree_impl.h" @@ -113,8 +114,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient, public RendererClient, public TileManagerClient, public LayerTreeImplClient, + public AnimationRegistrar, public NON_EXPORTED_BASE(WebKit::WebCompositorOutputSurfaceClient) { typedef std::vector<LayerImpl*> LayerList; + typedef base::hash_set<LayerAnimationController*> AnimationControllerSet; public: static scoped_ptr<LayerTreeHostImpl> create(const LayerTreeSettings&, LayerTreeHostImplClient*, Proxy*); @@ -243,9 +246,7 @@ public: bool hasTransparentBackground() const { return m_hasTransparentBackground; } void setHasTransparentBackground(bool transparent) { m_hasTransparentBackground = transparent; } - - bool needsAnimateLayers() const { return m_needsAnimateLayers; } - void setNeedsAnimateLayers() { m_needsAnimateLayers = true; } + bool needsAnimateLayers() const { return !m_activeAnimationControllers.empty(); } void setNeedsRedraw(); @@ -335,7 +336,14 @@ private: void dumpRenderSurfaces(std::string*, int indent, const LayerImpl*) const; + // AnimationRegistar implementation. + virtual void DidActivateAnimationController(LayerAnimationController*) OVERRIDE; + virtual void DidDeactivateAnimationController(LayerAnimationController*) OVERRIDE; + virtual void RegisterAnimationController(LayerAnimationController*) OVERRIDE; + virtual void UnregisterAnimationController(LayerAnimationController*) OVERRIDE; + scoped_ptr<OutputSurface> m_outputSurface; + scoped_ptr<ResourceProvider> m_resourceProvider; scoped_ptr<Renderer> m_renderer; scoped_ptr<TileManager> m_tileManager; @@ -356,7 +364,6 @@ private: bool m_hasTransparentBackground; // If this is true, it is necessary to traverse the layer tree ticking the animators. - bool m_needsAnimateLayers; bool m_pinchGestureActive; gfx::Point m_previousPinchAnchor; @@ -379,6 +386,12 @@ private: size_t m_cumulativeNumLayersDrawn; + AnimationControllerSet m_activeAnimationControllers; + +#if !defined(NDEBUG) + AnimationControllerSet m_allAnimationControllers; +#endif + DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl); }; @@ -81,8 +81,6 @@ public: // like compositeAndReadback while commits are deferred. virtual void setDeferCommits(bool) = 0; - virtual void didAddAnimation() = 0; - virtual bool commitRequested() const = 0; virtual void start() = 0; // Must be called before using the proxy. diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc index d26d666..d3787bc 100644 --- a/cc/single_thread_proxy.cc +++ b/cc/single_thread_proxy.cc @@ -241,10 +241,6 @@ bool SingleThreadProxy::commitRequested() const return false; } -void SingleThreadProxy::didAddAnimation() -{ -} - size_t SingleThreadProxy::maxPartialTextureUpdates() const { return std::numeric_limits<size_t>::max(); diff --git a/cc/single_thread_proxy.h b/cc/single_thread_proxy.h index 51deb25..d30acf9 100644 --- a/cc/single_thread_proxy.h +++ b/cc/single_thread_proxy.h @@ -39,7 +39,6 @@ public: virtual void setNeedsRedraw() OVERRIDE; virtual void setDeferCommits(bool) OVERRIDE; virtual bool commitRequested() const OVERRIDE; - virtual void didAddAnimation() OVERRIDE; virtual void start() OVERRIDE; virtual void stop() OVERRIDE; virtual size_t maxPartialTextureUpdates() const OVERRIDE; diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc index fd6ba2d..73e0960 100644 --- a/cc/test/animation_test_common.cc +++ b/cc/test/animation_test_common.cc @@ -150,40 +150,6 @@ float FakeFloatTransition::getValue(double time) const return (1 - time) * m_from + time * m_to; } -FakeLayerAnimationControllerClient::FakeLayerAnimationControllerClient() - : m_opacity(0) -{ -} - -FakeLayerAnimationControllerClient::~FakeLayerAnimationControllerClient() -{ -} - -int FakeLayerAnimationControllerClient::id() const -{ - return 0; -} - -void FakeLayerAnimationControllerClient::setOpacityFromAnimation(float opacity) -{ - m_opacity = opacity; -} - -float FakeLayerAnimationControllerClient::opacity() const -{ - return m_opacity; -} - -void FakeLayerAnimationControllerClient::setTransformFromAnimation(const gfx::Transform& transform) -{ - m_transform = transform; -} - -const gfx::Transform& FakeLayerAnimationControllerClient::transform() const -{ - return m_transform; -} - scoped_ptr<cc::AnimationCurve> FakeFloatTransition::clone() const { return make_scoped_ptr(new FakeFloatTransition(*this)).PassAs<cc::AnimationCurve>(); diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h index d293206..c136f41 100644 --- a/cc/test/animation_test_common.h +++ b/cc/test/animation_test_common.h @@ -60,23 +60,6 @@ private: float m_to; }; -class FakeLayerAnimationControllerClient : public cc::LayerAnimationControllerClient { -public: - FakeLayerAnimationControllerClient(); - virtual ~FakeLayerAnimationControllerClient(); - - // LayerAnimationControllerClient implementation - virtual int id() const OVERRIDE; - virtual void setOpacityFromAnimation(float) OVERRIDE; - virtual float opacity() const OVERRIDE; - virtual void setTransformFromAnimation(const gfx::Transform&) OVERRIDE; - virtual const gfx::Transform& transform() const OVERRIDE; - -private: - float m_opacity; - gfx::Transform m_transform; -}; - int addOpacityTransitionToController(cc::LayerAnimationController&, double duration, float startOpacity, float endOpacity, bool useTimingFunction); int addAnimatedTransformToController(cc::LayerAnimationController&, double duration, int deltaX, int deltaY); diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index c89f120..a87310e 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h @@ -30,7 +30,6 @@ public: virtual void setNeedsCommit() OVERRIDE { } virtual void setNeedsRedraw() OVERRIDE { } virtual void setDeferCommits(bool) OVERRIDE { } - virtual void didAddAnimation() OVERRIDE { } virtual bool commitRequested() const OVERRIDE; virtual void start() OVERRIDE { } virtual void stop() OVERRIDE { } diff --git a/cc/test/layer_tree_test_common.cc b/cc/test/layer_tree_test_common.cc index 35bdab7..a1b04e9 100644 --- a/cc/test/layer_tree_test_common.cc +++ b/cc/test/layer_tree_test_common.cc @@ -164,12 +164,6 @@ public: return MockLayerTreeHostImpl::create(m_testHooks, settings(), client, proxy()).PassAs<cc::LayerTreeHostImpl>(); } - virtual void didAddAnimation() OVERRIDE - { - LayerTreeHost::didAddAnimation(); - m_testHooks->didAddAnimation(); - } - virtual void setNeedsCommit() OVERRIDE { if (!m_testStarted) @@ -177,6 +171,12 @@ public: LayerTreeHost::setNeedsCommit(); } + virtual void DidActivateAnimationController(cc::LayerAnimationController* controller) OVERRIDE + { + LayerTreeHost::DidActivateAnimationController(controller); + m_testHooks->didAddAnimation(); + } + void setTestStarted(bool started) { m_testStarted = started; } virtual void didDeferCommit() OVERRIDE @@ -343,11 +343,6 @@ void ThreadedTest::postSetVisibleToMainThread(bool visible) m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadedTest::dispatchSetVisible, base::Unretained(this), visible)); } -void ThreadedTest::postDidAddAnimationToMainThread() -{ - m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadedTest::dispatchDidAddAnimation, base::Unretained(this))); -} - void ThreadedTest::doBeginTest() { m_client = ThreadedMockLayerTreeHostClient::create(this); @@ -477,17 +472,6 @@ void ThreadedTest::dispatchComposite() m_layerTreeHost->composite(); } -void ThreadedTest::dispatchDidAddAnimation() -{ - DCHECK(!proxy() || proxy()->isMainThread()); - - if (m_finished) - return; - - if (m_layerTreeHost.get()) - m_layerTreeHost->didAddAnimation(); -} - void ThreadedTest::runTest(bool threaded) { if (threaded) { diff --git a/cc/test/layer_tree_test_common.h b/cc/test/layer_tree_test_common.h index 4403326..e85927d 100644 --- a/cc/test/layer_tree_test_common.h +++ b/cc/test/layer_tree_test_common.h @@ -84,7 +84,6 @@ public: void postAcquireLayerTextures(); void postSetNeedsRedrawToMainThread(); void postSetVisibleToMainThread(bool visible); - void postDidAddAnimationToMainThread(); void doBeginTest(); void timeout(); diff --git a/cc/thread_proxy.h b/cc/thread_proxy.h index da4f386..c0a661a 100644 --- a/cc/thread_proxy.h +++ b/cc/thread_proxy.h @@ -47,7 +47,6 @@ public: virtual void setNeedsRedraw() OVERRIDE; virtual void setDeferCommits(bool) OVERRIDE; virtual bool commitRequested() const OVERRIDE; - virtual void didAddAnimation() OVERRIDE { } virtual void start() OVERRIDE; virtual void stop() OVERRIDE; virtual size_t maxPartialTextureUpdates() const OVERRIDE; diff --git a/cc/tree_synchronizer_unittest.cc b/cc/tree_synchronizer_unittest.cc index ae27443..61aeb2b 100644 --- a/cc/tree_synchronizer_unittest.cc +++ b/cc/tree_synchronizer_unittest.cc @@ -77,19 +77,20 @@ private: class FakeLayerAnimationController : public LayerAnimationController { public: - static scoped_ptr<FakeLayerAnimationController> create(LayerAnimationControllerClient* client) + static scoped_refptr<LayerAnimationController> create() { - return make_scoped_ptr(new FakeLayerAnimationController(client)); + return static_cast<LayerAnimationController*>(new FakeLayerAnimationController); } bool synchronizedAnimations() const { return m_synchronizedAnimations; } private: - explicit FakeLayerAnimationController(LayerAnimationControllerClient* client) - : LayerAnimationController(client) + FakeLayerAnimationController() + : LayerAnimationController() , m_synchronizedAnimations(false) - { - } + { } + + virtual ~FakeLayerAnimationController() { } virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl) { @@ -394,8 +395,7 @@ TEST(TreeSynchronizerTest, synchronizeAnimations) scoped_refptr<Layer> layerTreeRoot = Layer::create(); - FakeLayerAnimationControllerClient dummy; - layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create(&dummy).PassAs<LayerAnimationController>()); + layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create()); EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations()); |