| OLD | NEW |
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/tree_synchronizer.h" | 5 #include "cc/trees/tree_synchronizer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <unordered_map> | |
| 11 | 10 |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 13 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
| 14 #include "cc/layers/layer.h" | 13 #include "cc/layers/layer.h" |
| 14 #include "cc/layers/layer_collections.h" |
| 15 #include "cc/layers/layer_impl.h" | 15 #include "cc/layers/layer_impl.h" |
| 16 #include "cc/trees/layer_tree_host.h" | 16 #include "cc/trees/layer_tree_host.h" |
| 17 #include "cc/trees/layer_tree_impl.h" | 17 #include "cc/trees/layer_tree_impl.h" |
| 18 | 18 |
| 19 namespace cc { | 19 namespace cc { |
| 20 | 20 |
| 21 using ScopedPtrLayerImplMap = std::unordered_map<int, scoped_ptr<LayerImpl>>; | 21 template <typename LayerType> |
| 22 using RawPtrLayerImplMap = std::unordered_map<int, LayerImpl*>; | 22 void SynchronizeTreesInternal(LayerType* layer_root, LayerTreeImpl* tree_impl) { |
| 23 DCHECK(tree_impl); |
| 23 | 24 |
| 24 void CollectExistingLayerImplRecursive(ScopedPtrLayerImplMap* old_layers, | 25 TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees"); |
| 25 scoped_ptr<LayerImpl> layer_impl) { | 26 scoped_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers()); |
| 26 if (!layer_impl) | |
| 27 return; | |
| 28 | 27 |
| 29 OwnedLayerImplList& children = layer_impl->children(); | 28 OwnedLayerImplMap old_layer_map; |
| 30 for (auto& child : children) | 29 for (auto& it : *old_layers) |
| 31 CollectExistingLayerImplRecursive(old_layers, std::move(child)); | 30 old_layer_map[it->id()] = std::move(it); |
| 32 | 31 |
| 33 CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeMaskLayer()); | 32 SynchronizeTreesRecursive(&old_layer_map, layer_root, tree_impl); |
| 34 CollectExistingLayerImplRecursive(old_layers, layer_impl->TakeReplicaLayer()); | |
| 35 | 33 |
| 36 int id = layer_impl->id(); | 34 for (auto& it : old_layer_map) { |
| 37 (*old_layers)[id] = std::move(layer_impl); | 35 if (it.second) { |
| 36 // Need to ensure that layer destruction doesn't tear down child |
| 37 // LayerImpl that have been used in the new tree. |
| 38 it.second->children().clear(); |
| 39 } |
| 40 } |
| 41 } |
| 42 |
| 43 void TreeSynchronizer::SynchronizeTrees(Layer* layer_root, |
| 44 LayerTreeImpl* tree_impl) { |
| 45 if (!layer_root) |
| 46 tree_impl->ClearLayers(); |
| 47 else |
| 48 SynchronizeTreesInternal(layer_root, tree_impl); |
| 49 } |
| 50 |
| 51 void TreeSynchronizer::SynchronizeTrees(LayerImpl* layer_root, |
| 52 LayerTreeImpl* tree_impl) { |
| 53 if (!layer_root) |
| 54 tree_impl->ClearLayers(); |
| 55 else |
| 56 SynchronizeTreesInternal(layer_root, tree_impl); |
| 38 } | 57 } |
| 39 | 58 |
| 40 template <typename LayerType> | 59 template <typename LayerType> |
| 41 scoped_ptr<LayerImpl> SynchronizeTreesInternal( | 60 scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(OwnedLayerImplMap* old_layers, |
| 42 LayerType* layer_root, | |
| 43 scoped_ptr<LayerImpl> old_layer_impl_root, | |
| 44 LayerTreeImpl* tree_impl) { | |
| 45 DCHECK(tree_impl); | |
| 46 | |
| 47 TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees"); | |
| 48 ScopedPtrLayerImplMap old_layers; | |
| 49 RawPtrLayerImplMap new_layers; | |
| 50 | |
| 51 CollectExistingLayerImplRecursive(&old_layers, | |
| 52 std::move(old_layer_impl_root)); | |
| 53 | |
| 54 scoped_ptr<LayerImpl> new_tree = SynchronizeTreesRecursive( | |
| 55 &new_layers, &old_layers, layer_root, tree_impl); | |
| 56 | |
| 57 return new_tree; | |
| 58 } | |
| 59 | |
| 60 scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees( | |
| 61 Layer* layer_root, | |
| 62 scoped_ptr<LayerImpl> old_layer_impl_root, | |
| 63 LayerTreeImpl* tree_impl) { | |
| 64 return SynchronizeTreesInternal(layer_root, std::move(old_layer_impl_root), | |
| 65 tree_impl); | |
| 66 } | |
| 67 | |
| 68 scoped_ptr<LayerImpl> TreeSynchronizer::SynchronizeTrees( | |
| 69 LayerImpl* layer_root, | |
| 70 scoped_ptr<LayerImpl> old_layer_impl_root, | |
| 71 LayerTreeImpl* tree_impl) { | |
| 72 return SynchronizeTreesInternal(layer_root, std::move(old_layer_impl_root), | |
| 73 tree_impl); | |
| 74 } | |
| 75 | |
| 76 template <typename LayerType> | |
| 77 scoped_ptr<LayerImpl> ReuseOrCreateLayerImpl(RawPtrLayerImplMap* new_layers, | |
| 78 ScopedPtrLayerImplMap* old_layers, | |
| 79 LayerType* layer, | 61 LayerType* layer, |
| 80 LayerTreeImpl* tree_impl) { | 62 LayerTreeImpl* tree_impl) { |
| 63 if (!layer) |
| 64 return nullptr; |
| 81 scoped_ptr<LayerImpl> layer_impl = std::move((*old_layers)[layer->id()]); | 65 scoped_ptr<LayerImpl> layer_impl = std::move((*old_layers)[layer->id()]); |
| 82 | |
| 83 if (!layer_impl) | 66 if (!layer_impl) |
| 84 layer_impl = layer->CreateLayerImpl(tree_impl); | 67 layer_impl = layer->CreateLayerImpl(tree_impl); |
| 85 | |
| 86 (*new_layers)[layer->id()] = layer_impl.get(); | |
| 87 return layer_impl; | 68 return layer_impl; |
| 88 } | 69 } |
| 89 | 70 |
| 90 template <typename LayerType> | 71 template <typename LayerType> |
| 91 scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( | 72 scoped_ptr<LayerImpl> SynchronizeTreesRecursiveInternal( |
| 92 RawPtrLayerImplMap* new_layers, | 73 OwnedLayerImplMap* old_layers, |
| 93 ScopedPtrLayerImplMap* old_layers, | |
| 94 LayerType* layer, | 74 LayerType* layer, |
| 95 LayerTreeImpl* tree_impl) { | 75 LayerTreeImpl* tree_impl) { |
| 96 if (!layer) | 76 if (!layer) |
| 97 return nullptr; | 77 return nullptr; |
| 98 | 78 |
| 99 scoped_ptr<LayerImpl> layer_impl = | 79 scoped_ptr<LayerImpl> layer_impl( |
| 100 ReuseOrCreateLayerImpl(new_layers, old_layers, layer, tree_impl); | 80 ReuseOrCreateLayerImpl(old_layers, layer, tree_impl)); |
| 101 | 81 |
| 102 layer_impl->ClearChildList(); | 82 layer_impl->children().clear(); |
| 103 for (size_t i = 0; i < layer->children().size(); ++i) { | 83 for (size_t i = 0; i < layer->children().size(); ++i) { |
| 104 layer_impl->AddChild(SynchronizeTreesRecursiveInternal( | 84 layer_impl->AddChild(SynchronizeTreesRecursiveInternal( |
| 105 new_layers, old_layers, layer->child_at(i), tree_impl)); | 85 old_layers, layer->child_at(i), tree_impl)); |
| 106 } | 86 } |
| 107 | 87 |
| 108 layer_impl->SetMaskLayer(SynchronizeTreesRecursiveInternal( | 88 scoped_ptr<LayerImpl> mask_layer = SynchronizeTreesRecursiveInternal( |
| 109 new_layers, old_layers, layer->mask_layer(), tree_impl)); | 89 old_layers, layer->mask_layer(), tree_impl); |
| 110 layer_impl->SetReplicaLayer(SynchronizeTreesRecursiveInternal( | 90 if (layer_impl->mask_layer() && mask_layer && |
| 111 new_layers, old_layers, layer->replica_layer(), tree_impl)); | 91 layer_impl->mask_layer() == mask_layer.get()) { |
| 92 // In this case, we only need to update the ownership, as we're essentially |
| 93 // just resetting the mask layer. |
| 94 tree_impl->AddLayer(std::move(mask_layer)); |
| 95 } else { |
| 96 layer_impl->SetMaskLayer(std::move(mask_layer)); |
| 97 } |
| 98 |
| 99 scoped_ptr<LayerImpl> replica_layer = SynchronizeTreesRecursiveInternal( |
| 100 old_layers, layer->replica_layer(), tree_impl); |
| 101 if (layer_impl->replica_layer() && replica_layer && |
| 102 layer_impl->replica_layer() == replica_layer.get()) { |
| 103 // In this case, we only need to update the ownership, as we're essentially |
| 104 // just resetting the replica layer. |
| 105 tree_impl->AddLayer(std::move(replica_layer)); |
| 106 } else { |
| 107 layer_impl->SetReplicaLayer(std::move(replica_layer)); |
| 108 } |
| 112 | 109 |
| 113 return layer_impl; | 110 return layer_impl; |
| 114 } | 111 } |
| 115 | 112 |
| 116 scoped_ptr<LayerImpl> SynchronizeTreesRecursive( | 113 void SynchronizeTreesRecursive(OwnedLayerImplMap* old_layers, |
| 117 RawPtrLayerImplMap* new_layers, | 114 Layer* old_root, |
| 118 ScopedPtrLayerImplMap* old_layers, | 115 LayerTreeImpl* tree_impl) { |
| 119 Layer* layer, | 116 tree_impl->SetRootLayer( |
| 120 LayerTreeImpl* tree_impl) { | 117 SynchronizeTreesRecursiveInternal(old_layers, old_root, tree_impl)); |
| 121 return SynchronizeTreesRecursiveInternal( | |
| 122 new_layers, old_layers, layer, tree_impl); | |
| 123 } | 118 } |
| 124 | 119 |
| 125 scoped_ptr<LayerImpl> SynchronizeTreesRecursive( | 120 void SynchronizeTreesRecursive(OwnedLayerImplMap* old_layers, |
| 126 RawPtrLayerImplMap* new_layers, | 121 LayerImpl* old_root, |
| 127 ScopedPtrLayerImplMap* old_layers, | 122 LayerTreeImpl* tree_impl) { |
| 128 LayerImpl* layer, | 123 tree_impl->SetRootLayer( |
| 129 LayerTreeImpl* tree_impl) { | 124 SynchronizeTreesRecursiveInternal(old_layers, old_root, tree_impl)); |
| 130 return SynchronizeTreesRecursiveInternal( | |
| 131 new_layers, old_layers, layer, tree_impl); | |
| 132 } | 125 } |
| 133 | 126 |
| 134 static void CheckScrollAndClipPointersRecursive(Layer* layer, | 127 static void CheckScrollAndClipPointersRecursive(Layer* layer, |
| 135 LayerImpl* layer_impl) { | 128 LayerImpl* layer_impl) { |
| 136 DCHECK_EQ(!!layer, !!layer_impl); | 129 DCHECK_EQ(!!layer, !!layer_impl); |
| 137 if (!layer) | 130 if (!layer) |
| 138 return; | 131 return; |
| 139 | 132 |
| 140 // Having a scroll parent on the impl thread implies having one the main | 133 // Having a scroll parent on the impl thread implies having one the main |
| 141 // thread, too. The main thread may have a scroll parent that is not in the | 134 // thread, too. The main thread may have a scroll parent that is not in the |
| 142 // tree because it's been removed but not deleted. In this case, the layer | 135 // tree because it's been removed but not deleted. In this case, the layer |
| 143 // impl will have no scroll parent. Same argument applies for clip parents and | 136 // impl will have no scroll parent. Same argument applies for clip parents and |
| 144 // scroll/clip children. | 137 // scroll/clip children. |
| 145 DCHECK(!layer_impl->scroll_parent() || !!layer->scroll_parent()); | 138 DCHECK(!layer_impl->scroll_parent() || !!layer->scroll_parent()); |
| 146 DCHECK(!layer_impl->clip_parent() || !!layer->clip_parent()); | 139 DCHECK(!layer_impl->clip_parent() || !!layer->clip_parent()); |
| 147 DCHECK(!layer_impl->scroll_children() || !!layer->scroll_children()); | 140 DCHECK(!layer_impl->scroll_children() || !!layer->scroll_children()); |
| 148 DCHECK(!layer_impl->clip_children() || !!layer->clip_children()); | 141 DCHECK(!layer_impl->clip_children() || !!layer->clip_children()); |
| 149 | 142 |
| 150 if (layer_impl->scroll_parent()) | 143 if (layer_impl->scroll_parent()) |
| 151 DCHECK_EQ(layer->scroll_parent()->id(), layer_impl->scroll_parent()->id()); | 144 DCHECK_EQ(layer->scroll_parent()->id(), layer_impl->scroll_parent()->id()); |
| 152 | 145 |
| 153 if (layer_impl->clip_parent()) | 146 if (layer_impl->clip_parent()) |
| 154 DCHECK_EQ(layer->clip_parent()->id(), layer_impl->clip_parent()->id()); | 147 DCHECK_EQ(layer->clip_parent()->id(), layer_impl->clip_parent()->id()); |
| 155 | 148 |
| 156 if (layer_impl->scroll_children()) { | 149 if (layer_impl->scroll_children()) { |
| 157 for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); | 150 for (std::set<Layer*>::iterator it = layer->scroll_children()->begin(); |
| 158 it != layer->scroll_children()->end(); | 151 it != layer->scroll_children()->end(); ++it) { |
| 159 ++it) { | |
| 160 DCHECK_EQ((*it)->scroll_parent(), layer); | 152 DCHECK_EQ((*it)->scroll_parent(), layer); |
| 161 } | 153 } |
| 162 for (std::set<LayerImpl*>::iterator it = | 154 for (std::set<LayerImpl*>::iterator it = |
| 163 layer_impl->scroll_children()->begin(); | 155 layer_impl->scroll_children()->begin(); |
| 164 it != layer_impl->scroll_children()->end(); | 156 it != layer_impl->scroll_children()->end(); ++it) { |
| 165 ++it) { | |
| 166 DCHECK_EQ((*it)->scroll_parent(), layer_impl); | 157 DCHECK_EQ((*it)->scroll_parent(), layer_impl); |
| 167 } | 158 } |
| 168 } | 159 } |
| 169 | 160 |
| 170 if (layer_impl->clip_children()) { | 161 if (layer_impl->clip_children()) { |
| 171 for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); | 162 for (std::set<Layer*>::iterator it = layer->clip_children()->begin(); |
| 172 it != layer->clip_children()->end(); | 163 it != layer->clip_children()->end(); ++it) { |
| 173 ++it) { | |
| 174 DCHECK_EQ((*it)->clip_parent(), layer); | 164 DCHECK_EQ((*it)->clip_parent(), layer); |
| 175 } | 165 } |
| 176 for (std::set<LayerImpl*>::iterator it = | 166 for (std::set<LayerImpl*>::iterator it = |
| 177 layer_impl->clip_children()->begin(); | 167 layer_impl->clip_children()->begin(); |
| 178 it != layer_impl->clip_children()->end(); | 168 it != layer_impl->clip_children()->end(); ++it) { |
| 179 ++it) { | |
| 180 DCHECK_EQ((*it)->clip_parent(), layer_impl); | 169 DCHECK_EQ((*it)->clip_parent(), layer_impl); |
| 181 } | 170 } |
| 182 } | 171 } |
| 183 | 172 |
| 184 for (size_t i = 0u; i < layer->children().size(); ++i) { | 173 for (size_t i = 0u; i < layer->children().size(); ++i) { |
| 185 CheckScrollAndClipPointersRecursive(layer->child_at(i), | 174 CheckScrollAndClipPointersRecursive(layer->child_at(i), |
| 186 layer_impl->child_at(i)); | 175 layer_impl->child_at(i)); |
| 187 } | 176 } |
| 188 } | 177 } |
| 189 | 178 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 210 impl_tree); | 199 impl_tree); |
| 211 | 200 |
| 212 #if DCHECK_IS_ON() | 201 #if DCHECK_IS_ON() |
| 213 if (host_tree->root_layer() && impl_tree->root_layer()) | 202 if (host_tree->root_layer() && impl_tree->root_layer()) |
| 214 CheckScrollAndClipPointersRecursive(host_tree->root_layer(), | 203 CheckScrollAndClipPointersRecursive(host_tree->root_layer(), |
| 215 impl_tree->root_layer()); | 204 impl_tree->root_layer()); |
| 216 #endif | 205 #endif |
| 217 } | 206 } |
| 218 | 207 |
| 219 } // namespace cc | 208 } // namespace cc |
| OLD | NEW |