summaryrefslogtreecommitdiffstats
path: root/cc/tree_synchronizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cc/tree_synchronizer.cc')
-rw-r--r--cc/tree_synchronizer.cc112
1 files changed, 112 insertions, 0 deletions
diff --git a/cc/tree_synchronizer.cc b/cc/tree_synchronizer.cc
new file mode 100644
index 0000000..b7e76bb
--- /dev/null
+++ b/cc/tree_synchronizer.cc
@@ -0,0 +1,112 @@
+// Copyright 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "TreeSynchronizer.h"
+
+#include "CCLayerImpl.h"
+#include "CCScrollbarAnimationController.h"
+#include "CCScrollbarLayerImpl.h"
+#include "LayerChromium.h"
+#include "ScrollbarLayerChromium.h"
+
+namespace cc {
+
+scoped_ptr<CCLayerImpl> TreeSynchronizer::synchronizeTrees(LayerChromium* layerChromiumRoot, scoped_ptr<CCLayerImpl> oldCCLayerImplRoot, CCLayerTreeHostImpl* hostImpl)
+{
+ ScopedPtrCCLayerImplMap oldLayers;
+ RawPtrCCLayerImplMap newLayers;
+
+ collectExistingCCLayerImplRecursive(oldLayers, oldCCLayerImplRoot.Pass());
+
+ scoped_ptr<CCLayerImpl> newTree = synchronizeTreeRecursive(newLayers, oldLayers, layerChromiumRoot, hostImpl);
+
+ updateScrollbarLayerPointersRecursive(newLayers, layerChromiumRoot);
+
+ return newTree.Pass();
+}
+
+void TreeSynchronizer::collectExistingCCLayerImplRecursive(ScopedPtrCCLayerImplMap& oldLayers, scoped_ptr<CCLayerImpl> ccLayerImpl)
+{
+ if (!ccLayerImpl)
+ return;
+
+ ScopedPtrVector<CCLayerImpl>& children = ccLayerImpl->m_children;
+ for (size_t i = 0; i < children.size(); ++i)
+ collectExistingCCLayerImplRecursive(oldLayers, children.take(i));
+
+ collectExistingCCLayerImplRecursive(oldLayers, ccLayerImpl->m_maskLayer.Pass());
+ collectExistingCCLayerImplRecursive(oldLayers, ccLayerImpl->m_replicaLayer.Pass());
+
+ int id = ccLayerImpl->id();
+ oldLayers.set(id, ccLayerImpl.Pass());
+}
+
+scoped_ptr<CCLayerImpl> TreeSynchronizer::reuseOrCreateCCLayerImpl(RawPtrCCLayerImplMap& newLayers, ScopedPtrCCLayerImplMap& oldLayers, LayerChromium* layer)
+{
+ scoped_ptr<CCLayerImpl> ccLayerImpl = oldLayers.take(layer->id());
+
+ if (!ccLayerImpl)
+ ccLayerImpl = layer->createCCLayerImpl();
+
+ newLayers[layer->id()] = ccLayerImpl.get();
+ return ccLayerImpl.Pass();
+}
+
+scoped_ptr<CCLayerImpl> TreeSynchronizer::synchronizeTreeRecursive(RawPtrCCLayerImplMap& newLayers, ScopedPtrCCLayerImplMap& oldLayers, LayerChromium* layer, CCLayerTreeHostImpl* hostImpl)
+{
+ if (!layer)
+ return scoped_ptr<CCLayerImpl>();
+
+ scoped_ptr<CCLayerImpl> ccLayerImpl = reuseOrCreateCCLayerImpl(newLayers, oldLayers, layer);
+
+ ccLayerImpl->clearChildList();
+ const std::vector<scoped_refptr<LayerChromium> >& children = layer->children();
+ for (size_t i = 0; i < children.size(); ++i)
+ ccLayerImpl->addChild(synchronizeTreeRecursive(newLayers, oldLayers, children[i].get(), hostImpl));
+
+ ccLayerImpl->setMaskLayer(synchronizeTreeRecursive(newLayers, oldLayers, layer->maskLayer(), hostImpl));
+ ccLayerImpl->setReplicaLayer(synchronizeTreeRecursive(newLayers, oldLayers, layer->replicaLayer(), hostImpl));
+
+ layer->pushPropertiesTo(ccLayerImpl.get());
+ ccLayerImpl->setLayerTreeHostImpl(hostImpl);
+
+ // Remove all dangling pointers. The pointers will be setup later in updateScrollbarLayerPointersRecursive phase
+ if (CCScrollbarAnimationController* scrollbarController = ccLayerImpl->scrollbarAnimationController()) {
+ scrollbarController->setHorizontalScrollbarLayer(0);
+ scrollbarController->setVerticalScrollbarLayer(0);
+ }
+
+ return ccLayerImpl.Pass();
+}
+
+void TreeSynchronizer::updateScrollbarLayerPointersRecursive(const RawPtrCCLayerImplMap& newLayers, LayerChromium* layer)
+{
+ if (!layer)
+ return;
+
+ const std::vector<scoped_refptr<LayerChromium> >& children = layer->children();
+ for (size_t i = 0; i < children.size(); ++i)
+ updateScrollbarLayerPointersRecursive(newLayers, children[i].get());
+
+ ScrollbarLayerChromium* scrollbarLayer = layer->toScrollbarLayerChromium();
+ if (!scrollbarLayer)
+ return;
+
+ RawPtrCCLayerImplMap::const_iterator iter = newLayers.find(scrollbarLayer->id());
+ CCScrollbarLayerImpl* ccScrollbarLayerImpl = iter != newLayers.end() ? static_cast<CCScrollbarLayerImpl*>(iter->second) : NULL;
+ iter = newLayers.find(scrollbarLayer->scrollLayerId());
+ CCLayerImpl* ccScrollLayerImpl = iter != newLayers.end() ? iter->second : NULL;
+
+ ASSERT(ccScrollbarLayerImpl);
+ ASSERT(ccScrollLayerImpl);
+
+ if (ccScrollbarLayerImpl->orientation() == WebKit::WebScrollbar::Horizontal)
+ ccScrollLayerImpl->setHorizontalScrollbarLayer(ccScrollbarLayerImpl);
+ else
+ ccScrollLayerImpl->setVerticalScrollbarLayer(ccScrollbarLayerImpl);
+}
+
+} // namespace cc