blob: bbce951aad05cb2fc36f68a1d837122922e7c027 [file] [log] [blame]
xingliue43518a2016-07-28 23:59:471// 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
rnk2f03c7f2016-08-17 17:10:595#include "cc/trees/layer_tree.h"
khushalsagar806556452016-08-17 01:36:266
khushalsagar86928f92016-08-17 21:49:057#include "base/auto_reset.h"
8#include "base/time/time.h"
9#include "cc/animation/animation_host.h"
10#include "cc/input/page_scale_animation.h"
11#include "cc/layers/heads_up_display_layer.h"
12#include "cc/layers/heads_up_display_layer_impl.h"
13#include "cc/layers/layer.h"
14#include "cc/layers/layer_proto_converter.h"
15#include "cc/proto/gfx_conversions.h"
16#include "cc/proto/layer_tree.pb.h"
17#include "cc/trees/layer_tree_host.h"
18#include "cc/trees/layer_tree_host_common.h"
19#include "cc/trees/layer_tree_impl.h"
20
xingliue43518a2016-07-28 23:59:4721namespace cc {
22
khushalsagar86928f92016-08-17 21:49:0523namespace {
24
25Layer* UpdateAndGetLayer(Layer* current_layer,
26 int layer_id,
27 LayerTree* layer_tree) {
28 if (layer_id == Layer::INVALID_ID) {
29 if (current_layer)
30 current_layer->SetLayerTreeHost(nullptr);
31
32 return nullptr;
33 }
34 Layer* layer = layer_tree->LayerById(layer_id);
35 DCHECK(layer);
36 if (current_layer && current_layer != layer)
37 current_layer->SetLayerTreeHost(nullptr);
38
39 return layer;
khushalsagar806556452016-08-17 01:36:2640}
41
khushalsagar86928f92016-08-17 21:49:0542} // namespace
43
44LayerTree::Inputs::Inputs()
45 : top_controls_height(0.f),
46 top_controls_shown_ratio(0.f),
47 top_controls_shrink_blink_size(false),
48 device_scale_factor(1.f),
49 painted_device_scale_factor(1.f),
50 page_scale_factor(1.f),
51 min_page_scale_factor(1.f),
52 max_page_scale_factor(1.f),
53 background_color(SK_ColorWHITE),
54 has_transparent_background(false),
55 have_scroll_event_handlers(false),
56 event_listener_properties() {}
57
58LayerTree::Inputs::~Inputs() = default;
59
60LayerTree::LayerTree(std::unique_ptr<AnimationHost> animation_host,
61 LayerTreeHost* layer_tree_host)
62 : needs_full_tree_sync_(true),
63 needs_meta_info_recomputation_(true),
64 in_paint_layer_contents_(false),
65 animation_host_(std::move(animation_host)),
66 layer_tree_host_(layer_tree_host) {
67 DCHECK(animation_host_);
68 DCHECK(layer_tree_host_);
69}
70
71LayerTree::~LayerTree() {
72 animation_host_->SetMutatorHostClient(nullptr);
73
74 // We must clear any pointers into the layer tree prior to destroying it.
75 RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr);
76
77 if (inputs_.root_layer) {
78 inputs_.root_layer->SetLayerTreeHost(nullptr);
79
80 // The root layer must be destroyed before the layer tree. We've made a
81 // contract with our animation controllers that the animation_host will
82 // outlive them, and we must make good.
83 inputs_.root_layer = nullptr;
84 }
85}
86
87void LayerTree::SetRootLayer(scoped_refptr<Layer> root_layer) {
88 if (inputs_.root_layer.get() == root_layer.get())
89 return;
90
91 if (inputs_.root_layer.get())
92 inputs_.root_layer->SetLayerTreeHost(nullptr);
93 inputs_.root_layer = root_layer;
94 if (inputs_.root_layer.get()) {
95 DCHECK(!inputs_.root_layer->parent());
96 inputs_.root_layer->SetLayerTreeHost(layer_tree_host_);
97 }
98
99 if (hud_layer_.get())
100 hud_layer_->RemoveFromParent();
101
102 // Reset gpu rasterization tracking.
103 // This flag is sticky until a new tree comes along.
104 layer_tree_host_->ResetGpuRasterizationTracking();
105
106 SetNeedsFullTreeSync();
107}
108
109void LayerTree::RegisterViewportLayers(
110 scoped_refptr<Layer> overscroll_elasticity_layer,
111 scoped_refptr<Layer> page_scale_layer,
112 scoped_refptr<Layer> inner_viewport_scroll_layer,
113 scoped_refptr<Layer> outer_viewport_scroll_layer) {
114 DCHECK(!inner_viewport_scroll_layer ||
115 inner_viewport_scroll_layer != outer_viewport_scroll_layer);
116 inputs_.overscroll_elasticity_layer = overscroll_elasticity_layer;
117 inputs_.page_scale_layer = page_scale_layer;
118 inputs_.inner_viewport_scroll_layer = inner_viewport_scroll_layer;
119 inputs_.outer_viewport_scroll_layer = outer_viewport_scroll_layer;
120}
121
122void LayerTree::RegisterSelection(const LayerSelection& selection) {
123 if (inputs_.selection == selection)
124 return;
125
126 inputs_.selection = selection;
127 SetNeedsCommit();
128}
129
130void LayerTree::SetHaveScrollEventHandlers(bool have_event_handlers) {
131 if (inputs_.have_scroll_event_handlers == have_event_handlers)
132 return;
133
134 inputs_.have_scroll_event_handlers = have_event_handlers;
135 SetNeedsCommit();
136}
137
138void LayerTree::SetEventListenerProperties(EventListenerClass event_class,
139 EventListenerProperties properties) {
140 const size_t index = static_cast<size_t>(event_class);
141 if (inputs_.event_listener_properties[index] == properties)
142 return;
143
144 inputs_.event_listener_properties[index] = properties;
145 SetNeedsCommit();
146}
147
148void LayerTree::SetViewportSize(const gfx::Size& device_viewport_size) {
149 if (inputs_.device_viewport_size == device_viewport_size)
150 return;
151
152 inputs_.device_viewport_size = device_viewport_size;
153
154 SetPropertyTreesNeedRebuild();
155 SetNeedsCommit();
156}
157
158void LayerTree::SetTopControlsHeight(float height, bool shrink) {
159 if (inputs_.top_controls_height == height &&
160 inputs_.top_controls_shrink_blink_size == shrink)
161 return;
162
163 inputs_.top_controls_height = height;
164 inputs_.top_controls_shrink_blink_size = shrink;
165 SetNeedsCommit();
166}
167
168void LayerTree::SetTopControlsShownRatio(float ratio) {
169 if (inputs_.top_controls_shown_ratio == ratio)
170 return;
171
172 inputs_.top_controls_shown_ratio = ratio;
173 SetNeedsCommit();
174}
175
176void LayerTree::SetPageScaleFactorAndLimits(float page_scale_factor,
177 float min_page_scale_factor,
178 float max_page_scale_factor) {
179 if (inputs_.page_scale_factor == page_scale_factor &&
180 inputs_.min_page_scale_factor == min_page_scale_factor &&
181 inputs_.max_page_scale_factor == max_page_scale_factor)
182 return;
183
184 inputs_.page_scale_factor = page_scale_factor;
185 inputs_.min_page_scale_factor = min_page_scale_factor;
186 inputs_.max_page_scale_factor = max_page_scale_factor;
187 SetPropertyTreesNeedRebuild();
188 SetNeedsCommit();
189}
190
191void LayerTree::StartPageScaleAnimation(const gfx::Vector2d& target_offset,
192 bool use_anchor,
193 float scale,
194 base::TimeDelta duration) {
195 inputs_.pending_page_scale_animation.reset(new PendingPageScaleAnimation(
196 target_offset, use_anchor, scale, duration));
197
198 SetNeedsCommit();
199}
200
201bool LayerTree::HasPendingPageScaleAnimation() const {
202 return !!inputs_.pending_page_scale_animation.get();
203}
204
205void LayerTree::SetDeviceScaleFactor(float device_scale_factor) {
206 if (inputs_.device_scale_factor == device_scale_factor)
207 return;
208 inputs_.device_scale_factor = device_scale_factor;
209
210 property_trees_.needs_rebuild = true;
211 SetNeedsCommit();
212}
213
214void LayerTree::SetPaintedDeviceScaleFactor(float painted_device_scale_factor) {
215 if (inputs_.painted_device_scale_factor == painted_device_scale_factor)
216 return;
217 inputs_.painted_device_scale_factor = painted_device_scale_factor;
218
219 SetNeedsCommit();
220}
xingliue43518a2016-07-28 23:59:47221
222void LayerTree::RegisterLayer(Layer* layer) {
223 DCHECK(!LayerById(layer->id()));
224 DCHECK(!in_paint_layer_contents_);
225 layer_id_map_[layer->id()] = layer;
226 if (layer->element_id()) {
227 animation_host_->RegisterElement(layer->element_id(),
228 ElementListType::ACTIVE);
229 }
230}
231
232void LayerTree::UnregisterLayer(Layer* layer) {
233 DCHECK(LayerById(layer->id()));
234 DCHECK(!in_paint_layer_contents_);
235 if (layer->element_id()) {
236 animation_host_->UnregisterElement(layer->element_id(),
237 ElementListType::ACTIVE);
238 }
239 RemoveLayerShouldPushProperties(layer);
240 layer_id_map_.erase(layer->id());
241}
242
243Layer* LayerTree::LayerById(int id) const {
244 LayerIdMap::const_iterator iter = layer_id_map_.find(id);
245 return iter != layer_id_map_.end() ? iter->second : nullptr;
246}
247
248bool LayerTree::UpdateLayers(const LayerList& update_layer_list,
249 bool* content_is_suitable_for_gpu) {
250 base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
251 bool did_paint_content = false;
252 for (const auto& layer : update_layer_list) {
253 did_paint_content |= layer->Update();
254 *content_is_suitable_for_gpu &= layer->IsSuitableForGpuRasterization();
255 }
256 return did_paint_content;
257}
258
259void LayerTree::AddLayerShouldPushProperties(Layer* layer) {
260 layers_that_should_push_properties_.insert(layer);
261}
262
263void LayerTree::RemoveLayerShouldPushProperties(Layer* layer) {
264 layers_that_should_push_properties_.erase(layer);
265}
266
267std::unordered_set<Layer*>& LayerTree::LayersThatShouldPushProperties() {
268 return layers_that_should_push_properties_;
269}
270
271bool LayerTree::LayerNeedsPushPropertiesForTesting(Layer* layer) const {
272 return layers_that_should_push_properties_.find(layer) !=
273 layers_that_should_push_properties_.end();
274}
275
khushalsagar86928f92016-08-17 21:49:05276void LayerTree::SetNeedsMetaInfoRecomputation(bool needs_recomputation) {
277 needs_meta_info_recomputation_ = needs_recomputation;
278}
279
280void LayerTree::SetPageScaleFromImplSide(float page_scale) {
281 DCHECK(layer_tree_host_->CommitRequested());
282 inputs_.page_scale_factor = page_scale;
283 SetPropertyTreesNeedRebuild();
284}
285
286void LayerTree::SetElasticOverscrollFromImplSide(
287 gfx::Vector2dF elastic_overscroll) {
288 DCHECK(layer_tree_host_->CommitRequested());
289 elastic_overscroll_ = elastic_overscroll;
290}
291
292void LayerTree::UpdateHudLayer(bool show_hud_info) {
293 if (show_hud_info) {
294 if (!hud_layer_.get()) {
295 hud_layer_ = HeadsUpDisplayLayer::Create();
296 }
297
298 if (inputs_.root_layer.get() && !hud_layer_->parent())
299 inputs_.root_layer->AddChild(hud_layer_);
300 } else if (hud_layer_.get()) {
301 hud_layer_->RemoveFromParent();
302 hud_layer_ = nullptr;
303 }
304}
305
306void LayerTree::SetNeedsFullTreeSync() {
307 needs_full_tree_sync_ = true;
308 needs_meta_info_recomputation_ = true;
309
310 property_trees_.needs_rebuild = true;
311 SetNeedsCommit();
312}
313
314void LayerTree::SetNeedsCommit() {
315 layer_tree_host_->SetNeedsCommit();
316}
317
318void LayerTree::SetPropertyTreesNeedRebuild() {
319 property_trees_.needs_rebuild = true;
320 layer_tree_host_->SetNeedsUpdateLayers();
321}
322
323void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl) {
324 tree_impl->set_needs_full_tree_sync(needs_full_tree_sync_);
325 needs_full_tree_sync_ = false;
326
327 if (hud_layer_.get()) {
328 LayerImpl* hud_impl = tree_impl->LayerById(hud_layer_->id());
329 tree_impl->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl));
330 } else {
331 tree_impl->set_hud_layer(nullptr);
332 }
333
334 tree_impl->set_background_color(inputs_.background_color);
335 tree_impl->set_has_transparent_background(inputs_.has_transparent_background);
336 tree_impl->set_have_scroll_event_handlers(inputs_.have_scroll_event_handlers);
337 tree_impl->set_event_listener_properties(
338 EventListenerClass::kTouchStartOrMove,
339 event_listener_properties(EventListenerClass::kTouchStartOrMove));
340 tree_impl->set_event_listener_properties(
341 EventListenerClass::kMouseWheel,
342 event_listener_properties(EventListenerClass::kMouseWheel));
343 tree_impl->set_event_listener_properties(
344 EventListenerClass::kTouchEndOrCancel,
345 event_listener_properties(EventListenerClass::kTouchEndOrCancel));
346
347 if (inputs_.page_scale_layer && inputs_.inner_viewport_scroll_layer) {
348 tree_impl->SetViewportLayersFromIds(
349 inputs_.overscroll_elasticity_layer
350 ? inputs_.overscroll_elasticity_layer->id()
351 : Layer::INVALID_ID,
352 inputs_.page_scale_layer->id(),
353 inputs_.inner_viewport_scroll_layer->id(),
354 inputs_.outer_viewport_scroll_layer
355 ? inputs_.outer_viewport_scroll_layer->id()
356 : Layer::INVALID_ID);
357 DCHECK(inputs_.inner_viewport_scroll_layer
358 ->IsContainerForFixedPositionLayers());
359 } else {
360 tree_impl->ClearViewportLayers();
361 }
362
363 tree_impl->RegisterSelection(inputs_.selection);
364
365 bool property_trees_changed_on_active_tree =
366 tree_impl->IsActiveTree() && tree_impl->property_trees()->changed;
367 // Property trees may store damage status. We preserve the sync tree damage
368 // status by pushing the damage status from sync tree property trees to main
369 // thread property trees or by moving it onto the layers.
370 if (inputs_.root_layer && property_trees_changed_on_active_tree) {
371 if (property_trees_.sequence_number ==
372 tree_impl->property_trees()->sequence_number)
373 tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_);
374 else
375 tree_impl->MoveChangeTrackingToLayers();
376 }
377 // Setting property trees must happen before pushing the page scale.
378 tree_impl->SetPropertyTrees(&property_trees_);
379
380 tree_impl->PushPageScaleFromMainThread(inputs_.page_scale_factor,
381 inputs_.min_page_scale_factor,
382 inputs_.max_page_scale_factor);
383
384 tree_impl->set_top_controls_shrink_blink_size(
385 inputs_.top_controls_shrink_blink_size);
386 tree_impl->set_top_controls_height(inputs_.top_controls_height);
387 tree_impl->PushTopControlsFromMainThread(inputs_.top_controls_shown_ratio);
388 tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_);
389 if (tree_impl->IsActiveTree())
390 tree_impl->elastic_overscroll()->PushPendingToActive();
391
392 tree_impl->set_painted_device_scale_factor(
393 inputs_.painted_device_scale_factor);
394
395 if (inputs_.pending_page_scale_animation) {
396 tree_impl->SetPendingPageScaleAnimation(
397 std::move(inputs_.pending_page_scale_animation));
398 }
399
400 DCHECK(!tree_impl->ViewportSizeInvalid());
401
402 tree_impl->set_has_ever_been_drawn(false);
403}
404
xingliue43518a2016-07-28 23:59:47405void LayerTree::ToProtobuf(proto::LayerTree* proto) {
khushalsagar86928f92016-08-17 21:49:05406 LayerProtoConverter::SerializeLayerHierarchy(inputs_.root_layer,
407 proto->mutable_root_layer());
408
xingliue43518a2016-07-28 23:59:47409 for (auto* layer : layers_that_should_push_properties_) {
410 proto->add_layers_that_should_push_properties(layer->id());
411 }
412 proto->set_in_paint_layer_contents(in_paint_layer_contents());
khushalsagar86928f92016-08-17 21:49:05413
414 proto->set_needs_full_tree_sync(needs_full_tree_sync_);
415 proto->set_needs_meta_info_recomputation(needs_meta_info_recomputation_);
416 proto->set_hud_layer_id(hud_layer_ ? hud_layer_->id() : Layer::INVALID_ID);
417
418 // Viewport layers.
419 proto->set_overscroll_elasticity_layer_id(
420 inputs_.overscroll_elasticity_layer
421 ? inputs_.overscroll_elasticity_layer->id()
422 : Layer::INVALID_ID);
423 proto->set_page_scale_layer_id(inputs_.page_scale_layer
424 ? inputs_.page_scale_layer->id()
425 : Layer::INVALID_ID);
426 proto->set_inner_viewport_scroll_layer_id(
427 inputs_.inner_viewport_scroll_layer
428 ? inputs_.inner_viewport_scroll_layer->id()
429 : Layer::INVALID_ID);
430 proto->set_outer_viewport_scroll_layer_id(
431 inputs_.outer_viewport_scroll_layer
432 ? inputs_.outer_viewport_scroll_layer->id()
433 : Layer::INVALID_ID);
434
435 SizeToProto(inputs_.device_viewport_size,
436 proto->mutable_device_viewport_size());
437 proto->set_top_controls_shrink_blink_size(
438 inputs_.top_controls_shrink_blink_size);
439 proto->set_top_controls_height(inputs_.top_controls_height);
440 proto->set_top_controls_shown_ratio(inputs_.top_controls_shown_ratio);
441 proto->set_device_scale_factor(inputs_.device_scale_factor);
442 proto->set_painted_device_scale_factor(inputs_.painted_device_scale_factor);
443 proto->set_page_scale_factor(inputs_.page_scale_factor);
444 proto->set_min_page_scale_factor(inputs_.min_page_scale_factor);
445 proto->set_max_page_scale_factor(inputs_.max_page_scale_factor);
446
447 proto->set_background_color(inputs_.background_color);
448 proto->set_has_transparent_background(inputs_.has_transparent_background);
449 proto->set_have_scroll_event_handlers(inputs_.have_scroll_event_handlers);
450 proto->set_wheel_event_listener_properties(static_cast<uint32_t>(
451 event_listener_properties(EventListenerClass::kMouseWheel)));
452 proto->set_touch_start_or_move_event_listener_properties(
453 static_cast<uint32_t>(
454 event_listener_properties(EventListenerClass::kTouchStartOrMove)));
455 proto->set_touch_end_or_cancel_event_listener_properties(
456 static_cast<uint32_t>(
457 event_listener_properties(EventListenerClass::kTouchEndOrCancel)));
458
459 LayerSelectionToProtobuf(inputs_.selection, proto->mutable_selection());
460 property_trees_.ToProtobuf(proto->mutable_property_trees());
xingliue43518a2016-07-28 23:59:47461}
462
463void LayerTree::FromProtobuf(const proto::LayerTree& proto) {
khushalsagar86928f92016-08-17 21:49:05464 // Layer hierarchy.
465 scoped_refptr<Layer> new_root_layer =
466 LayerProtoConverter::DeserializeLayerHierarchy(
467 inputs_.root_layer, proto.root_layer(), layer_tree_host_);
468 if (inputs_.root_layer != new_root_layer) {
469 inputs_.root_layer = new_root_layer;
470 }
471
xingliue43518a2016-07-28 23:59:47472 for (auto layer_id : proto.layers_that_should_push_properties()) {
473 AddLayerShouldPushProperties(layer_id_map_[layer_id]);
474 }
475 in_paint_layer_contents_ = proto.in_paint_layer_contents();
khushalsagar86928f92016-08-17 21:49:05476
477 needs_full_tree_sync_ = proto.needs_full_tree_sync();
478 needs_meta_info_recomputation_ = proto.needs_meta_info_recomputation();
479
480 inputs_.overscroll_elasticity_layer =
481 UpdateAndGetLayer(inputs_.overscroll_elasticity_layer.get(),
482 proto.overscroll_elasticity_layer_id(), this);
483 inputs_.page_scale_layer = UpdateAndGetLayer(
484 inputs_.page_scale_layer.get(), proto.page_scale_layer_id(), this);
485 inputs_.inner_viewport_scroll_layer =
486 UpdateAndGetLayer(inputs_.inner_viewport_scroll_layer.get(),
487 proto.inner_viewport_scroll_layer_id(), this);
488 inputs_.outer_viewport_scroll_layer =
489 UpdateAndGetLayer(inputs_.outer_viewport_scroll_layer.get(),
490 proto.outer_viewport_scroll_layer_id(), this);
491
492 inputs_.device_viewport_size = ProtoToSize(proto.device_viewport_size());
493 inputs_.top_controls_shrink_blink_size =
494 proto.top_controls_shrink_blink_size();
495 inputs_.top_controls_height = proto.top_controls_height();
496 inputs_.top_controls_shown_ratio = proto.top_controls_shown_ratio();
497 inputs_.device_scale_factor = proto.device_scale_factor();
498 inputs_.painted_device_scale_factor = proto.painted_device_scale_factor();
499 inputs_.page_scale_factor = proto.page_scale_factor();
500 inputs_.min_page_scale_factor = proto.min_page_scale_factor();
501 inputs_.max_page_scale_factor = proto.max_page_scale_factor();
502 inputs_.background_color = proto.background_color();
503 inputs_.has_transparent_background = proto.has_transparent_background();
504 inputs_.have_scroll_event_handlers = proto.have_scroll_event_handlers();
505 inputs_.event_listener_properties[static_cast<size_t>(
506 EventListenerClass::kMouseWheel)] =
507 static_cast<EventListenerProperties>(
508 proto.wheel_event_listener_properties());
509 inputs_.event_listener_properties[static_cast<size_t>(
510 EventListenerClass::kTouchStartOrMove)] =
511 static_cast<EventListenerProperties>(
512 proto.touch_start_or_move_event_listener_properties());
513 inputs_.event_listener_properties[static_cast<size_t>(
514 EventListenerClass::kTouchEndOrCancel)] =
515 static_cast<EventListenerProperties>(
516 proto.touch_end_or_cancel_event_listener_properties());
517
518 hud_layer_ = static_cast<HeadsUpDisplayLayer*>(
519 UpdateAndGetLayer(hud_layer_.get(), proto.hud_layer_id(), this));
520
521 LayerSelectionFromProtobuf(&inputs_.selection, proto.selection());
522
523 // It is required to create new PropertyTrees before deserializing it.
524 property_trees_ = PropertyTrees();
525 property_trees_.FromProtobuf(proto.property_trees());
526
527 // Forcefully override the sequence number of all layers in the tree to have
528 // a valid sequence number. Changing the sequence number for a layer does not
529 // need a commit, so the value will become out of date for layers that are not
530 // updated for other reasons. All layers that at this point are part of the
531 // layer tree are valid, so it is OK that they have a valid sequence number.
532 int seq_num = property_trees_.sequence_number;
533 LayerTreeHostCommon::CallFunctionForEveryLayer(
534 layer_tree_host_, [seq_num](Layer* layer) {
535 layer->set_property_tree_sequence_number(seq_num);
536 });
xingliue43518a2016-07-28 23:59:47537}
538
539} // namespace cc