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 |