1 // Copyright 2011 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/trees/layer_tree_impl.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <algorithm>
11 #include <iterator>
12 #include <limits>
13 #include <set>
14 
15 #include "base/containers/adapters.h"
16 #include "base/debug/crash_logging.h"
17 #include "base/debug/dump_without_crashing.h"
18 #include "base/json/json_writer.h"
19 #include "base/metrics/histogram_macros.h"
20 #include "base/numerics/ranges.h"
21 #include "base/stl_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/timer/elapsed_timer.h"
24 #include "base/trace_event/trace_event.h"
25 #include "base/trace_event/traced_value.h"
26 #include "cc/base/devtools_instrumentation.h"
27 #include "cc/base/histograms.h"
28 #include "cc/base/math_util.h"
29 #include "cc/base/synced_property.h"
30 #include "cc/input/page_scale_animation.h"
31 #include "cc/input/scrollbar_animation_controller.h"
32 #include "cc/layers/effect_tree_layer_list_iterator.h"
33 #include "cc/layers/heads_up_display_layer_impl.h"
34 #include "cc/layers/layer.h"
35 #include "cc/layers/render_surface_impl.h"
36 #include "cc/layers/scrollbar_layer_impl_base.h"
37 #include "cc/resources/ui_resource_request.h"
38 #include "cc/trees/clip_node.h"
39 #include "cc/trees/draw_property_utils.h"
40 #include "cc/trees/effect_node.h"
41 #include "cc/trees/layer_tree_frame_sink.h"
42 #include "cc/trees/layer_tree_host_impl.h"
43 #include "cc/trees/mutator_host.h"
44 #include "cc/trees/occlusion_tracker.h"
45 #include "cc/trees/property_tree.h"
46 #include "cc/trees/scroll_node.h"
47 #include "cc/trees/transform_node.h"
48 #include "components/viz/common/traced_value.h"
49 #include "ui/gfx/geometry/box_f.h"
50 #include "ui/gfx/geometry/point_conversions.h"
51 #include "ui/gfx/geometry/rect_conversions.h"
52 #include "ui/gfx/geometry/size_conversions.h"
53 #include "ui/gfx/geometry/vector2d_conversions.h"
54 
55 namespace cc {
56 namespace {
57 // Small helper class that saves the current viewport location as the user sees
58 // it and resets to the same location.
59 class ViewportAnchor {
60  public:
ViewportAnchor(ScrollNode * inner_scroll,ScrollNode * outer_scroll,LayerTreeImpl * tree_impl)61   ViewportAnchor(ScrollNode* inner_scroll,
62                  ScrollNode* outer_scroll,
63                  LayerTreeImpl* tree_impl)
64       : inner_(inner_scroll), outer_(outer_scroll), tree_impl_(tree_impl) {
65     viewport_in_content_coordinates_ =
66         scroll_tree().current_scroll_offset(inner_->element_id);
67 
68     if (outer_) {
69       viewport_in_content_coordinates_ +=
70           scroll_tree().current_scroll_offset(outer_->element_id);
71     }
72   }
73 
ResetViewportToAnchoredPosition()74   void ResetViewportToAnchoredPosition() {
75     DCHECK(outer_);
76 
77     scroll_tree().ClampScrollToMaxScrollOffset(*inner_, tree_impl_);
78     scroll_tree().ClampScrollToMaxScrollOffset(*outer_, tree_impl_);
79 
80     gfx::ScrollOffset viewport_location =
81         scroll_tree().current_scroll_offset(inner_->element_id) +
82         scroll_tree().current_scroll_offset(outer_->element_id);
83 
84     gfx::Vector2dF delta =
85         viewport_in_content_coordinates_.DeltaFrom(viewport_location);
86 
87     delta = scroll_tree().ScrollBy(*inner_, delta, tree_impl_);
88     scroll_tree().ScrollBy(*outer_, delta, tree_impl_);
89   }
90 
91  private:
scroll_tree()92   ScrollTree& scroll_tree() {
93     return tree_impl_->property_trees()->scroll_tree;
94   }
95 
96   ScrollNode* inner_;
97   ScrollNode* outer_;
98   LayerTreeImpl* tree_impl_;
99   gfx::ScrollOffset viewport_in_content_coordinates_;
100 };
101 
GetVisibleSelectionEndPoints(const gfx::RectF & rect,const gfx::PointF & top,const gfx::PointF & bottom)102 std::pair<gfx::PointF, gfx::PointF> GetVisibleSelectionEndPoints(
103     const gfx::RectF& rect,
104     const gfx::PointF& top,
105     const gfx::PointF& bottom) {
106   gfx::PointF start(base::ClampToRange(top.x(), rect.x(), rect.right()),
107                     base::ClampToRange(top.y(), rect.y(), rect.bottom()));
108   gfx::PointF end =
109       start + gfx::Vector2dF(bottom.x() - top.x(), bottom.y() - top.y());
110   return {start, end};
111 }
112 
113 }  // namespace
114 
AdvanceTo(LifecycleState next_state)115 void LayerTreeLifecycle::AdvanceTo(LifecycleState next_state) {
116   switch (next_state) {
117     case (kNotSyncing):
118       DCHECK_EQ(state_, kLastSyncState);
119       break;
120     case (kBeginningSync):
121     case (kSyncedPropertyTrees):
122     case (kSyncedLayerProperties):
123       // Only allow tree synchronization states to be transitioned in order.
124       DCHECK_EQ(state_ + 1, next_state);
125       break;
126   }
127   state_ = next_state;
128 }
129 
LayerTreeImpl(LayerTreeHostImpl * host_impl,scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio,scoped_refptr<SyncedBrowserControls> bottom_controls_shown_ratio,scoped_refptr<SyncedElasticOverscroll> elastic_overscroll)130 LayerTreeImpl::LayerTreeImpl(
131     LayerTreeHostImpl* host_impl,
132     scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
133     scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio,
134     scoped_refptr<SyncedBrowserControls> bottom_controls_shown_ratio,
135     scoped_refptr<SyncedElasticOverscroll> elastic_overscroll)
136     : host_impl_(host_impl),
137       source_frame_number_(-1),
138       is_first_frame_after_commit_tracker_(-1),
139       hud_layer_(nullptr),
140       background_color_(0),
141       last_scrolled_scroll_node_index_(ScrollTree::kInvalidNodeId),
142       page_scale_factor_(page_scale_factor),
143       min_page_scale_factor_(0),
144       max_page_scale_factor_(0),
145       external_page_scale_factor_(1.f),
146       device_scale_factor_(1.f),
147       painted_device_scale_factor_(1.f),
148       elastic_overscroll_(elastic_overscroll),
149       needs_update_draw_properties_(true),
150       scrollbar_geometries_need_update_(false),
151       needs_full_tree_sync_(true),
152       needs_surface_ranges_sync_(false),
153       next_activation_forces_redraw_(false),
154       has_ever_been_drawn_(false),
155       handle_visibility_changed_(false),
156       have_scroll_event_handlers_(false),
157       event_listener_properties_(),
158       top_controls_shown_ratio_(std::move(top_controls_shown_ratio)),
159       bottom_controls_shown_ratio_(std::move(bottom_controls_shown_ratio)) {
160   property_trees()->is_main_thread = false;
161 }
162 
~LayerTreeImpl()163 LayerTreeImpl::~LayerTreeImpl() {
164   // Need to explicitly clear the tree prior to destroying this so that
165   // the LayerTreeImpl pointer is still valid in the LayerImpl dtor.
166   DCHECK(LayerListIsEmpty());
167 }
168 
Shutdown()169 void LayerTreeImpl::Shutdown() {
170   DetachLayers();
171   BreakSwapPromises(IsActiveTree() ? SwapPromise::SWAP_FAILS
172                                    : SwapPromise::ACTIVATION_FAILS);
173   DCHECK(LayerListIsEmpty());
174 }
175 
ReleaseResources()176 void LayerTreeImpl::ReleaseResources() {
177   for (auto* layer : *this)
178     layer->ReleaseResources();
179 }
180 
OnPurgeMemory()181 void LayerTreeImpl::OnPurgeMemory() {
182   for (auto* layer : *this)
183     layer->OnPurgeMemory();
184 }
185 
ReleaseTileResources()186 void LayerTreeImpl::ReleaseTileResources() {
187   for (auto* layer : *this)
188     layer->ReleaseTileResources();
189 }
190 
RecreateTileResources()191 void LayerTreeImpl::RecreateTileResources() {
192   for (auto* layer : *this)
193     layer->RecreateTileResources();
194 }
195 
DidUpdateScrollOffset(ElementId id)196 void LayerTreeImpl::DidUpdateScrollOffset(ElementId id) {
197   // Scrollbar positions depend on the current scroll offset.
198   SetScrollbarGeometriesNeedUpdate();
199 
200   DCHECK(lifecycle().AllowsPropertyTreeAccess());
201   ScrollTree& scroll_tree = property_trees()->scroll_tree;
202   const auto* scroll_node = scroll_tree.FindNodeFromElementId(id);
203 
204   if (!scroll_node) {
205     // A scroll node should always exist on the active tree but may not exist
206     // if we're updating the other trees from the active tree. This can occur
207     // when the pending tree represents a different page, for example.
208     DCHECK(!IsActiveTree());
209     return;
210   }
211 
212   DCHECK(scroll_node->transform_id != TransformTree::kInvalidNodeId);
213   TransformTree& transform_tree = property_trees()->transform_tree;
214   auto* transform_node = transform_tree.Node(scroll_node->transform_id);
215   if (transform_node->scroll_offset != scroll_tree.current_scroll_offset(id)) {
216     transform_node->scroll_offset = scroll_tree.current_scroll_offset(id);
217     transform_node->needs_local_transform_update = true;
218     transform_tree.set_needs_update(true);
219   }
220   transform_node->transform_changed = true;
221   property_trees()->changed = true;
222   set_needs_update_draw_properties();
223 
224   if (IsActiveTree()) {
225     // Ensure the other trees are kept in sync.
226     if (host_impl_->pending_tree())
227       host_impl_->pending_tree()->DidUpdateScrollOffset(id);
228     if (host_impl_->recycle_tree())
229       host_impl_->recycle_tree()->DidUpdateScrollOffset(id);
230   }
231 }
232 
UpdateScrollbarGeometries()233 void LayerTreeImpl::UpdateScrollbarGeometries() {
234   if (!IsActiveTree())
235     return;
236 
237   DCHECK(lifecycle().AllowsPropertyTreeAccess());
238 
239   // Layer properties such as bounds should be up-to-date.
240   DCHECK(lifecycle().AllowsLayerPropertyAccess());
241 
242   if (!scrollbar_geometries_need_update_)
243     return;
244 
245   for (auto& pair : element_id_to_scrollbar_layer_ids_) {
246     ElementId scrolling_element_id = pair.first;
247 
248     auto& scroll_tree = property_trees()->scroll_tree;
249     auto* scroll_node = scroll_tree.FindNodeFromElementId(scrolling_element_id);
250     if (!scroll_node)
251       continue;
252     gfx::ScrollOffset current_offset =
253         scroll_tree.current_scroll_offset(scrolling_element_id);
254     gfx::SizeF scrolling_size(scroll_node->bounds);
255     gfx::Size bounds_size(scroll_tree.container_bounds(scroll_node->id));
256 
257     bool is_viewport_scrollbar = scroll_node == InnerViewportScrollNode() ||
258                                  scroll_node == OuterViewportScrollNode();
259     if (is_viewport_scrollbar) {
260       gfx::SizeF viewport_bounds(bounds_size);
261       if (scroll_node == InnerViewportScrollNode()) {
262         DCHECK_EQ(scroll_node, InnerViewportScrollNode());
263         auto* outer_scroll_node = OuterViewportScrollNode();
264         DCHECK(outer_scroll_node);
265 
266         // Add offset and bounds contribution of outer viewport.
267         current_offset +=
268             scroll_tree.current_scroll_offset(outer_scroll_node->element_id);
269         gfx::SizeF outer_viewport_bounds(
270             scroll_tree.container_bounds(outer_scroll_node->id));
271         viewport_bounds.SetToMin(outer_viewport_bounds);
272         // The scrolling size is only determined by the outer viewport.
273         scrolling_size = gfx::SizeF(outer_scroll_node->bounds);
274       } else {
275         DCHECK_EQ(scroll_node, OuterViewportScrollNode());
276         auto* inner_scroll_node = InnerViewportScrollNode();
277         DCHECK(inner_scroll_node);
278         // Add offset and bounds contribution of inner viewport.
279         current_offset +=
280             scroll_tree.current_scroll_offset(inner_scroll_node->element_id);
281         gfx::SizeF inner_viewport_bounds(
282             scroll_tree.container_bounds(inner_scroll_node->id));
283         viewport_bounds.SetToMin(inner_viewport_bounds);
284       }
285       viewport_bounds.Scale(1 / current_page_scale_factor());
286       bounds_size = ToCeiledSize(viewport_bounds);
287     }
288 
289     for (auto* scrollbar : ScrollbarsFor(scrolling_element_id)) {
290       if (scrollbar->orientation() == HORIZONTAL) {
291         scrollbar->SetCurrentPos(current_offset.x());
292         scrollbar->SetClipLayerLength(bounds_size.width());
293         scrollbar->SetScrollLayerLength(scrolling_size.width());
294       } else {
295         scrollbar->SetCurrentPos(current_offset.y());
296         scrollbar->SetClipLayerLength(bounds_size.height());
297         scrollbar->SetScrollLayerLength(scrolling_size.height());
298       }
299       if (is_viewport_scrollbar) {
300         scrollbar->SetVerticalAdjust(
301             property_trees_.inner_viewport_container_bounds_delta().y());
302       }
303     }
304   }
305 
306   scrollbar_geometries_need_update_ = false;
307 }
308 
RootRenderSurface() const309 const RenderSurfaceImpl* LayerTreeImpl::RootRenderSurface() const {
310   return property_trees_.effect_tree.GetRenderSurface(
311       EffectTree::kContentsRootNodeId);
312 }
313 
LayerListIsEmpty() const314 bool LayerTreeImpl::LayerListIsEmpty() const {
315   return layer_list_.empty();
316 }
317 
SetRootLayerForTesting(std::unique_ptr<LayerImpl> layer)318 void LayerTreeImpl::SetRootLayerForTesting(std::unique_ptr<LayerImpl> layer) {
319   DetachLayers();
320   if (layer)
321     AddLayer(std::move(layer));
322   host_impl_->OnCanDrawStateChangedForTree();
323 }
324 
OnCanDrawStateChangedForTree()325 void LayerTreeImpl::OnCanDrawStateChangedForTree() {
326   host_impl_->OnCanDrawStateChangedForTree();
327 }
328 
InvalidateRegionForImages(const PaintImageIdFlatSet & images_to_invalidate)329 void LayerTreeImpl::InvalidateRegionForImages(
330     const PaintImageIdFlatSet& images_to_invalidate) {
331   TRACE_EVENT_BEGIN1("cc", "LayerTreeImpl::InvalidateRegionForImages",
332                      "total_layer_count", picture_layers_.size());
333   DCHECK(IsSyncTree());
334 
335   size_t no_images_count = 0;
336   size_t no_invalidation_count = 0;
337   size_t invalidated_count = 0;
338   if (!images_to_invalidate.empty()) {
339     // TODO(khushalsagar): It might be better to keep track of layers with
340     // images and only iterate through those here.
341     for (auto* picture_layer : picture_layers_) {
342       auto result =
343           picture_layer->InvalidateRegionForImages(images_to_invalidate);
344       switch (result) {
345         case PictureLayerImpl::ImageInvalidationResult::kNoImages:
346           ++no_images_count;
347           break;
348         case PictureLayerImpl::ImageInvalidationResult::kNoInvalidation:
349           ++no_invalidation_count;
350           break;
351         case PictureLayerImpl::ImageInvalidationResult::kInvalidated:
352           ++invalidated_count;
353           break;
354       }
355     }
356   }
357   TRACE_EVENT_END1(
358       "cc", "LayerTreeImpl::InvalidateRegionForImages", "counts",
359       base::StringPrintf("no_images[%zu] no_invalidaton[%zu] invalidated[%zu]",
360                          no_images_count, no_invalidation_count,
361                          invalidated_count));
362 }
363 
UpdateViewportContainerSizes()364 void LayerTreeImpl::UpdateViewportContainerSizes() {
365   if (!InnerViewportScrollNode())
366     return;
367 
368   DCHECK(OuterViewportScrollNode());
369   ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollNode(),
370                         this);
371 
372   float top_controls_shown_ratio =
373       top_controls_shown_ratio_->Current(IsActiveTree());
374   float bottom_controls_shown_ratio =
375       bottom_controls_shown_ratio_->Current(IsActiveTree());
376   float top_controls_layout_height = browser_controls_shrink_blink_size()
377                                          ? top_controls_height()
378                                          : top_controls_min_height();
379   float top_content_offset =
380       top_controls_height() > 0
381           ? top_controls_height() * top_controls_shown_ratio
382           : 0.f;
383   float delta_from_top_controls =
384       top_controls_layout_height - top_content_offset;
385   float bottom_controls_layout_height = browser_controls_shrink_blink_size()
386                                             ? bottom_controls_height()
387                                             : bottom_controls_min_height();
388   float bottom_content_offset =
389       bottom_controls_height() > 0
390           ? bottom_controls_height() * bottom_controls_shown_ratio
391           : 0.f;
392   delta_from_top_controls +=
393       bottom_controls_layout_height - bottom_content_offset;
394 
395   // Adjust the viewport layers by shrinking/expanding the container to account
396   // for changes in the size (e.g. browser controls) since the last resize from
397   // Blink.
398   auto* property_trees = this->property_trees();
399   gfx::Vector2dF bounds_delta(0.f, delta_from_top_controls);
400   if (property_trees->inner_viewport_container_bounds_delta() == bounds_delta)
401     return;
402 
403   property_trees->SetInnerViewportContainerBoundsDelta(bounds_delta);
404 
405   // Adjust the outer viewport container as well, since adjusting only the
406   // inner may cause its bounds to exceed those of the outer, causing scroll
407   // clamping.
408   gfx::Vector2dF scaled_bounds_delta =
409       gfx::ScaleVector2d(bounds_delta, 1.f / min_page_scale_factor());
410 
411   property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta);
412   // outer_viewport_container_bounds_delta and
413   // inner_viewport_scroll_bounds_delta are the same thing.
414   DCHECK_EQ(scaled_bounds_delta,
415             property_trees->inner_viewport_scroll_bounds_delta());
416 
417   if (auto* outer_clip_node = OuterViewportClipNode()) {
418     float adjusted_container_height =
419         OuterViewportScrollNode()->container_bounds.height() +
420         scaled_bounds_delta.y();
421     outer_clip_node->clip.set_height(adjusted_container_height);
422   }
423 
424   anchor.ResetViewportToAnchoredPosition();
425 
426   property_trees->clip_tree.set_needs_update(true);
427   property_trees->full_tree_damaged = true;
428   set_needs_update_draw_properties();
429 
430   // Viewport scrollbar positions are determined using the viewport bounds
431   // delta.
432   SetScrollbarGeometriesNeedUpdate();
433   set_needs_update_draw_properties();
434 }
435 
IsRootLayer(const LayerImpl * layer) const436 bool LayerTreeImpl::IsRootLayer(const LayerImpl* layer) const {
437   return !layer_list_.empty() && layer_list_[0].get() == layer;
438 }
439 
TotalScrollOffset() const440 gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const {
441   gfx::ScrollOffset offset;
442   const auto& scroll_tree = property_trees()->scroll_tree;
443 
444   if (auto* inner_scroll = InnerViewportScrollNode()) {
445     offset += scroll_tree.current_scroll_offset(inner_scroll->element_id);
446     DCHECK(OuterViewportScrollNode());
447     offset += scroll_tree.current_scroll_offset(
448         OuterViewportScrollNode()->element_id);
449   }
450 
451   return offset;
452 }
453 
TotalMaxScrollOffset() const454 gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const {
455   gfx::ScrollOffset offset;
456   const auto& scroll_tree = property_trees()->scroll_tree;
457 
458   if (viewport_property_ids_.inner_scroll != ScrollTree::kInvalidNodeId)
459     offset += scroll_tree.MaxScrollOffset(viewport_property_ids_.inner_scroll);
460 
461   if (viewport_property_ids_.outer_scroll != ScrollTree::kInvalidNodeId)
462     offset += scroll_tree.MaxScrollOffset(viewport_property_ids_.outer_scroll);
463 
464   return offset;
465 }
466 
DetachLayers()467 OwnedLayerImplList LayerTreeImpl::DetachLayers() {
468   render_surface_list_.clear();
469   set_needs_update_draw_properties();
470   return std::move(layer_list_);
471 }
472 
DetachLayersKeepingRootLayerForTesting()473 OwnedLayerImplList LayerTreeImpl::DetachLayersKeepingRootLayerForTesting() {
474   auto layers = DetachLayers();
475   SetRootLayerForTesting(std::move(layers[0]));
476   return layers;
477 }
478 
SetPropertyTrees(PropertyTrees * property_trees)479 void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) {
480   std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces;
481   property_trees_.effect_tree.TakeRenderSurfaces(&old_render_surfaces);
482   property_trees_ = *property_trees;
483   bool render_surfaces_changed =
484       property_trees_.effect_tree.CreateOrReuseRenderSurfaces(
485           &old_render_surfaces, this);
486   if (render_surfaces_changed)
487     set_needs_update_draw_properties();
488   property_trees->effect_tree.PushCopyRequestsTo(&property_trees_.effect_tree);
489   property_trees_.is_main_thread = false;
490   property_trees_.is_active = IsActiveTree();
491   // The value of some effect node properties (like is_drawn) depends on
492   // whether we are on the active tree or not. So, we need to update the
493   // effect tree.
494   if (IsActiveTree())
495     property_trees_.effect_tree.set_needs_update(true);
496 }
497 
PushPropertyTreesTo(LayerTreeImpl * target_tree)498 void LayerTreeImpl::PushPropertyTreesTo(LayerTreeImpl* target_tree) {
499   TRACE_EVENT0("cc", "LayerTreeImpl::PushPropertyTreesTo");
500   // Property trees may store damage status. We preserve the active tree
501   // damage status by pushing the damage status from active tree property
502   // trees to pending tree property trees or by moving it onto the layers.
503   if (target_tree->property_trees()->changed) {
504     if (property_trees()->sequence_number ==
505         target_tree->property_trees()->sequence_number)
506       target_tree->property_trees()->PushChangeTrackingTo(property_trees());
507     else
508       target_tree->MoveChangeTrackingToLayers();
509   }
510 
511   // To maintain the current scrolling node we need to use element ids which
512   // are stable across the property tree update in SetPropertyTrees.
513   ElementId scrolling_element_id;
514   if (ScrollNode* scrolling_node = target_tree->CurrentlyScrollingNode())
515     scrolling_element_id = scrolling_node->element_id;
516 
517   target_tree->SetPropertyTrees(&property_trees_);
518 
519   const ScrollNode* scrolling_node = nullptr;
520   if (scrolling_element_id) {
521     auto& scroll_tree = target_tree->property_trees()->scroll_tree;
522     scrolling_node = scroll_tree.FindNodeFromElementId(scrolling_element_id);
523   }
524   target_tree->SetCurrentlyScrollingNode(scrolling_node);
525 
526   std::vector<EventMetrics> events_metrics;
527   events_metrics.swap(events_metrics_from_main_thread_);
528   target_tree->AppendEventsMetricsFromMainThread(std::move(events_metrics));
529 }
530 
PushSurfaceRangesTo(LayerTreeImpl * target_tree)531 void LayerTreeImpl::PushSurfaceRangesTo(LayerTreeImpl* target_tree) {
532   if (needs_surface_ranges_sync()) {
533     target_tree->ClearSurfaceRanges();
534     target_tree->SetSurfaceRanges(SurfaceRanges());
535     // Reset for next update
536     set_needs_surface_ranges_sync(false);
537   }
538 }
539 
PushPropertiesTo(LayerTreeImpl * target_tree)540 void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
541   TRACE_EVENT0("cc", "LayerTreeImpl::PushPropertiesTo");
542   // The request queue should have been processed and does not require a push.
543   DCHECK_EQ(ui_resource_request_queue_.size(), 0u);
544 
545   PushSurfaceRangesTo(target_tree);
546   target_tree->property_trees()->scroll_tree.PushScrollUpdatesFromPendingTree(
547       &property_trees_, target_tree);
548 
549   if (next_activation_forces_redraw_) {
550     target_tree->ForceRedrawNextActivation();
551     next_activation_forces_redraw_ = false;
552   }
553 
554   target_tree->PassSwapPromises(std::move(swap_promise_list_));
555   swap_promise_list_.clear();
556 
557   // The page scale factor update can affect scrolling which requires that
558   // these ids are set, so this must be before PushPageScaleFactorAndLimits.
559   // Setting browser controls below also needs viewport scroll properties.
560   target_tree->SetViewportPropertyIds(viewport_property_ids_);
561 
562   // Active tree already shares the page_scale_factor object with pending
563   // tree so only the limits need to be provided.
564   target_tree->PushPageScaleFactorAndLimits(nullptr, min_page_scale_factor(),
565                                             max_page_scale_factor());
566   target_tree->SetExternalPageScaleFactor(external_page_scale_factor_);
567 
568   target_tree->SetBrowserControlsParams(browser_controls_params_);
569   target_tree->PushBrowserControls(nullptr, nullptr);
570 
571   target_tree->set_overscroll_behavior(overscroll_behavior_);
572 
573   target_tree->SetRasterColorSpace(raster_color_space_);
574   target_tree->elastic_overscroll()->PushPendingToActive();
575 
576   target_tree->set_painted_device_scale_factor(painted_device_scale_factor());
577   target_tree->SetDeviceScaleFactor(device_scale_factor());
578   target_tree->SetDeviceViewportRect(device_viewport_rect_);
579 
580   if (TakeNewLocalSurfaceIdRequest())
581     target_tree->RequestNewLocalSurfaceId();
582   target_tree->SetLocalSurfaceIdAllocationFromParent(
583       local_surface_id_allocation_from_parent());
584 
585   target_tree->pending_page_scale_animation_ =
586       std::move(pending_page_scale_animation_);
587 
588   if (TakeForceSendMetadataRequest())
589     target_tree->RequestForceSendMetadata();
590 
591   target_tree->RegisterSelection(selection_);
592 
593   // This should match the property synchronization in
594   // LayerTreeHost::finishCommitOnImplThread().
595   target_tree->set_source_frame_number(source_frame_number());
596   target_tree->set_background_color(background_color());
597   target_tree->set_have_scroll_event_handlers(have_scroll_event_handlers());
598   target_tree->set_event_listener_properties(
599       EventListenerClass::kTouchStartOrMove,
600       event_listener_properties(EventListenerClass::kTouchStartOrMove));
601   target_tree->set_event_listener_properties(
602       EventListenerClass::kMouseWheel,
603       event_listener_properties(EventListenerClass::kMouseWheel));
604   target_tree->set_event_listener_properties(
605       EventListenerClass::kTouchEndOrCancel,
606       event_listener_properties(EventListenerClass::kTouchEndOrCancel));
607 
608   if (hud_layer())
609     target_tree->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(
610         target_tree->LayerById(hud_layer()->id())));
611   else
612     target_tree->set_hud_layer(nullptr);
613 
614   target_tree->has_ever_been_drawn_ = false;
615 
616   // Note: this needs to happen after SetPropertyTrees.
617   target_tree->HandleTickmarksVisibilityChange();
618   target_tree->HandleScrollbarShowRequestsFromMain();
619   target_tree->AddPresentationCallbacks(std::move(presentation_callbacks_));
620   presentation_callbacks_.clear();
621 }
622 
HandleTickmarksVisibilityChange()623 void LayerTreeImpl::HandleTickmarksVisibilityChange() {
624   if (!host_impl_->OuterViewportScrollNode())
625     return;
626 
627   ScrollbarAnimationController* controller =
628       host_impl_->ScrollbarAnimationControllerForElementId(
629           host_impl_->OuterViewportScrollNode()->element_id);
630 
631   if (!controller)
632     return;
633 
634   for (ScrollbarLayerImplBase* scrollbar : controller->Scrollbars()) {
635     if (scrollbar->orientation() != VERTICAL)
636       continue;
637 
638     // Android Overlay Scrollbar don't have FindInPage Tickmarks.
639     if (scrollbar->GetScrollbarAnimator() != LayerTreeSettings::AURA_OVERLAY)
640       DCHECK(!scrollbar->HasFindInPageTickmarks());
641 
642     controller->UpdateTickmarksVisibility(scrollbar->HasFindInPageTickmarks());
643   }
644 }
645 
HandleScrollbarShowRequestsFromMain()646 void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() {
647   for (auto* layer : *this) {
648     if (!layer->needs_show_scrollbars())
649       continue;
650     ScrollbarAnimationController* controller =
651         host_impl_->ScrollbarAnimationControllerForElementId(
652             layer->element_id());
653     if (controller) {
654       controller->DidRequestShowFromMainThread();
655       layer->set_needs_show_scrollbars(false);
656     }
657   }
658 }
659 
MoveChangeTrackingToLayers()660 void LayerTreeImpl::MoveChangeTrackingToLayers() {
661   // We need to update the change tracking on property trees before we move it
662   // onto the layers.
663   property_trees_.UpdateChangeTracking();
664   for (auto* layer : *this) {
665     if (layer->LayerPropertyChangedFromPropertyTrees())
666       layer->NoteLayerPropertyChangedFromPropertyTrees();
667   }
668   EffectTree& effect_tree = property_trees_.effect_tree;
669   for (int id = EffectTree::kContentsRootNodeId;
670        id < static_cast<int>(effect_tree.size()); ++id) {
671     RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(id);
672     if (render_surface && render_surface->AncestorPropertyChanged())
673       render_surface->NoteAncestorPropertyChanged();
674   }
675 }
676 
ForceRecalculateRasterScales()677 void LayerTreeImpl::ForceRecalculateRasterScales() {
678   for (auto* layer : picture_layers_)
679     layer->ResetRasterScale();
680 }
681 
IsElementInPropertyTree(ElementId element_id) const682 bool LayerTreeImpl::IsElementInPropertyTree(ElementId element_id) const {
683   return property_trees()->HasElement(element_id);
684 }
685 
GetElementTypeForAnimation() const686 ElementListType LayerTreeImpl::GetElementTypeForAnimation() const {
687   return IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING;
688 }
689 
AddToElementLayerList(ElementId element_id,LayerImpl * layer)690 void LayerTreeImpl::AddToElementLayerList(ElementId element_id,
691                                           LayerImpl* layer) {
692   if (!element_id)
693     return;
694 
695   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("layer-element"),
696                "LayerTreeImpl::AddToElementLayerList", "element",
697                element_id.ToString());
698 
699   if (!settings().use_layer_lists) {
700     host_impl_->mutator_host()->RegisterElementId(element_id,
701                                                   GetElementTypeForAnimation());
702   }
703 }
704 
RemoveFromElementLayerList(ElementId element_id)705 void LayerTreeImpl::RemoveFromElementLayerList(ElementId element_id) {
706   if (!element_id)
707     return;
708 
709   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("layer-element"),
710                "LayerTreeImpl::RemoveFromElementLayerList", "element",
711                element_id.ToString());
712 
713   if (!settings().use_layer_lists) {
714     host_impl_->mutator_host()->UnregisterElementId(
715         element_id, GetElementTypeForAnimation());
716   }
717 }
718 
SetTransformMutated(ElementId element_id,const gfx::Transform & transform)719 void LayerTreeImpl::SetTransformMutated(ElementId element_id,
720                                         const gfx::Transform& transform) {
721   DCHECK_EQ(1u, property_trees()->element_id_to_transform_node_index.count(
722                     element_id));
723   if (IsSyncTree() || IsRecycleTree())
724     element_id_to_transform_animations_[element_id] = transform;
725   if (property_trees()->transform_tree.OnTransformAnimated(element_id,
726                                                            transform))
727     set_needs_update_draw_properties();
728 }
729 
SetOpacityMutated(ElementId element_id,float opacity)730 void LayerTreeImpl::SetOpacityMutated(ElementId element_id, float opacity) {
731   DCHECK_EQ(
732       1u, property_trees()->element_id_to_effect_node_index.count(element_id));
733   if (IsSyncTree() || IsRecycleTree())
734     element_id_to_opacity_animations_[element_id] = opacity;
735   if (property_trees()->effect_tree.OnOpacityAnimated(element_id, opacity))
736     set_needs_update_draw_properties();
737 }
738 
SetFilterMutated(ElementId element_id,const FilterOperations & filters)739 void LayerTreeImpl::SetFilterMutated(ElementId element_id,
740                                      const FilterOperations& filters) {
741   DCHECK_EQ(
742       1u, property_trees()->element_id_to_effect_node_index.count(element_id));
743   if (IsSyncTree() || IsRecycleTree())
744     element_id_to_filter_animations_[element_id] = filters;
745   if (property_trees()->effect_tree.OnFilterAnimated(element_id, filters))
746     set_needs_update_draw_properties();
747 }
748 
SetBackdropFilterMutated(ElementId element_id,const FilterOperations & backdrop_filters)749 void LayerTreeImpl::SetBackdropFilterMutated(
750     ElementId element_id,
751     const FilterOperations& backdrop_filters) {
752   DCHECK_EQ(
753       1u, property_trees()->element_id_to_effect_node_index.count(element_id));
754   if (IsSyncTree() || IsRecycleTree())
755     element_id_to_backdrop_filter_animations_[element_id] = backdrop_filters;
756   if (property_trees()->effect_tree.OnBackdropFilterAnimated(element_id,
757                                                              backdrop_filters))
758     set_needs_update_draw_properties();
759 }
760 
AddPresentationCallbacks(std::vector<LayerTreeHost::PresentationTimeCallback> callbacks)761 void LayerTreeImpl::AddPresentationCallbacks(
762     std::vector<LayerTreeHost::PresentationTimeCallback> callbacks) {
763   std::copy(std::make_move_iterator(callbacks.begin()),
764             std::make_move_iterator(callbacks.end()),
765             std::back_inserter(presentation_callbacks_));
766 }
767 
768 std::vector<LayerTreeHost::PresentationTimeCallback>
TakePresentationCallbacks()769 LayerTreeImpl::TakePresentationCallbacks() {
770   std::vector<LayerTreeHost::PresentationTimeCallback> callbacks;
771   callbacks.swap(presentation_callbacks_);
772   return callbacks;
773 }
774 
InnerViewportScrollLayerForTesting() const775 LayerImpl* LayerTreeImpl::InnerViewportScrollLayerForTesting() const {
776   if (auto* scroll_node = InnerViewportScrollNode())
777     return LayerByElementId(scroll_node->element_id);
778   return nullptr;
779 }
780 
OuterViewportScrollLayerForTesting() const781 LayerImpl* LayerTreeImpl::OuterViewportScrollLayerForTesting() const {
782   if (auto* scroll_node = OuterViewportScrollNode())
783     return LayerByElementId(scroll_node->element_id);
784   return nullptr;
785 }
786 
CurrentlyScrollingNode()787 ScrollNode* LayerTreeImpl::CurrentlyScrollingNode() {
788   DCHECK(IsActiveTree());
789   return property_trees_.scroll_tree.CurrentlyScrollingNode();
790 }
791 
CurrentlyScrollingNode() const792 const ScrollNode* LayerTreeImpl::CurrentlyScrollingNode() const {
793   return property_trees_.scroll_tree.CurrentlyScrollingNode();
794 }
795 
LastScrolledScrollNodeIndex() const796 int LayerTreeImpl::LastScrolledScrollNodeIndex() const {
797   return last_scrolled_scroll_node_index_;
798 }
799 
SetCurrentlyScrollingNode(const ScrollNode * node)800 void LayerTreeImpl::SetCurrentlyScrollingNode(const ScrollNode* node) {
801   if (node)
802     last_scrolled_scroll_node_index_ = node->id;
803 
804   ScrollTree& scroll_tree = property_trees()->scroll_tree;
805   ScrollNode* old_node = scroll_tree.CurrentlyScrollingNode();
806 
807   ElementId old_element_id = old_node ? old_node->element_id : ElementId();
808   ElementId new_element_id = node ? node->element_id : ElementId();
809   if (old_element_id == new_element_id)
810     return;
811 
812   scroll_tree.set_currently_scrolling_node(node ? node->id
813                                                 : ScrollTree::kInvalidNodeId);
814 }
815 
ClearCurrentlyScrollingNode()816 void LayerTreeImpl::ClearCurrentlyScrollingNode() {
817   SetCurrentlyScrollingNode(nullptr);
818 }
819 
ClampPageScaleFactorToLimits(float page_scale_factor) const820 float LayerTreeImpl::ClampPageScaleFactorToLimits(
821     float page_scale_factor) const {
822   if (min_page_scale_factor_ && page_scale_factor < min_page_scale_factor_)
823     page_scale_factor = min_page_scale_factor_;
824   else if (max_page_scale_factor_ && page_scale_factor > max_page_scale_factor_)
825     page_scale_factor = max_page_scale_factor_;
826   return page_scale_factor;
827 }
828 
UpdatePropertyTreeAnimationFromMainThread()829 void LayerTreeImpl::UpdatePropertyTreeAnimationFromMainThread() {
830   // TODO(enne): This should get replaced by pulling out animations into their
831   // own trees.  Then animations would have their own ways of synchronizing
832   // across commits.  This occurs to push updates from animations that have
833   // ticked since begin frame to a newly-committed property tree.
834   if (layer_list_.empty())
835     return;
836 
837   // Note we lazily delete element ids from the |element_id_to_xxx|
838   // maps below if we find they have no node present in their
839   // respective tree. This can be the case if the layer associated
840   // with that element id has been removed.
841 
842   // This code is assumed to only run on the sync tree; the node updates are
843   // then synced when the tree is activated. See http://crbug.com/916512
844   DCHECK(IsSyncTree());
845 
846   auto element_id_to_opacity = element_id_to_opacity_animations_.begin();
847   while (element_id_to_opacity != element_id_to_opacity_animations_.end()) {
848     const ElementId id = element_id_to_opacity->first;
849     EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id);
850     if (!node || !node->is_currently_animating_opacity ||
851         node->opacity == element_id_to_opacity->second) {
852       element_id_to_opacity_animations_.erase(element_id_to_opacity++);
853       continue;
854     }
855     node->opacity = element_id_to_opacity->second;
856     property_trees_.effect_tree.set_needs_update(true);
857     ++element_id_to_opacity;
858   }
859 
860   auto element_id_to_filter = element_id_to_filter_animations_.begin();
861   while (element_id_to_filter != element_id_to_filter_animations_.end()) {
862     const ElementId id = element_id_to_filter->first;
863     EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id);
864     if (!node || !node->is_currently_animating_filter ||
865         node->filters == element_id_to_filter->second) {
866       element_id_to_filter_animations_.erase(element_id_to_filter++);
867       continue;
868     }
869     node->filters = element_id_to_filter->second;
870     property_trees_.effect_tree.set_needs_update(true);
871     ++element_id_to_filter;
872   }
873 
874   auto element_id_to_backdrop_filter =
875       element_id_to_backdrop_filter_animations_.begin();
876   while (element_id_to_backdrop_filter !=
877          element_id_to_backdrop_filter_animations_.end()) {
878     const ElementId id = element_id_to_backdrop_filter->first;
879     EffectNode* node = property_trees_.effect_tree.FindNodeFromElementId(id);
880     if (!node || !node->is_currently_animating_backdrop_filter ||
881         node->backdrop_filters == element_id_to_backdrop_filter->second) {
882       element_id_to_backdrop_filter_animations_.erase(
883           element_id_to_backdrop_filter++);
884       continue;
885     }
886     node->backdrop_filters = element_id_to_backdrop_filter->second;
887     property_trees_.effect_tree.set_needs_update(true);
888     ++element_id_to_backdrop_filter;
889   }
890 
891   auto element_id_to_transform = element_id_to_transform_animations_.begin();
892   while (element_id_to_transform != element_id_to_transform_animations_.end()) {
893     const ElementId id = element_id_to_transform->first;
894     TransformNode* node =
895         property_trees_.transform_tree.FindNodeFromElementId(id);
896     if (!node || !node->is_currently_animating ||
897         node->local == element_id_to_transform->second) {
898       element_id_to_transform_animations_.erase(element_id_to_transform++);
899       continue;
900     }
901     node->local = element_id_to_transform->second;
902     node->needs_local_transform_update = true;
903     property_trees_.transform_tree.set_needs_update(true);
904     ++element_id_to_transform;
905   }
906 
907   for (auto transform_it : property_trees()->element_id_to_transform_node_index)
908     UpdateTransformAnimation(transform_it.first, transform_it.second);
909 }
910 
UpdateTransformAnimation(ElementId element_id,int transform_node_index)911 void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id,
912                                              int transform_node_index) {
913   // This includes all animations, even those that are finished but
914   // haven't yet been deleted.
915   if (mutator_host()->HasAnyAnimationTargetingProperty(
916           element_id, TargetProperty::TRANSFORM)) {
917     TransformTree& transform_tree = property_trees()->transform_tree;
918     if (TransformNode* node = transform_tree.Node(transform_node_index)) {
919       ElementListType list_type = GetElementTypeForAnimation();
920       bool has_potential_animation =
921           mutator_host()->HasPotentiallyRunningTransformAnimation(element_id,
922                                                                   list_type);
923       if (node->has_potential_animation != has_potential_animation) {
924         node->has_potential_animation = has_potential_animation;
925         mutator_host()->GetAnimationScales(element_id, list_type,
926                                            &node->maximum_animation_scale,
927                                            &node->starting_animation_scale);
928         transform_tree.set_needs_update(true);
929         set_needs_update_draw_properties();
930       }
931     }
932   }
933 }
934 
UpdatePageScaleNode()935 void LayerTreeImpl::UpdatePageScaleNode() {
936   if (!PageScaleTransformNode()) {
937     DCHECK(layer_list_.empty() || current_page_scale_factor() == 1);
938     return;
939   }
940   draw_property_utils::UpdatePageScaleFactor(
941       property_trees(), PageScaleTransformNode(), current_page_scale_factor());
942 }
943 
SetPageScaleOnActiveTree(float active_page_scale)944 void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) {
945   DCHECK(IsActiveTree());
946   DCHECK(lifecycle().AllowsPropertyTreeAccess());
947   float clamped_page_scale = ClampPageScaleFactorToLimits(active_page_scale);
948   // Temporary crash logging for https://crbug.com/845097.
949   static bool has_dumped_without_crashing = false;
950   if (host_impl_->settings().is_layer_tree_for_subframe &&
951       clamped_page_scale != 1.f && !has_dumped_without_crashing) {
952     has_dumped_without_crashing = true;
953     static auto* psf_oopif_error = base::debug::AllocateCrashKeyString(
954         "psf_oopif_error", base::debug::CrashKeySize::Size32);
955     base::debug::SetCrashKeyString(
956         psf_oopif_error, base::StringPrintf("%f", clamped_page_scale));
957     base::debug::DumpWithoutCrashing();
958   }
959   if (page_scale_factor()->SetCurrent(clamped_page_scale)) {
960     DidUpdatePageScale();
961     UpdatePageScaleNode();
962   }
963 }
964 
PushPageScaleFromMainThread(float page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)965 void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor,
966                                                 float min_page_scale_factor,
967                                                 float max_page_scale_factor) {
968   PushPageScaleFactorAndLimits(&page_scale_factor, min_page_scale_factor,
969                                max_page_scale_factor);
970 }
971 
PushPageScaleFactorAndLimits(const float * page_scale_factor,float min_page_scale_factor,float max_page_scale_factor)972 void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
973                                                  float min_page_scale_factor,
974                                                  float max_page_scale_factor) {
975   DCHECK(page_scale_factor || IsActiveTree());
976   bool changed_page_scale = false;
977 
978   changed_page_scale |=
979       SetPageScaleFactorLimits(min_page_scale_factor, max_page_scale_factor);
980 
981   if (page_scale_factor) {
982     DCHECK(!IsActiveTree() || !host_impl_->pending_tree());
983     changed_page_scale |=
984         page_scale_factor_->PushMainToPending(*page_scale_factor);
985   }
986 
987   if (IsActiveTree()) {
988     changed_page_scale |= page_scale_factor_->PushPendingToActive();
989   }
990 
991   if (changed_page_scale)
992     DidUpdatePageScale();
993 
994   DCHECK(lifecycle().AllowsPropertyTreeAccess());
995   if (page_scale_factor)
996     UpdatePageScaleNode();
997 }
998 
SetBrowserControlsParams(const BrowserControlsParams & params)999 void LayerTreeImpl::SetBrowserControlsParams(
1000     const BrowserControlsParams& params) {
1001   if (browser_controls_params_ == params)
1002     return;
1003 
1004   browser_controls_params_ = params;
1005   UpdateViewportContainerSizes();
1006 
1007   if (IsActiveTree()) {
1008     host_impl_->browser_controls_manager()->OnBrowserControlsParamsChanged(
1009         params.animate_browser_controls_height_changes);
1010   }
1011 }
1012 
set_overscroll_behavior(const OverscrollBehavior & behavior)1013 void LayerTreeImpl::set_overscroll_behavior(
1014     const OverscrollBehavior& behavior) {
1015   overscroll_behavior_ = behavior;
1016 }
1017 
ClampTopControlsShownRatio()1018 bool LayerTreeImpl::ClampTopControlsShownRatio() {
1019   float ratio = top_controls_shown_ratio_->Current(true);
1020   auto range = std::make_pair(0.f, 1.f);
1021   if (IsActiveTree()) {
1022     // BCOM might need to set ratios outside the [0, 1] range (e.g. animation
1023     // running). So, use the values it provides instead of clamping to [0, 1].
1024     range =
1025         host_impl_->browser_controls_manager()->TopControlsShownRatioRange();
1026   }
1027   return top_controls_shown_ratio_->SetCurrent(
1028       base::ClampToRange(ratio, range.first, range.second));
1029 }
1030 
ClampBottomControlsShownRatio()1031 bool LayerTreeImpl::ClampBottomControlsShownRatio() {
1032   float ratio = bottom_controls_shown_ratio_->Current(true);
1033   auto range = std::make_pair(0.f, 1.f);
1034   if (IsActiveTree()) {
1035     // BCOM might need to set ratios outside the [0, 1] range (e.g. animation
1036     // running). So, use the values it provides instead of clamping to [0, 1].
1037     range =
1038         host_impl_->browser_controls_manager()->BottomControlsShownRatioRange();
1039   }
1040   return bottom_controls_shown_ratio_->SetCurrent(
1041       base::ClampToRange(ratio, range.first, range.second));
1042 }
1043 
SetCurrentBrowserControlsShownRatio(float top_ratio,float bottom_ratio)1044 bool LayerTreeImpl::SetCurrentBrowserControlsShownRatio(float top_ratio,
1045                                                         float bottom_ratio) {
1046   TRACE_EVENT2("cc", "LayerTreeImpl::SetCurrentBrowserControlsShownRatio",
1047                "top_ratio", top_ratio, "bottom_ratio", bottom_ratio);
1048   bool changed = top_controls_shown_ratio_->SetCurrent(top_ratio);
1049   changed |= ClampTopControlsShownRatio();
1050   changed |= bottom_controls_shown_ratio_->SetCurrent(bottom_ratio);
1051   changed |= ClampBottomControlsShownRatio();
1052   return changed;
1053 }
1054 
PushBrowserControlsFromMainThread(float top_controls_shown_ratio,float bottom_controls_shown_ratio)1055 void LayerTreeImpl::PushBrowserControlsFromMainThread(
1056     float top_controls_shown_ratio,
1057     float bottom_controls_shown_ratio) {
1058   PushBrowserControls(&top_controls_shown_ratio, &bottom_controls_shown_ratio);
1059 }
1060 
PushBrowserControls(const float * top_controls_shown_ratio,const float * bottom_controls_shown_ratio)1061 void LayerTreeImpl::PushBrowserControls(
1062     const float* top_controls_shown_ratio,
1063     const float* bottom_controls_shown_ratio) {
1064   DCHECK(top_controls_shown_ratio || bottom_controls_shown_ratio ||
1065          IsActiveTree());
1066   DCHECK(!top_controls_shown_ratio || bottom_controls_shown_ratio);
1067   DCHECK(top_controls_shown_ratio || IsActiveTree());
1068 
1069   if (top_controls_shown_ratio) {
1070     DCHECK(!IsActiveTree() || !host_impl_->pending_tree());
1071     bool changed_pending =
1072         top_controls_shown_ratio_->PushMainToPending(*top_controls_shown_ratio);
1073     changed_pending |= bottom_controls_shown_ratio_->PushMainToPending(
1074         *bottom_controls_shown_ratio);
1075     if (!IsActiveTree() && changed_pending)
1076       UpdateViewportContainerSizes();
1077   }
1078   if (IsActiveTree()) {
1079     bool changed_active = top_controls_shown_ratio_->PushPendingToActive();
1080     changed_active |= ClampTopControlsShownRatio();
1081     changed_active |= bottom_controls_shown_ratio_->PushPendingToActive();
1082     changed_active |= ClampBottomControlsShownRatio();
1083     if (changed_active)
1084       host_impl_->DidChangeBrowserControlsPosition();
1085   }
1086 }
1087 
SetPageScaleFactorLimits(float min_page_scale_factor,float max_page_scale_factor)1088 bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor,
1089                                              float max_page_scale_factor) {
1090   if (min_page_scale_factor == min_page_scale_factor_ &&
1091       max_page_scale_factor == max_page_scale_factor_)
1092     return false;
1093 
1094   min_page_scale_factor_ = min_page_scale_factor;
1095   max_page_scale_factor_ = max_page_scale_factor;
1096 
1097   return true;
1098 }
1099 
DidUpdatePageScale()1100 void LayerTreeImpl::DidUpdatePageScale() {
1101   if (IsActiveTree())
1102     page_scale_factor()->SetCurrent(
1103         ClampPageScaleFactorToLimits(current_page_scale_factor()));
1104 
1105   set_needs_update_draw_properties();
1106 
1107   // Viewport scrollbar sizes depend on the page scale factor.
1108   SetScrollbarGeometriesNeedUpdate();
1109 
1110   if (IsActiveTree()) {
1111     if (settings().scrollbar_flash_after_any_scroll_update) {
1112       host_impl_->FlashAllScrollbars(true);
1113       return;
1114     }
1115     if (auto* scroll_node = host_impl_->OuterViewportScrollNode()) {
1116       if (ScrollbarAnimationController* controller =
1117               host_impl_->ScrollbarAnimationControllerForElementId(
1118                   scroll_node->element_id))
1119         controller->DidScrollUpdate();
1120     }
1121   }
1122 }
1123 
SetDeviceScaleFactor(float device_scale_factor)1124 void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) {
1125   if (device_scale_factor == device_scale_factor_)
1126     return;
1127   device_scale_factor_ = device_scale_factor;
1128 
1129   set_needs_update_draw_properties();
1130   if (IsActiveTree())
1131     host_impl_->SetViewportDamage(GetDeviceViewport());
1132   host_impl_->SetNeedUpdateGpuRasterizationStatus();
1133 }
1134 
SetLocalSurfaceIdAllocationFromParent(const viz::LocalSurfaceIdAllocation & local_surface_id_allocation_from_parent)1135 void LayerTreeImpl::SetLocalSurfaceIdAllocationFromParent(
1136     const viz::LocalSurfaceIdAllocation&
1137         local_surface_id_allocation_from_parent) {
1138   local_surface_id_allocation_from_parent_ =
1139       local_surface_id_allocation_from_parent;
1140 }
1141 
RequestNewLocalSurfaceId()1142 void LayerTreeImpl::RequestNewLocalSurfaceId() {
1143   new_local_surface_id_request_ = true;
1144 }
1145 
TakeNewLocalSurfaceIdRequest()1146 bool LayerTreeImpl::TakeNewLocalSurfaceIdRequest() {
1147   bool new_local_surface_id_request = new_local_surface_id_request_;
1148   new_local_surface_id_request_ = false;
1149   return new_local_surface_id_request;
1150 }
1151 
SetDeviceViewportRect(const gfx::Rect & device_viewport_rect)1152 void LayerTreeImpl::SetDeviceViewportRect(
1153     const gfx::Rect& device_viewport_rect) {
1154   if (device_viewport_rect == device_viewport_rect_)
1155     return;
1156   device_viewport_rect_ = device_viewport_rect;
1157 
1158   set_needs_update_draw_properties();
1159   if (!IsActiveTree())
1160     return;
1161 
1162   UpdateViewportContainerSizes();
1163   host_impl_->OnCanDrawStateChangedForTree();
1164   host_impl_->SetViewportDamage(GetDeviceViewport());
1165 }
1166 
GetDeviceViewport() const1167 gfx::Rect LayerTreeImpl::GetDeviceViewport() const {
1168   // TODO(fsamuel): We should plumb |external_viewport| similar to the
1169   // way we plumb |device_viewport_rect_|.
1170   const gfx::Rect& external_viewport = host_impl_->external_viewport();
1171   if (external_viewport.IsEmpty())
1172     return device_viewport_rect_;
1173   return external_viewport;
1174 }
1175 
SetRasterColorSpace(const gfx::ColorSpace & raster_color_space)1176 void LayerTreeImpl::SetRasterColorSpace(
1177     const gfx::ColorSpace& raster_color_space) {
1178   if (raster_color_space == raster_color_space_)
1179     return;
1180   raster_color_space_ = raster_color_space;
1181 }
1182 
SetExternalPageScaleFactor(float external_page_scale_factor)1183 void LayerTreeImpl::SetExternalPageScaleFactor(
1184     float external_page_scale_factor) {
1185   if (external_page_scale_factor_ == external_page_scale_factor)
1186     return;
1187 
1188   external_page_scale_factor_ = external_page_scale_factor;
1189   DidUpdatePageScale();
1190 }
1191 
page_scale_factor()1192 SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() {
1193   return page_scale_factor_.get();
1194 }
1195 
page_scale_factor() const1196 const SyncedProperty<ScaleGroup>* LayerTreeImpl::page_scale_factor() const {
1197   return page_scale_factor_.get();
1198 }
1199 
ScrollableViewportSize() const1200 gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
1201   auto* inner_node = InnerViewportScrollNode();
1202   if (!inner_node)
1203     return gfx::SizeF();
1204 
1205   return gfx::ScaleSize(gfx::SizeF(inner_node->container_bounds),
1206                         1.0f / page_scale_factor_for_scroll());
1207 }
1208 
RootScrollLayerDeviceViewportBounds() const1209 gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
1210   const ScrollNode* root_scroll_node = OuterViewportScrollNode();
1211   if (!root_scroll_node) {
1212     DCHECK(!InnerViewportScrollNode());
1213     return gfx::Rect();
1214   }
1215   return MathUtil::MapEnclosingClippedRect(
1216       property_trees()->transform_tree.ToScreen(root_scroll_node->transform_id),
1217       gfx::Rect(root_scroll_node->bounds));
1218 }
1219 
ApplySentScrollAndScaleDeltasFromAbortedCommit()1220 void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() {
1221   DCHECK(IsActiveTree());
1222 
1223   page_scale_factor()->AbortCommit();
1224   top_controls_shown_ratio()->AbortCommit();
1225   elastic_overscroll()->AbortCommit();
1226 
1227   if (layer_list_.empty())
1228     return;
1229 
1230   property_trees()->scroll_tree.ApplySentScrollDeltasFromAbortedCommit();
1231 }
1232 
SetViewportPropertyIds(const ViewportPropertyIds & ids)1233 void LayerTreeImpl::SetViewportPropertyIds(const ViewportPropertyIds& ids) {
1234   viewport_property_ids_ = ids;
1235   // Outer viewport properties exist only if inner viewport property exists.
1236   DCHECK(ids.inner_scroll != ScrollTree::kInvalidNodeId ||
1237          (ids.outer_scroll == ScrollTree::kInvalidNodeId &&
1238           ids.outer_clip == ClipTree::kInvalidNodeId));
1239 
1240   if (auto* inner_scroll = InnerViewportScrollNode()) {
1241     if (auto* inner_scroll_layer = LayerByElementId(inner_scroll->element_id))
1242       inner_scroll_layer->set_is_inner_viewport_scroll_layer();
1243   }
1244 }
1245 
OverscrollElasticityTransformNode() const1246 const TransformNode* LayerTreeImpl::OverscrollElasticityTransformNode() const {
1247   return property_trees()->transform_tree.Node(
1248       viewport_property_ids_.overscroll_elasticity_transform);
1249 }
1250 
PageScaleTransformNode() const1251 const TransformNode* LayerTreeImpl::PageScaleTransformNode() const {
1252   return property_trees()->transform_tree.Node(
1253       viewport_property_ids_.page_scale_transform);
1254 }
1255 
InnerViewportScrollNode() const1256 const ScrollNode* LayerTreeImpl::InnerViewportScrollNode() const {
1257   return property_trees()->scroll_tree.Node(
1258       viewport_property_ids_.inner_scroll);
1259 }
1260 
OuterViewportClipNode() const1261 const ClipNode* LayerTreeImpl::OuterViewportClipNode() const {
1262   return property_trees()->clip_tree.Node(viewport_property_ids_.outer_clip);
1263 }
1264 
OuterViewportScrollNode() const1265 const ScrollNode* LayerTreeImpl::OuterViewportScrollNode() const {
1266   return property_trees()->scroll_tree.Node(
1267       viewport_property_ids_.outer_scroll);
1268 }
1269 
1270 // For unit tests, we use the layer's id as its element id.
SetElementIdsForTesting()1271 void LayerTreeImpl::SetElementIdsForTesting() {
1272   for (auto* layer : *this) {
1273     if (!layer->element_id())
1274       layer->SetElementId(LayerIdToElementIdForTesting(layer->id()));
1275   }
1276 }
1277 
UpdateDrawProperties(bool update_image_animation_controller,LayerImplList * output_update_layer_list_for_testing)1278 bool LayerTreeImpl::UpdateDrawProperties(
1279     bool update_image_animation_controller,
1280     LayerImplList* output_update_layer_list_for_testing) {
1281   if (!needs_update_draw_properties_)
1282     return true;
1283 
1284   TRACE_EVENT0("cc,benchmark", "LayerTreeImpl::UpdateDrawProperties");
1285 
1286   // Ensure the scrollbar geometries are up-to-date for hit testing and quads
1287   // generation. This may cause damage on the scrollbar layers which is why
1288   // it occurs before we reset |needs_update_draw_properties_|.
1289   UpdateScrollbarGeometries();
1290 
1291   // Calling UpdateDrawProperties must clear this flag, so there can be no
1292   // early outs before this.
1293   needs_update_draw_properties_ = false;
1294 
1295   // For max_texture_size. When a new output surface is received the needs
1296   // update draw properties flag is set again.
1297   if (!host_impl_->layer_tree_frame_sink())
1298     return false;
1299 
1300   // Clear this after the renderer early out, as it should still be
1301   // possible to hit test even without a renderer.
1302   render_surface_list_.clear();
1303 
1304   if (layer_list_.empty())
1305     return false;
1306 
1307   {
1308     base::ElapsedTimer timer;
1309     TRACE_EVENT2("cc,benchmark",
1310                  "LayerTreeImpl::UpdateDrawProperties::CalculateDrawProperties",
1311                  "IsActive", IsActiveTree(), "SourceFrameNumber",
1312                  source_frame_number_);
1313     // We verify visible rect calculations whenever we verify clip tree
1314     // calculations except when this function is explicitly passed a flag asking
1315     // us to skip it.
1316     draw_property_utils::CalculateDrawProperties(
1317         this, &render_surface_list_, output_update_layer_list_for_testing);
1318 
1319     if (const char* client_name = GetClientNameForMetrics()) {
1320       UMA_HISTOGRAM_COUNTS_1M(
1321           base::StringPrintf(
1322               "Compositing.%s.LayerTreeImpl.CalculateDrawPropertiesUs",
1323               client_name),
1324           timer.Elapsed().InMicroseconds());
1325       UMA_HISTOGRAM_COUNTS_100(
1326           base::StringPrintf("Compositing.%s.NumRenderSurfaces", client_name),
1327           base::saturated_cast<int>(render_surface_list_.size()));
1328     }
1329   }
1330 
1331   if (settings().enable_occlusion) {
1332     TRACE_EVENT2("cc,benchmark",
1333                  "LayerTreeImpl::UpdateDrawProperties::Occlusion", "IsActive",
1334                  IsActiveTree(), "SourceFrameNumber", source_frame_number_);
1335     OcclusionTracker occlusion_tracker(RootRenderSurface()->content_rect());
1336     occlusion_tracker.set_minimum_tracking_size(
1337         settings().minimum_occlusion_tracking_size);
1338 
1339     for (EffectTreeLayerListIterator it(this);
1340          it.state() != EffectTreeLayerListIterator::State::END; ++it) {
1341       occlusion_tracker.EnterLayer(it);
1342 
1343       if (it.state() == EffectTreeLayerListIterator::State::LAYER) {
1344         LayerImpl* layer = it.current_layer();
1345         layer->draw_properties().occlusion_in_content_space =
1346             occlusion_tracker.GetCurrentOcclusionForLayer(
1347                 layer->DrawTransform());
1348       }
1349 
1350       if (it.state() ==
1351           EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
1352         const RenderSurfaceImpl* occlusion_surface =
1353             occlusion_tracker.OcclusionSurfaceForContributingSurface();
1354         gfx::Transform draw_transform;
1355         RenderSurfaceImpl* render_surface = it.current_render_surface();
1356         if (occlusion_surface) {
1357           // We are calculating transform between two render surfaces. So, we
1358           // need to apply the surface contents scale at target and remove the
1359           // surface contents scale at source.
1360           property_trees()->GetToTarget(render_surface->TransformTreeIndex(),
1361                                         occlusion_surface->EffectTreeIndex(),
1362                                         &draw_transform);
1363           const EffectNode* effect_node = property_trees()->effect_tree.Node(
1364               render_surface->EffectTreeIndex());
1365           draw_property_utils::ConcatInverseSurfaceContentsScale(
1366               effect_node, &draw_transform);
1367         }
1368 
1369         Occlusion occlusion =
1370             occlusion_tracker.GetCurrentOcclusionForContributingSurface(
1371                 draw_transform);
1372         render_surface->set_occlusion_in_content_space(occlusion);
1373       }
1374 
1375       occlusion_tracker.LeaveLayer(it);
1376     }
1377 
1378     unoccluded_screen_space_region_ =
1379         occlusion_tracker.ComputeVisibleRegionInScreen(this);
1380   } else {
1381     // No occlusion, entire root content rect is unoccluded.
1382     unoccluded_screen_space_region_ =
1383         Region(RootRenderSurface()->content_rect());
1384   }
1385 
1386   // Resourceless draw do not need tiles and should not affect existing tile
1387   // priorities.
1388   if (!is_in_resourceless_software_draw_mode()) {
1389     TRACE_EVENT_BEGIN2(
1390         "cc,benchmark", "LayerTreeImpl::UpdateDrawProperties::UpdateTiles",
1391         "IsActive", IsActiveTree(), "SourceFrameNumber", source_frame_number_);
1392     size_t layers_updated_count = 0;
1393     bool tile_priorities_updated = false;
1394     for (PictureLayerImpl* layer : picture_layers_) {
1395       if (!layer->HasValidTilePriorities())
1396         continue;
1397       ++layers_updated_count;
1398       tile_priorities_updated |= layer->UpdateTiles();
1399     }
1400 
1401     if (tile_priorities_updated)
1402       DidModifyTilePriorities();
1403 
1404     TRACE_EVENT_END1("cc,benchmark",
1405                      "LayerTreeImpl::UpdateDrawProperties::UpdateTiles",
1406                      "layers_updated_count", layers_updated_count);
1407   }
1408 
1409   if (update_image_animation_controller && image_animation_controller()) {
1410     image_animation_controller()->UpdateStateFromDrivers();
1411   }
1412 
1413   DCHECK(!needs_update_draw_properties_)
1414       << "CalcDrawProperties should not set_needs_update_draw_properties()";
1415   return true;
1416 }
1417 
UpdateCanUseLCDText()1418 void LayerTreeImpl::UpdateCanUseLCDText() {
1419   // If this is not the sync tree, then it is not safe to update lcd text
1420   // as it causes invalidations and the tiles may be in use.
1421   DCHECK(IsSyncTree());
1422   bool tile_priorities_updated = false;
1423   for (auto* layer : picture_layers_)
1424     tile_priorities_updated |= layer->UpdateCanUseLCDTextAfterCommit();
1425   if (tile_priorities_updated)
1426     DidModifyTilePriorities();
1427 }
1428 
GetRenderSurfaceList() const1429 const RenderSurfaceList& LayerTreeImpl::GetRenderSurfaceList() const {
1430   // If this assert triggers, then the list is dirty.
1431   DCHECK(!needs_update_draw_properties_);
1432   return render_surface_list_;
1433 }
1434 
UnoccludedScreenSpaceRegion() const1435 const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const {
1436   // If this assert triggers, then the render_surface_list_ is dirty, so the
1437   // unoccluded_screen_space_region_ is not valid anymore.
1438   DCHECK(!needs_update_draw_properties_);
1439   return unoccluded_screen_space_region_;
1440 }
1441 
ScrollableSize() const1442 gfx::SizeF LayerTreeImpl::ScrollableSize() const {
1443   auto* scroll_node = OuterViewportScrollNode();
1444   if (!scroll_node) {
1445     DCHECK(!InnerViewportScrollNode());
1446     return gfx::SizeF();
1447   }
1448   const auto& scroll_tree = property_trees()->scroll_tree;
1449   auto size = scroll_tree.scroll_bounds(scroll_node->id);
1450   size.SetToMax(gfx::SizeF(scroll_tree.container_bounds(scroll_node->id)));
1451   return size;
1452 }
1453 
LayerById(int id) const1454 LayerImpl* LayerTreeImpl::LayerById(int id) const {
1455   auto iter = layer_id_map_.find(id);
1456   return iter != layer_id_map_.end() ? iter->second : nullptr;
1457 }
1458 
1459 // TODO(masonfreed): If this shows up on profiles, this could use
1460 // a layer_element_map_ approach similar to LayerById().
LayerByElementId(ElementId element_id) const1461 LayerImpl* LayerTreeImpl::LayerByElementId(ElementId element_id) const {
1462   auto it =
1463       std::find_if(rbegin(), rend(), [&element_id](LayerImpl* layer_impl) {
1464         return layer_impl->element_id() == element_id;
1465       });
1466   if (it == rend())
1467     return nullptr;
1468   return *it;
1469 }
1470 
SetSurfaceRanges(const base::flat_set<viz::SurfaceRange> surface_ranges)1471 void LayerTreeImpl::SetSurfaceRanges(
1472     const base::flat_set<viz::SurfaceRange> surface_ranges) {
1473   DCHECK(surface_layer_ranges_.empty());
1474   surface_layer_ranges_ = std::move(surface_ranges);
1475   needs_surface_ranges_sync_ = true;
1476 }
1477 
SurfaceRanges() const1478 const base::flat_set<viz::SurfaceRange>& LayerTreeImpl::SurfaceRanges() const {
1479   return surface_layer_ranges_;
1480 }
1481 
ClearSurfaceRanges()1482 void LayerTreeImpl::ClearSurfaceRanges() {
1483   surface_layer_ranges_.clear();
1484   needs_surface_ranges_sync_ = true;
1485 }
1486 
AddLayerShouldPushProperties(LayerImpl * layer)1487 void LayerTreeImpl::AddLayerShouldPushProperties(LayerImpl* layer) {
1488   DCHECK(!IsActiveTree()) << "The active tree does not push layer properties";
1489   // TODO(crbug.com/303943): PictureLayerImpls always push properties so should
1490   // not go into this set or we'd push them twice.
1491   DCHECK(!base::Contains(picture_layers_, layer));
1492   layers_that_should_push_properties_.insert(layer);
1493 }
1494 
ClearLayersThatShouldPushProperties()1495 void LayerTreeImpl::ClearLayersThatShouldPushProperties() {
1496   layers_that_should_push_properties_.clear();
1497 }
1498 
RegisterLayer(LayerImpl * layer)1499 void LayerTreeImpl::RegisterLayer(LayerImpl* layer) {
1500   DCHECK(!LayerById(layer->id()));
1501   layer_id_map_[layer->id()] = layer;
1502 }
1503 
UnregisterLayer(LayerImpl * layer)1504 void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) {
1505   DCHECK(LayerById(layer->id()));
1506   layers_that_should_push_properties_.erase(layer);
1507   layer_id_map_.erase(layer->id());
1508 }
1509 
AddLayer(std::unique_ptr<LayerImpl> layer)1510 void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) {
1511   DCHECK(layer);
1512   DCHECK(!base::Contains(layer_list_, layer));
1513   layer_list_.push_back(std::move(layer));
1514   set_needs_update_draw_properties();
1515 }
1516 
NumLayers()1517 size_t LayerTreeImpl::NumLayers() {
1518   return layer_id_map_.size();
1519 }
1520 
DidBecomeActive()1521 void LayerTreeImpl::DidBecomeActive() {
1522   if (next_activation_forces_redraw_) {
1523     host_impl_->SetViewportDamage(GetDeviceViewport());
1524     next_activation_forces_redraw_ = false;
1525   }
1526 
1527   // Always reset this flag on activation, as we would only have activated
1528   // if we were in a good state.
1529   host_impl_->ResetRequiresHighResToDraw();
1530 
1531   for (auto* layer : *this)
1532     layer->DidBecomeActive();
1533 
1534   for (const auto& swap_promise : swap_promise_list_)
1535     swap_promise->DidActivate();
1536   devtools_instrumentation::DidActivateLayerTree(host_impl_->id(),
1537                                                  source_frame_number_);
1538 }
1539 
RequiresHighResToDraw() const1540 bool LayerTreeImpl::RequiresHighResToDraw() const {
1541   return host_impl_->RequiresHighResToDraw();
1542 }
1543 
task_runner_provider() const1544 TaskRunnerProvider* LayerTreeImpl::task_runner_provider() const {
1545   return host_impl_->task_runner_provider();
1546 }
1547 
layer_tree_frame_sink()1548 LayerTreeFrameSink* LayerTreeImpl::layer_tree_frame_sink() {
1549   return host_impl_->layer_tree_frame_sink();
1550 }
1551 
max_texture_size() const1552 int LayerTreeImpl::max_texture_size() const {
1553   return host_impl_->max_texture_size();
1554 }
1555 
settings() const1556 const LayerTreeSettings& LayerTreeImpl::settings() const {
1557   return host_impl_->settings();
1558 }
1559 
debug_state() const1560 const LayerTreeDebugState& LayerTreeImpl::debug_state() const {
1561   return host_impl_->debug_state();
1562 }
1563 
context_provider() const1564 viz::ContextProvider* LayerTreeImpl::context_provider() const {
1565   return host_impl_->layer_tree_frame_sink()->context_provider();
1566 }
1567 
resource_provider() const1568 viz::ClientResourceProvider* LayerTreeImpl::resource_provider() const {
1569   return host_impl_->resource_provider();
1570 }
1571 
tile_manager() const1572 TileManager* LayerTreeImpl::tile_manager() const {
1573   return host_impl_->tile_manager();
1574 }
1575 
image_decode_cache() const1576 ImageDecodeCache* LayerTreeImpl::image_decode_cache() const {
1577   return host_impl_->image_decode_cache();
1578 }
1579 
image_animation_controller() const1580 ImageAnimationController* LayerTreeImpl::image_animation_controller() const {
1581   return host_impl_->image_animation_controller();
1582 }
1583 
frame_rate_counter() const1584 FrameRateCounter* LayerTreeImpl::frame_rate_counter() const {
1585   return host_impl_->fps_counter();
1586 }
1587 
memory_history() const1588 MemoryHistory* LayerTreeImpl::memory_history() const {
1589   return host_impl_->memory_history();
1590 }
1591 
debug_rect_history() const1592 DebugRectHistory* LayerTreeImpl::debug_rect_history() const {
1593   return host_impl_->debug_rect_history();
1594 }
1595 
IsActiveTree() const1596 bool LayerTreeImpl::IsActiveTree() const {
1597   return host_impl_->active_tree() == this;
1598 }
1599 
IsPendingTree() const1600 bool LayerTreeImpl::IsPendingTree() const {
1601   return host_impl_->pending_tree() == this;
1602 }
1603 
IsRecycleTree() const1604 bool LayerTreeImpl::IsRecycleTree() const {
1605   return host_impl_->recycle_tree() == this;
1606 }
1607 
IsSyncTree() const1608 bool LayerTreeImpl::IsSyncTree() const {
1609   return host_impl_->sync_tree() == this;
1610 }
1611 
FindActiveTreeLayerById(int id)1612 LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) {
1613   LayerTreeImpl* tree = host_impl_->active_tree();
1614   if (!tree)
1615     return nullptr;
1616   return tree->LayerById(id);
1617 }
1618 
FindPendingTreeLayerById(int id)1619 LayerImpl* LayerTreeImpl::FindPendingTreeLayerById(int id) {
1620   LayerTreeImpl* tree = host_impl_->pending_tree();
1621   if (!tree)
1622     return nullptr;
1623   return tree->LayerById(id);
1624 }
1625 
PinchGestureActive() const1626 bool LayerTreeImpl::PinchGestureActive() const {
1627   return host_impl_->pinch_gesture_active();
1628 }
1629 
CurrentBeginFrameArgs() const1630 viz::BeginFrameArgs LayerTreeImpl::CurrentBeginFrameArgs() const {
1631   return host_impl_->CurrentBeginFrameArgs();
1632 }
1633 
CurrentBeginFrameInterval() const1634 base::TimeDelta LayerTreeImpl::CurrentBeginFrameInterval() const {
1635   return host_impl_->CurrentBeginFrameInterval();
1636 }
1637 
ViewportRectForTilePriority() const1638 const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const {
1639   const gfx::Rect& viewport_rect_for_tile_priority =
1640       host_impl_->viewport_rect_for_tile_priority();
1641   return viewport_rect_for_tile_priority.IsEmpty()
1642              ? GetDeviceViewport()
1643              : viewport_rect_for_tile_priority;
1644 }
1645 
1646 std::unique_ptr<ScrollbarAnimationController>
CreateScrollbarAnimationController(ElementId scroll_element_id,float initial_opacity)1647 LayerTreeImpl::CreateScrollbarAnimationController(ElementId scroll_element_id,
1648                                                   float initial_opacity) {
1649   DCHECK(!settings().scrollbar_fade_delay.is_zero());
1650   DCHECK(!settings().scrollbar_fade_duration.is_zero());
1651   base::TimeDelta fade_delay = settings().scrollbar_fade_delay;
1652   base::TimeDelta fade_duration = settings().scrollbar_fade_duration;
1653   switch (settings().scrollbar_animator) {
1654     case LayerTreeSettings::ANDROID_OVERLAY: {
1655       return ScrollbarAnimationController::
1656           CreateScrollbarAnimationControllerAndroid(
1657               scroll_element_id, host_impl_, fade_delay, fade_duration,
1658               initial_opacity);
1659     }
1660     case LayerTreeSettings::AURA_OVERLAY: {
1661       base::TimeDelta thinning_duration =
1662           settings().scrollbar_thinning_duration;
1663       return ScrollbarAnimationController::
1664           CreateScrollbarAnimationControllerAuraOverlay(
1665               scroll_element_id, host_impl_, fade_delay, fade_duration,
1666               thinning_duration, initial_opacity);
1667     }
1668     case LayerTreeSettings::NO_ANIMATOR:
1669       NOTREACHED();
1670       break;
1671   }
1672   return nullptr;
1673 }
1674 
DidAnimateScrollOffset()1675 void LayerTreeImpl::DidAnimateScrollOffset() {
1676   host_impl_->DidAnimateScrollOffset();
1677 }
1678 
use_gpu_rasterization() const1679 bool LayerTreeImpl::use_gpu_rasterization() const {
1680   return host_impl_->use_gpu_rasterization();
1681 }
1682 
GetGpuRasterizationStatus() const1683 GpuRasterizationStatus LayerTreeImpl::GetGpuRasterizationStatus() const {
1684   return host_impl_->gpu_rasterization_status();
1685 }
1686 
create_low_res_tiling() const1687 bool LayerTreeImpl::create_low_res_tiling() const {
1688   return host_impl_->create_low_res_tiling();
1689 }
1690 
SetNeedsRedraw()1691 void LayerTreeImpl::SetNeedsRedraw() {
1692   host_impl_->SetNeedsRedraw();
1693 }
1694 
GetAllPrioritizedTilesForTracing(std::vector<PrioritizedTile> * prioritized_tiles) const1695 void LayerTreeImpl::GetAllPrioritizedTilesForTracing(
1696     std::vector<PrioritizedTile>* prioritized_tiles) const {
1697   for (auto* layer : base::Reversed(*this)) {
1698     if (!layer->contributes_to_drawn_render_surface())
1699       continue;
1700     layer->GetAllPrioritizedTilesForTracing(prioritized_tiles);
1701   }
1702 }
1703 
AsValueInto(base::trace_event::TracedValue * state) const1704 void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const {
1705   viz::TracedValue::MakeDictIntoImplicitSnapshot(state, "cc::LayerTreeImpl",
1706                                                  this);
1707   state->SetInteger("source_frame_number", source_frame_number_);
1708 
1709   state->BeginArray("render_surface_layer_list");
1710   for (auto* layer : base::Reversed(*this)) {
1711     if (layer->contributes_to_drawn_render_surface())
1712       continue;
1713     viz::TracedValue::AppendIDRef(layer, state);
1714   }
1715   state->EndArray();
1716 
1717   state->BeginArray("swap_promise_trace_ids");
1718   for (const auto& swap_promise : swap_promise_list_)
1719     state->AppendDouble(swap_promise->TraceId());
1720   state->EndArray();
1721 
1722   state->BeginArray("pinned_swap_promise_trace_ids");
1723   for (const auto& swap_promise : pinned_swap_promise_list_)
1724     state->AppendDouble(swap_promise->TraceId());
1725   state->EndArray();
1726 
1727   state->BeginArray("layers");
1728   for (auto* layer : *this) {
1729     state->BeginDictionary();
1730     layer->AsValueInto(state);
1731     state->EndDictionary();
1732   }
1733   state->EndArray();
1734 }
1735 
QueueSwapPromise(std::unique_ptr<SwapPromise> swap_promise)1736 void LayerTreeImpl::QueueSwapPromise(
1737     std::unique_ptr<SwapPromise> swap_promise) {
1738   DCHECK(swap_promise);
1739   swap_promise_list_.push_back(std::move(swap_promise));
1740 }
1741 
QueuePinnedSwapPromise(std::unique_ptr<SwapPromise> swap_promise)1742 void LayerTreeImpl::QueuePinnedSwapPromise(
1743     std::unique_ptr<SwapPromise> swap_promise) {
1744   DCHECK(IsActiveTree());
1745   DCHECK(swap_promise);
1746   pinned_swap_promise_list_.push_back(std::move(swap_promise));
1747 }
1748 
PassSwapPromises(std::vector<std::unique_ptr<SwapPromise>> new_swap_promises)1749 void LayerTreeImpl::PassSwapPromises(
1750     std::vector<std::unique_ptr<SwapPromise>> new_swap_promises) {
1751   for (auto& swap_promise : swap_promise_list_) {
1752     if (swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS) ==
1753         SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
1754       // |swap_promise| must remain active, so place it in |new_swap_promises|
1755       // in order to keep it alive and active.
1756       new_swap_promises.push_back(std::move(swap_promise));
1757     }
1758   }
1759   swap_promise_list_.clear();
1760   swap_promise_list_.swap(new_swap_promises);
1761 }
1762 
AppendSwapPromises(std::vector<std::unique_ptr<SwapPromise>> new_swap_promises)1763 void LayerTreeImpl::AppendSwapPromises(
1764     std::vector<std::unique_ptr<SwapPromise>> new_swap_promises) {
1765   std::move(new_swap_promises.begin(), new_swap_promises.end(),
1766             std::back_inserter(swap_promise_list_));
1767   new_swap_promises.clear();
1768 }
1769 
FinishSwapPromises(viz::CompositorFrameMetadata * metadata)1770 void LayerTreeImpl::FinishSwapPromises(viz::CompositorFrameMetadata* metadata) {
1771   for (const auto& swap_promise : swap_promise_list_)
1772     swap_promise->WillSwap(metadata);
1773   for (const auto& swap_promise : pinned_swap_promise_list_)
1774     swap_promise->WillSwap(metadata);
1775 }
1776 
ClearSwapPromises()1777 void LayerTreeImpl::ClearSwapPromises() {
1778   for (const auto& swap_promise : swap_promise_list_)
1779     swap_promise->DidSwap();
1780   swap_promise_list_.clear();
1781   for (const auto& swap_promise : pinned_swap_promise_list_)
1782     swap_promise->DidSwap();
1783   pinned_swap_promise_list_.clear();
1784 }
1785 
BreakSwapPromises(SwapPromise::DidNotSwapReason reason)1786 void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) {
1787   {
1788     std::vector<std::unique_ptr<SwapPromise>> persistent_swap_promises;
1789     for (auto& swap_promise : swap_promise_list_) {
1790       if (swap_promise->DidNotSwap(reason) ==
1791           SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
1792         persistent_swap_promises.push_back(std::move(swap_promise));
1793       }
1794     }
1795     // |persistent_swap_promises| must remain active even when swap fails.
1796     swap_promise_list_ = std::move(persistent_swap_promises);
1797   }
1798 
1799   {
1800     std::vector<std::unique_ptr<SwapPromise>> persistent_swap_promises;
1801     for (auto& swap_promise : pinned_swap_promise_list_) {
1802       if (swap_promise->DidNotSwap(reason) ==
1803           SwapPromise::DidNotSwapAction::KEEP_ACTIVE) {
1804         persistent_swap_promises.push_back(std::move(swap_promise));
1805       }
1806     }
1807 
1808     // |persistent_swap_promises| must remain active even when swap fails.
1809     pinned_swap_promise_list_ = std::move(persistent_swap_promises);
1810   }
1811 }
1812 
DidModifyTilePriorities()1813 void LayerTreeImpl::DidModifyTilePriorities() {
1814   host_impl_->DidModifyTilePriorities();
1815 }
1816 
set_ui_resource_request_queue(UIResourceRequestQueue queue)1817 void LayerTreeImpl::set_ui_resource_request_queue(
1818     UIResourceRequestQueue queue) {
1819   ui_resource_request_queue_ = std::move(queue);
1820 }
1821 
ResourceIdForUIResource(UIResourceId uid) const1822 viz::ResourceId LayerTreeImpl::ResourceIdForUIResource(UIResourceId uid) const {
1823   return host_impl_->ResourceIdForUIResource(uid);
1824 }
1825 
IsUIResourceOpaque(UIResourceId uid) const1826 bool LayerTreeImpl::IsUIResourceOpaque(UIResourceId uid) const {
1827   return host_impl_->IsUIResourceOpaque(uid);
1828 }
1829 
ProcessUIResourceRequestQueue()1830 void LayerTreeImpl::ProcessUIResourceRequestQueue() {
1831   TRACE_EVENT1("cc", "ProcessUIResourceRequestQueue", "queue_size",
1832                ui_resource_request_queue_.size());
1833   for (const auto& req : ui_resource_request_queue_) {
1834     switch (req.GetType()) {
1835       case UIResourceRequest::UI_RESOURCE_CREATE:
1836         host_impl_->CreateUIResource(req.GetId(), req.GetBitmap());
1837         break;
1838       case UIResourceRequest::UI_RESOURCE_DELETE:
1839         host_impl_->DeleteUIResource(req.GetId());
1840         break;
1841       case UIResourceRequest::UI_RESOURCE_INVALID_REQUEST:
1842         NOTREACHED();
1843         break;
1844     }
1845   }
1846   ui_resource_request_queue_.clear();
1847 
1848   // If all UI resource evictions were not recreated by processing this queue,
1849   // then another commit is required.
1850   if (host_impl_->EvictedUIResourcesExist())
1851     host_impl_->SetNeedsCommit();
1852 }
1853 
RegisterPictureLayerImpl(PictureLayerImpl * layer)1854 void LayerTreeImpl::RegisterPictureLayerImpl(PictureLayerImpl* layer) {
1855   DCHECK(!base::Contains(picture_layers_, layer));
1856   picture_layers_.push_back(layer);
1857 }
1858 
UnregisterPictureLayerImpl(PictureLayerImpl * layer)1859 void LayerTreeImpl::UnregisterPictureLayerImpl(PictureLayerImpl* layer) {
1860   auto it = std::find(picture_layers_.begin(), picture_layers_.end(), layer);
1861   DCHECK(it != picture_layers_.end());
1862   picture_layers_.erase(it);
1863 
1864   // Make sure that |picture_layers_with_paint_worklets_| doesn't get left with
1865   // dead layers. They should already have been removed (via calling
1866   // NotifyLayerHasPaintWorkletsChanged) before the layer was unregistered.
1867   DCHECK(!picture_layers_with_paint_worklets_.contains(layer));
1868 }
1869 
NotifyLayerHasPaintWorkletsChanged(PictureLayerImpl * layer,bool has_worklets)1870 void LayerTreeImpl::NotifyLayerHasPaintWorkletsChanged(PictureLayerImpl* layer,
1871                                                        bool has_worklets) {
1872   if (has_worklets) {
1873     auto insert_pair = picture_layers_with_paint_worklets_.insert(layer);
1874     DCHECK(insert_pair.second);
1875   } else {
1876     auto it = picture_layers_with_paint_worklets_.find(layer);
1877     DCHECK(it != picture_layers_with_paint_worklets_.end());
1878     picture_layers_with_paint_worklets_.erase(it);
1879   }
1880 }
1881 
RegisterScrollbar(ScrollbarLayerImplBase * scrollbar_layer)1882 void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) {
1883   ElementId scroll_element_id = scrollbar_layer->scroll_element_id();
1884   if (!scroll_element_id)
1885     return;
1886 
1887   auto* scrollbar_ids = &element_id_to_scrollbar_layer_ids_[scroll_element_id];
1888   int* scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL
1889                                 ? &scrollbar_ids->horizontal
1890                                 : &scrollbar_ids->vertical;
1891 
1892   // We used to DCHECK this was not the case but this can occur on Android: as
1893   // the visual viewport supplies scrollbars for the outer viewport, if the
1894   // outer viewport is changed, we race between updating the visual viewport
1895   // scrollbars and registering new scrollbars on the old outer viewport. It'd
1896   // be nice if we could fix this to be cleaner but its harmless to just
1897   // unregister here.
1898   if (*scrollbar_layer_id != Layer::INVALID_ID) {
1899     UnregisterScrollbar(scrollbar_layer);
1900 
1901     // The scrollbar_ids could have been erased above so get it again.
1902     scrollbar_ids = &element_id_to_scrollbar_layer_ids_[scroll_element_id];
1903     scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL
1904                              ? &scrollbar_ids->horizontal
1905                              : &scrollbar_ids->vertical;
1906   }
1907 
1908   *scrollbar_layer_id = scrollbar_layer->id();
1909 
1910   if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() &&
1911       scrollbar_layer->GetScrollbarAnimator() !=
1912           LayerTreeSettings::NO_ANIMATOR) {
1913     host_impl_->RegisterScrollbarAnimationController(
1914         scroll_element_id, scrollbar_layer->Opacity());
1915   }
1916 
1917   // The new scrollbar's geometries need to be initialized.
1918   SetScrollbarGeometriesNeedUpdate();
1919 }
1920 
UnregisterScrollbar(ScrollbarLayerImplBase * scrollbar_layer)1921 void LayerTreeImpl::UnregisterScrollbar(
1922     ScrollbarLayerImplBase* scrollbar_layer) {
1923   ElementId scroll_element_id = scrollbar_layer->scroll_element_id();
1924   if (!scroll_element_id)
1925     return;
1926 
1927   auto& scrollbar_ids = element_id_to_scrollbar_layer_ids_[scroll_element_id];
1928   if (scrollbar_layer->orientation() == HORIZONTAL)
1929     scrollbar_ids.horizontal = Layer::INVALID_ID;
1930   else
1931     scrollbar_ids.vertical = Layer::INVALID_ID;
1932 
1933   if (scrollbar_ids.horizontal == Layer::INVALID_ID &&
1934       scrollbar_ids.vertical == Layer::INVALID_ID) {
1935     element_id_to_scrollbar_layer_ids_.erase(scroll_element_id);
1936     if (IsActiveTree()) {
1937       host_impl_->DidUnregisterScrollbarLayer(scroll_element_id);
1938     }
1939   }
1940 }
1941 
ScrollbarsFor(ElementId scroll_element_id) const1942 ScrollbarSet LayerTreeImpl::ScrollbarsFor(ElementId scroll_element_id) const {
1943   ScrollbarSet scrollbars;
1944   auto it = element_id_to_scrollbar_layer_ids_.find(scroll_element_id);
1945   if (it != element_id_to_scrollbar_layer_ids_.end()) {
1946     const ScrollbarLayerIds& layer_ids = it->second;
1947     if (layer_ids.horizontal != Layer::INVALID_ID)
1948       scrollbars.insert(LayerById(layer_ids.horizontal)->ToScrollbarLayer());
1949     if (layer_ids.vertical != Layer::INVALID_ID)
1950       scrollbars.insert(LayerById(layer_ids.vertical)->ToScrollbarLayer());
1951   }
1952   return scrollbars;
1953 }
1954 
PointHitsRect(const gfx::PointF & screen_space_point,const gfx::Transform & local_space_to_screen_space_transform,const gfx::Rect & local_space_rect,float * distance_to_camera)1955 static bool PointHitsRect(
1956     const gfx::PointF& screen_space_point,
1957     const gfx::Transform& local_space_to_screen_space_transform,
1958     const gfx::Rect& local_space_rect,
1959     float* distance_to_camera) {
1960   // If the transform is not invertible, then assume that this point doesn't hit
1961   // this rect.
1962   gfx::Transform inverse_local_space_to_screen_space(
1963       gfx::Transform::kSkipInitialization);
1964   if (!local_space_to_screen_space_transform.GetInverse(
1965           &inverse_local_space_to_screen_space))
1966     return false;
1967 
1968   // Transform the hit test point from screen space to the local space of the
1969   // given rect.
1970   bool clipped = false;
1971   gfx::Point3F planar_point = MathUtil::ProjectPoint3D(
1972       inverse_local_space_to_screen_space, screen_space_point, &clipped);
1973   gfx::PointF hit_test_point_in_local_space =
1974       gfx::PointF(planar_point.x(), planar_point.y());
1975 
1976   // If ProjectPoint could not project to a valid value, then we assume that
1977   // this point doesn't hit this rect.
1978   if (clipped)
1979     return false;
1980 
1981   if (!gfx::RectF(local_space_rect).Contains(hit_test_point_in_local_space))
1982     return false;
1983 
1984   if (distance_to_camera) {
1985     // To compute the distance to the camera, we have to take the planar point
1986     // and pull it back to world space and compute the displacement along the
1987     // z-axis.
1988     gfx::Point3F planar_point_in_screen_space(planar_point);
1989     local_space_to_screen_space_transform.TransformPoint(
1990         &planar_point_in_screen_space);
1991     *distance_to_camera = planar_point_in_screen_space.z();
1992   }
1993 
1994   return true;
1995 }
1996 
PointIsClippedByAncestorClipNode(const gfx::PointF & screen_space_point,const LayerImpl * layer)1997 static bool PointIsClippedByAncestorClipNode(
1998     const gfx::PointF& screen_space_point,
1999     const LayerImpl* layer) {
2000   // We need to visit all ancestor clip nodes to check this. Checking with just
2001   // the combined clip stored at a clip node is not enough because parent
2002   // combined clip can sometimes be smaller than current combined clip. This can
2003   // happen when we have transforms like rotation that inflate the combined
2004   // clip's bounds. Also, the point can be clipped by the content rect of an
2005   // ancestor render surface.
2006 
2007   // We first check if the point is clipped by viewport.
2008   const PropertyTrees* property_trees =
2009       layer->layer_tree_impl()->property_trees();
2010   const ClipTree& clip_tree = property_trees->clip_tree;
2011   const TransformTree& transform_tree = property_trees->transform_tree;
2012   gfx::Rect clip = gfx::ToEnclosingRect(clip_tree.Node(1)->clip);
2013   if (!PointHitsRect(screen_space_point, gfx::Transform(), clip, nullptr))
2014     return true;
2015 
2016   for (const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
2017        clip_node->id > ClipTree::kViewportNodeId;
2018        clip_node = clip_tree.parent(clip_node)) {
2019     if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) {
2020       clip = gfx::ToEnclosingRect(clip_node->clip);
2021 
2022       gfx::Transform screen_space_transform =
2023           transform_tree.ToScreen(clip_node->transform_id);
2024       if (!PointHitsRect(screen_space_point, screen_space_transform, clip,
2025                          nullptr)) {
2026         return true;
2027       }
2028     }
2029   }
2030   return false;
2031 }
2032 
PointIsClippedBySurfaceOrClipRect(const gfx::PointF & screen_space_point,const LayerImpl * layer)2033 static bool PointIsClippedBySurfaceOrClipRect(
2034     const gfx::PointF& screen_space_point,
2035     const LayerImpl* layer) {
2036   // Walk up the layer tree and hit-test any render_surfaces and any layer
2037   // clip rects that are active.
2038   return PointIsClippedByAncestorClipNode(screen_space_point, layer);
2039 }
2040 
PointHitsRegion(const gfx::PointF & screen_space_point,const gfx::Transform & screen_space_transform,const Region & layer_space_region,const LayerImpl * layer_impl)2041 static bool PointHitsRegion(const gfx::PointF& screen_space_point,
2042                             const gfx::Transform& screen_space_transform,
2043                             const Region& layer_space_region,
2044                             const LayerImpl* layer_impl) {
2045   if (layer_space_region.IsEmpty())
2046     return false;
2047 
2048   // If the transform is not invertible, then assume that this point doesn't hit
2049   // this region.
2050   gfx::Transform inverse_screen_space_transform(
2051       gfx::Transform::kSkipInitialization);
2052   if (!screen_space_transform.GetInverse(&inverse_screen_space_transform))
2053     return false;
2054 
2055   // Transform the hit test point from screen space to the local space of the
2056   // given region.
2057   bool clipped = false;
2058   gfx::PointF hit_test_point_in_layer_space = MathUtil::ProjectPoint(
2059       inverse_screen_space_transform, screen_space_point, &clipped);
2060 
2061   // If ProjectPoint could not project to a valid value, then we assume that
2062   // this point doesn't hit this region.
2063   if (clipped)
2064     return false;
2065 
2066   // We need to walk up the parents to ensure that the layer is not clipped in
2067   // such a way that it is impossible for the point to hit the layer.
2068   if (layer_impl &&
2069       PointIsClippedBySurfaceOrClipRect(screen_space_point, layer_impl))
2070     return false;
2071 
2072   return layer_space_region.Contains(
2073       gfx::ToRoundedPoint(hit_test_point_in_layer_space));
2074 }
2075 
PointHitsLayer(const LayerImpl * layer,const gfx::PointF & screen_space_point,float * distance_to_intersection)2076 static bool PointHitsLayer(const LayerImpl* layer,
2077                            const gfx::PointF& screen_space_point,
2078                            float* distance_to_intersection) {
2079   gfx::Rect content_rect(layer->bounds());
2080   if (!PointHitsRect(screen_space_point, layer->ScreenSpaceTransform(),
2081                      content_rect, distance_to_intersection)) {
2082     return false;
2083   }
2084 
2085   // At this point, we think the point does hit the layer, but we need to walk
2086   // up the parents to ensure that the layer was not clipped in such a way
2087   // that the hit point actually should not hit the layer.
2088   if (PointIsClippedBySurfaceOrClipRect(screen_space_point, layer))
2089     return false;
2090 
2091   // Skip the HUD layer.
2092   if (layer == layer->layer_tree_impl()->hud_layer())
2093     return false;
2094 
2095   return true;
2096 }
2097 
2098 struct FindClosestMatchingLayerState {
FindClosestMatchingLayerStatecc::FindClosestMatchingLayerState2099   FindClosestMatchingLayerState()
2100       : closest_match(nullptr),
2101         closest_distance(-std::numeric_limits<float>::infinity()) {}
2102   LayerImpl* closest_match;
2103   // Note that the positive z-axis points towards the camera, so bigger means
2104   // closer in this case, counterintuitively.
2105   float closest_distance;
2106 };
2107 
2108 template <typename Functor>
FindClosestMatchingLayer(const gfx::PointF & screen_space_point,LayerImpl * root_layer,const Functor & func,FindClosestMatchingLayerState * state)2109 static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point,
2110                                      LayerImpl* root_layer,
2111                                      const Functor& func,
2112                                      FindClosestMatchingLayerState* state) {
2113   base::ElapsedTimer timer;
2114   // We want to iterate from front to back when hit testing.
2115   for (auto* layer : base::Reversed(*root_layer->layer_tree_impl())) {
2116     if (!func(layer))
2117       continue;
2118 
2119     float distance_to_intersection = 0.f;
2120     bool hit = false;
2121     if (layer->Is3dSorted()) {
2122       hit =
2123           PointHitsLayer(layer, screen_space_point, &distance_to_intersection);
2124     } else {
2125       hit = PointHitsLayer(layer, screen_space_point, nullptr);
2126     }
2127 
2128     if (!hit)
2129       continue;
2130 
2131     bool in_front_of_previous_candidate =
2132         state->closest_match &&
2133         layer->GetSortingContextId() ==
2134             state->closest_match->GetSortingContextId() &&
2135         distance_to_intersection >
2136             state->closest_distance + std::numeric_limits<float>::epsilon();
2137 
2138     if (!state->closest_match || in_front_of_previous_candidate) {
2139       state->closest_distance = distance_to_intersection;
2140       state->closest_match = layer;
2141     }
2142   }
2143   if (const char* client_name = GetClientNameForMetrics()) {
2144     UMA_HISTOGRAM_COUNTS_1M(
2145         base::StringPrintf("Compositing.%s.HitTestTimeToFindClosestLayer",
2146                            client_name),
2147         timer.Elapsed().InMicroseconds());
2148   }
2149 }
2150 
FindFirstScrollingLayerOrScrollbarThatIsHitByPoint(const gfx::PointF & screen_space_point)2151 LayerImpl* LayerTreeImpl::FindFirstScrollingLayerOrScrollbarThatIsHitByPoint(
2152     const gfx::PointF& screen_space_point) {
2153   if (layer_list_.empty())
2154     return nullptr;
2155 
2156   FindClosestMatchingLayerState state;
2157   LayerImpl* root_layer = layer_list_[0].get();
2158   auto HitTestScrollingLayerOrScrollbarFunctor =
2159       [this](const LayerImpl* layer) {
2160         return layer->HitTestable() &&
2161                (layer->is_scrollbar() ||
2162                 (property_trees()->scroll_tree.FindNodeFromElementId(
2163                     layer->element_id())));
2164       };
2165   FindClosestMatchingLayer(screen_space_point, root_layer,
2166                            HitTestScrollingLayerOrScrollbarFunctor, &state);
2167   return state.closest_match;
2168 }
2169 
2170 struct HitTestVisibleScrollableOrTouchableFunctor {
operator ()cc::HitTestVisibleScrollableOrTouchableFunctor2171   bool operator()(LayerImpl* layer) const { return layer->HitTestable(); }
2172 };
2173 
FindLayerThatIsHitByPoint(const gfx::PointF & screen_space_point)2174 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint(
2175     const gfx::PointF& screen_space_point) {
2176   if (layer_list_.empty())
2177     return nullptr;
2178   if (!UpdateDrawProperties())
2179     return nullptr;
2180   FindClosestMatchingLayerState state;
2181   FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(),
2182                            HitTestVisibleScrollableOrTouchableFunctor(),
2183                            &state);
2184   return state.closest_match;
2185 }
2186 
2187 struct FindTouchEventLayerFunctor {
operator ()cc::FindTouchEventLayerFunctor2188   bool operator()(LayerImpl* layer) const {
2189     if (!layer->has_touch_action_regions())
2190       return false;
2191     return PointHitsRegion(screen_space_point, layer->ScreenSpaceTransform(),
2192                            layer->GetAllTouchActionRegions(), layer);
2193   }
2194   const gfx::PointF screen_space_point;
2195 };
2196 
2197 struct FindWheelEventHandlerLayerFunctor {
operator ()cc::FindWheelEventHandlerLayerFunctor2198   bool operator()(LayerImpl* layer) const {
2199     return PointHitsRegion(screen_space_point, layer->ScreenSpaceTransform(),
2200                            layer->wheel_event_handler_region(), layer);
2201   }
2202   const gfx::PointF screen_space_point;
2203 };
2204 
2205 template <typename Functor>
FindLayerThatIsHitByPointInEventHandlerRegion(const gfx::PointF & screen_space_point,const Functor & func)2206 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInEventHandlerRegion(
2207     const gfx::PointF& screen_space_point,
2208     const Functor& func) {
2209   if (layer_list_.empty())
2210     return nullptr;
2211   if (!UpdateDrawProperties())
2212     return nullptr;
2213   FindClosestMatchingLayerState state;
2214   FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), func,
2215                            &state);
2216   return state.closest_match;
2217 }
2218 
FindLayerThatIsHitByPointInTouchHandlerRegion(const gfx::PointF & screen_space_point)2219 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInTouchHandlerRegion(
2220     const gfx::PointF& screen_space_point) {
2221   FindTouchEventLayerFunctor func = {screen_space_point};
2222   return FindLayerThatIsHitByPointInEventHandlerRegion(screen_space_point,
2223                                                        func);
2224 }
2225 
FindLayerThatIsHitByPointInWheelEventHandlerRegion(const gfx::PointF & screen_space_point)2226 LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInWheelEventHandlerRegion(
2227     const gfx::PointF& screen_space_point) {
2228   FindWheelEventHandlerLayerFunctor func = {screen_space_point};
2229   return FindLayerThatIsHitByPointInEventHandlerRegion(screen_space_point,
2230                                                        func);
2231 }
2232 
2233 std::vector<const LayerImpl*>
FindLayersHitByPointInNonFastScrollableRegion(const gfx::PointF & screen_space_point)2234 LayerTreeImpl::FindLayersHitByPointInNonFastScrollableRegion(
2235     const gfx::PointF& screen_space_point) {
2236   std::vector<const LayerImpl*> layers;
2237   if (layer_list_.empty())
2238     return layers;
2239   if (!UpdateDrawProperties())
2240     return layers;
2241   for (const auto* layer : *this) {
2242     if (layer->non_fast_scrollable_region().IsEmpty())
2243       continue;
2244     if (!PointHitsLayer(layer, screen_space_point, nullptr))
2245       continue;
2246     if (PointHitsRegion(screen_space_point, layer->ScreenSpaceTransform(),
2247                         layer->non_fast_scrollable_region(), layer)) {
2248       layers.push_back(layer);
2249     }
2250   }
2251 
2252   return layers;
2253 }
2254 
2255 struct HitTestFramedVisibleScrollableOrTouchableFunctor {
operator ()cc::HitTestFramedVisibleScrollableOrTouchableFunctor2256   bool operator()(LayerImpl* layer) const {
2257     return layer->HitTestable() && layer->frame_element_id();
2258   }
2259 };
2260 
FindFrameElementIdAtPoint(const gfx::PointF & screen_space_point)2261 ElementId LayerTreeImpl::FindFrameElementIdAtPoint(
2262     const gfx::PointF& screen_space_point) {
2263   if (layer_list_.empty())
2264     return {};
2265   if (!UpdateDrawProperties())
2266     return {};
2267   FindClosestMatchingLayerState state;
2268   FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(),
2269                            HitTestFramedVisibleScrollableOrTouchableFunctor(),
2270                            &state);
2271 
2272   if (auto* layer = state.closest_match) {
2273     // TODO(https://crbug.com/1058870): Permit hit testing only if the framed
2274     // element hit has a simple mask/clip. We don't have enough information
2275     // about complex masks/clips on the impl-side to do accurate hit testing.
2276     bool layer_hit_test_region_is_masked =
2277         property_trees()->effect_tree.HitTestMayBeAffectedByMask(
2278             layer->effect_tree_index());
2279 
2280     if (!layer_hit_test_region_is_masked)
2281       return layer->frame_element_id();
2282   }
2283   return {};
2284 }
2285 
RegisterSelection(const LayerSelection & selection)2286 void LayerTreeImpl::RegisterSelection(const LayerSelection& selection) {
2287   if (selection_ == selection)
2288     return;
2289 
2290   handle_visibility_changed_ = true;
2291   selection_ = selection;
2292 }
2293 
ResetHandleVisibilityChanged()2294 void LayerTreeImpl::ResetHandleVisibilityChanged() {
2295   handle_visibility_changed_ = false;
2296 }
2297 
ComputeViewportSelectionBound(const LayerSelectionBound & layer_bound,LayerImpl * layer,float device_scale_factor)2298 static gfx::SelectionBound ComputeViewportSelectionBound(
2299     const LayerSelectionBound& layer_bound,
2300     LayerImpl* layer,
2301     float device_scale_factor) {
2302   gfx::SelectionBound viewport_bound;
2303   viewport_bound.set_type(layer_bound.type);
2304 
2305   if (!layer || layer_bound.type == gfx::SelectionBound::EMPTY)
2306     return viewport_bound;
2307 
2308   auto layer_start = gfx::PointF(layer_bound.edge_start);
2309   auto layer_end = gfx::PointF(layer_bound.edge_end);
2310   gfx::Transform screen_space_transform = layer->ScreenSpaceTransform();
2311 
2312   bool clipped = false;
2313   gfx::PointF screen_start =
2314       MathUtil::MapPoint(screen_space_transform, layer_start, &clipped);
2315   gfx::PointF screen_end =
2316       MathUtil::MapPoint(screen_space_transform, layer_end, &clipped);
2317 
2318   // MapPoint can produce points with NaN components (even when no inputs are
2319   // NaN). Since consumers of gfx::SelectionBounds may round |edge_start| or
2320   // |edge_end| (and since rounding will crash on NaN), we return an empty
2321   // bound instead.
2322   if (std::isnan(screen_start.x()) || std::isnan(screen_start.y()) ||
2323       std::isnan(screen_end.x()) || std::isnan(screen_end.y()))
2324     return gfx::SelectionBound();
2325 
2326   const float inv_scale = 1.f / device_scale_factor;
2327   viewport_bound.SetEdgeStart(gfx::ScalePoint(screen_start, inv_scale));
2328   viewport_bound.SetEdgeEnd(gfx::ScalePoint(screen_end, inv_scale));
2329 
2330   // If |layer_bound| is already hidden due to being occluded by painted content
2331   // within the layer, it must remain hidden. Otherwise, check whether its
2332   // position is outside the bounds of the layer.
2333   if (layer_bound.hidden) {
2334     viewport_bound.set_visible(false);
2335   } else {
2336     // The bottom edge point is used for visibility testing as it is the logical
2337     // focal point for bound selection handles (this may change in the future).
2338     // Shifting the visibility point fractionally inward ensures that
2339     // neighboring or logically coincident layers aligned to integral DPI
2340     // coordinates will not spuriously occlude the bound.
2341     gfx::Vector2dF visibility_offset = layer_start - layer_end;
2342     visibility_offset.Scale(device_scale_factor / visibility_offset.Length());
2343     gfx::PointF visibility_point = layer_end + visibility_offset;
2344     if (visibility_point.x() <= 0)
2345       visibility_point.set_x(visibility_point.x() + device_scale_factor);
2346     visibility_point =
2347         MathUtil::MapPoint(screen_space_transform, visibility_point, &clipped);
2348 
2349     float intersect_distance = 0.f;
2350     viewport_bound.set_visible(
2351         PointHitsLayer(layer, visibility_point, &intersect_distance));
2352   }
2353 
2354   if (viewport_bound.visible()) {
2355     viewport_bound.SetVisibleEdge(viewport_bound.edge_start(),
2356                                   viewport_bound.edge_end());
2357   } else {
2358     // The |layer_start| and |layer_end| might be clipped.
2359     gfx::RectF visible_layer_rect(layer->visible_layer_rect());
2360     auto visible_layer_start = layer_start;
2361     auto visible_layer_end = layer_end;
2362     if (!visible_layer_rect.Contains(visible_layer_start) &&
2363         !visible_layer_rect.Contains(visible_layer_end))
2364       std::tie(visible_layer_start, visible_layer_end) =
2365           GetVisibleSelectionEndPoints(visible_layer_rect, layer_start,
2366                                        layer_end);
2367 
2368     gfx::PointF visible_screen_start = MathUtil::MapPoint(
2369         screen_space_transform, visible_layer_start, &clipped);
2370     gfx::PointF visible_screen_end =
2371         MathUtil::MapPoint(screen_space_transform, visible_layer_end, &clipped);
2372 
2373     viewport_bound.SetVisibleEdgeStart(
2374         gfx::ScalePoint(visible_screen_start, inv_scale));
2375     viewport_bound.SetVisibleEdgeEnd(
2376         gfx::ScalePoint(visible_screen_end, inv_scale));
2377   }
2378 
2379   return viewport_bound;
2380 }
2381 
GetViewportSelection(viz::Selection<gfx::SelectionBound> * selection)2382 void LayerTreeImpl::GetViewportSelection(
2383     viz::Selection<gfx::SelectionBound>* selection) {
2384   DCHECK(selection);
2385 
2386   selection->start = ComputeViewportSelectionBound(
2387       selection_.start,
2388       selection_.start.layer_id ? LayerById(selection_.start.layer_id)
2389                                 : nullptr,
2390       device_scale_factor() * painted_device_scale_factor());
2391   if (selection->start.type() == gfx::SelectionBound::CENTER ||
2392       selection->start.type() == gfx::SelectionBound::EMPTY) {
2393     selection->end = selection->start;
2394   } else {
2395     selection->end = ComputeViewportSelectionBound(
2396         selection_.end,
2397         selection_.end.layer_id ? LayerById(selection_.end.layer_id) : nullptr,
2398         device_scale_factor() * painted_device_scale_factor());
2399   }
2400 }
2401 
SmoothnessTakesPriority() const2402 bool LayerTreeImpl::SmoothnessTakesPriority() const {
2403   return host_impl_->GetTreePriority() == SMOOTHNESS_TAKES_PRIORITY;
2404 }
2405 
GetVideoFrameControllerClient() const2406 VideoFrameControllerClient* LayerTreeImpl::GetVideoFrameControllerClient()
2407     const {
2408   return host_impl_;
2409 }
2410 
UpdateImageDecodingHints(base::flat_map<PaintImage::Id,PaintImage::DecodingMode> decoding_mode_map)2411 void LayerTreeImpl::UpdateImageDecodingHints(
2412     base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
2413         decoding_mode_map) {
2414   host_impl_->UpdateImageDecodingHints(std::move(decoding_mode_map));
2415 }
2416 
GetMSAASampleCountForRaster(const scoped_refptr<DisplayItemList> & display_list)2417 int LayerTreeImpl::GetMSAASampleCountForRaster(
2418     const scoped_refptr<DisplayItemList>& display_list) {
2419   return host_impl_->GetMSAASampleCountForRaster(display_list);
2420 }
2421 
SetPendingPageScaleAnimation(std::unique_ptr<PendingPageScaleAnimation> pending_animation)2422 void LayerTreeImpl::SetPendingPageScaleAnimation(
2423     std::unique_ptr<PendingPageScaleAnimation> pending_animation) {
2424   pending_page_scale_animation_ = std::move(pending_animation);
2425 }
2426 
2427 std::unique_ptr<PendingPageScaleAnimation>
TakePendingPageScaleAnimation()2428 LayerTreeImpl::TakePendingPageScaleAnimation() {
2429   return std::move(pending_page_scale_animation_);
2430 }
2431 
AppendEventsMetricsFromMainThread(std::vector<EventMetrics> events_metrics)2432 void LayerTreeImpl::AppendEventsMetricsFromMainThread(
2433     std::vector<EventMetrics> events_metrics) {
2434   events_metrics_from_main_thread_.reserve(
2435       events_metrics_from_main_thread_.size() + events_metrics.size());
2436   events_metrics_from_main_thread_.insert(
2437       events_metrics_from_main_thread_.end(), events_metrics.begin(),
2438       events_metrics.end());
2439 }
2440 
TakeEventsMetrics()2441 std::vector<EventMetrics> LayerTreeImpl::TakeEventsMetrics() {
2442   std::vector<EventMetrics> main_event_metrics_result;
2443   main_event_metrics_result.swap(events_metrics_from_main_thread_);
2444   return main_event_metrics_result;
2445 }
2446 
TakeForceSendMetadataRequest()2447 bool LayerTreeImpl::TakeForceSendMetadataRequest() {
2448   bool force_send_metadata_request = force_send_metadata_request_;
2449   force_send_metadata_request_ = false;
2450   return force_send_metadata_request;
2451 }
2452 
ResetAllChangeTracking()2453 void LayerTreeImpl::ResetAllChangeTracking() {
2454   layers_that_should_push_properties_.clear();
2455   // Iterate over all layers, including masks.
2456   for (auto* layer : *this)
2457     layer->ResetChangeTracking();
2458   property_trees_.ResetAllChangeTracking();
2459 }
2460 
LayerListAsJson() const2461 std::string LayerTreeImpl::LayerListAsJson() const {
2462   base::trace_event::TracedValueJSON value;
2463   value.BeginArray("LayerTreeImpl");
2464   for (auto* layer : *this) {
2465     value.BeginDictionary();
2466     layer->AsValueInto(&value);
2467     value.EndDictionary();
2468   }
2469   value.EndArray();
2470   return value.ToFormattedJSON();
2471 }
2472 
2473 }  // namespace cc
2474