Enable snappy for IndexedDB.
[chromium-blink-merge.git] / cc / trees / tree_synchronizer.cc
blob48a9d5bd966e35bb9ca6e8dafc797efde999d537
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/trees/tree_synchronizer.h"
7 #include "base/containers/hash_tables.h"
8 #include "base/containers/scoped_ptr_hash_map.h"
9 #include "base/debug/trace_event.h"
10 #include "base/logging.h"
11 #include "cc/animation/scrollbar_animation_controller.h"
12 #include "cc/input/scrollbar.h"
13 #include "cc/layers/layer.h"
14 #include "cc/layers/layer_impl.h"
15 #include "cc/layers/scrollbar_layer_impl_base.h"
16 #include "cc/layers/scrollbar_layer_interface.h"
18 namespace cc {
20 typedef base::ScopedPtrHashMap<int, LayerImpl> ScopedPtrLayerImplMap;
21 typedef base::hash_map<int, LayerImpl*> RawPtrLayerImplMap;
23 void CollectExistingLayerImplRecursive(ScopedPtrLayerImplMap* old_layers,
24 scoped_ptr<LayerImpl> layer_impl) {
25 if (!layer_impl)
26 return;
28 OwnedLayerImplList& children = layer_impl->children();
29 for (OwnedLayerImplList::iterator it = children.begin();
30 it != children.end();
31 ++it)
32 CollectExistingLayerImplRecursive(old_layers, children.take(it));
34 CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeMaskLayer());
35 CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeReplicaLayer());
37 int id = layer_impl->id();
38 old_layers->set(id, layer_impl.Pass());
41 template <typename LayerType>
42 scoped_ptr<LayerImpl> SynchronizeTreesInternal(
43 LayerType* layer_root,
44 scoped_ptr<LayerImpl> old_layer_impl_root,
45 LayerTreeImpl* tree_impl) {
46 DCHECK(tree_impl);
48 TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees");
49 ScopedPtrLayerImplMap old_layers;
50 RawPtrLayerImplMap new_layers;
52 CollectExistingLayerImplRecursive(&old_layers, old_layer_impl_root.Pass());
54 scoped_ptr<LayerImpl> new_tree = SynchronizeTreesRecursive(
55 &new_layers, &old_layers, layer_root, tree_impl);
57 UpdateScrollbarLayerPointersRecursive(&new_layers, layer_root);
59 return new_tree.Pass();
62 scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees(
63 Layer* layer_root,
64 scoped_ptr<LayerImpl> old_layer_impl_root,
65 LayerTreeImpl* tree_impl) {
66 return SynchronizeTreesInternal(
67 layer_root, old_layer_impl_root.Pass(), tree_impl);
70 scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees(
71 LayerImpl* layer_root,
72 scoped_ptr<LayerImpl> old_layer_impl_root,
73 LayerTreeImpl* tree_impl) {
74 return SynchronizeTreesInternal(
75 layer_root, old_layer_impl_root.Pass(), tree_impl);
78 template <typename LayerType>
79 scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(RawPtrLayerImplMap* new_layers,
80 ScopedPtrLayerImplMap* old_layers,
81 LayerType* layer,
82 LayerTreeImpl* tree_impl) {
83 scoped_ptr<LayerImpl> layer_impl = old_layers->take(layer->id());
85 if (!layer_impl)
86 layer_impl = layer->CreateLayerImpl(tree_impl);
88 (*new_layers)[layer->id()] = layer_impl.get();
89 return layer_impl.Pass();
92 template <typename LayerType>
93 scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal(
94 RawPtrLayerImplMap* new_layers,
95 ScopedPtrLayerImplMap* old_layers,
96 LayerType* layer,
97 LayerTreeImpl* tree_impl) {
98 if (!layer)
99 return scoped_ptr<LayerImpl>();
101 scoped_ptr<LayerImpl> layer_impl =
102 ReuseOrCreateLayerImpl(new_layers, old_layers, layer, tree_impl);
104 layer_impl->ClearChildList();
105 for (size_t i = 0; i < layer->children().size(); ++i) {
106 layer_impl->AddChild(SynchronizeTreesRecursiveInternal(
107 new_layers, old_layers, layer->child_at(i), tree_impl));
110 layer_impl->SetMaskLayer(SynchronizeTreesRecursiveInternal(
111 new_layers, old_layers, layer->mask_layer(), tree_impl));
112 layer_impl->SetReplicaLayer(SynchronizeTreesRecursiveInternal(
113 new_layers, old_layers, layer->replica_layer(), tree_impl));
115 // Remove all dangling pointers. The pointers will be setup later in
116 // UpdateScrollbarLayerPointersRecursive phase
117 layer_impl->SetHorizontalScrollbarLayer(NULL);
118 layer_impl->SetVerticalScrollbarLayer(NULL);
120 return layer_impl.Pass();
123 scoped_ptr<LayerImpl> SynchronizeTreesRecursive(
124 RawPtrLayerImplMap* new_layers,
125 ScopedPtrLayerImplMap* old_layers,
126 Layer* layer,
127 LayerTreeImpl* tree_impl) {
128 return SynchronizeTreesRecursiveInternal(
129 new_layers, old_layers, layer, tree_impl);
132 scoped_ptr<LayerImpl> SynchronizeTreesRecursive(
133 RawPtrLayerImplMap* new_layers,
134 ScopedPtrLayerImplMap* old_layers,
135 LayerImpl* layer,
136 LayerTreeImpl* tree_impl) {
137 return SynchronizeTreesRecursiveInternal(
138 new_layers, old_layers, layer, tree_impl);
141 template <typename LayerType, typename ScrollbarLayerType>
142 void UpdateScrollbarLayerPointersRecursiveInternal(
143 const RawPtrLayerImplMap* new_layers,
144 LayerType* layer) {
145 if (!layer)
146 return;
148 for (size_t i = 0; i < layer->children().size(); ++i) {
149 UpdateScrollbarLayerPointersRecursiveInternal<
150 LayerType, ScrollbarLayerType>(new_layers, layer->child_at(i));
153 ScrollbarLayerType* scrollbar_layer = layer->ToScrollbarLayer();
154 if (!scrollbar_layer)
155 return;
157 RawPtrLayerImplMap::const_iterator iter =
158 new_layers->find(layer->id());
159 ScrollbarLayerImplBase* scrollbar_layer_impl =
160 iter != new_layers->end()
161 ? static_cast<ScrollbarLayerImplBase*>(iter->second)
162 : NULL;
163 iter = new_layers->find(scrollbar_layer->ScrollLayerId());
164 LayerImpl* scroll_layer_impl =
165 iter != new_layers->end() ? iter->second : NULL;
167 DCHECK(scrollbar_layer_impl);
168 DCHECK(scroll_layer_impl);
170 if (scrollbar_layer->orientation() == HORIZONTAL)
171 scroll_layer_impl->SetHorizontalScrollbarLayer(scrollbar_layer_impl);
172 else
173 scroll_layer_impl->SetVerticalScrollbarLayer(scrollbar_layer_impl);
176 void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers,
177 Layer* layer) {
178 UpdateScrollbarLayerPointersRecursiveInternal<Layer, ScrollbarLayerInterface>(
179 new_layers, layer);
182 void UpdateScrollbarLayerPointersRecursive(const RawPtrLayerImplMap* new_layers,
183 LayerImpl* layer) {
184 UpdateScrollbarLayerPointersRecursiveInternal<
185 LayerImpl,
186 ScrollbarLayerImplBase>(new_layers, layer);
189 // static
190 void TreeSynchronizer::SetNumDependentsNeedPushProperties(
191 Layer* layer, size_t num) {
192 layer->num_dependents_need_push_properties_ = num;
195 // static
196 void TreeSynchronizer::SetNumDependentsNeedPushProperties(
197 LayerImpl* layer, size_t num) {
200 // static
201 template <typename LayerType>
202 void TreeSynchronizer::PushPropertiesInternal(
203 LayerType* layer,
204 LayerImpl* layer_impl,
205 size_t* num_dependents_need_push_properties_for_parent) {
206 if (!layer) {
207 DCHECK(!layer_impl);
208 return;
211 DCHECK_EQ(layer->id(), layer_impl->id());
213 bool push_layer = layer->needs_push_properties();
214 bool recurse_on_children_and_dependents =
215 layer->descendant_needs_push_properties();
217 if (push_layer)
218 layer->PushPropertiesTo(layer_impl);
220 size_t num_dependents_need_push_properties = 0;
221 if (recurse_on_children_and_dependents) {
222 PushPropertiesInternal(layer->mask_layer(),
223 layer_impl->mask_layer(),
224 &num_dependents_need_push_properties);
225 PushPropertiesInternal(layer->replica_layer(),
226 layer_impl->replica_layer(),
227 &num_dependents_need_push_properties);
229 const OwnedLayerImplList& impl_children = layer_impl->children();
230 DCHECK_EQ(layer->children().size(), impl_children.size());
232 for (size_t i = 0; i < layer->children().size(); ++i) {
233 PushPropertiesInternal(layer->child_at(i),
234 impl_children[i],
235 &num_dependents_need_push_properties);
238 // When PushPropertiesTo completes for a layer, it may still keep
239 // its needs_push_properties() state if the layer must push itself
240 // every PushProperties tree walk. Here we keep track of those layers, and
241 // ensure that their ancestors know about them for the next PushProperties
242 // tree walk.
243 SetNumDependentsNeedPushProperties(
244 layer, num_dependents_need_push_properties);
247 bool add_self_to_parent = num_dependents_need_push_properties > 0 ||
248 layer->needs_push_properties();
249 *num_dependents_need_push_properties_for_parent += add_self_to_parent ? 1 : 0;
252 void TreeSynchronizer::PushProperties(Layer* layer,
253 LayerImpl* layer_impl) {
254 size_t num_dependents_need_push_properties = 0;
255 PushPropertiesInternal(
256 layer, layer_impl, &num_dependents_need_push_properties);
259 void TreeSynchronizer::PushProperties(LayerImpl* layer, LayerImpl* layer_impl) {
260 size_t num_dependents_need_push_properties = 0;
261 PushPropertiesInternal(
262 layer, layer_impl, &num_dependents_need_push_properties);
265 } // namespace cc