0

Revert 171714 - Use an auxiliary list of 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.
>
> BUG=162111
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=171714

TBR=vollick@chromium.org
BUG=

Review URL: https://codereview.chromium.org/11491003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171981 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
vollick@chromium.org
2012-12-08 17:01:18 +00:00
parent 9b39fe5ba8
commit df1ec1ac79
24 changed files with 434 additions and 414 deletions

@@ -1,35 +0,0 @@
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CC_ANIMATION_REGISTRAR_H_
#define CC_ANIMATION_REGISTRAR_H_
namespace cc {
class LayerAnimationController;
// TODO(vollick): we need to rename:
// AnimationRegistrar -> AnimationController
// LayerAnimationController -> LayerAnimator
class CC_EXPORT AnimationRegistrar {
public:
// Registers the given animation controller as active. An active animation
// controller is one that has a running animation that needs to be ticked.
virtual void DidActivateAnimationController(LayerAnimationController*) = 0;
// Unregisters the given animation controller. When this happens, the
// animation controller will no longer be ticked (since it's not active). It
// is not an error to call this function with a deactivated controller.
virtual void DidDeactivateAnimationController(LayerAnimationController*) = 0;
// Registers the given controller as alive.
virtual void RegisterAnimationController(LayerAnimationController*) = 0;
// Unregisters the given controller as alive.
virtual void UnregisterAnimationController(LayerAnimationController*) = 0;
};
} // namespace cc
#endif // CC_ANIMATION_REGISTRAR_H_

@@ -10,7 +10,6 @@
'animation_curve.cc', 'animation_curve.cc',
'animation_curve.h', 'animation_curve.h',
'animation_events.h', 'animation_events.h',
'animation_registrar.h',
'append_quads_data.h', 'append_quads_data.h',
'bitmap_content_layer_updater.cc', 'bitmap_content_layer_updater.cc',
'bitmap_content_layer_updater.h', 'bitmap_content_layer_updater.h',

@@ -32,7 +32,7 @@ Layer::Layer()
, m_layerId(s_nextLayerId++) , m_layerId(s_nextLayerId++)
, m_parent(0) , m_parent(0)
, m_layerTreeHost(0) , m_layerTreeHost(0)
, m_layerAnimationController(LayerAnimationController::create()) , m_layerAnimationController(LayerAnimationController::create(this))
, m_scrollable(false) , m_scrollable(false)
, m_shouldScrollOnMainThread(false) , m_shouldScrollOnMainThread(false)
, m_haveWheelEventHandlers(false) , m_haveWheelEventHandlers(false)
@@ -40,6 +40,7 @@ Layer::Layer()
, m_touchEventHandlerRegionChanged(false) , m_touchEventHandlerRegionChanged(false)
, m_anchorPoint(0.5, 0.5) , m_anchorPoint(0.5, 0.5)
, m_backgroundColor(0) , m_backgroundColor(0)
, m_opacity(1.0)
, m_anchorPointZ(0) , m_anchorPointZ(0)
, m_isContainerForFixedPositionLayers(false) , m_isContainerForFixedPositionLayers(false)
, m_fixedToContainerLayer(false) , m_fixedToContainerLayer(false)
@@ -63,7 +64,6 @@ Layer::Layer()
s_nextLayerId = 1; s_nextLayerId = 1;
m_layerId = s_nextLayerId++; m_layerId = s_nextLayerId++;
} }
m_layerAnimationController->setId(m_layerId);
} }
Layer::~Layer() Layer::~Layer()
@@ -96,7 +96,9 @@ void Layer::setLayerTreeHost(LayerTreeHost* host)
if (m_replicaLayer) if (m_replicaLayer)
m_replicaLayer->setLayerTreeHost(host); m_replicaLayer->setLayerTreeHost(host);
m_layerAnimationController->setAnimationRegistrar(host); // If this layer already has active animations, the host needs to be notified.
if (host && m_layerAnimationController->hasActiveAnimation())
host->didAddAnimation();
} }
void Layer::setNeedsCommit() void Layer::setNeedsCommit()
@@ -356,16 +358,12 @@ bool Layer::needsDisplay() const
void Layer::setOpacity(float opacity) void Layer::setOpacity(float opacity)
{ {
if (!m_layerAnimationController->setOpacity(opacity)) if (m_opacity == opacity)
return; return;
m_opacity = opacity;
setNeedsCommit(); setNeedsCommit();
} }
float Layer::opacity() const
{
return m_layerAnimationController->opacity();
}
bool Layer::opacityIsAnimating() const bool Layer::opacityIsAnimating() const
{ {
return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity); return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Opacity);
@@ -397,16 +395,12 @@ void Layer::setSublayerTransform(const gfx::Transform& sublayerTransform)
void Layer::setTransform(const gfx::Transform& transform) void Layer::setTransform(const gfx::Transform& transform)
{ {
if (!m_layerAnimationController->setTransform(transform)) if (m_transform == transform)
return; return;
m_transform = transform;
setNeedsCommit(); setNeedsCommit();
} }
const gfx::Transform& Layer::transform() const
{
return m_layerAnimationController->transform();
}
bool Layer::transformIsAnimating() const bool Layer::transformIsAnimating() const
{ {
return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform); return m_layerAnimationController->isAnimatingProperty(ActiveAnimation::Transform);
@@ -589,6 +583,8 @@ void Layer::pushPropertiesTo(LayerImpl* layer)
m_touchEventHandlerRegionChanged = false; m_touchEventHandlerRegionChanged = false;
} }
layer->setContentsOpaque(m_contentsOpaque); layer->setContentsOpaque(m_contentsOpaque);
if (!opacityIsAnimating())
layer->setOpacity(m_opacity);
layer->setPosition(m_position); layer->setPosition(m_position);
layer->setIsContainerForFixedPositionLayers(m_isContainerForFixedPositionLayers); layer->setIsContainerForFixedPositionLayers(m_isContainerForFixedPositionLayers);
layer->setFixedToContainerLayer(m_fixedToContainerLayer); layer->setFixedToContainerLayer(m_fixedToContainerLayer);
@@ -597,6 +593,8 @@ void Layer::pushPropertiesTo(LayerImpl* layer)
layer->setScrollOffset(m_scrollOffset); layer->setScrollOffset(m_scrollOffset);
layer->setMaxScrollOffset(m_maxScrollOffset); layer->setMaxScrollOffset(m_maxScrollOffset);
layer->setSublayerTransform(m_sublayerTransform); 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 // 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 // will become incorrect if we simply clobber the updateRect here. The LayerImpl's updateRect needs to
@@ -720,6 +718,32 @@ int Layer::id() const
return m_layerId; 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) bool Layer::addAnimation(scoped_ptr <ActiveAnimation> animation)
{ {
// WebCore currently assumes that accelerated animations will start soon // WebCore currently assumes that accelerated animations will start soon
@@ -739,7 +763,10 @@ bool Layer::addAnimation(scoped_ptr <ActiveAnimation> animation)
#endif #endif
m_layerAnimationController->addAnimation(animation.Pass()); m_layerAnimationController->addAnimation(animation.Pass());
if (m_layerTreeHost) {
m_layerTreeHost->didAddAnimation();
setNeedsCommit(); setNeedsCommit();
}
return true; return true;
} }
@@ -767,24 +794,21 @@ void Layer::resumeAnimations(double monotonicTime)
setNeedsCommit(); setNeedsCommit();
} }
void Layer::setLayerAnimationController(scoped_refptr<LayerAnimationController> layerAnimationController) void Layer::setLayerAnimationController(scoped_ptr<LayerAnimationController> layerAnimationController)
{ {
m_layerAnimationController = layerAnimationController; m_layerAnimationController = layerAnimationController.Pass();
if (m_layerAnimationController) { if (m_layerAnimationController) {
m_layerAnimationController->setId(id()); m_layerAnimationController->setClient(this);
m_layerAnimationController->setForceSync(); m_layerAnimationController->setForceSync();
} }
setNeedsCommit(); setNeedsCommit();
} }
scoped_refptr<LayerAnimationController> Layer::releaseLayerAnimationController() scoped_ptr<LayerAnimationController> Layer::releaseLayerAnimationController()
{ {
scoped_refptr<LayerAnimationController> toReturn = m_layerAnimationController; scoped_ptr<LayerAnimationController> toReturn = m_layerAnimationController.Pass();
m_layerAnimationController = LayerAnimationController::create(); m_layerAnimationController = LayerAnimationController::create(this);
m_layerAnimationController->setId(id()); return toReturn.Pass();
m_layerAnimationController->setTransform(toReturn->transform());
m_layerAnimationController->setOpacity(toReturn->opacity());
return toReturn;
} }
bool Layer::hasActiveAnimation() const bool Layer::hasActiveAnimation() const

@@ -44,13 +44,21 @@ struct RenderingStats;
// Base class for composited layers. Special layer types are derived from // Base class for composited layers. Special layer types are derived from
// this class. // this class.
class CC_EXPORT Layer : public base::RefCounted<Layer> { class CC_EXPORT Layer : public base::RefCounted<Layer>, public LayerAnimationControllerClient {
public: public:
typedef std::vector<scoped_refptr<Layer> > LayerList; typedef std::vector<scoped_refptr<Layer> > LayerList;
static scoped_refptr<Layer> create(); static scoped_refptr<Layer> create();
int id() const; // 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;
Layer* rootLayer(); Layer* rootLayer();
Layer* parent() { return m_parent; } Layer* parent() { return m_parent; }
@@ -91,7 +99,6 @@ public:
virtual bool needsDisplay() const; virtual bool needsDisplay() const;
void setOpacity(float); void setOpacity(float);
float opacity() const;
bool opacityIsAnimating() const; bool opacityIsAnimating() const;
void setFilters(const WebKit::WebFilterOperations&); void setFilters(const WebKit::WebFilterOperations&);
@@ -121,7 +128,6 @@ public:
const gfx::Transform& sublayerTransform() const { return m_sublayerTransform; } const gfx::Transform& sublayerTransform() const { return m_sublayerTransform; }
void setTransform(const gfx::Transform&); void setTransform(const gfx::Transform&);
const gfx::Transform& transform() const;
bool transformIsAnimating() const; bool transformIsAnimating() const;
DrawProperties<Layer, RenderSurface>& drawProperties() { return m_drawProperties; } DrawProperties<Layer, RenderSurface>& drawProperties() { return m_drawProperties; }
@@ -261,8 +267,8 @@ public:
void resumeAnimations(double monotonicTime); void resumeAnimations(double monotonicTime);
LayerAnimationController* layerAnimationController() { return m_layerAnimationController.get(); } LayerAnimationController* layerAnimationController() { return m_layerAnimationController.get(); }
void setLayerAnimationController(scoped_refptr<LayerAnimationController>); void setLayerAnimationController(scoped_ptr<LayerAnimationController>);
scoped_refptr<LayerAnimationController> releaseLayerAnimationController(); scoped_ptr<LayerAnimationController> releaseLayerAnimationController();
void setLayerAnimationDelegate(WebKit::WebAnimationDelegate* layerAnimationDelegate) { m_layerAnimationDelegate = layerAnimationDelegate; } void setLayerAnimationDelegate(WebKit::WebAnimationDelegate* layerAnimationDelegate) { m_layerAnimationDelegate = layerAnimationDelegate; }
@@ -333,7 +339,7 @@ private:
// updated via setLayerTreeHost() if a layer moves between trees. // updated via setLayerTreeHost() if a layer moves between trees.
LayerTreeHost* m_layerTreeHost; LayerTreeHost* m_layerTreeHost;
scoped_refptr<LayerAnimationController> m_layerAnimationController; scoped_ptr<LayerAnimationController> m_layerAnimationController;
// Layer properties. // Layer properties.
gfx::Size m_bounds; gfx::Size m_bounds;
@@ -351,6 +357,7 @@ private:
gfx::PointF m_anchorPoint; gfx::PointF m_anchorPoint;
SkColor m_backgroundColor; SkColor m_backgroundColor;
std::string m_debugName; std::string m_debugName;
float m_opacity;
skia::RefPtr<SkImageFilter> m_filter; skia::RefPtr<SkImageFilter> m_filter;
WebKit::WebFilterOperations m_filters; WebKit::WebFilterOperations m_filters;
WebKit::WebFilterOperations m_backgroundFilters; WebKit::WebFilterOperations m_backgroundFilters;
@@ -367,6 +374,7 @@ private:
bool m_drawCheckerboardForMissingTiles; bool m_drawCheckerboardForMissingTiles;
bool m_forceRenderSurface; bool m_forceRenderSurface;
gfx::Transform m_transform;
gfx::Transform m_sublayerTransform; gfx::Transform m_sublayerTransform;
// Replica layer used for reflections. // Replica layer used for reflections.

@@ -5,29 +5,24 @@
#include "cc/layer_animation_controller.h" #include "cc/layer_animation_controller.h"
#include "cc/active_animation.h" #include "cc/active_animation.h"
#include "cc/animation_registrar.h"
#include "cc/keyframed_animation_curve.h" #include "cc/keyframed_animation_curve.h"
#include "ui/gfx/transform.h" #include "ui/gfx/transform.h"
namespace cc { namespace cc {
LayerAnimationController::LayerAnimationController() LayerAnimationController::LayerAnimationController(LayerAnimationControllerClient* client)
: m_forceSync(false) : m_forceSync(false)
, m_id(-1) , m_client(client)
, m_opacity(1.0)
, m_registrar(0)
{ {
} }
LayerAnimationController::~LayerAnimationController() LayerAnimationController::~LayerAnimationController()
{ {
if (m_registrar)
m_registrar->DidDeactivateAnimationController(this);
} }
scoped_refptr<LayerAnimationController> LayerAnimationController::create() scoped_ptr<LayerAnimationController> LayerAnimationController::create(LayerAnimationControllerClient* client)
{ {
return make_scoped_refptr(new LayerAnimationController()); return make_scoped_ptr(new LayerAnimationController(client));
} }
void LayerAnimationController::pauseAnimation(int animationId, double timeOffset) void LayerAnimationController::pauseAnimation(int animationId, double timeOffset)
@@ -46,7 +41,6 @@ void LayerAnimationController::removeAnimation(int animationId)
else else
i++; i++;
} }
updateRegistration();
} }
void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::TargetProperty targetProperty) void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation::TargetProperty targetProperty)
@@ -57,7 +51,6 @@ void LayerAnimationController::removeAnimation(int animationId, ActiveAnimation:
else else
i++; i++;
} }
updateRegistration();
} }
// According to render layer backing, these are for testing only. // According to render layer backing, these are for testing only.
@@ -82,12 +75,6 @@ void LayerAnimationController::resumeAnimations(double monotonicTime)
// are kept in sync. // are kept in sync.
void LayerAnimationController::pushAnimationUpdatesTo(LayerAnimationController* controllerImpl) 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) { if (m_forceSync) {
replaceImplThreadAnimations(controllerImpl); replaceImplThreadAnimations(controllerImpl);
m_forceSync = false; m_forceSync = false;
@@ -113,14 +100,11 @@ void LayerAnimationController::animate(double monotonicTime, AnimationEventsVect
tickAnimations(monotonicTime); tickAnimations(monotonicTime);
markAnimationsForDeletion(monotonicTime, events); markAnimationsForDeletion(monotonicTime, events);
startAnimationsWaitingForTargetAvailability(monotonicTime, events); startAnimationsWaitingForTargetAvailability(monotonicTime, events);
updateRegistration();
} }
void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation) void LayerAnimationController::addAnimation(scoped_ptr<ActiveAnimation> animation)
{ {
m_activeAnimations.append(animation.Pass()); m_activeAnimations.append(animation.Pass());
updateRegistration();
} }
ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const ActiveAnimation* LayerAnimationController::getActiveAnimation(int groupId, ActiveAnimation::TargetProperty targetProperty) const
@@ -170,40 +154,9 @@ void LayerAnimationController::notifyAnimationStarted(const AnimationEvent& even
} }
} }
void LayerAnimationController::setAnimationRegistrar(AnimationRegistrar* registrar) void LayerAnimationController::setClient(LayerAnimationControllerClient* client)
{ {
if (m_registrar == registrar) m_client = client;
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)
{
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 void LayerAnimationController::pushNewAnimationsToImplThread(LayerAnimationController* controllerImpl) const
@@ -261,7 +214,7 @@ void LayerAnimationController::startAnimationsWaitingForNextTick(double monotoni
if (!m_activeAnimations[i]->hasSetStartTime()) if (!m_activeAnimations[i]->hasSetStartTime())
m_activeAnimations[i]->setStartTime(monotonicTime); m_activeAnimations[i]->setStartTime(monotonicTime);
if (events) if (events)
events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
} }
} }
} }
@@ -272,7 +225,7 @@ void LayerAnimationController::startAnimationsWaitingForStartTime(double monoton
if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) { if (m_activeAnimations[i]->runState() == ActiveAnimation::WaitingForStartTime && m_activeAnimations[i]->startTime() <= monotonicTime) {
m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime); m_activeAnimations[i]->setRunState(ActiveAnimation::Running, monotonicTime);
if (events) if (events)
events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
} }
} }
} }
@@ -311,7 +264,7 @@ void LayerAnimationController::startAnimationsWaitingForTargetAvailability(doubl
if (!m_activeAnimations[i]->hasSetStartTime()) if (!m_activeAnimations[i]->hasSetStartTime())
m_activeAnimations[i]->setStartTime(monotonicTime); m_activeAnimations[i]->setStartTime(monotonicTime);
if (events) if (events)
events->push_back(AnimationEvent(AnimationEvent::Started, m_id, m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime)); events->push_back(AnimationEvent(AnimationEvent::Started, m_client->id(), m_activeAnimations[i]->group(), m_activeAnimations[i]->targetProperty(), monotonicTime));
for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) { for (size_t j = i + 1; j < m_activeAnimations.size(); ++j) {
if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) { if (m_activeAnimations[i]->group() == m_activeAnimations[j]->group()) {
m_activeAnimations[j]->setRunState(ActiveAnimation::Running, monotonicTime); m_activeAnimations[j]->setRunState(ActiveAnimation::Running, monotonicTime);
@@ -367,7 +320,7 @@ void LayerAnimationController::markAnimationsForDeletion(double monotonicTime, A
for (size_t j = i; j < m_activeAnimations.size(); j++) { for (size_t j = i; j < m_activeAnimations.size(); j++) {
if (groupId == m_activeAnimations[j]->group()) { if (groupId == m_activeAnimations[j]->group()) {
if (events) if (events)
events->push_back(AnimationEvent(AnimationEvent::Finished, m_id, m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime)); events->push_back(AnimationEvent(AnimationEvent::Finished, m_client->id(), m_activeAnimations[j]->group(), m_activeAnimations[j]->targetProperty(), monotonicTime));
m_activeAnimations[j]->setRunState(ActiveAnimation::WaitingForDeletion, monotonicTime); m_activeAnimations[j]->setRunState(ActiveAnimation::WaitingForDeletion, monotonicTime);
} }
} }
@@ -405,7 +358,7 @@ void LayerAnimationController::replaceImplThreadAnimations(LayerAnimationControl
void LayerAnimationController::tickAnimations(double monotonicTime) 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) { if (m_activeAnimations[i]->runState() == ActiveAnimation::Running || m_activeAnimations[i]->runState() == ActiveAnimation::Paused) {
double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime); double trimmed = m_activeAnimations[i]->trimTimeToCurrentIteration(monotonicTime);
@@ -418,17 +371,21 @@ void LayerAnimationController::tickAnimations(double monotonicTime)
case ActiveAnimation::Transform: { case ActiveAnimation::Transform: {
const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve(); const TransformAnimationCurve* transformAnimationCurve = m_activeAnimations[i]->curve()->toTransformAnimationCurve();
m_transform = transformAnimationCurve->getValue(trimmed).toTransform(); const gfx::Transform matrix = transformAnimationCurve->getValue(trimmed).toTransform();
if (m_activeAnimations[i]->isFinishedAt(monotonicTime)) if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime); m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
m_client->setTransformFromAnimation(matrix);
break; break;
} }
case ActiveAnimation::Opacity: { case ActiveAnimation::Opacity: {
const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve(); const FloatAnimationCurve* floatAnimationCurve = m_activeAnimations[i]->curve()->toFloatAnimationCurve();
m_opacity = floatAnimationCurve->getValue(trimmed); const float opacity = floatAnimationCurve->getValue(trimmed);
if (m_activeAnimations[i]->isFinishedAt(monotonicTime)) if (m_activeAnimations[i]->isFinishedAt(monotonicTime))
m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime); m_activeAnimations[i]->setRunState(ActiveAnimation::Finished, monotonicTime);
m_client->setOpacityFromAnimation(opacity);
break; break;
} }
@@ -440,14 +397,4 @@ void LayerAnimationController::tickAnimations(double monotonicTime)
} }
} }
void LayerAnimationController::updateRegistration()
{
if (m_registrar) {
if (hasActiveAnimation())
m_registrar->DidActivateAnimationController(this);
else
m_registrar->DidDeactivateAnimationController(this);
}
}
} // namespace cc } // namespace cc

@@ -7,13 +7,10 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/hash_tables.h" #include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "cc/animation_events.h" #include "cc/animation_events.h"
#include "cc/cc_export.h" #include "cc/cc_export.h"
#include "cc/scoped_ptr_vector.h" #include "cc/scoped_ptr_vector.h"
#include "ui/gfx/transform.h"
namespace gfx { namespace gfx {
class Transform; class Transform;
@@ -22,13 +19,24 @@ class Transform;
namespace cc { namespace cc {
class Animation; class Animation;
class AnimationRegistrar;
class KeyframeValueList; class KeyframeValueList;
class CC_EXPORT LayerAnimationController class CC_EXPORT LayerAnimationControllerClient {
: public base::RefCounted<LayerAnimationController> {
public: public:
static scoped_refptr<LayerAnimationController> create(); 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();
// These methods are virtual for testing. // These methods are virtual for testing.
virtual void addAnimation(scoped_ptr<ActiveAnimation>); virtual void addAnimation(scoped_ptr<ActiveAnimation>);
@@ -67,30 +75,10 @@ public:
// thread, all animations will be transferred. // thread, all animations will be transferred.
void setForceSync() { m_forceSync = true; } void setForceSync() { m_forceSync = true; }
void setAnimationRegistrar(AnimationRegistrar*); void setClient(LayerAnimationControllerClient*);
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: protected:
friend class base::RefCounted<LayerAnimationController>; explicit LayerAnimationController(LayerAnimationControllerClient*);
LayerAnimationController();
virtual ~LayerAnimationController();
private: private:
typedef base::hash_set<int> TargetProperties; typedef base::hash_set<int> TargetProperties;
@@ -109,16 +97,10 @@ private:
void tickAnimations(double monotonicTime); void tickAnimations(double monotonicTime);
void updateRegistration();
// If this is true, we force a sync to the impl thread. // If this is true, we force a sync to the impl thread.
bool m_forceSync; bool m_forceSync;
float m_opacity; LayerAnimationControllerClient* m_client;
gfx::Transform m_transform;
AnimationRegistrar* m_registrar;
int m_id;
ScopedPtrVector<ActiveAnimation> m_activeAnimations; ScopedPtrVector<ActiveAnimation> m_activeAnimations;
DISALLOW_COPY_AND_ASSIGN(LayerAnimationController); DISALLOW_COPY_AND_ASSIGN(LayerAnimationController);

@@ -26,8 +26,10 @@ scoped_ptr<ActiveAnimation> createActiveAnimation(scoped_ptr<AnimationCurve> cur
TEST(LayerAnimationControllerTest, syncNewAnimation) TEST(LayerAnimationControllerTest, syncNewAnimation)
{ {
scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummyImpl;
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy));
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -43,8 +45,10 @@ TEST(LayerAnimationControllerTest, syncNewAnimation)
// thread, we must be sure to respect the synchronized start time. // thread, we must be sure to respect the synchronized start time.
TEST(LayerAnimationControllerTest, doNotClobberStartTimes) TEST(LayerAnimationControllerTest, doNotClobberStartTimes)
{ {
scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummyImpl;
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy));
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -70,8 +74,10 @@ TEST(LayerAnimationControllerTest, doNotClobberStartTimes)
TEST(LayerAnimationControllerTest, syncPauseAndResume) TEST(LayerAnimationControllerTest, syncPauseAndResume)
{ {
scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummyImpl;
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy));
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -108,8 +114,10 @@ TEST(LayerAnimationControllerTest, syncPauseAndResume)
TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation) TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation)
{ {
scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummyImpl;
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); scoped_ptr<LayerAnimationController> controllerImpl(LayerAnimationController::create(&dummyImpl));
FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(LayerAnimationController::create(&dummy));
EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity)); EXPECT_FALSE(controllerImpl->getActiveAnimation(0, ActiveAnimation::Opacity));
@@ -139,16 +147,18 @@ TEST(LayerAnimationControllerTest, doNotSyncFinishedAnimation)
TEST(LayerAnimationControllerTest, TrivialTransition) TEST(LayerAnimationControllerTest, TrivialTransition)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
controller->addAnimation(toAdd.Pass()); controller->addAnimation(toAdd.Pass());
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -156,7 +166,9 @@ TEST(LayerAnimationControllerTest, TrivialTransition)
TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfTheyWaitLongerToStartThanTheirDuration) TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfTheyWaitLongerToStartThanTheirDuration)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
toAdd->setNeedsSynchronizedStartTime(true); toAdd->setNeedsSynchronizedStartTime(true);
@@ -165,18 +177,18 @@ TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfThe
controller->addAnimation(toAdd.Pass()); controller->addAnimation(toAdd.Pass());
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(2, events.get()); controller->animate(2, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
// Send the synchronized start time. // Send the synchronized start time.
controller->notifyAnimationStarted(AnimationEvent(AnimationEvent::Started, 0, 1, ActiveAnimation::Opacity, 2)); controller->notifyAnimationStarted(AnimationEvent(AnimationEvent::Started, 0, 1, ActiveAnimation::Opacity, 2));
controller->animate(5, events.get()); controller->animate(5, events.get());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -184,19 +196,21 @@ TEST(LayerAnimationControllerTest, AnimationsWaitingForStartTimeDoNotFinishIfThe
TEST(LayerAnimationControllerTest, TrivialQueuing) TEST(LayerAnimationControllerTest, TrivialQueuing)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&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, 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->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 1, 0.5)).PassAs<AnimationCurve>(), 2, ActiveAnimation::Opacity));
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
controller->animate(2, events.get()); controller->animate(2, events.get());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -204,12 +218,13 @@ TEST(LayerAnimationControllerTest, TrivialQueuing)
TEST(LayerAnimationControllerTest, Interrupt) TEST(LayerAnimationControllerTest, Interrupt)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&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, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 1, 0.5)).PassAs<AnimationCurve>(), 2, ActiveAnimation::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); toAdd->setRunState(ActiveAnimation::WaitingForNextTick, 0);
@@ -219,9 +234,9 @@ TEST(LayerAnimationControllerTest, Interrupt)
// this call to animate. // this call to animate.
controller->animate(0.5, events.get()); controller->animate(0.5, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
controller->animate(1.5, events.get()); controller->animate(1.5, events.get());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -229,23 +244,24 @@ TEST(LayerAnimationControllerTest, Interrupt)
TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked) TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
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>(), 1, ActiveAnimation::Transform));
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), 2, 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->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 2, ActiveAnimation::Opacity));
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
controller->animate(1, events.get()); controller->animate(1, events.get());
// Should not have started the float transition yet. // Should not have started the float transition yet.
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
// The float animation should have started at time 1 and should be done. // The float animation should have started at time 1 and should be done.
controller->animate(2, events.get()); controller->animate(2, events.get());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -255,7 +271,9 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWhenAPropertyIsBlocked)
TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting) TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(2)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Transform)); 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)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
@@ -264,18 +282,18 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting)
// Animations with id 1 should both start now. // Animations with id 1 should both start now.
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
// The opacity animation should have finished at time 1, but the group // 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 animations with id 1 don't finish until time 2 because of the length
// of the transform animation. // of the transform animation.
controller->animate(2, events.get()); controller->animate(2, events.get());
// Should not have started the float transition yet. // Should not have started the float transition yet.
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
// The second opacity animation should start at time 2 and should be done by time 3 // The second opacity animation should start at time 2 and should be done by time 3
controller->animate(3, events.get()); controller->animate(3, events.get());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -283,9 +301,10 @@ TEST(LayerAnimationControllerTest, ScheduleTogetherWithAnAnimWaiting)
TEST(LayerAnimationControllerTest, ScheduleAnimation) TEST(LayerAnimationControllerTest, ScheduleAnimation)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
controller->setOpacity(0);
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
toAdd->setRunState(ActiveAnimation::WaitingForStartTime, 0); toAdd->setRunState(ActiveAnimation::WaitingForStartTime, 0);
toAdd->setStartTime(1); toAdd->setStartTime(1);
@@ -293,12 +312,12 @@ TEST(LayerAnimationControllerTest, ScheduleAnimation)
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(2, events.get()); controller->animate(2, events.get());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -306,7 +325,9 @@ TEST(LayerAnimationControllerTest, ScheduleAnimation)
TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation) TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
@@ -318,15 +339,15 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation)
// First 2s opacity transition should start immediately. // First 2s opacity transition should start immediately.
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(0.5, events.get()); controller->animate(0.5, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.25, controller->opacity()); EXPECT_EQ(0.25, dummy.opacity());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
controller->animate(2, events.get()); controller->animate(2, events.get());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -335,7 +356,9 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimation)
TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationWithAnimInQueue) TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationWithAnimInQueue)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
@@ -349,19 +372,19 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationW
// First 2s opacity transition should start immediately. // First 2s opacity transition should start immediately.
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(0.5, events.get()); controller->animate(0.5, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.25, controller->opacity()); EXPECT_EQ(0.25, dummy.opacity());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
controller->animate(3, events.get()); controller->animate(3, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(4, events.get()); controller->animate(4, events.get());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
} }
@@ -369,7 +392,9 @@ TEST(LayerAnimationControllerTest, ScheduledAnimationInterruptsRunningAnimationW
TEST(LayerAnimationControllerTest, TrivialLooping) TEST(LayerAnimationControllerTest, TrivialLooping)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity)); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), 1, ActiveAnimation::Opacity));
toAdd->setIterations(3); toAdd->setIterations(3);
@@ -377,33 +402,35 @@ TEST(LayerAnimationControllerTest, TrivialLooping)
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1.25, events.get()); controller->animate(1.25, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.25, controller->opacity()); EXPECT_EQ(0.25, dummy.opacity());
controller->animate(1.75, events.get()); controller->animate(1.75, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
controller->animate(2.25, events.get()); controller->animate(2.25, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.25, controller->opacity()); EXPECT_EQ(0.25, dummy.opacity());
controller->animate(2.75, events.get()); controller->animate(2.75, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
controller->animate(3, events.get()); controller->animate(3, events.get());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
// Just be extra sure. // Just be extra sure.
controller->animate(4, events.get()); controller->animate(4, events.get());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
} }
// Test that an infinitely looping animation does indeed go until aborted. // Test that an infinitely looping animation does indeed go until aborted.
TEST(LayerAnimationControllerTest, InfiniteLooping) TEST(LayerAnimationControllerTest, InfiniteLooping)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
const int id = 1; const int id = 1;
scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity)); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity));
@@ -412,65 +439,69 @@ TEST(LayerAnimationControllerTest, InfiniteLooping)
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1.25, events.get()); controller->animate(1.25, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.25, controller->opacity()); EXPECT_EQ(0.25, dummy.opacity());
controller->animate(1.75, events.get()); controller->animate(1.75, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
controller->animate(1073741824.25, events.get()); controller->animate(1073741824.25, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.25, controller->opacity()); EXPECT_EQ(0.25, dummy.opacity());
controller->animate(1073741824.75, events.get()); controller->animate(1073741824.75, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity));
controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Aborted, 0.75); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Aborted, 0.75);
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
} }
// Test that pausing and resuming work as expected. // Test that pausing and resuming work as expected.
TEST(LayerAnimationControllerTest, PauseResume) TEST(LayerAnimationControllerTest, PauseResume)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
const int id = 1; const int id = 1;
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(1, 0, 1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Opacity));
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(0.5, events.get()); controller->animate(0.5, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity));
controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Paused, 0.5); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Paused, 0.5);
controller->animate(1024, events.get()); controller->animate(1024, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity));
controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Running, 1024); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Running, 1024);
controller->animate(1024.25, events.get()); controller->animate(1024.25, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
controller->animate(1024.5, events.get()); controller->animate(1024.5, events.get());
EXPECT_FALSE(controller->hasActiveAnimation()); EXPECT_FALSE(controller->hasActiveAnimation());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
} }
TEST(LayerAnimationControllerTest, AbortAGroupedAnimation) TEST(LayerAnimationControllerTest, AbortAGroupedAnimation)
{ {
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
scoped_ptr<LayerAnimationController> controller(
LayerAnimationController::create(&dummy));
const int id = 1; const int id = 1;
controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Transform)); controller->addAnimation(createActiveAnimation(make_scoped_ptr(new FakeTransformTransition(1)).PassAs<AnimationCurve>(), id, ActiveAnimation::Transform));
@@ -479,25 +510,29 @@ TEST(LayerAnimationControllerTest, AbortAGroupedAnimation)
controller->animate(0, events.get()); controller->animate(0, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0, controller->opacity()); EXPECT_EQ(0, dummy.opacity());
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(0.5, controller->opacity()); EXPECT_EQ(0.5, dummy.opacity());
EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity)); EXPECT_TRUE(controller->getActiveAnimation(id, ActiveAnimation::Opacity));
controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Aborted, 1); controller->getActiveAnimation(id, ActiveAnimation::Opacity)->setRunState(ActiveAnimation::Aborted, 1);
controller->animate(1, events.get()); controller->animate(1, events.get());
EXPECT_TRUE(controller->hasActiveAnimation()); EXPECT_TRUE(controller->hasActiveAnimation());
EXPECT_EQ(1, controller->opacity()); EXPECT_EQ(1, dummy.opacity());
controller->animate(2, events.get()); controller->animate(2, events.get());
EXPECT_TRUE(!controller->hasActiveAnimation()); EXPECT_TRUE(!controller->hasActiveAnimation());
EXPECT_EQ(0.75, controller->opacity()); EXPECT_EQ(0.75, dummy.opacity());
} }
TEST(LayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded) TEST(LayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded)
{ {
scoped_refptr<LayerAnimationController> controllerImpl(LayerAnimationController::create()); FakeLayerAnimationControllerClient dummyImpl;
scoped_refptr<LayerAnimationController> controller(LayerAnimationController::create()); 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_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 0, ActiveAnimation::Opacity)); scoped_ptr<ActiveAnimation> toAdd(createActiveAnimation(make_scoped_ptr(new FakeFloatTransition(2, 0, 1)).PassAs<AnimationCurve>(), 0, ActiveAnimation::Opacity));
toAdd->setNeedsSynchronizedStartTime(true); toAdd->setNeedsSynchronizedStartTime(true);

@@ -38,6 +38,7 @@ LayerImpl::LayerImpl(LayerTreeHostImpl* hostImpl, int id)
, m_layerSurfacePropertyChanged(false) , m_layerSurfacePropertyChanged(false)
, m_masksToBounds(false) , m_masksToBounds(false)
, m_contentsOpaque(false) , m_contentsOpaque(false)
, m_opacity(1.0)
, m_preserves3D(false) , m_preserves3D(false)
, m_useParentBackfaceVisibility(false) , m_useParentBackfaceVisibility(false)
, m_drawCheckerboardForMissingTiles(false) , m_drawCheckerboardForMissingTiles(false)
@@ -50,12 +51,10 @@ LayerImpl::LayerImpl(LayerTreeHostImpl* hostImpl, int id)
#ifndef NDEBUG #ifndef NDEBUG
, m_betweenWillDrawAndDidDraw(false) , m_betweenWillDrawAndDidDraw(false)
#endif #endif
, m_layerAnimationController(LayerAnimationController::create()) , m_layerAnimationController(LayerAnimationController::create(this))
{ {
DCHECK(m_layerId > 0); DCHECK(m_layerId > 0);
DCHECK(m_layerTreeHostImpl); DCHECK(m_layerTreeHostImpl);
m_layerAnimationController->setId(m_layerId);
m_layerAnimationController->setAnimationRegistrar(hostImpl);
} }
LayerImpl::~LayerImpl() LayerImpl::~LayerImpl()
@@ -452,6 +451,26 @@ int LayerImpl::id() const
return m_layerId; 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) void LayerImpl::setBounds(const gfx::Size& bounds)
{ {
if (m_bounds == bounds) if (m_bounds == bounds)
@@ -578,14 +597,11 @@ void LayerImpl::setContentsOpaque(bool opaque)
void LayerImpl::setOpacity(float opacity) void LayerImpl::setOpacity(float opacity)
{ {
if (!m_layerAnimationController->setOpacity(opacity)) if (m_opacity == opacity)
return; return;
m_layerSurfacePropertyChanged = true;
}
float LayerImpl::opacity() const m_opacity = opacity;
{ m_layerSurfacePropertyChanged = true;
return m_layerAnimationController->opacity();
} }
bool LayerImpl::opacityIsAnimating() const bool LayerImpl::opacityIsAnimating() const
@@ -623,14 +639,11 @@ void LayerImpl::setSublayerTransform(const gfx::Transform& sublayerTransform)
void LayerImpl::setTransform(const gfx::Transform& transform) void LayerImpl::setTransform(const gfx::Transform& transform)
{ {
if (!m_layerAnimationController->setTransform(transform)) if (m_transform == transform)
return; return;
m_layerSurfacePropertyChanged = true;
}
const gfx::Transform& LayerImpl::transform() const m_transform = transform;
{ m_layerSurfacePropertyChanged = true;
return m_layerAnimationController->transform();
} }
bool LayerImpl::transformIsAnimating() const bool LayerImpl::transformIsAnimating() const

@@ -42,7 +42,7 @@ class Layer;
struct AppendQuadsData; struct AppendQuadsData;
class CC_EXPORT LayerImpl { class CC_EXPORT LayerImpl : public LayerAnimationControllerClient {
public: public:
typedef ScopedPtrVector<LayerImpl> LayerList; typedef ScopedPtrVector<LayerImpl> LayerList;
@@ -53,7 +53,12 @@ public:
virtual ~LayerImpl(); virtual ~LayerImpl();
int id() const; // 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;
// Tree structure. // Tree structure.
LayerImpl* parent() { return m_parent; } LayerImpl* parent() { return m_parent; }
@@ -129,7 +134,6 @@ public:
bool contentsOpaque() const { return m_contentsOpaque; } bool contentsOpaque() const { return m_contentsOpaque; }
void setOpacity(float); void setOpacity(float);
float opacity() const;
bool opacityIsAnimating() const; bool opacityIsAnimating() const;
void setPosition(const gfx::PointF&); void setPosition(const gfx::PointF&);
@@ -238,7 +242,6 @@ public:
void setDoubleSided(bool); void setDoubleSided(bool);
void setTransform(const gfx::Transform&); void setTransform(const gfx::Transform&);
const gfx::Transform& transform() const;
bool transformIsAnimating() const; bool transformIsAnimating() const;
const gfx::RectF& updateRect() const { return m_updateRect; } const gfx::RectF& updateRect() const { return m_updateRect; }
@@ -344,11 +347,13 @@ private:
bool m_masksToBounds; bool m_masksToBounds;
bool m_contentsOpaque; bool m_contentsOpaque;
float m_opacity;
gfx::PointF m_position; gfx::PointF m_position;
bool m_preserves3D; bool m_preserves3D;
bool m_useParentBackfaceVisibility; bool m_useParentBackfaceVisibility;
bool m_drawCheckerboardForMissingTiles; bool m_drawCheckerboardForMissingTiles;
gfx::Transform m_sublayerTransform; gfx::Transform m_sublayerTransform;
gfx::Transform m_transform;
bool m_useLCDText; bool m_useLCDText;
bool m_drawsContent; bool m_drawsContent;
@@ -385,7 +390,7 @@ private:
gfx::RectF m_updateRect; gfx::RectF m_updateRect;
// Manages animations for this layer. // Manages animations for this layer.
scoped_refptr<LayerAnimationController> m_layerAnimationController; scoped_ptr<LayerAnimationController> m_layerAnimationController;
// Manages scrollbars for this layer // Manages scrollbars for this layer
scoped_ptr<ScrollbarAnimationController> m_scrollbarAnimationController; scoped_ptr<ScrollbarAnimationController> m_scrollbarAnimationController;

@@ -7,7 +7,6 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/debug/trace_event.h" #include "base/debug/trace_event.h"
#include "base/message_loop.h" #include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/string_number_conversions.h" #include "base/string_number_conversions.h"
#include "cc/font_atlas.h" #include "cc/font_atlas.h"
#include "cc/heads_up_display_layer.h" #include "cc/heads_up_display_layer.h"
@@ -178,6 +177,7 @@ scoped_ptr<LayerTreeHost> LayerTreeHost::create(LayerTreeHostClient* client, con
LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings) LayerTreeHost::LayerTreeHost(LayerTreeHostClient* client, const LayerTreeSettings& settings)
: m_animating(false) : m_animating(false)
, m_needsAnimateLayers(false)
, m_needsFullTreeSync(true) , m_needsFullTreeSync(true)
, m_client(client) , m_client(client)
, m_commitNumber(0) , m_commitNumber(0)
@@ -235,9 +235,6 @@ LayerTreeHost::~LayerTreeHost()
RateLimiterMap::iterator it = m_rateLimiters.begin(); RateLimiterMap::iterator it = m_rateLimiters.begin();
if (it != m_rateLimiters.end()) if (it != m_rateLimiters.end())
it->second->stop(); it->second->stop();
if (m_rootLayer)
m_rootLayer = 0;
} }
void LayerTreeHost::setSurfaceReady() void LayerTreeHost::setSurfaceReady()
@@ -390,6 +387,11 @@ void LayerTreeHost::finishCommitOnImplThread(LayerTreeHostImpl* hostImpl)
else else
hostImpl->activeTree()->set_hud_layer(0); 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->activeTree()->set_source_frame_number(commitNumber());
hostImpl->setViewportSize(layoutViewportSize(), deviceViewportSize()); hostImpl->setViewportSize(layoutViewportSize(), deviceViewportSize());
hostImpl->setDeviceScaleFactor(deviceScaleFactor()); hostImpl->setDeviceScaleFactor(deviceScaleFactor());
@@ -523,6 +525,12 @@ void LayerTreeHost::setAnimationEvents(scoped_ptr<AnimationEventsVector> events,
setAnimationEventsRecursive(*events.get(), m_rootLayer.get(), wallClockTime); setAnimationEventsRecursive(*events.get(), m_rootLayer.get(), wallClockTime);
} }
void LayerTreeHost::didAddAnimation()
{
m_needsAnimateLayers = true;
m_proxy->didAddAnimation();
}
void LayerTreeHost::setRootLayer(scoped_refptr<Layer> rootLayer) void LayerTreeHost::setRootLayer(scoped_refptr<Layer> rootLayer)
{ {
if (m_rootLayer == rootLayer) if (m_rootLayer == rootLayer)
@@ -925,16 +933,33 @@ void LayerTreeHost::setDeviceScaleFactor(float deviceScaleFactor)
void LayerTreeHost::animateLayers(base::TimeTicks time) void LayerTreeHost::animateLayers(base::TimeTicks time)
{ {
if (!m_settings.acceleratedAnimationEnabled || m_activeAnimationControllers.empty()) if (!m_settings.acceleratedAnimationEnabled || !m_needsAnimateLayers)
return; return;
TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); 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(); double monotonicTime = (time - base::TimeTicks()).InSecondsF();
currentController->animate(monotonicTime, 0);
AnimationControllerSet copy = m_activeAnimationControllers; // If the current controller still has an active animation, we must continue animating layers.
for (AnimationControllerSet::iterator iter = copy.begin(); iter != copy.end(); ++iter) if (currentController->hasActiveAnimation())
(*iter)->animate(monotonicTime, 0); subtreeNeedsAnimateLayers = true;
for (size_t i = 0; i < current->children().size(); ++i) {
if (animateLayersRecursive(current->children()[i].get(), time))
subtreeNeedsAnimateLayers = true;
}
return subtreeNeedsAnimateLayers;
} }
void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& events, Layer* layer, base::Time wallClockTime) void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& events, Layer* layer, base::Time wallClockTime)
@@ -955,30 +980,4 @@ void LayerTreeHost::setAnimationEventsRecursive(const AnimationEventsVector& eve
setAnimationEventsRecursive(events, layer->children()[childIndex].get(), wallClockTime); 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 } // namespace cc

@@ -14,7 +14,6 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time.h" #include "base/time.h"
#include "cc/animation_events.h" #include "cc/animation_events.h"
#include "cc/animation_registrar.h"
#include "cc/cc_export.h" #include "cc/cc_export.h"
#include "cc/layer_tree_host_client.h" #include "cc/layer_tree_host_client.h"
#include "cc/layer_tree_host_common.h" #include "cc/layer_tree_host_common.h"
@@ -37,15 +36,6 @@ struct hash<WebKit::WebGraphicsContext3D*> {
} }
}; };
} // namespace BASE_HASH_NAMESPACE } // 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 #endif // COMPILER
namespace cc { namespace cc {
@@ -123,8 +113,7 @@ struct CC_EXPORT RendererCapabilities {
int maxTextureSize; int maxTextureSize;
}; };
class CC_EXPORT LayerTreeHost : public RateLimiterClient, class CC_EXPORT LayerTreeHost : public RateLimiterClient {
public AnimationRegistrar {
public: public:
static scoped_ptr<LayerTreeHost> create(LayerTreeHostClient*, const LayerTreeSettings&, scoped_ptr<Thread> implThread); static scoped_ptr<LayerTreeHost> create(LayerTreeHostClient*, const LayerTreeSettings&, scoped_ptr<Thread> implThread);
virtual ~LayerTreeHost(); virtual ~LayerTreeHost();
@@ -201,6 +190,7 @@ public:
bool commitRequested() const; bool commitRequested() const;
void setAnimationEvents(scoped_ptr<AnimationEventsVector>, base::Time wallClockTime); void setAnimationEvents(scoped_ptr<AnimationEventsVector>, base::Time wallClockTime);
virtual void didAddAnimation();
Layer* rootLayer() { return m_rootLayer.get(); } Layer* rootLayer() { return m_rootLayer.get(); }
const Layer* rootLayer() const { return m_rootLayer.get(); } const Layer* rootLayer() const { return m_rootLayer.get(); }
@@ -258,15 +248,8 @@ protected:
bool initialize(scoped_ptr<Thread> implThread); bool initialize(scoped_ptr<Thread> implThread);
bool initializeForTesting(scoped_ptr<Proxy> proxyForTesting); 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: private:
typedef std::vector<scoped_refptr<Layer> > LayerList; typedef std::vector<scoped_refptr<Layer> > LayerList;
typedef base::hash_set<LayerAnimationController*> AnimationControllerSet;
bool initializeProxy(scoped_ptr<Proxy> proxy); bool initializeProxy(scoped_ptr<Proxy> proxy);
void initializeRenderer(); void initializeRenderer();
@@ -288,6 +271,7 @@ private:
void setAnimationEventsRecursive(const AnimationEventsVector&, Layer*, base::Time wallClockTime); void setAnimationEventsRecursive(const AnimationEventsVector&, Layer*, base::Time wallClockTime);
bool m_animating; bool m_animating;
bool m_needsAnimateLayers;
bool m_needsFullTreeSync; bool m_needsFullTreeSync;
base::CancelableClosure m_prepaintCallback; base::CancelableClosure m_prepaintCallback;
@@ -334,12 +318,6 @@ private:
static bool s_needsFilterContext; static bool s_needsFilterContext;
AnimationControllerSet m_activeAnimationControllers;
#if !defined(NDEBUG)
AnimationControllerSet m_allAnimationControllers;
#endif
DISALLOW_COPY_AND_ASSIGN(LayerTreeHost); DISALLOW_COPY_AND_ASSIGN(LayerTreeHost);
}; };

@@ -1702,11 +1702,24 @@ TEST(LayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
renderSurface1->setForceRenderSurface(true); renderSurface1->setForceRenderSurface(true);
renderSurface2->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; gfx::Transform layerTransform;
layerTransform.Translate(1, 1); layerTransform.Translate(1, 1);
gfx::Transform sublayerTransform; gfx::Transform sublayerTransform;
sublayerTransform.Scale3d(10, 1, 1); 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(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(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); setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false);
@@ -1717,19 +1730,6 @@ TEST(LayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
setLayerPropertiesForTesting(grandChildOfRS1.get(), layerTransform, sublayerTransform, gfx::PointF(0.25, 0), gfx::PointF(2.5, 0), gfx::Size(10, 10), false); 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); 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()); executeCalculateDrawProperties(parent.get());
// Only layers that are associated with render surfaces should have an actual renderSurface() value. // Only layers that are associated with render surfaces should have an actual renderSurface() value.

@@ -9,7 +9,6 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/debug/trace_event.h" #include "base/debug/trace_event.h"
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/stl_util.h"
#include "cc/append_quads_data.h" #include "cc/append_quads_data.h"
#include "cc/damage_tracker.h" #include "cc/damage_tracker.h"
#include "cc/debug_rect_history.h" #include "cc/debug_rect_history.h"
@@ -219,6 +218,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre
PriorityCalculator::allowNothingCutoff()) PriorityCalculator::allowNothingCutoff())
, m_backgroundColor(0) , m_backgroundColor(0)
, m_hasTransparentBackground(false) , m_hasTransparentBackground(false)
, m_needsAnimateLayers(false)
, m_pinchGestureActive(false) , m_pinchGestureActive(false)
, m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread())) , m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread()))
, m_debugRectHistory(DebugRectHistory::create()) , m_debugRectHistory(DebugRectHistory::create())
@@ -243,13 +243,8 @@ LayerTreeHostImpl::~LayerTreeHostImpl()
DCHECK(m_proxy->isImplThread()); DCHECK(m_proxy->isImplThread());
TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
if (rootLayer()) { if (rootLayer())
clearRenderSurfaces(); 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() void LayerTreeHostImpl::beginCommit()
@@ -597,6 +592,35 @@ bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame)
return drawFrame; 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) void LayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled)
{ {
// Lazily create the timeSource adapter so that we can vary the interval for testing. // Lazily create the timeSource adapter so that we can vary the interval for testing.
@@ -953,7 +977,7 @@ void LayerTreeHostImpl::setVisible(bool visible)
m_renderer->setVisible(visible); m_renderer->setVisible(visible);
setBackgroundTickingEnabled(!m_visible && !m_activeAnimationControllers.empty()); setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
} }
bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface) bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface)
@@ -1508,23 +1532,23 @@ void LayerTreeHostImpl::animatePageScale(base::TimeTicks time)
void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime) void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime)
{ {
if (!m_settings.acceleratedAnimationEnabled || m_activeAnimationControllers.empty() || !rootLayer()) if (!m_settings.acceleratedAnimationEnabled || !m_needsAnimateLayers || !rootLayer())
return; return;
TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers");
double monotonicSeconds = (monotonicTime - base::TimeTicks()).InSecondsF();
scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector));
AnimationControllerSet copy = m_activeAnimationControllers;
for (AnimationControllerSet::iterator iter = copy.begin(); iter != copy.end(); ++iter) bool didAnimate = false;
(*iter)->animate(monotonicSeconds, events.get()); animateLayersRecursive(rootLayer(), monotonicTime, wallClockTime, events.get(), didAnimate, m_needsAnimateLayers);
if (!events->empty()) if (!events->empty())
m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime); m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime);
m_client->setNeedsRedrawOnImplThread(); if (didAnimate)
setBackgroundTickingEnabled(!m_visible && !m_activeAnimationControllers.empty()); m_client->setNeedsRedrawOnImplThread();
setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers);
} }
base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const
@@ -1654,27 +1678,4 @@ void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeT
animateScrollbarsRecursive(layer->children()[i], time); 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 } // namespace cc

@@ -9,7 +9,6 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time.h" #include "base/time.h"
#include "cc/animation_events.h" #include "cc/animation_events.h"
#include "cc/animation_registrar.h"
#include "cc/cc_export.h" #include "cc/cc_export.h"
#include "cc/input_handler.h" #include "cc/input_handler.h"
#include "cc/layer_tree_impl.h" #include "cc/layer_tree_impl.h"
@@ -114,10 +113,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandlerClient,
public RendererClient, public RendererClient,
public TileManagerClient, public TileManagerClient,
public LayerTreeImplClient, public LayerTreeImplClient,
public AnimationRegistrar,
public OutputSurfaceClient { public OutputSurfaceClient {
typedef std::vector<LayerImpl*> LayerList; typedef std::vector<LayerImpl*> LayerList;
typedef base::hash_set<LayerAnimationController*> AnimationControllerSet;
public: public:
static scoped_ptr<LayerTreeHostImpl> create(const LayerTreeSettings&, LayerTreeHostImplClient*, Proxy*); static scoped_ptr<LayerTreeHostImpl> create(const LayerTreeSettings&, LayerTreeHostImplClient*, Proxy*);
@@ -248,7 +245,9 @@ public:
bool hasTransparentBackground() const { return m_hasTransparentBackground; } bool hasTransparentBackground() const { return m_hasTransparentBackground; }
void setHasTransparentBackground(bool transparent) { m_hasTransparentBackground = transparent; } void setHasTransparentBackground(bool transparent) { m_hasTransparentBackground = transparent; }
bool needsAnimateLayers() const { return !m_activeAnimationControllers.empty(); }
bool needsAnimateLayers() const { return m_needsAnimateLayers; }
void setNeedsAnimateLayers() { m_needsAnimateLayers = true; }
void setNeedsRedraw(); void setNeedsRedraw();
@@ -343,14 +342,7 @@ private:
void dumpRenderSurfaces(std::string*, int indent, const LayerImpl*) const; 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<OutputSurface> m_outputSurface;
scoped_ptr<ResourceProvider> m_resourceProvider; scoped_ptr<ResourceProvider> m_resourceProvider;
scoped_ptr<Renderer> m_renderer; scoped_ptr<Renderer> m_renderer;
scoped_ptr<TileManager> m_tileManager; scoped_ptr<TileManager> m_tileManager;
@@ -371,6 +363,7 @@ private:
bool m_hasTransparentBackground; bool m_hasTransparentBackground;
// If this is true, it is necessary to traverse the layer tree ticking the animators. // If this is true, it is necessary to traverse the layer tree ticking the animators.
bool m_needsAnimateLayers;
bool m_pinchGestureActive; bool m_pinchGestureActive;
gfx::Point m_previousPinchAnchor; gfx::Point m_previousPinchAnchor;
@@ -395,12 +388,6 @@ private:
int64 m_cumulativeNumMissingTiles; int64 m_cumulativeNumMissingTiles;
AnimationControllerSet m_activeAnimationControllers;
#if !defined(NDEBUG)
AnimationControllerSet m_allAnimationControllers;
#endif
size_t m_lastSentMemoryVisibleBytes; size_t m_lastSentMemoryVisibleBytes;
size_t m_lastSentMemoryVisibleAndNearbyBytes; size_t m_lastSentMemoryVisibleAndNearbyBytes;
size_t m_lastSentMemoryUseBytes; size_t m_lastSentMemoryUseBytes;

@@ -80,6 +80,8 @@ public:
// like compositeAndReadback while commits are deferred. // like compositeAndReadback while commits are deferred.
virtual void setDeferCommits(bool) = 0; virtual void setDeferCommits(bool) = 0;
virtual void didAddAnimation() = 0;
virtual bool commitRequested() const = 0; virtual bool commitRequested() const = 0;
virtual void start() = 0; // Must be called before using the proxy. virtual void start() = 0; // Must be called before using the proxy.

@@ -241,6 +241,10 @@ bool SingleThreadProxy::commitRequested() const
return false; return false;
} }
void SingleThreadProxy::didAddAnimation()
{
}
size_t SingleThreadProxy::maxPartialTextureUpdates() const size_t SingleThreadProxy::maxPartialTextureUpdates() const
{ {
return std::numeric_limits<size_t>::max(); return std::numeric_limits<size_t>::max();

@@ -39,6 +39,7 @@ public:
virtual void setNeedsRedraw() OVERRIDE; virtual void setNeedsRedraw() OVERRIDE;
virtual void setDeferCommits(bool) OVERRIDE; virtual void setDeferCommits(bool) OVERRIDE;
virtual bool commitRequested() const OVERRIDE; virtual bool commitRequested() const OVERRIDE;
virtual void didAddAnimation() OVERRIDE;
virtual void start() OVERRIDE; virtual void start() OVERRIDE;
virtual void stop() OVERRIDE; virtual void stop() OVERRIDE;
virtual size_t maxPartialTextureUpdates() const OVERRIDE; virtual size_t maxPartialTextureUpdates() const OVERRIDE;

@@ -150,6 +150,40 @@ float FakeFloatTransition::getValue(double time) const
return (1 - time) * m_from + time * m_to; 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 scoped_ptr<cc::AnimationCurve> FakeFloatTransition::clone() const
{ {
return make_scoped_ptr(new FakeFloatTransition(*this)).PassAs<cc::AnimationCurve>(); return make_scoped_ptr(new FakeFloatTransition(*this)).PassAs<cc::AnimationCurve>();

@@ -60,6 +60,23 @@ private:
float m_to; 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 addOpacityTransitionToController(cc::LayerAnimationController&, double duration, float startOpacity, float endOpacity, bool useTimingFunction);
int addAnimatedTransformToController(cc::LayerAnimationController&, double duration, int deltaX, int deltaY); int addAnimatedTransformToController(cc::LayerAnimationController&, double duration, int deltaX, int deltaY);

@@ -30,6 +30,7 @@ public:
virtual void setNeedsCommit() OVERRIDE { } virtual void setNeedsCommit() OVERRIDE { }
virtual void setNeedsRedraw() OVERRIDE { } virtual void setNeedsRedraw() OVERRIDE { }
virtual void setDeferCommits(bool) OVERRIDE { } virtual void setDeferCommits(bool) OVERRIDE { }
virtual void didAddAnimation() OVERRIDE { }
virtual bool commitRequested() const OVERRIDE; virtual bool commitRequested() const OVERRIDE;
virtual void start() OVERRIDE { } virtual void start() OVERRIDE { }
virtual void stop() OVERRIDE { } virtual void stop() OVERRIDE { }

@@ -156,6 +156,12 @@ public:
return MockLayerTreeHostImpl::create(m_testHooks, settings(), client, proxy()).PassAs<cc::LayerTreeHostImpl>(); return MockLayerTreeHostImpl::create(m_testHooks, settings(), client, proxy()).PassAs<cc::LayerTreeHostImpl>();
} }
virtual void didAddAnimation() OVERRIDE
{
LayerTreeHost::didAddAnimation();
m_testHooks->didAddAnimation();
}
virtual void setNeedsCommit() OVERRIDE virtual void setNeedsCommit() OVERRIDE
{ {
if (!m_testStarted) if (!m_testStarted)
@@ -163,12 +169,6 @@ public:
LayerTreeHost::setNeedsCommit(); LayerTreeHost::setNeedsCommit();
} }
virtual void DidActivateAnimationController(cc::LayerAnimationController* controller) OVERRIDE
{
LayerTreeHost::DidActivateAnimationController(controller);
m_testHooks->didAddAnimation();
}
void setTestStarted(bool started) { m_testStarted = started; } void setTestStarted(bool started) { m_testStarted = started; }
virtual void didDeferCommit() OVERRIDE virtual void didDeferCommit() OVERRIDE
@@ -335,6 +335,11 @@ void ThreadedTest::postSetVisibleToMainThread(bool visible)
m_mainThreadProxy->postTask(FROM_HERE, base::Bind(&ThreadedTest::dispatchSetVisible, base::Unretained(this), 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() void ThreadedTest::doBeginTest()
{ {
m_client = ThreadedMockLayerTreeHostClient::create(this); m_client = ThreadedMockLayerTreeHostClient::create(this);
@@ -464,6 +469,17 @@ void ThreadedTest::dispatchComposite()
m_layerTreeHost->composite(); 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) void ThreadedTest::runTest(bool threaded)
{ {
if (threaded) { if (threaded) {

@@ -84,6 +84,7 @@ public:
void postAcquireLayerTextures(); void postAcquireLayerTextures();
void postSetNeedsRedrawToMainThread(); void postSetNeedsRedrawToMainThread();
void postSetVisibleToMainThread(bool visible); void postSetVisibleToMainThread(bool visible);
void postDidAddAnimationToMainThread();
void doBeginTest(); void doBeginTest();
void timeout(); void timeout();

@@ -47,6 +47,7 @@ public:
virtual void setNeedsRedraw() OVERRIDE; virtual void setNeedsRedraw() OVERRIDE;
virtual void setDeferCommits(bool) OVERRIDE; virtual void setDeferCommits(bool) OVERRIDE;
virtual bool commitRequested() const OVERRIDE; virtual bool commitRequested() const OVERRIDE;
virtual void didAddAnimation() OVERRIDE { }
virtual void start() OVERRIDE; virtual void start() OVERRIDE;
virtual void stop() OVERRIDE; virtual void stop() OVERRIDE;
virtual size_t maxPartialTextureUpdates() const OVERRIDE; virtual size_t maxPartialTextureUpdates() const OVERRIDE;

@@ -75,20 +75,19 @@ private:
class FakeLayerAnimationController : public LayerAnimationController { class FakeLayerAnimationController : public LayerAnimationController {
public: public:
static scoped_refptr<LayerAnimationController> create() static scoped_ptr<FakeLayerAnimationController> create(LayerAnimationControllerClient* client)
{ {
return static_cast<LayerAnimationController*>(new FakeLayerAnimationController); return make_scoped_ptr(new FakeLayerAnimationController(client));
} }
bool synchronizedAnimations() const { return m_synchronizedAnimations; } bool synchronizedAnimations() const { return m_synchronizedAnimations; }
private: private:
FakeLayerAnimationController() explicit FakeLayerAnimationController(LayerAnimationControllerClient* client)
: LayerAnimationController() : LayerAnimationController(client)
, m_synchronizedAnimations(false) , m_synchronizedAnimations(false)
{ } {
}
virtual ~FakeLayerAnimationController() { }
virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl) virtual void pushAnimationUpdatesTo(LayerAnimationController* controllerImpl)
{ {
@@ -393,7 +392,8 @@ TEST(TreeSynchronizerTest, synchronizeAnimations)
scoped_refptr<Layer> layerTreeRoot = Layer::create(); scoped_refptr<Layer> layerTreeRoot = Layer::create();
layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create()); FakeLayerAnimationControllerClient dummy;
layerTreeRoot->setLayerAnimationController(FakeLayerAnimationController::create(&dummy).PassAs<LayerAnimationController>());
EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations()); EXPECT_FALSE(static_cast<FakeLayerAnimationController*>(layerTreeRoot->layerAnimationController())->synchronizedAnimations());