Chromium Code Reviews| 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 EngineIdToLayerMap new_engine_id_to_layer; | |
| 79 if (layer_tree_proto.has_root_layer()) { | |
| 80 const proto::LayerNode& root_layer_node = layer_tree_proto.root_layer(); | |
| 81 layer_tree->SetRootLayer( | |
| 82 GetLayerAndAddToNewMap(root_layer_node, &new_engine_id_to_layer)); | |
| 83 SynchronizeLayerHeirarchyRecursive( | |
|
ajuma
2016/10/04 15:45:10
Is this happening every frame? Are there plans to
Khushal
2016/10/04 18:34:47
Yeah, the existing code was doing this so I didn't
| |
| 84 layer_tree->root_layer(), root_layer_node, &new_engine_id_to_layer); | |
| 85 } else { | |
| 86 layer_tree->SetRootLayer(nullptr); | |
| 87 } | |
| 88 engine_id_to_layer_.swap(new_engine_id_to_layer); | |
| 89 | |
| 90 // Synchronize rest of the tree state. | |
| 91 layer_tree->RegisterViewportLayers( | |
| 92 GetLayer(layer_tree_proto.overscroll_elasticity_layer_id()), | |
| 93 GetLayer(layer_tree_proto.page_scale_layer_id()), | |
| 94 GetLayer(layer_tree_proto.inner_viewport_scroll_layer_id()), | |
| 95 GetLayer(layer_tree_proto.outer_viewport_scroll_layer_id())); | |
| 96 | |
| 97 layer_tree->SetDeviceScaleFactor(layer_tree_proto.device_scale_factor()); | |
| 98 layer_tree->SetPaintedDeviceScaleFactor( | |
| 99 layer_tree_proto.painted_device_scale_factor()); | |
| 100 | |
| 101 float min_page_scale_factor = layer_tree_proto.min_page_scale_factor(); | |
| 102 float max_page_scale_factor = layer_tree_proto.max_page_scale_factor(); | |
| 103 float page_scale_factor = layer_tree_proto.page_scale_factor(); | |
| 104 if (client_->ShouldRetainClientPageScale(page_scale_factor)) | |
| 105 page_scale_factor = layer_tree->page_scale_factor(); | |
| 106 layer_tree->SetPageScaleFactorAndLimits( | |
| 107 page_scale_factor, min_page_scale_factor, max_page_scale_factor); | |
| 108 | |
| 109 layer_tree->set_background_color(layer_tree_proto.background_color()); | |
| 110 layer_tree->set_has_transparent_background( | |
| 111 layer_tree_proto.has_transparent_background()); | |
| 112 | |
| 113 LayerSelection selection; | |
| 114 LayerSelectionFromProtobuf(&selection, layer_tree_proto.selection()); | |
| 115 layer_tree->RegisterSelection(selection); | |
| 116 layer_tree->SetViewportSize( | |
| 117 ProtoToSize(layer_tree_proto.device_viewport_size())); | |
| 118 | |
| 119 layer_tree->SetHaveScrollEventHandlers( | |
| 120 layer_tree_proto.have_scroll_event_handlers()); | |
| 121 layer_tree->SetEventListenerProperties( | |
| 122 EventListenerClass::kMouseWheel, | |
| 123 static_cast<EventListenerProperties>( | |
| 124 layer_tree_proto.wheel_event_listener_properties())); | |
| 125 layer_tree->SetEventListenerProperties( | |
| 126 EventListenerClass::kTouchStartOrMove, | |
| 127 static_cast<EventListenerProperties>( | |
| 128 layer_tree_proto.touch_start_or_move_event_listener_properties())); | |
| 129 layer_tree->SetEventListenerProperties( | |
| 130 EventListenerClass::kTouchEndOrCancel, | |
| 131 static_cast<EventListenerProperties>( | |
| 132 layer_tree_proto.touch_end_or_cancel_event_listener_properties())); | |
| 133 } | |
| 134 | |
| 135 void CompositorStateDeserializer::SynchronizeLayerState( | |
| 136 const proto::LayerProperties& layer_properties_proto) { | |
| 137 int engine_layer_id = layer_properties_proto.id(); | |
| 138 Layer* layer = GetLayerForEngineId(engine_layer_id); | |
| 139 | |
| 140 const proto::BaseLayerProperties& base = layer_properties_proto.base(); | |
| 141 | |
| 142 layer->SetNeedsDisplayRect(ProtoToRect(base.update_rect())); | |
| 143 layer->SetBounds(ProtoToSize(base.bounds())); | |
| 144 layer->SetMasksToBounds(base.masks_to_bounds()); | |
| 145 layer->SetOpacity(base.opacity()); | |
| 146 layer->SetBlendMode(SkXfermodeModeFromProto(base.blend_mode())); | |
| 147 layer->SetIsRootForIsolatedGroup(base.is_root_for_isolated_group()); | |
| 148 layer->SetContentsOpaque(base.contents_opaque()); | |
| 149 layer->SetPosition(ProtoToPointF(base.position())); | |
| 150 layer->SetTransform(ProtoToTransform(base.transform())); | |
| 151 layer->SetTransformOrigin(ProtoToPoint3F(base.transform_origin())); | |
| 152 layer->SetIsDrawable(base.is_drawable()); | |
| 153 layer->SetDoubleSided(base.double_sided()); | |
| 154 layer->SetShouldFlattenTransform(base.should_flatten_transform()); | |
| 155 layer->Set3dSortingContextId(base.sorting_context_id()); | |
| 156 layer->SetUseParentBackfaceVisibility(base.use_parent_backface_visibility()); | |
| 157 layer->SetBackgroundColor(base.background_color()); | |
| 158 | |
| 159 gfx::ScrollOffset scroll_offset = ProtoToScrollOffset(base.scroll_offset()); | |
| 160 if (client_->ShouldRetainClientScroll(engine_layer_id, scroll_offset)) | |
| 161 scroll_offset = layer->scroll_offset(); | |
| 162 layer->SetScrollOffset(scroll_offset); | |
| 163 | |
| 164 layer->SetScrollClipLayerId( | |
| 165 GetClientIdFromEngineId(base.scroll_clip_layer_id())); | |
| 166 layer->SetUserScrollable(base.user_scrollable_horizontal(), | |
| 167 base.user_scrollable_vertical()); | |
| 168 | |
| 169 if (layer->main_thread_scrolling_reasons()) { | |
| 170 layer->ClearMainThreadScrollingReasons( | |
| 171 layer->main_thread_scrolling_reasons()); | |
| 172 } | |
| 173 if (base.main_thread_scrolling_reasons()) { | |
| 174 layer->AddMainThreadScrollingReasons(base.main_thread_scrolling_reasons()); | |
| 175 } | |
| 176 | |
| 177 layer->SetNonFastScrollableRegion( | |
| 178 RegionFromProto(base.non_fast_scrollable_region())); | |
| 179 layer->SetTouchEventHandlerRegion( | |
| 180 RegionFromProto(base.touch_event_handler_region())); | |
| 181 | |
| 182 layer->SetIsContainerForFixedPositionLayers( | |
| 183 base.is_container_for_fixed_position_layers()); | |
| 184 | |
| 185 LayerPositionConstraint position_constraint; | |
| 186 position_constraint.FromProtobuf(base.position_constraint()); | |
| 187 layer->SetPositionConstraint(position_constraint); | |
| 188 | |
| 189 LayerStickyPositionConstraint sticky_position_constraint; | |
| 190 sticky_position_constraint.FromProtobuf(base.sticky_position_constraint()); | |
| 191 layer->SetStickyPositionConstraint(sticky_position_constraint); | |
| 192 layer->SetScrollParent(GetLayerForEngineId(base.scroll_parent_id())); | |
| 193 layer->SetClipParent(GetLayerForEngineId(base.clip_parent_id())); | |
| 194 | |
| 195 layer->SetHasWillChangeTransformHint(base.has_will_change_transform_hint()); | |
| 196 layer->SetHideLayerAndSubtree(base.hide_layer_and_subtree()); | |
| 197 } | |
| 198 | |
| 199 void CompositorStateDeserializer::SynchronizeLayerHeirarchyRecursive( | |
|
ajuma
2016/10/04 15:45:10
typo: "Hierarchy"
Khushal
2016/10/04 18:34:47
Done.
| |
| 200 Layer* layer, | |
| 201 const proto::LayerNode& layer_node, | |
| 202 EngineIdToLayerMap* new_layer_map) { | |
| 203 layer->RemoveAllChildren(); | |
| 204 | |
| 205 // Children. | |
| 206 for (int i = 0; i < layer_node.children_size(); i++) { | |
| 207 const proto::LayerNode& child_layer_node = layer_node.children(i); | |
| 208 scoped_refptr<Layer> child_layer = | |
| 209 GetLayerAndAddToNewMap(child_layer_node, new_layer_map); | |
| 210 layer->AddChild(child_layer); | |
| 211 SynchronizeLayerHeirarchyRecursive(child_layer.get(), child_layer_node, | |
| 212 new_layer_map); | |
| 213 } | |
| 214 | |
| 215 // Mask Layer. | |
| 216 if (layer_node.has_mask_layer()) { | |
| 217 const proto::LayerNode& mask_layer_node = layer_node.mask_layer(); | |
| 218 scoped_refptr<Layer> mask_layer = | |
| 219 GetLayerAndAddToNewMap(mask_layer_node, new_layer_map); | |
| 220 layer->SetMaskLayer(mask_layer.get()); | |
| 221 SynchronizeLayerHeirarchyRecursive(mask_layer.get(), mask_layer_node, | |
| 222 new_layer_map); | |
| 223 } else { | |
| 224 layer->SetMaskLayer(nullptr); | |
| 225 } | |
| 226 | |
| 227 // Scroll callback. | |
| 228 layer->set_did_scroll_callback(base::Bind(scroll_callback_, layer_node.id())); | |
| 229 } | |
| 230 | |
| 231 scoped_refptr<Layer> CompositorStateDeserializer::GetLayerAndAddToNewMap( | |
| 232 const proto::LayerNode& layer_node, | |
| 233 EngineIdToLayerMap* new_layer_map) { | |
| 234 DCHECK(new_layer_map->find(layer_node.id()) == new_layer_map->end()) | |
| 235 << "A LayerNode should have been de-serialized only once"; | |
| 236 | |
| 237 EngineIdToLayerMap::iterator layer_map_it = | |
| 238 engine_id_to_layer_.find(layer_node.id()); | |
| 239 | |
| 240 if (layer_map_it != engine_id_to_layer_.end()) { | |
| 241 // We can re-use the old layer. | |
| 242 (*new_layer_map)[layer_node.id()] = layer_map_it->second; | |
| 243 return layer_map_it->second; | |
| 244 } | |
| 245 | |
| 246 // We need to create a new layer. | |
| 247 scoped_refptr<Layer> layer; | |
| 248 switch (layer_node.type()) { | |
| 249 case proto::LayerNode::UNKNOWN: | |
| 250 NOTREACHED() << "Unknown Layer type"; | |
| 251 case proto::LayerNode::LAYER: | |
| 252 layer = layer_factory_->CreateLayer(layer_node.id()); | |
| 253 break; | |
| 254 default: | |
| 255 // TODO(khushalsagar): Add other Layer types. | |
| 256 NOTREACHED(); | |
| 257 } | |
| 258 | |
| 259 (*new_layer_map)[layer_node.id()] = layer; | |
| 260 return layer; | |
| 261 } | |
| 262 | |
| 263 int CompositorStateDeserializer::GetClientIdFromEngineId(int engine_layer_id) { | |
| 264 Layer* layer = GetLayerForEngineId(engine_layer_id); | |
| 265 return layer ? layer->id() : Layer::LayerIdLabels::INVALID_ID; | |
| 266 } | |
| 267 | |
| 268 scoped_refptr<Layer> CompositorStateDeserializer::GetLayer( | |
| 269 int engine_layer_id) { | |
| 270 EngineIdToLayerMap::const_iterator layer_it = | |
| 271 engine_id_to_layer_.find(engine_layer_id); | |
| 272 return layer_it != engine_id_to_layer_.end() ? layer_it->second : nullptr; | |
| 273 } | |
| 274 | |
| 275 } // namespace cc | |
| OLD | NEW |