summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-20 00:11:34 +0000
committervollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-20 00:11:34 +0000
commitde4afb5eaff3e756cc13d915532402c651302a32 (patch)
treed7517e1363c8cf3698dc1fd08af4623705a4263d
parent8f95c562479b3be9776e77b597d72b464bb447a5 (diff)
downloadchromium_src-de4afb5eaff3e756cc13d915532402c651302a32.zip
chromium_src-de4afb5eaff3e756cc13d915532402c651302a32.tar.gz
chromium_src-de4afb5eaff3e756cc13d915532402c651302a32.tar.bz2
Ref count layer animation controllers.
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. R=nduca@chromium.org,enne@chromium.org BUG=162111 Review URL: https://chromiumcodereview.appspot.com/11598005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174043 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/animation_registrar.cc46
-rw-r--r--cc/animation_registrar.h65
-rw-r--r--cc/cc.gyp5
-rw-r--r--cc/layer.cc76
-rw-r--r--cc/layer.h35
-rw-r--r--cc/layer_animation_controller.cc86
-rw-r--r--cc/layer_animation_controller.h53
-rw-r--r--cc/layer_animation_controller_unittest.cc129
-rw-r--r--cc/layer_animation_event_observer.h (renamed from cc/layer_animation_observer.h)8
-rw-r--r--cc/layer_animation_value_observer.h21
-rw-r--r--cc/layer_impl.cc30
-rw-r--r--cc/layer_impl.h18
-rw-r--r--cc/layer_tree_host.cc47
-rw-r--r--cc/layer_tree_host.h7
-rw-r--r--cc/layer_tree_host_common_unittest.cc26
-rw-r--r--cc/layer_tree_host_impl.cc61
-rw-r--r--cc/layer_tree_host_impl.h13
-rw-r--r--cc/layer_tree_host_unittest_animation.cc60
-rw-r--r--cc/layer_tree_impl.cc3
-rw-r--r--cc/layer_tree_impl.h2
-rw-r--r--cc/proxy.h2
-rw-r--r--cc/single_thread_proxy.cc4
-rw-r--r--cc/single_thread_proxy.h1
-rw-r--r--cc/test/animation_test_common.cc23
-rw-r--r--cc/test/animation_test_common.h21
-rw-r--r--cc/test/fake_proxy.h1
-rw-r--r--cc/test/layer_tree_test_common.cc30
-rw-r--r--cc/test/layer_tree_test_common.h3
-rw-r--r--cc/thread_proxy.h1
-rw-r--r--cc/tree_synchronizer_unittest.cc16
30 files changed, 530 insertions, 363 deletions
diff --git a/cc/animation_registrar.cc b/cc/animation_registrar.cc
new file mode 100644
index 0000000..5eb7a81
--- /dev/null
+++ b/cc/animation_registrar.cc
@@ -0,0 +1,46 @@
+// 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.
+
+#include "cc/animation_registrar.h"
+
+#include "cc/layer_animation_controller.h"
+
+namespace cc {
+
+AnimationRegistrar::AnimationRegistrar() { }
+AnimationRegistrar::~AnimationRegistrar() { }
+
+scoped_refptr<LayerAnimationController>
+AnimationRegistrar::GetAnimationControllerForId(int id)
+{
+ scoped_refptr<LayerAnimationController> toReturn;
+ if (!ContainsKey(all_animation_controllers_, id)) {
+ toReturn = LayerAnimationController::create(id);
+ toReturn->setAnimationRegistrar(this);
+ all_animation_controllers_[id] = toReturn.get();
+ } else
+ toReturn = all_animation_controllers_[id];
+ return toReturn;
+}
+
+void AnimationRegistrar::DidActivateAnimationController(LayerAnimationController* controller) {
+ active_animation_controllers_[controller->id()] = controller;
+}
+
+void AnimationRegistrar::DidDeactivateAnimationController(LayerAnimationController* controller) {
+ if (ContainsKey(active_animation_controllers_, controller->id()))
+ active_animation_controllers_.erase(controller->id());
+}
+
+void AnimationRegistrar::RegisterAnimationController(LayerAnimationController* controller) {
+ all_animation_controllers_[controller->id()] = controller;
+}
+
+void AnimationRegistrar::UnregisterAnimationController(LayerAnimationController* controller) {
+ if (ContainsKey(all_animation_controllers_, controller->id()))
+ all_animation_controllers_.erase(controller->id());
+ DidDeactivateAnimationController(controller);
+}
+
+} // namespace cc
diff --git a/cc/animation_registrar.h b/cc/animation_registrar.h
new file mode 100644
index 0000000..8799022
--- /dev/null
+++ b/cc/animation_registrar.h
@@ -0,0 +1,65 @@
+// 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_
+
+#include "base/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
+#include "cc/cc_export.h"
+
+namespace cc {
+
+class LayerAnimationController;
+
+class CC_EXPORT AnimationRegistrar {
+ public:
+ typedef base::hash_map<int, LayerAnimationController*> AnimationControllerMap;
+
+ static scoped_ptr<AnimationRegistrar> create() {
+ return make_scoped_ptr(new AnimationRegistrar());
+ }
+
+ virtual ~AnimationRegistrar();
+
+ // If an animation has been registered for the given id, return it. Otherwise
+ // creates a new one and returns a scoped_refptr to it.
+ scoped_refptr<LayerAnimationController> GetAnimationControllerForId(int id);
+
+ // Registers the given animation controller as active. An active animation
+ // controller is one that has a running animation that needs to be ticked.
+ void DidActivateAnimationController(LayerAnimationController*);
+
+ // 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.
+ void DidDeactivateAnimationController(LayerAnimationController*);
+
+ // Registers the given controller as alive.
+ void RegisterAnimationController(LayerAnimationController*);
+
+ // Unregisters the given controller as alive.
+ void UnregisterAnimationController(LayerAnimationController*);
+
+ const AnimationControllerMap& active_animation_controllers() const {
+ return active_animation_controllers_;
+ }
+
+ const AnimationControllerMap& all_animation_controllers() const {
+ return all_animation_controllers_;
+ }
+
+ private:
+ AnimationRegistrar();
+
+ AnimationControllerMap active_animation_controllers_;
+ AnimationControllerMap all_animation_controllers_;
+
+ DISALLOW_COPY_AND_ASSIGN(AnimationRegistrar);
+};
+
+} // namespace cc
+
+#endif // CC_ANIMATION_REGISTRAR_H_
diff --git a/cc/cc.gyp b/cc/cc.gyp
index 4c3b540..2b71e90 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -10,6 +10,8 @@
'animation_curve.cc',
'animation_curve.h',
'animation_events.h',
+ 'animation_registrar.cc',
+ 'animation_registrar.h',
'append_quads_data.h',
'bitmap_content_layer_updater.cc',
'bitmap_content_layer_updater.h',
@@ -92,7 +94,8 @@
'layer.h',
'layer_animation_controller.cc',
'layer_animation_controller.h',
- 'layer_animation_observer.h',
+ 'layer_animation_event_observer.h',
+ 'layer_animation_value_observer.h',
'layer_impl.cc',
'layer_impl.h',
'layer_iterator.cc',
diff --git a/cc/layer.cc b/cc/layer.cc
index b277735..35063b9 100644
--- a/cc/layer.cc
+++ b/cc/layer.cc
@@ -32,7 +32,6 @@ Layer::Layer()
, m_layerId(s_nextLayerId++)
, m_parent(0)
, m_layerTreeHost(0)
- , m_layerAnimationController(LayerAnimationController::create(this))
, m_scrollable(false)
, m_shouldScrollOnMainThread(false)
, m_haveWheelEventHandlers(false)
@@ -64,7 +63,9 @@ Layer::Layer()
m_layerId = s_nextLayerId++;
}
- addLayerAnimationObserver(m_layerAnimationController.get());
+ m_layerAnimationController = LayerAnimationController::create(m_layerId);
+ m_layerAnimationController->addObserver(this);
+ addLayerAnimationEventObserver(m_layerAnimationController.get());
}
Layer::~Layer()
@@ -73,6 +74,8 @@ Layer::~Layer()
// way for us to be destroyed while we still have a parent.
DCHECK(!parent());
+ m_layerAnimationController->removeObserver(this);
+
// Remove the parent reference from all children.
removeAllChildren();
}
@@ -92,9 +95,10 @@ 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 ? host->animationRegistrar() : 0);
+
+ if (host && m_layerAnimationController->hasAnyAnimation())
+ host->setNeedsCommit();
}
void Layer::setNeedsCommit()
@@ -373,6 +377,11 @@ void Layer::setOpacity(float opacity)
setNeedsCommit();
}
+float Layer::opacity() const
+{
+ return m_opacity;
+}
+
bool Layer::opacityIsAnimating() const
{
return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity);
@@ -410,6 +419,11 @@ void Layer::setTransform(const gfx::Transform& transform)
setNeedsCommit();
}
+const gfx::Transform& Layer::transform() const
+{
+ return m_transform;
+}
+
bool Layer::transformIsAnimating() const
{
return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform);
@@ -703,12 +717,7 @@ int Layer::id() const
return m_layerId;
}
-float Layer::opacity() const
-{
- return m_opacity;
-}
-
-void Layer::setOpacityFromAnimation(float opacity)
+void Layer::OnOpacityAnimated(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
@@ -716,12 +725,7 @@ void Layer::setOpacityFromAnimation(float opacity)
m_opacity = opacity;
}
-const gfx::Transform& Layer::transform() const
-{
- return m_transform;
-}
-
-void Layer::setTransformFromAnimation(const gfx::Transform& transform)
+void Layer::OnTransformAnimated(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
@@ -748,10 +752,7 @@ bool Layer::addAnimation(scoped_ptr <ActiveAnimation> animation)
#endif
m_layerAnimationController->addAnimation(animation.Pass());
- if (m_layerTreeHost) {
- m_layerTreeHost->didAddAnimation();
- setNeedsCommit();
- }
+ setNeedsCommit();
return true;
}
@@ -779,25 +780,24 @@ void Layer::resumeAnimations(double monotonicTime)
setNeedsCommit();
}
-void Layer::setLayerAnimationController(scoped_ptr<LayerAnimationController> layerAnimationController)
+void Layer::setLayerAnimationController(scoped_refptr<LayerAnimationController> layerAnimationController)
{
- if (m_layerAnimationController)
- removeLayerAnimationObserver(m_layerAnimationController.get());
-
- m_layerAnimationController = layerAnimationController.Pass();
- if (m_layerAnimationController) {
- m_layerAnimationController->setClient(this);
- m_layerAnimationController->setForceSync();
- addLayerAnimationObserver(m_layerAnimationController.get());
- }
+ removeLayerAnimationEventObserver(m_layerAnimationController.get());
+ m_layerAnimationController->removeObserver(this);
+ m_layerAnimationController = layerAnimationController;
+ m_layerAnimationController->setForceSync();
+ m_layerAnimationController->addObserver(this);
+ addLayerAnimationEventObserver(m_layerAnimationController.get());
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();
+ m_layerAnimationController->removeObserver(this);
+ scoped_refptr<LayerAnimationController> toReturn = m_layerAnimationController;
+ m_layerAnimationController = LayerAnimationController::create(id());
+ m_layerAnimationController->addObserver(this);
+ return toReturn;
}
bool Layer::hasActiveAnimation() const
@@ -807,7 +807,7 @@ bool Layer::hasActiveAnimation() const
void Layer::notifyAnimationStarted(const AnimationEvent& event, double wallClockTime)
{
- FOR_EACH_OBSERVER(LayerAnimationObserver, m_layerAnimationObservers,
+ FOR_EACH_OBSERVER(LayerAnimationEventObserver, m_layerAnimationObservers,
OnAnimationStarted(event));
if (m_layerAnimationDelegate)
m_layerAnimationDelegate->notifyAnimationStarted(wallClockTime);
@@ -819,13 +819,13 @@ void Layer::notifyAnimationFinished(double wallClockTime)
m_layerAnimationDelegate->notifyAnimationFinished(wallClockTime);
}
-void Layer::addLayerAnimationObserver(LayerAnimationObserver* animationObserver)
+void Layer::addLayerAnimationEventObserver(LayerAnimationEventObserver* animationObserver)
{
if (!m_layerAnimationObservers.HasObserver(animationObserver))
m_layerAnimationObservers.AddObserver(animationObserver);
}
-void Layer::removeLayerAnimationObserver(LayerAnimationObserver* animationObserver)
+void Layer::removeLayerAnimationEventObserver(LayerAnimationEventObserver* animationObserver)
{
m_layerAnimationObservers.RemoveObserver(animationObserver);
}
diff --git a/cc/layer.h b/cc/layer.h
index 87839b4..4483c32 100644
--- a/cc/layer.h
+++ b/cc/layer.h
@@ -13,7 +13,8 @@
#include "cc/cc_export.h"
#include "cc/draw_properties.h"
#include "cc/layer_animation_controller.h"
-#include "cc/layer_animation_observer.h"
+#include "cc/layer_animation_event_observer.h"
+#include "cc/layer_animation_value_observer.h"
#include "cc/occlusion_tracker.h"
#include "cc/region.h"
#include "cc/render_surface.h"
@@ -46,21 +47,14 @@ 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 LayerAnimationValueObserver {
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; }
@@ -102,6 +96,7 @@ public:
virtual bool needsDisplay() const;
void setOpacity(float);
+ float opacity() const;
bool opacityIsAnimating() const;
void setFilters(const WebKit::WebFilterOperations&);
@@ -131,6 +126,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; }
@@ -269,8 +265,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; }
@@ -279,8 +275,8 @@ public:
virtual void notifyAnimationStarted(const AnimationEvent&, double wallClockTime);
virtual void notifyAnimationFinished(double wallClockTime);
- void addLayerAnimationObserver(LayerAnimationObserver* animationObserver);
- void removeLayerAnimationObserver(LayerAnimationObserver* animationObserver);
+ void addLayerAnimationEventObserver(LayerAnimationEventObserver* animationObserver);
+ void removeLayerAnimationEventObserver(LayerAnimationEventObserver* animationObserver);
virtual Region visibleContentOpaqueRegion() const;
@@ -336,6 +332,10 @@ private:
// This should only be called from removeFromParent.
void removeChild(Layer*);
+ // LayerAnimationValueObserver implementation.
+ virtual void OnOpacityAnimated(float) OVERRIDE;
+ virtual void OnTransformAnimated(const gfx::Transform&) OVERRIDE;
+
LayerList m_children;
Layer* m_parent;
@@ -344,8 +344,9 @@ private:
// updated via setLayerTreeHost() if a layer moves between trees.
LayerTreeHost* m_layerTreeHost;
- scoped_ptr<LayerAnimationController> m_layerAnimationController;
- ObserverList<LayerAnimationObserver> m_layerAnimationObservers;
+ ObserverList<LayerAnimationEventObserver> m_layerAnimationObservers;
+
+ scoped_refptr<LayerAnimationController> m_layerAnimationController;
// Layer properties.
gfx::Size m_bounds;
diff --git a/cc/layer_animation_controller.cc b/cc/layer_animation_controller.cc
index a45bb43..c72df04 100644
--- a/cc/layer_animation_controller.cc
+++ b/cc/layer_animation_controller.cc
@@ -5,24 +5,30 @@
#include "cc/layer_animation_controller.h"
#include "cc/active_animation.h"
+#include "cc/animation_registrar.h"
#include "cc/keyframed_animation_curve.h"
+#include "cc/layer_animation_value_observer.h"
#include "ui/gfx/transform.h"
namespace cc {
-LayerAnimationController::LayerAnimationController(LayerAnimationControllerClient* client)
+LayerAnimationController::LayerAnimationController(int id)
: m_forceSync(false)
- , m_client(client)
+ , m_id(id)
+ , m_registrar(0)
+ , m_isActive(false)
{
}
LayerAnimationController::~LayerAnimationController()
{
+ if (m_registrar)
+ m_registrar->UnregisterAnimationController(this);
}
-scoped_ptr<LayerAnimationController> LayerAnimationController::create(LayerAnimationControllerClient* client)
+scoped_refptr<LayerAnimationController> LayerAnimationController::create(int id)
{
- return make_scoped_ptr(new LayerAnimationController(client));
+ return make_scoped_refptr(new LayerAnimationController(id));
}
void LayerAnimationController::pauseAnimation(int animationId, double timeOffset)
@@ -41,6 +47,7 @@ void LayerAnimationController::removeAnimation(int animationId)
else
i++;
}
+ updateActivation();
}
void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::TargetProperty targetProperty)
@@ -51,6 +58,7 @@ void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation:
else
i++;
}
+ updateActivation();
}
// According to render layer backing, these are for testing only.
@@ -89,6 +97,8 @@ void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController*
pushPropertiesToImplThread(controllerImpl);
}
+ controllerImpl->updateActivation();
+ updateActivation();
}
void LayerAnimationController::animate(double monotonicTime, AnimationEventsVector* events)
@@ -100,11 +110,14 @@ void LayerAnimationController::animate(double monotonicTime, AnimationEventsVect
tickAnimations(monotonicTime);
markAnimationsForDeletion(monotonicTime, events);
startAnimationsWaitingForTargetAvailability(monotonicTime, events);
+
+ updateActivation();
}
void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation)
{
m_activeAnimations.append(animation.Pass());
+ updateActivation();
}
ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const
@@ -154,9 +167,31 @@ void LayerAnimationController::OnAnimationStarted(const AnimationEvent& event)
}
}
-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);
+
+ bool force = true;
+ updateActivation(force);
+}
+
+void LayerAnimationController::addObserver(LayerAnimationValueObserver* observer)
+{
+ if (!m_observers.HasObserver(observer))
+ m_observers.AddObserver(observer);
+}
+
+void LayerAnimationController::removeObserver(LayerAnimationValueObserver* observer)
{
- m_client = client;
+ m_observers.RemoveObserver(observer);
}
void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
@@ -214,7 +249,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 +260,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 +299,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 +355,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);
}
}
@@ -371,11 +406,11 @@ void LayerAnimationController::tickAnimations(double monotonicTime)
case ActiveAnimation::Transform: {
const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
- const gfx::Transform matrix = transformAnimationCurve->getValue(trimmed).toTransform();
+ const gfx::Transform transform = transformAnimationCurve->getValue(trimmed).toTransform();
if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
- m_client->setTransformFromAnimation(matrix);
+ notifyObserversTransformAnimated(transform);
break;
}
@@ -385,7 +420,7 @@ void LayerAnimationController::tickAnimations(double monotonicTime)
if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
- m_client->setOpacityFromAnimation(opacity);
+ notifyObserversOpacityAnimated(opacity);
break;
}
@@ -397,4 +432,29 @@ void LayerAnimationController::tickAnimations(double monotonicTime)
}
}
+void LayerAnimationController::updateActivation(bool force)
+{
+ if (m_registrar) {
+ if (!m_activeAnimations.isEmpty() && (!m_isActive || force))
+ m_registrar->DidActivateAnimationController(this);
+ else if (m_activeAnimations.isEmpty() && (m_isActive || force))
+ m_registrar->DidDeactivateAnimationController(this);
+ m_isActive = !m_activeAnimations.isEmpty();
+ }
+}
+
+void LayerAnimationController::notifyObserversOpacityAnimated(float opacity)
+{
+ FOR_EACH_OBSERVER(LayerAnimationValueObserver,
+ m_observers,
+ OnOpacityAnimated(opacity));
+}
+
+void LayerAnimationController::notifyObserversTransformAnimated(const gfx::Transform& transform)
+{
+ FOR_EACH_OBSERVER(LayerAnimationValueObserver,
+ m_observers,
+ OnTransformAnimated(transform));
+}
+
} // namespace cc
diff --git a/cc/layer_animation_controller.h b/cc/layer_animation_controller.h
index e7a01e0..aeb5048 100644
--- a/cc/layer_animation_controller.h
+++ b/cc/layer_animation_controller.h
@@ -7,11 +7,15 @@
#include "base/basictypes.h"
#include "base/hash_tables.h"
+#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
+#include "base/observer_list.h"
+#include "base/time.h"
#include "cc/animation_events.h"
#include "cc/cc_export.h"
-#include "cc/layer_animation_observer.h"
+#include "cc/layer_animation_event_observer.h"
#include "cc/scoped_ptr_vector.h"
+#include "ui/gfx/transform.h"
namespace gfx {
class Transform;
@@ -20,24 +24,17 @@ class Transform;
namespace cc {
class Animation;
+class AnimationRegistrar;
class KeyframeValueList;
+class LayerAnimationValueObserver;
-class CC_EXPORT LayerAnimationControllerClient {
+class CC_EXPORT LayerAnimationController
+ : public base::RefCounted<LayerAnimationController>,
+ public LayerAnimationEventObserver {
public:
- virtual ~LayerAnimationControllerClient() { }
+ static scoped_refptr<LayerAnimationController> create(int id);
- 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 LayerAnimationObserver {
-public:
- static scoped_ptr<LayerAnimationController> create(LayerAnimationControllerClient*);
-
- virtual ~LayerAnimationController();
+ int id() const { return m_id; }
// These methods are virtual for testing.
virtual void addAnimation(scoped_ptr<ActiveAnimation>);
@@ -64,6 +61,9 @@ public:
// Returns true if there are any animations that have neither finished nor aborted.
bool hasActiveAnimation() const;
+ // Returns true if there are any animations at all to process.
+ bool hasAnyAnimation() const { return !m_activeAnimations.isEmpty(); }
+
// Returns true if there is an animation currently animating the given property, or
// if there is an animation scheduled to animate this property in the future.
bool isAnimatingProperty(ActiveAnimation::TargetProperty) const;
@@ -76,10 +76,16 @@ public:
// thread, all animations will be transferred.
void setForceSync() { m_forceSync = true; }
- void setClient(LayerAnimationControllerClient*);
+ void setAnimationRegistrar(AnimationRegistrar*);
+
+ void addObserver(LayerAnimationValueObserver*);
+ void removeObserver(LayerAnimationValueObserver*);
protected:
- explicit LayerAnimationController(LayerAnimationControllerClient*);
+ friend class base::RefCounted<LayerAnimationController>;
+
+ LayerAnimationController(int id);
+ virtual ~LayerAnimationController();
private:
typedef base::hash_set<int> TargetProperties;
@@ -98,12 +104,23 @@ private:
void tickAnimations(double monotonicTime);
+ void updateActivation(bool force = false);
+
+ void notifyObserversOpacityAnimated(float opacity);
+ void notifyObserversTransformAnimated(const gfx::Transform& transform);
+
// If this is true, we force a sync to the impl thread.
bool m_forceSync;
- LayerAnimationControllerClient* m_client;
+ AnimationRegistrar* m_registrar;
+ int m_id;
ScopedPtrVector<ActiveAnimation> m_activeAnimations;
+ // This is used to ensure that we don't spam the registrar.
+ bool m_isActive;
+
+ ObserverList<LayerAnimationValueObserver> m_observers;
+
DISALLOW_COPY_AND_ASSIGN(LayerAnimationController);
};
diff --git a/cc/layer_animation_controller_unittest.cc b/cc/layer_animation_controller_unittest.cc
index 698fe77..f93ea7c 100644
--- a/cc/layer_animation_controller_unittest.cc
+++ b/cc/layer_animation_controller_unittest.cc
@@ -26,10 +26,12 @@ 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));
+ FakeLayerAnimationValueObserver dummyImpl;
+ scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(0));
+ controllerImpl->addObserver(&dummyImpl);
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -45,10 +47,12 @@ 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));
+ FakeLayerAnimationValueObserver dummyImpl;
+ scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(0));
+ controllerImpl->addObserver(&dummyImpl);
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -74,10 +78,12 @@ TEST(LayerAnimationControllerTest, doNotClobberStartTimes)
TEST(LayerAnimationControllerTest, syncPauseAndResume)
{
- FakeLayerAnimationControllerClient dummyImpl;
- scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummyImpl;
+ scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(0));
+ controllerImpl->addObserver(&dummyImpl);
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -114,10 +120,12 @@ TEST(LayerAnimationControllerTest, syncPauseAndResume)
TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation)
{
- FakeLayerAnimationControllerClient dummyImpl;
- scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummyImpl;
+ scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(0));
+ controllerImpl->addObserver(&dummyImpl);
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -147,9 +155,9 @@ TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation)
TEST(LayerAnimationControllerTest, TrivialTransition)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
@@ -166,9 +174,9 @@ TEST(LayerAnimationControllerTest, TrivialTransition)
TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfTheyWaitLongerToStartThanTheirDuration)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
toAdd->setNeedsSynchronizedStartTime(true);
@@ -196,9 +204,9 @@ TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfThe
TEST(LayerAnimationControllerTest, TrivialQueuing)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
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));
@@ -218,9 +226,9 @@ TEST(LayerAnimationControllerTest, TrivialQueuing)
TEST(LayerAnimationControllerTest, Interrupt)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
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());
@@ -244,9 +252,9 @@ TEST(LayerAnimationControllerTest, Interrupt)
TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
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));
@@ -271,9 +279,9 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked)
TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
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));
@@ -301,9 +309,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));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
toAdd->setRunState(ActiveAnimation::WaitingForStartTime, 0);
@@ -325,9 +333,9 @@ TEST(LayerAnimationControllerTest, ScheduleAnimation)
TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
@@ -356,9 +364,9 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation)
TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationWithAnimInQueue)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
@@ -392,9 +400,9 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationW
TEST(LayerAnimationControllerTest, TrivialLooping)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
toAdd->setIterations(3);
@@ -428,9 +436,9 @@ TEST(LayerAnimationControllerTest, TrivialLooping)
TEST(LayerAnimationControllerTest, InfiniteLooping)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
const int id = 1;
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity));
@@ -464,9 +472,9 @@ TEST(LayerAnimationControllerTest, InfiniteLooping)
TEST(LayerAnimationControllerTest, PauseResume)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
const int id = 1;
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity));
@@ -499,9 +507,9 @@ TEST(LayerAnimationControllerTest, PauseResume)
TEST(LayerAnimationControllerTest, AbortAGroupedAnimation)
{
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
const int id = 1;
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Transform));
@@ -527,12 +535,13 @@ TEST(LayerAnimationControllerTest, AbortAGroupedAnimation)
TEST(LayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded)
{
- FakeLayerAnimationControllerClient dummyImpl;
- scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
+ FakeLayerAnimationValueObserver dummyImpl;
+ scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(0));
+ controllerImpl->addObserver(&dummyImpl);
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
- FakeLayerAnimationControllerClient dummy;
- scoped_ptr<LayerAnimationController> controller(
- LayerAnimationController::create(&dummy));
+ FakeLayerAnimationValueObserver dummy;
+ scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create(0));
+ controller->addObserver(&dummy);
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_animation_observer.h b/cc/layer_animation_event_observer.h
index 16a10b9..a66d026 100644
--- a/cc/layer_animation_observer.h
+++ b/cc/layer_animation_event_observer.h
@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CC_LAYER_ANIMATION_OBSERVER_H_
-#define CC_LAYER_ANIMATION_OBSERVER_H_
+#ifndef CC_LAYER_ANIMATION_EVENT_OBSERVER_H_
+#define CC_LAYER_ANIMATION_EVENT_OBSERVER_H_
namespace cc {
-class CC_EXPORT LayerAnimationObserver {
+class CC_EXPORT LayerAnimationEventObserver {
public:
virtual void OnAnimationStarted(const AnimationEvent& event) = 0;
};
} // namespace cc
-#endif // CC_LAYER_ANIMATION_OBSERVER_H_
+#endif // CC_LAYER_ANIMATION_EVENT_OBSERVER_H_
diff --git a/cc/layer_animation_value_observer.h b/cc/layer_animation_value_observer.h
new file mode 100644
index 0000000..bb8e2ab
--- /dev/null
+++ b/cc/layer_animation_value_observer.h
@@ -0,0 +1,21 @@
+// 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_LAYER_ANIMATION_VALUE_OBSERVER_H_
+#define CC_LAYER_ANIMATION_VALUE_OBSERVER_H_
+
+namespace cc {
+
+class CC_EXPORT LayerAnimationValueObserver {
+ public:
+ virtual ~LayerAnimationValueObserver() { }
+
+ virtual void OnOpacityAnimated(float) = 0;
+ virtual void OnTransformAnimated(const gfx::Transform&) = 0;
+};
+
+} // namespace cc
+
+#endif // CC_LAYER_ANIMATION_VALUE_OBSERVER_H_
+
diff --git a/cc/layer_impl.cc b/cc/layer_impl.cc
index e1cf9d4..6c81c1d 100644
--- a/cc/layer_impl.cc
+++ b/cc/layer_impl.cc
@@ -7,6 +7,7 @@
#include "base/debug/trace_event.h"
#include "base/stringprintf.h"
#include "base/values.h"
+#include "cc/animation_registrar.h"
#include "cc/debug_border_draw_quad.h"
#include "cc/debug_colors.h"
#include "cc/layer_tree_debug_state.h"
@@ -50,11 +51,13 @@ LayerImpl::LayerImpl(LayerTreeImpl* treeImpl, int id)
#ifndef NDEBUG
, m_betweenWillDrawAndDidDraw(false)
#endif
- , m_layerAnimationController(LayerAnimationController::create(this))
{
DCHECK(m_layerId > 0);
DCHECK(m_layerTreeImpl);
m_layerTreeImpl->RegisterLayer(this);
+ AnimationRegistrar* registrar = m_layerTreeImpl->animationRegistrar();
+ m_layerAnimationController = registrar->GetAnimationControllerForId(m_layerId);
+ m_layerAnimationController->addObserver(this);
}
LayerImpl::~LayerImpl()
@@ -63,6 +66,7 @@ LayerImpl::~LayerImpl()
DCHECK(!m_betweenWillDrawAndDidDraw);
#endif
m_layerTreeImpl->UnregisterLayer(this);
+ m_layerAnimationController->removeObserver(this);
}
void LayerImpl::addChild(scoped_ptr<LayerImpl> child)
@@ -459,22 +463,12 @@ int LayerImpl::id() const
return m_layerId;
}
-float LayerImpl::opacity() const
-{
- return m_opacity;
-}
-
-void LayerImpl::setOpacityFromAnimation(float opacity)
+void LayerImpl::OnOpacityAnimated(float opacity)
{
setOpacity(opacity);
}
-const gfx::Transform& LayerImpl::transform() const
-{
- return m_transform;
-}
-
-void LayerImpl::setTransformFromAnimation(const gfx::Transform& transform)
+void LayerImpl::OnTransformAnimated(const gfx::Transform& transform)
{
setTransform(transform);
}
@@ -626,6 +620,11 @@ void LayerImpl::setOpacity(float opacity)
noteLayerSurfacePropertyChanged();
}
+float LayerImpl::opacity() const
+{
+ return m_opacity;
+}
+
bool LayerImpl::opacityIsAnimating() const
{
return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity);
@@ -668,6 +667,11 @@ void LayerImpl::setTransform(const gfx::Transform& transform)
noteLayerSurfacePropertyChanged();
}
+const gfx::Transform& LayerImpl::transform() const
+{
+ return m_transform;
+}
+
bool LayerImpl::transformIsAnimating() const
{
return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform);
diff --git a/cc/layer_impl.h b/cc/layer_impl.h
index b767d9e..59937ba9 100644
--- a/cc/layer_impl.h
+++ b/cc/layer_impl.h
@@ -13,6 +13,7 @@
#include "cc/draw_properties.h"
#include "cc/input_handler.h"
#include "cc/layer_animation_controller.h"
+#include "cc/layer_animation_value_observer.h"
#include "cc/region.h"
#include "cc/render_pass.h"
#include "cc/render_surface_impl.h"
@@ -43,7 +44,7 @@ class Layer;
struct AppendQuadsData;
-class CC_EXPORT LayerImpl : public LayerAnimationControllerClient {
+class CC_EXPORT LayerImpl : LayerAnimationValueObserver {
public:
typedef ScopedPtrVector<LayerImpl> LayerList;
@@ -54,12 +55,11 @@ 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;
+
+ // LayerAnimationValueObserver implementation.
+ virtual void OnOpacityAnimated(float) OVERRIDE;
+ virtual void OnTransformAnimated(const gfx::Transform&) OVERRIDE;
// Tree structure.
LayerImpl* parent() { return m_parent; }
@@ -131,6 +131,7 @@ public:
bool contentsOpaque() const { return m_contentsOpaque; }
void setOpacity(float);
+ float opacity() const;
bool opacityIsAnimating() const;
void setPosition(const gfx::PointF&);
@@ -239,6 +240,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; }
@@ -388,7 +390,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 70e1620..3ec9c82 100644
--- a/cc/layer_tree_host.cc
+++ b/cc/layer_tree_host.cc
@@ -7,7 +7,9 @@
#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/animation_registrar.h"
#include "cc/font_atlas.h"
#include "cc/heads_up_display_layer.h"
#include "cc/heads_up_display_layer_impl.h"
@@ -70,7 +72,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)
@@ -90,6 +91,7 @@ LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSetting
, m_backgroundColor(SK_ColorWHITE)
, m_hasTransparentBackground(false)
, m_partialTextureUpdateRequests(0)
+ , m_animationRegistrar(AnimationRegistrar::create())
{
numLayerTreeInstances++;
}
@@ -128,6 +130,13 @@ LayerTreeHost::~LayerTreeHost()
RateLimiterMap::iterator it = m_rateLimiters.begin();
if (it != m_rateLimiters.end())
it->second->stop();
+
+ if (m_rootLayer) {
+ // The layer tree 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_rootLayer = NULL;
+ }
}
void LayerTreeHost::setSurfaceReady()
@@ -285,11 +294,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());
@@ -423,12 +427,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)
@@ -831,33 +829,16 @@ void LayerTreeHost::setDeviceScaleFactor(float deviceScaleFactor)
void LayerTreeHost::animateLayers(base::TimeTicks time)
{
- if (!m_settings.acceleratedAnimationEnabled || !m_needsAnimateLayers)
+ if (!m_settings.acceleratedAnimationEnabled || m_animationRegistrar->active_animation_controllers().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;
+ AnimationRegistrar::AnimationControllerMap copy = m_animationRegistrar->active_animation_controllers();
+ for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); iter != copy.end(); ++iter)
+ (*iter).second->animate(monotonicTime, 0);
}
void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& events, Layer* layer, base::Time wallClockTime)
diff --git a/cc/layer_tree_host.h b/cc/layer_tree_host.h
index dfb4094..51ae3d7 100644
--- a/cc/layer_tree_host.h
+++ b/cc/layer_tree_host.h
@@ -41,6 +41,7 @@ struct hash<WebKit::WebGraphicsContext3D*> {
namespace cc {
+class AnimationRegistrar;
class Layer;
class LayerTreeHostImpl;
class LayerTreeHostImplClient;
@@ -146,7 +147,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(); }
@@ -199,6 +199,8 @@ public:
Proxy* proxy() const { return m_proxy.get(); }
+ AnimationRegistrar* animationRegistrar() const { return m_animationRegistrar.get(); }
+
protected:
LayerTreeHost(LayerTreeHostClient*, const LayerTreeSettings&);
bool initialize(scoped_ptr<Thread> implThread);
@@ -227,7 +229,6 @@ private:
void setAnimationEventsRecursive(const AnimationEventsVector&, Layer*, base::Time wallClockTime);
bool m_animating;
- bool m_needsAnimateLayers;
bool m_needsFullTreeSync;
base::CancelableClosure m_prepaintCallback;
@@ -272,6 +273,8 @@ private:
typedef ScopedPtrVector<PrioritizedResource> TextureList;
size_t m_partialTextureUpdateRequests;
+ scoped_ptr<AnimationRegistrar> m_animationRegistrar;
+
static bool s_needsFilterContext;
DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
diff --git a/cc/layer_tree_host_common_unittest.cc b/cc/layer_tree_host_common_unittest.cc
index 7888a6a..0fd26e4 100644
--- a/cc/layer_tree_host_common_unittest.cc
+++ b/cc/layer_tree_host_common_unittest.cc
@@ -1700,24 +1700,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);
@@ -1728,6 +1715,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 685effb..907bf1b 100644
--- a/cc/layer_tree_host_impl.cc
+++ b/cc/layer_tree_host_impl.cc
@@ -9,6 +9,7 @@
#include "base/basictypes.h"
#include "base/debug/trace_event.h"
#include "base/json/json_writer.h"
+#include "base/stl_util.h"
#include "cc/append_quads_data.h"
#include "cc/compositor_frame_metadata.h"
#include "cc/damage_tracker.h"
@@ -220,7 +221,6 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre
PriorityCalculator::allowNothingCutoff())
, m_backgroundColor(0)
, m_hasTransparentBackground(false)
- , m_needsAnimateLayers(false)
, m_needsUpdateDrawProperties(false)
, m_pinchGestureActive(false)
, m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread()))
@@ -232,6 +232,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre
, m_lastSentMemoryVisibleBytes(0)
, m_lastSentMemoryVisibleAndNearbyBytes(0)
, m_lastSentMemoryUseBytes(0)
+ , m_animationRegistrar(AnimationRegistrar::create())
{
DCHECK(m_proxy->isImplThread());
didVisibilityChange(this, m_visible);
@@ -246,8 +247,14 @@ 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();
+ m_pendingTree.reset();
+ }
}
void LayerTreeHostImpl::beginCommit()
@@ -612,35 +619,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.
@@ -1045,7 +1023,7 @@ void LayerTreeHostImpl::setVisible(bool visible)
m_renderer->setVisible(visible);
- setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
+ setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty());
}
bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface)
@@ -1587,25 +1565,24 @@ 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_animationRegistrar->active_animation_controllers().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));
+ AnimationRegistrar::AnimationControllerMap copy = m_animationRegistrar->active_animation_controllers();
+ for (AnimationRegistrar::AnimationControllerMap::iterator iter = copy.begin(); iter != copy.end(); ++iter)
+ (*iter).second->animate(monotonicSeconds, events.get());
if (!events->empty())
m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime);
- if (didAnimate) {
- m_client->setNeedsRedrawOnImplThread();
- setNeedsUpdateDrawProperties();
- }
-
- setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
+ m_client->setNeedsRedrawOnImplThread();
+ setNeedsUpdateDrawProperties();
+ setBackgroundTickingEnabled(!m_visible && !m_animationRegistrar->active_animation_controllers().empty());
}
base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const
diff --git a/cc/layer_tree_host_impl.h b/cc/layer_tree_host_impl.h
index c7e9c0b..d56a550 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/output_surface_client.h"
@@ -248,9 +249,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_animationRegistrar->active_animation_controllers().empty(); }
bool needsUpdateDrawProperties() const { return m_needsUpdateDrawProperties; }
void setNeedsUpdateDrawProperties() { m_needsUpdateDrawProperties = true; }
@@ -270,6 +269,8 @@ public:
Proxy* proxy() const { return m_proxy; }
+ AnimationRegistrar* animationRegistrar() const { return m_animationRegistrar.get(); }
+
void setDebugState(const LayerTreeDebugState& debugState) { m_debugState = debugState; }
const LayerTreeDebugState& debugState() const { return m_debugState; }
@@ -314,6 +315,8 @@ protected:
// Virtual for testing.
virtual base::TimeDelta lowFrequencyAnimationInterval() const;
+ const AnimationRegistrar::AnimationControllerMap& activeAnimationControllers() const { return m_animationRegistrar->active_animation_controllers(); }
+
LayerTreeHostImplClient* m_client;
Proxy* m_proxy;
@@ -369,8 +372,6 @@ private:
SkColor m_backgroundColor;
bool m_hasTransparentBackground;
- // If this is true, it is necessary to traverse the layer tree ticking the animators.
- bool m_needsAnimateLayers;
bool m_needsUpdateDrawProperties;
bool m_pinchGestureActive;
gfx::Point m_previousPinchAnchor;
@@ -400,6 +401,8 @@ private:
size_t m_lastSentMemoryVisibleAndNearbyBytes;
size_t m_lastSentMemoryUseBytes;
+ scoped_ptr<AnimationRegistrar> m_animationRegistrar;
+
DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImpl);
};
diff --git a/cc/layer_tree_host_unittest_animation.cc b/cc/layer_tree_host_unittest_animation.cc
index 8900c93..485a25f 100644
--- a/cc/layer_tree_host_unittest_animation.cc
+++ b/cc/layer_tree_host_unittest_animation.cc
@@ -124,11 +124,12 @@ class LayerTreeHostAnimationTestAddAnimation :
virtual void animateLayers(
LayerTreeHostImpl* impl_host,
- base::TimeTicks monotonic_time) OVERRIDE {
+ base::TimeTicks monotonic_time,
+ bool hasUnfinishedAnimation) OVERRIDE {
if (!num_animates_) {
// The animation had zero duration so layerTreeHostImpl should no
// longer need to animate its layers.
- EXPECT_FALSE(impl_host->needsAnimateLayers());
+ EXPECT_FALSE(hasUnfinishedAnimation);
num_animates_++;
first_monotonic_time_ = monotonic_time;
return;
@@ -169,7 +170,8 @@ class LayerTreeHostAnimationTestCheckerboardDoesNotStarveDraws :
virtual void animateLayers(
LayerTreeHostImpl* host_impl,
- base::TimeTicks monotonicTime) OVERRIDE {
+ base::TimeTicks monotonicTime,
+ bool hasUnfinishedAnimation) OVERRIDE {
started_animating_ = true;
}
@@ -242,7 +244,8 @@ public:
virtual void animateLayers(
LayerTreeHostImpl* host_impl,
- base::TimeTicks monotonicTime) OVERRIDE {
+ base::TimeTicks monotonicTime,
+ bool hasUnfinishedAnimation) OVERRIDE {
LayerAnimationController* controller =
m_layerTreeHost->rootLayer()->layerAnimationController();
ActiveAnimation* animation =
@@ -306,7 +309,8 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes :
virtual void animateLayers(
LayerTreeHostImpl* impl_host,
- base::TimeTicks monotonicTime) OVERRIDE {
+ base::TimeTicks monotonicTime,
+ bool hasUnfinishedAnimation) OVERRIDE {
LayerAnimationController* controller =
impl_host->rootLayer()->layerAnimationController();
ActiveAnimation* animation =
@@ -402,37 +406,37 @@ MULTI_THREAD_TEST_F(
class LayerTreeHostAnimationTestLayerAddedWithAnimation :
public LayerTreeHostAnimationTest {
public:
- LayerTreeHostAnimationTestLayerAddedWithAnimation()
- : added_animation_(false) {
- }
+ LayerTreeHostAnimationTestLayerAddedWithAnimation() { }
virtual void beginTest() OVERRIDE {
- EXPECT_FALSE(added_animation_);
-
- scoped_refptr<Layer> layer = Layer::create();
- layer->setLayerAnimationDelegate(this);
-
- // Any valid AnimationCurve will do here.
- scoped_ptr<AnimationCurve> curve(EaseTimingFunction::create());
- scoped_ptr<ActiveAnimation> animation(
- ActiveAnimation::create(curve.Pass(), 1, 1, ActiveAnimation::Opacity));
- layer->layerAnimationController()->addAnimation(animation.Pass());
-
- // We add the animation *before* attaching the layer to the tree.
- m_layerTreeHost->rootLayer()->addChild(layer);
- EXPECT_TRUE(added_animation_);
+ postSetNeedsCommitToMainThread();
+ }
- endTest();
+ virtual void didCommit() OVERRIDE {
+ if (m_layerTreeHost->commitNumber() == 1) {
+ scoped_refptr<Layer> layer = Layer::create();
+ layer->setLayerAnimationDelegate(this);
+
+ // Any valid AnimationCurve will do here.
+ scoped_ptr<AnimationCurve> curve(EaseTimingFunction::create());
+ scoped_ptr<ActiveAnimation> animation(
+ ActiveAnimation::create(curve.Pass(), 1, 1,
+ ActiveAnimation::Opacity));
+ layer->layerAnimationController()->addAnimation(animation.Pass());
+
+ // We add the animation *before* attaching the layer to the tree.
+ m_layerTreeHost->rootLayer()->addChild(layer);
+ }
}
- virtual void didAddAnimation() OVERRIDE {
- added_animation_ = true;
+ virtual void animateLayers(
+ LayerTreeHostImpl* impl_host,
+ base::TimeTicks monotonic_time,
+ bool hasUnfinishedAnimation) OVERRIDE {
+ endTest();
}
virtual void afterTest() OVERRIDE {}
-
-private:
- bool added_animation_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(
diff --git a/cc/layer_tree_impl.cc b/cc/layer_tree_impl.cc
index 0c68bb9..8d7e722 100644
--- a/cc/layer_tree_impl.cc
+++ b/cc/layer_tree_impl.cc
@@ -160,5 +160,8 @@ DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
return layer_tree_host_impl_->debugRectHistory();
}
+AnimationRegistrar* LayerTreeImpl::animationRegistrar() const {
+ return layer_tree_host_impl_->animationRegistrar();
+}
} // namespace cc
diff --git a/cc/layer_tree_impl.h b/cc/layer_tree_impl.h
index 8b7c925..c8a0ef9 100644
--- a/cc/layer_tree_impl.h
+++ b/cc/layer_tree_impl.h
@@ -92,6 +92,8 @@ class CC_EXPORT LayerTreeImpl {
void RegisterLayer(LayerImpl* layer);
void UnregisterLayer(LayerImpl* layer);
+ AnimationRegistrar* animationRegistrar() const;
+
protected:
LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl);
diff --git a/cc/proxy.h b/cc/proxy.h
index 6382afc..b175f8f 100644
--- a/cc/proxy.h
+++ b/cc/proxy.h
@@ -80,8 +80,6 @@ public:
// like compositeAndReadback while commits are deferred.
virtual void setDeferCommits(bool) = 0;
- virtual void didAddAnimation() = 0;
-
virtual void mainThreadHasStoppedFlinging() = 0;
virtual bool commitRequested() const = 0;
diff --git a/cc/single_thread_proxy.cc b/cc/single_thread_proxy.cc
index 63d70d8..296bbf4 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 9eb0280..40f2b1b 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 mainThreadHasStoppedFlinging() OVERRIDE { }
virtual void start() OVERRIDE;
virtual void stop() OVERRIDE;
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index 9920751..258a266 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -146,40 +146,25 @@ float FakeFloatTransition::getValue(double time) const
return (1 - time) * m_from + time * m_to;
}
-FakeLayerAnimationControllerClient::FakeLayerAnimationControllerClient()
+FakeLayerAnimationValueObserver::FakeLayerAnimationValueObserver()
: m_opacity(0)
{
}
-FakeLayerAnimationControllerClient::~FakeLayerAnimationControllerClient()
+FakeLayerAnimationValueObserver::~FakeLayerAnimationValueObserver()
{
}
-int FakeLayerAnimationControllerClient::id() const
-{
- return 0;
-}
-
-void FakeLayerAnimationControllerClient::setOpacityFromAnimation(float opacity)
+void FakeLayerAnimationValueObserver::OnOpacityAnimated(float opacity)
{
m_opacity = opacity;
}
-float FakeLayerAnimationControllerClient::opacity() const
-{
- return m_opacity;
-}
-
-void FakeLayerAnimationControllerClient::setTransformFromAnimation(const gfx::Transform& transform)
+void FakeLayerAnimationValueObserver::OnTransformAnimated(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 6ee0cdd..6df5db2 100644
--- a/cc/test/animation_test_common.h
+++ b/cc/test/animation_test_common.h
@@ -8,6 +8,7 @@
#include "cc/active_animation.h"
#include "cc/animation_curve.h"
#include "cc/layer_animation_controller.h"
+#include "cc/layer_animation_value_observer.h"
namespace cc {
class LayerImpl;
@@ -60,17 +61,17 @@ private:
float m_to;
};
-class FakeLayerAnimationControllerClient : public cc::LayerAnimationControllerClient {
+class FakeLayerAnimationValueObserver : public cc::LayerAnimationValueObserver {
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;
+ FakeLayerAnimationValueObserver();
+ virtual ~FakeLayerAnimationValueObserver();
+
+ // LayerAnimationValueObserver implementation
+ virtual void OnOpacityAnimated(float) OVERRIDE;
+ virtual void OnTransformAnimated(const gfx::Transform&) OVERRIDE;
+
+ float opacity() const { return m_opacity; }
+ const gfx::Transform& transform() const { return m_transform; }
private:
float m_opacity;
diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h
index 280c1a4..ba0014f 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 void mainThreadHasStoppedFlinging() OVERRIDE { }
virtual bool commitRequested() const OVERRIDE;
virtual void start() OVERRIDE { }
diff --git a/cc/test/layer_tree_test_common.cc b/cc/test/layer_tree_test_common.cc
index c5f0bde..57c52c7 100644
--- a/cc/test/layer_tree_test_common.cc
+++ b/cc/test/layer_tree_test_common.cc
@@ -5,6 +5,7 @@
#include "cc/test/layer_tree_test_common.h"
#include "cc/active_animation.h"
+#include "cc/animation_registrar.h"
#include "cc/content_layer.h"
#include "cc/font_atlas.h"
#include "cc/input_handler.h"
@@ -73,7 +74,15 @@ void MockLayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::T
{
m_testHooks->willAnimateLayers(this, monotonicTime);
LayerTreeHostImpl::animateLayers(monotonicTime, wallClockTime);
- m_testHooks->animateLayers(this, monotonicTime);
+ bool hasUnfinishedAnimation = false;
+ AnimationRegistrar::AnimationControllerMap::const_iterator iter = activeAnimationControllers().begin();
+ for (; iter != activeAnimationControllers().end(); ++iter) {
+ if (iter->second->hasActiveAnimation()) {
+ hasUnfinishedAnimation = true;
+ break;
+ }
+ }
+ m_testHooks->animateLayers(this, monotonicTime, hasUnfinishedAnimation);
}
base::TimeDelta MockLayerTreeHostImpl::lowFrequencyAnimationInterval() const
@@ -103,12 +112,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)
@@ -279,11 +282,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);
@@ -408,14 +406,6 @@ void ThreadedTest::dispatchComposite()
m_layerTreeHost->composite();
}
-void ThreadedTest::dispatchDidAddAnimation()
-{
- DCHECK(!proxy() || proxy()->isMainThread());
-
- 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 ee86818..bdaac44 100644
--- a/cc/test/layer_tree_test_common.h
+++ b/cc/test/layer_tree_test_common.h
@@ -28,7 +28,7 @@ public:
virtual void commitCompleteOnThread(LayerTreeHostImpl*) { }
virtual bool prepareToDrawOnThread(LayerTreeHostImpl*);
virtual void drawLayersOnThread(LayerTreeHostImpl*) { }
- virtual void animateLayers(LayerTreeHostImpl*, base::TimeTicks monotonicTime) { }
+ virtual void animateLayers(LayerTreeHostImpl*, base::TimeTicks monotonicTime, bool hasUnfinishedAnimation) { }
virtual void willAnimateLayers(LayerTreeHostImpl*, base::TimeTicks monotonicTime) { }
virtual void applyScrollAndScale(gfx::Vector2d, float) { }
virtual void animate(base::TimeTicks monotonicTime) { }
@@ -81,7 +81,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 f661a36..8c8feea 100644
--- a/cc/thread_proxy.h
+++ b/cc/thread_proxy.h
@@ -48,7 +48,6 @@ public:
virtual void setNeedsRedraw() OVERRIDE;
virtual void setDeferCommits(bool) OVERRIDE;
virtual bool commitRequested() const OVERRIDE;
- virtual void didAddAnimation() OVERRIDE { }
virtual void mainThreadHasStoppedFlinging() OVERRIDE;
virtual void start() OVERRIDE;
virtual void stop() OVERRIDE;
diff --git a/cc/tree_synchronizer_unittest.cc b/cc/tree_synchronizer_unittest.cc
index 585db8f..1c7e927 100644
--- a/cc/tree_synchronizer_unittest.cc
+++ b/cc/tree_synchronizer_unittest.cc
@@ -76,19 +76,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(1)
, m_synchronizedAnimations(false)
- {
- }
+ { }
+
+ virtual ~FakeLayerAnimationController() { }
virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
{
@@ -370,8 +371,7 @@ TEST_F(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());