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