OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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. |
| 4 |
| 5 #include "cc/blimp/compositor_state_deserializer.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 #include "cc/blimp/compositor_state_deserializer_client.h" |
| 10 #include "cc/blimp/layer_factory.h" |
| 11 #include "cc/input/layer_selection_bound.h" |
| 12 #include "cc/layers/layer.h" |
| 13 #include "cc/proto/cc_conversions.h" |
| 14 #include "cc/proto/gfx_conversions.h" |
| 15 #include "cc/proto/layer_tree_host.pb.h" |
| 16 #include "cc/proto/skia_conversions.h" |
| 17 #include "cc/trees/layer_tree_host.h" |
| 18 |
| 19 namespace cc { |
| 20 namespace { |
| 21 |
| 22 class DefaultLayerFactory : public LayerFactory { |
| 23 public: |
| 24 DefaultLayerFactory() = default; |
| 25 ~DefaultLayerFactory() override = default; |
| 26 |
| 27 // LayerFactory implementation. |
| 28 scoped_refptr<Layer> CreateLayer(int engine_layer_id) override { |
| 29 return Layer::Create(); |
| 30 } |
| 31 }; |
| 32 |
| 33 } // namespace |
| 34 |
| 35 CompositorStateDeserializer::CompositorStateDeserializer( |
| 36 LayerTreeHost* layer_tree_host, |
| 37 ScrollCallback scroll_callback, |
| 38 CompositorStateDeserializerClient* client) |
| 39 : layer_factory_(base::MakeUnique<DefaultLayerFactory>()), |
| 40 layer_tree_host_(layer_tree_host), |
| 41 scroll_callback_(scroll_callback), |
| 42 client_(client) { |
| 43 DCHECK(layer_tree_host_); |
| 44 DCHECK(client_); |
| 45 } |
| 46 |
| 47 CompositorStateDeserializer::~CompositorStateDeserializer() = default; |
| 48 |
| 49 Layer* CompositorStateDeserializer::GetLayerForEngineId( |
| 50 int engine_layer_id) const { |
| 51 EngineIdToLayerMap::const_iterator layer_it = |
| 52 engine_id_to_layer_.find(engine_layer_id); |
| 53 return layer_it != engine_id_to_layer_.end() ? layer_it->second.get() |
| 54 : nullptr; |
| 55 } |
| 56 |
| 57 void CompositorStateDeserializer::DeserializeCompositorUpdate( |
| 58 const proto::LayerTreeHost& layer_tree_host_proto) { |
| 59 SychronizeLayerTreeState(layer_tree_host_proto.layer_tree()); |
| 60 |
| 61 const proto::LayerUpdate& layer_updates = |
| 62 layer_tree_host_proto.layer_updates(); |
| 63 for (int i = 0; i < layer_updates.layers_size(); ++i) { |
| 64 SynchronizeLayerState(layer_updates.layers(i)); |
| 65 } |
| 66 } |
| 67 |
| 68 void CompositorStateDeserializer::SetLayerFactoryForTesting( |
| 69 std::unique_ptr<LayerFactory> layer_factory) { |
| 70 layer_factory_ = std::move(layer_factory); |
| 71 } |
| 72 |
| 73 void CompositorStateDeserializer::SychronizeLayerTreeState( |
| 74 const proto::LayerTree& layer_tree_proto) { |
| 75 LayerTree* layer_tree = layer_tree_host_->GetLayerTree(); |
| 76 |
| 77 // Synchronize the tree hierarchy first. |
| 78 // TODO(khushalsagar): Don't do this if the hierarchy didn't change. See |
| 79 // crbug.com/605170. |
| 80 EngineIdToLayerMap new_engine_id_to_layer; |
| 81 if (layer_tree_proto.has_root_layer()) { |
| 82 const proto::LayerNode& root_layer_node = layer_tree_proto.root_layer(); |
| 83 layer_tree->SetRootLayer( |
| 84 GetLayerAndAddToNewMap(root_layer_node, &new_engine_id_to_layer)); |
| 85 SynchronizeLayerHierarchyRecursive( |
| 86 layer_tree->root_layer(), root_layer_node, &new_engine_id_to_layer); |
| 87 } else { |
| 88 layer_tree->SetRootLayer(nullptr); |
| 89 } |
| 90 engine_id_to_layer_.swap(new_engine_id_to_layer); |
| 91 |
| 92 // Synchronize rest of the tree state. |
| 93 layer_tree->RegisterViewportLayers( |
| 94 GetLayer(layer_tree_proto.overscroll_elasticity_layer_id()), |
| 95 GetLayer(layer_tree_proto.page_scale_layer_id()), |
| 96 GetLayer(layer_tree_proto.inner_viewport_scroll_layer_id()), |
| 97 GetLayer(layer_tree_proto.outer_viewport_scroll_layer_id())); |
| 98 |
| 99 layer_tree->SetDeviceScaleFactor(layer_tree_proto.device_scale_factor()); |
| 100 layer_tree->SetPaintedDeviceScaleFactor( |
| 101 layer_tree_proto.painted_device_scale_factor()); |
| 102 |
| 103 float min_page_scale_factor = layer_tree_proto.min_page_scale_factor(); |
| 104 float max_page_scale_factor = layer_tree_proto.max_page_scale_factor(); |
| 105 float page_scale_factor = layer_tree_proto.page_scale_factor(); |
| 106 if (client_->ShouldRetainClientPageScale(page_scale_factor)) |
| 107 page_scale_factor = layer_tree->page_scale_factor(); |
| 108 layer_tree->SetPageScaleFactorAndLimits( |
| 109 page_scale_factor, min_page_scale_factor, max_page_scale_factor); |
| 110 |
| 111 layer_tree->set_background_color(layer_tree_proto.background_color()); |
| 112 layer_tree->set_has_transparent_background( |
| 113 layer_tree_proto.has_transparent_background()); |
| 114 |
| 115 LayerSelection selection; |
| 116 LayerSelectionFromProtobuf(&selection, layer_tree_proto.selection()); |
| 117 layer_tree->RegisterSelection(selection); |
| 118 layer_tree->SetViewportSize( |
| 119 ProtoToSize(layer_tree_proto.device_viewport_size())); |
| 120 |
| 121 layer_tree->SetHaveScrollEventHandlers( |
| 122 layer_tree_proto.have_scroll_event_handlers()); |
| 123 layer_tree->SetEventListenerProperties( |
| 124 EventListenerClass::kMouseWheel, |
| 125 static_cast<EventListenerProperties>( |
| 126 layer_tree_proto.wheel_event_listener_properties())); |
| 127 layer_tree->SetEventListenerProperties( |
| 128 EventListenerClass::kTouchStartOrMove, |
| 129 static_cast<EventListenerProperties>( |
| 130 layer_tree_proto.touch_start_or_move_event_listener_properties())); |
| 131 layer_tree->SetEventListenerProperties( |
| 132 EventListenerClass::kTouchEndOrCancel, |
| 133 static_cast<EventListenerProperties>( |
| 134 layer_tree_proto.touch_end_or_cancel_event_listener_properties())); |
| 135 } |
| 136 |
| 137 void CompositorStateDeserializer::SynchronizeLayerState( |
| 138 const proto::LayerProperties& layer_properties_proto) { |
| 139 int engine_layer_id = layer_properties_proto.id(); |
| 140 Layer* layer = GetLayerForEngineId(engine_layer_id); |
| 141 |
| 142 const proto::BaseLayerProperties& base = layer_properties_proto.base(); |
| 143 |
| 144 layer->SetNeedsDisplayRect(ProtoToRect(base.update_rect())); |
| 145 layer->SetBounds(ProtoToSize(base.bounds())); |
| 146 layer->SetMasksToBounds(base.masks_to_bounds()); |
| 147 layer->SetOpacity(base.opacity()); |
| 148 layer->SetBlendMode(SkXfermodeModeFromProto(base.blend_mode())); |
| 149 layer->SetIsRootForIsolatedGroup(base.is_root_for_isolated_group()); |
| 150 layer->SetContentsOpaque(base.contents_opaque()); |
| 151 layer->SetPosition(ProtoToPointF(base.position())); |
| 152 layer->SetTransform(ProtoToTransform(base.transform())); |
| 153 layer->SetTransformOrigin(ProtoToPoint3F(base.transform_origin())); |
| 154 layer->SetIsDrawable(base.is_drawable()); |
| 155 layer->SetDoubleSided(base.double_sided()); |
| 156 layer->SetShouldFlattenTransform(base.should_flatten_transform()); |
| 157 layer->Set3dSortingContextId(base.sorting_context_id()); |
| 158 layer->SetUseParentBackfaceVisibility(base.use_parent_backface_visibility()); |
| 159 layer->SetBackgroundColor(base.background_color()); |
| 160 |
| 161 gfx::ScrollOffset scroll_offset = ProtoToScrollOffset(base.scroll_offset()); |
| 162 if (client_->ShouldRetainClientScroll(engine_layer_id, scroll_offset)) |
| 163 scroll_offset = layer->scroll_offset(); |
| 164 layer->SetScrollOffset(scroll_offset); |
| 165 |
| 166 layer->SetScrollClipLayerId( |
| 167 GetClientIdFromEngineId(base.scroll_clip_layer_id())); |
| 168 layer->SetUserScrollable(base.user_scrollable_horizontal(), |
| 169 base.user_scrollable_vertical()); |
| 170 |
| 171 if (layer->main_thread_scrolling_reasons()) { |
| 172 layer->ClearMainThreadScrollingReasons( |
| 173 layer->main_thread_scrolling_reasons()); |
| 174 } |
| 175 if (base.main_thread_scrolling_reasons()) { |
| 176 layer->AddMainThreadScrollingReasons(base.main_thread_scrolling_reasons()); |
| 177 } |
| 178 |
| 179 layer->SetNonFastScrollableRegion( |
| 180 RegionFromProto(base.non_fast_scrollable_region())); |
| 181 layer->SetTouchEventHandlerRegion( |
| 182 RegionFromProto(base.touch_event_handler_region())); |
| 183 |
| 184 layer->SetIsContainerForFixedPositionLayers( |
| 185 base.is_container_for_fixed_position_layers()); |
| 186 |
| 187 LayerPositionConstraint position_constraint; |
| 188 position_constraint.FromProtobuf(base.position_constraint()); |
| 189 layer->SetPositionConstraint(position_constraint); |
| 190 |
| 191 LayerStickyPositionConstraint sticky_position_constraint; |
| 192 sticky_position_constraint.FromProtobuf(base.sticky_position_constraint()); |
| 193 layer->SetStickyPositionConstraint(sticky_position_constraint); |
| 194 layer->SetScrollParent(GetLayerForEngineId(base.scroll_parent_id())); |
| 195 layer->SetClipParent(GetLayerForEngineId(base.clip_parent_id())); |
| 196 |
| 197 layer->SetHasWillChangeTransformHint(base.has_will_change_transform_hint()); |
| 198 layer->SetHideLayerAndSubtree(base.hide_layer_and_subtree()); |
| 199 } |
| 200 |
| 201 void CompositorStateDeserializer::SynchronizeLayerHierarchyRecursive( |
| 202 Layer* layer, |
| 203 const proto::LayerNode& layer_node, |
| 204 EngineIdToLayerMap* new_layer_map) { |
| 205 layer->RemoveAllChildren(); |
| 206 |
| 207 // Children. |
| 208 for (int i = 0; i < layer_node.children_size(); i++) { |
| 209 const proto::LayerNode& child_layer_node = layer_node.children(i); |
| 210 scoped_refptr<Layer> child_layer = |
| 211 GetLayerAndAddToNewMap(child_layer_node, new_layer_map); |
| 212 layer->AddChild(child_layer); |
| 213 SynchronizeLayerHierarchyRecursive(child_layer.get(), child_layer_node, |
| 214 new_layer_map); |
| 215 } |
| 216 |
| 217 // Mask Layer. |
| 218 if (layer_node.has_mask_layer()) { |
| 219 const proto::LayerNode& mask_layer_node = layer_node.mask_layer(); |
| 220 scoped_refptr<Layer> mask_layer = |
| 221 GetLayerAndAddToNewMap(mask_layer_node, new_layer_map); |
| 222 layer->SetMaskLayer(mask_layer.get()); |
| 223 SynchronizeLayerHierarchyRecursive(mask_layer.get(), mask_layer_node, |
| 224 new_layer_map); |
| 225 } else { |
| 226 layer->SetMaskLayer(nullptr); |
| 227 } |
| 228 |
| 229 // Scroll callback. |
| 230 layer->set_did_scroll_callback(base::Bind(scroll_callback_, layer_node.id())); |
| 231 } |
| 232 |
| 233 scoped_refptr<Layer> CompositorStateDeserializer::GetLayerAndAddToNewMap( |
| 234 const proto::LayerNode& layer_node, |
| 235 EngineIdToLayerMap* new_layer_map) { |
| 236 DCHECK(new_layer_map->find(layer_node.id()) == new_layer_map->end()) |
| 237 << "A LayerNode should have been de-serialized only once"; |
| 238 |
| 239 EngineIdToLayerMap::iterator layer_map_it = |
| 240 engine_id_to_layer_.find(layer_node.id()); |
| 241 |
| 242 if (layer_map_it != engine_id_to_layer_.end()) { |
| 243 // We can re-use the old layer. |
| 244 (*new_layer_map)[layer_node.id()] = layer_map_it->second; |
| 245 return layer_map_it->second; |
| 246 } |
| 247 |
| 248 // We need to create a new layer. |
| 249 scoped_refptr<Layer> layer; |
| 250 switch (layer_node.type()) { |
| 251 case proto::LayerNode::UNKNOWN: |
| 252 NOTREACHED() << "Unknown Layer type"; |
| 253 case proto::LayerNode::LAYER: |
| 254 layer = layer_factory_->CreateLayer(layer_node.id()); |
| 255 break; |
| 256 default: |
| 257 // TODO(khushalsagar): Add other Layer types. |
| 258 NOTREACHED(); |
| 259 } |
| 260 |
| 261 (*new_layer_map)[layer_node.id()] = layer; |
| 262 return layer; |
| 263 } |
| 264 |
| 265 int CompositorStateDeserializer::GetClientIdFromEngineId(int engine_layer_id) { |
| 266 Layer* layer = GetLayerForEngineId(engine_layer_id); |
| 267 return layer ? layer->id() : Layer::LayerIdLabels::INVALID_ID; |
| 268 } |
| 269 |
| 270 scoped_refptr<Layer> CompositorStateDeserializer::GetLayer( |
| 271 int engine_layer_id) { |
| 272 EngineIdToLayerMap::const_iterator layer_it = |
| 273 engine_id_to_layer_.find(engine_layer_id); |
| 274 return layer_it != engine_id_to_layer_.end() ? layer_it->second : nullptr; |
| 275 } |
| 276 |
| 277 } // namespace cc |
OLD | NEW |