summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authorvollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-07 07:37:08 +0000
committervollick@chromium.org <vollick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-07 07:37:08 +0000
commit0a9fd4dd4f05423a83479ace4d2b2469eced588e (patch)
treebf8de741db7e373a398bde755180b926b608c51d /cc
parent3d871d9695ec44bf3b5cabd09549bd2c1f999eb5 (diff)
downloadchromium_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.h35
-rw-r--r--cc/cc.gyp1
-rw-r--r--cc/layer.cc74
-rw-r--r--cc/layer.h22
-rw-r--r--cc/layer_animation_controller.cc87
-rw-r--r--cc/layer_animation_controller.h54
-rw-r--r--cc/layer_animation_controller_unittest.cc191
-rw-r--r--cc/layer_impl.cc48
-rw-r--r--cc/layer_impl.h17
-rw-r--r--cc/layer_tree_host.cc67
-rw-r--r--cc/layer_tree_host.h28
-rw-r--r--cc/layer_tree_host_common_unittest.cc26
-rw-r--r--cc/layer_tree_host_impl.cc79
-rw-r--r--cc/layer_tree_host_impl.h21
-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.cc34
-rw-r--r--cc/test/animation_test_common.h17
-rw-r--r--cc/test/fake_proxy.h1
-rw-r--r--cc/test/layer_tree_test_common.cc28
-rw-r--r--cc/test/layer_tree_test_common.h1
-rw-r--r--cc/thread_proxy.h1
-rw-r--r--cc/tree_synchronizer_unittest.cc16
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_
diff --git a/cc/cc.gyp b/cc/cc.gyp
index af60c38..73d7956 100644
--- a/cc/cc.gyp
+++ b/cc/cc.gyp
@@ -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
diff --git a/cc/layer.h b/cc/layer.h
index af5df0f..6d8f07b 100644
--- a/cc/layer.h
+++ b/cc/layer.h
@@ -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);
};
diff --git a/cc/proxy.h b/cc/proxy.h
index 8b8f272..7a1fd27 100644
--- a/cc/proxy.h
+++ b/cc/proxy.h
@@ -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());