Index: cc/layer_tree_host_impl.cc |
diff --git a/cc/layer_tree_host_impl.cc b/cc/layer_tree_host_impl.cc |
index 1690ad96c1729ed9c98abe6e6be0385df14d05d7..c02d2e35fc347f1e35ba88480fcec256447333d0 100644 |
--- a/cc/layer_tree_host_impl.cc |
+++ b/cc/layer_tree_host_impl.cc |
@@ -8,6 +8,7 @@ |
#include "base/basictypes.h" |
#include "base/debug/trace_event.h" |
+#include "base/stl_util.h" |
#include "cc/append_quads_data.h" |
#include "cc/damage_tracker.h" |
#include "cc/debug_rect_history.h" |
@@ -215,7 +216,6 @@ LayerTreeHostImpl::LayerTreeHostImpl(const LayerTreeSettings& settings, LayerTre |
PriorityCalculator::allowNothingCutoff()) |
, m_backgroundColor(0) |
, m_hasTransparentBackground(false) |
- , m_needsAnimateLayers(false) |
, m_pinchGestureActive(false) |
, m_fpsCounter(FrameRateCounter::create(m_proxy->hasImplThread())) |
, m_debugRectHistory(DebugRectHistory::create()) |
@@ -236,8 +236,13 @@ LayerTreeHostImpl::~LayerTreeHostImpl() |
DCHECK(m_proxy->isImplThread()); |
TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()"); |
- if (rootLayer()) |
+ if (rootLayer()) { |
clearRenderSurfaces(); |
+ // The layer trees must be destroyed before the layer tree host. We've |
+ // made a contract with our animation controllers that the registrar |
+ // will outlive them, and we must make good. |
+ m_activeTree.reset(); |
+ } |
} |
void LayerTreeHostImpl::beginCommit() |
@@ -584,35 +589,6 @@ bool LayerTreeHostImpl::calculateRenderPasses(FrameData& frame) |
return drawFrame; |
} |
-void LayerTreeHostImpl::animateLayersRecursive(LayerImpl* current, base::TimeTicks monotonicTime, base::Time wallClockTime, AnimationEventsVector* events, bool& didAnimate, bool& needsAnimateLayers) |
-{ |
- bool subtreeNeedsAnimateLayers = false; |
- |
- LayerAnimationController* currentController = current->layerAnimationController(); |
- |
- bool hadActiveAnimation = currentController->hasActiveAnimation(); |
- double monotonicTimeSeconds = (monotonicTime - base::TimeTicks()).InSecondsF(); |
- currentController->animate(monotonicTimeSeconds, events); |
- bool startedAnimation = events->size() > 0; |
- |
- // We animated if we either ticked a running animation, or started a new animation. |
- if (hadActiveAnimation || startedAnimation) |
- didAnimate = true; |
- |
- // If the current controller still has an active animation, we must continue animating layers. |
- if (currentController->hasActiveAnimation()) |
- subtreeNeedsAnimateLayers = true; |
- |
- for (size_t i = 0; i < current->children().size(); ++i) { |
- bool childNeedsAnimateLayers = false; |
- animateLayersRecursive(current->children()[i], monotonicTime, wallClockTime, events, didAnimate, childNeedsAnimateLayers); |
- if (childNeedsAnimateLayers) |
- subtreeNeedsAnimateLayers = true; |
- } |
- |
- needsAnimateLayers = subtreeNeedsAnimateLayers; |
-} |
- |
void LayerTreeHostImpl::setBackgroundTickingEnabled(bool enabled) |
{ |
// Lazily create the timeSource adapter so that we can vary the interval for testing. |
@@ -955,7 +931,7 @@ void LayerTreeHostImpl::setVisible(bool visible) |
m_renderer->setVisible(visible); |
- setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers); |
+ setBackgroundTickingEnabled(!m_visible && !m_activeAnimationControllers.empty()); |
} |
bool LayerTreeHostImpl::initializeRenderer(scoped_ptr<OutputSurface> outputSurface) |
@@ -1508,23 +1484,23 @@ void LayerTreeHostImpl::animatePageScale(base::TimeTicks time) |
void LayerTreeHostImpl::animateLayers(base::TimeTicks monotonicTime, base::Time wallClockTime) |
{ |
- if (!m_settings.acceleratedAnimationEnabled || !m_needsAnimateLayers || !rootLayer()) |
+ if (!m_settings.acceleratedAnimationEnabled || m_activeAnimationControllers.empty() || !rootLayer()) |
return; |
TRACE_EVENT0("cc", "LayerTreeHostImpl::animateLayers"); |
- scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); |
+ double monotonicSeconds = (monotonicTime - base::TimeTicks()).InSecondsF(); |
- bool didAnimate = false; |
- animateLayersRecursive(rootLayer(), monotonicTime, wallClockTime, events.get(), didAnimate, m_needsAnimateLayers); |
+ scoped_ptr<AnimationEventsVector> events(make_scoped_ptr(new AnimationEventsVector)); |
+ AnimationControllerSet copy = m_activeAnimationControllers; |
+ for (AnimationControllerSet::iterator iter = copy.begin(); iter != copy.end(); ++iter) |
+ (*iter)->animate(monotonicSeconds, events.get()); |
if (!events->empty()) |
m_client->postAnimationEventsToMainThreadOnImplThread(events.Pass(), wallClockTime); |
- if (didAnimate) |
- m_client->setNeedsRedrawOnImplThread(); |
- |
- setBackgroundTickingEnabled(!m_visible && m_needsAnimateLayers); |
+ m_client->setNeedsRedrawOnImplThread(); |
+ setBackgroundTickingEnabled(!m_visible && !m_activeAnimationControllers.empty()); |
} |
base::TimeDelta LayerTreeHostImpl::lowFrequencyAnimationInterval() const |
@@ -1614,4 +1590,27 @@ void LayerTreeHostImpl::animateScrollbarsRecursive(LayerImpl* layer, base::TimeT |
animateScrollbarsRecursive(layer->children()[i], time); |
} |
+void LayerTreeHostImpl::DidActivateAnimationController(LayerAnimationController* controller) { |
+ m_activeAnimationControllers.insert(controller); |
+} |
+ |
+void LayerTreeHostImpl::DidDeactivateAnimationController(LayerAnimationController* controller) { |
+ if (ContainsKey(m_activeAnimationControllers, controller)) |
+ m_activeAnimationControllers.erase(controller); |
+} |
+ |
+void LayerTreeHostImpl::RegisterAnimationController(LayerAnimationController* controller) { |
+#if !defined(NDEBUG) |
+ m_allAnimationControllers.insert(controller); |
+#endif |
+} |
+ |
+void LayerTreeHostImpl::UnregisterAnimationController(LayerAnimationController* controller) { |
+#if !defined(NDEBUG) |
+ if (ContainsKey(m_allAnimationControllers, controller)) |
+ m_allAnimationControllers.erase(controller); |
+#endif |
+ DidDeactivateAnimationController(controller); |
+} |
+ |
} // namespace cc |