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_host_impl.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <algorithm>
11 #include <limits>
12 #include <list>
13 #include <string>
14 
15 #include "base/auto_reset.h"
16 #include "base/bind.h"
17 #include "base/command_line.h"
18 #include "base/compiler_specific.h"
19 #include "base/containers/adapters.h"
20 #include "base/containers/flat_map.h"
21 #include "base/debug/crash_logging.h"
22 #include "base/debug/dump_without_crashing.h"
23 #include "base/location.h"
24 #include "base/logging.h"
25 #include "base/memory/ptr_util.h"
26 #include "base/memory/read_only_shared_memory_region.h"
27 #include "base/metrics/histogram.h"
28 #include "base/numerics/safe_conversions.h"
29 #include "base/stl_util.h"
30 #include "base/strings/stringprintf.h"
31 #include "base/system/sys_info.h"
32 #include "base/trace_event/traced_value.h"
33 #include "build/build_config.h"
34 #include "cc/base/devtools_instrumentation.h"
35 #include "cc/base/features.h"
36 #include "cc/base/histograms.h"
37 #include "cc/base/math_util.h"
38 #include "cc/base/switches.h"
39 #include "cc/benchmarks/benchmark_instrumentation.h"
40 #include "cc/debug/rendering_stats_instrumentation.h"
41 #include "cc/input/browser_controls_offset_manager.h"
42 #include "cc/input/main_thread_scrolling_reason.h"
43 #include "cc/input/page_scale_animation.h"
44 #include "cc/input/scroll_elasticity_helper.h"
45 #include "cc/input/scroll_state.h"
46 #include "cc/input/scroll_utils.h"
47 #include "cc/input/scrollbar.h"
48 #include "cc/input/scrollbar_animation_controller.h"
49 #include "cc/input/scroller_size_metrics.h"
50 #include "cc/input/snap_selection_strategy.h"
51 #include "cc/layers/append_quads_data.h"
52 #include "cc/layers/effect_tree_layer_list_iterator.h"
53 #include "cc/layers/heads_up_display_layer_impl.h"
54 #include "cc/layers/layer_impl.h"
55 #include "cc/layers/painted_scrollbar_layer_impl.h"
56 #include "cc/layers/render_surface_impl.h"
57 #include "cc/layers/scrollbar_layer_impl_base.h"
58 #include "cc/layers/surface_layer_impl.h"
59 #include "cc/layers/viewport.h"
60 #include "cc/metrics/compositor_frame_reporting_controller.h"
61 #include "cc/metrics/frame_sequence_metrics.h"
62 #include "cc/metrics/lcd_text_metrics_reporter.h"
63 #include "cc/metrics/ukm_smoothness_data.h"
64 #include "cc/paint/display_item_list.h"
65 #include "cc/paint/paint_worklet_job.h"
66 #include "cc/paint/paint_worklet_layer_painter.h"
67 #include "cc/raster/bitmap_raster_buffer_provider.h"
68 #include "cc/raster/gpu_raster_buffer_provider.h"
69 #include "cc/raster/one_copy_raster_buffer_provider.h"
70 #include "cc/raster/raster_buffer_provider.h"
71 #include "cc/raster/synchronous_task_graph_runner.h"
72 #include "cc/raster/zero_copy_raster_buffer_provider.h"
73 #include "cc/resources/memory_history.h"
74 #include "cc/resources/resource_pool.h"
75 #include "cc/resources/ui_resource_bitmap.h"
76 #include "cc/tiles/eviction_tile_priority_queue.h"
77 #include "cc/tiles/frame_viewer_instrumentation.h"
78 #include "cc/tiles/gpu_image_decode_cache.h"
79 #include "cc/tiles/picture_layer_tiling.h"
80 #include "cc/tiles/raster_tile_priority_queue.h"
81 #include "cc/tiles/software_image_decode_cache.h"
82 #include "cc/trees/clip_node.h"
83 #include "cc/trees/compositor_commit_data.h"
84 #include "cc/trees/damage_tracker.h"
85 #include "cc/trees/debug_rect_history.h"
86 #include "cc/trees/draw_property_utils.h"
87 #include "cc/trees/effect_node.h"
88 #include "cc/trees/image_animation_controller.h"
89 #include "cc/trees/latency_info_swap_promise_monitor.h"
90 #include "cc/trees/layer_tree_frame_sink.h"
91 #include "cc/trees/layer_tree_impl.h"
92 #include "cc/trees/mutator_host.h"
93 #include "cc/trees/presentation_time_callback_buffer.h"
94 #include "cc/trees/render_frame_metadata.h"
95 #include "cc/trees/render_frame_metadata_observer.h"
96 #include "cc/trees/scroll_node.h"
97 #include "cc/trees/single_thread_proxy.h"
98 #include "cc/trees/transform_node.h"
99 #include "cc/trees/tree_synchronizer.h"
100 #include "components/viz/common/features.h"
101 #include "components/viz/common/frame_sinks/copy_output_request.h"
102 #include "components/viz/common/frame_sinks/delay_based_time_source.h"
103 #include "components/viz/common/frame_timing_details.h"
104 #include "components/viz/common/hit_test/hit_test_region_list.h"
105 #include "components/viz/common/quads/compositor_frame.h"
106 #include "components/viz/common/quads/compositor_frame_metadata.h"
107 #include "components/viz/common/quads/compositor_render_pass_draw_quad.h"
108 #include "components/viz/common/quads/frame_deadline.h"
109 #include "components/viz/common/quads/shared_quad_state.h"
110 #include "components/viz/common/quads/solid_color_draw_quad.h"
111 #include "components/viz/common/quads/texture_draw_quad.h"
112 #include "components/viz/common/resources/bitmap_allocation.h"
113 #include "components/viz/common/resources/platform_color.h"
114 #include "components/viz/common/resources/resource_sizes.h"
115 #include "components/viz/common/traced_value.h"
116 #include "gpu/GLES2/gl2extchromium.h"
117 #include "gpu/command_buffer/client/context_support.h"
118 #include "gpu/command_buffer/client/gles2_interface.h"
119 #include "gpu/command_buffer/client/raster_interface.h"
120 #include "gpu/command_buffer/client/shared_image_interface.h"
121 #include "gpu/command_buffer/common/shared_image_usage.h"
122 #include "services/metrics/public/cpp/ukm_recorder.h"
123 #include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.h"
124 #include "third_party/skia/include/gpu/GrDirectContext.h"
125 #include "ui/events/types/scroll_input_type.h"
126 #include "ui/gfx/display_color_spaces.h"
127 #include "ui/gfx/geometry/point_conversions.h"
128 #include "ui/gfx/geometry/rect_conversions.h"
129 #include "ui/gfx/geometry/scroll_offset.h"
130 #include "ui/gfx/geometry/size_conversions.h"
131 #include "ui/gfx/geometry/vector2d_conversions.h"
132 #include "ui/gfx/geometry/vector2d_f.h"
133 #include "ui/gfx/skia_util.h"
134 
135 using ScrollThread = cc::InputHandler::ScrollThread;
136 
137 namespace cc {
138 namespace {
139 
140 // Used to accommodate finite precision when comparing scaled viewport and
141 // content widths. While this value may seem large, width=device-width on an N7
142 // V1 saw errors of ~0.065 between computed window and content widths.
143 const float kMobileViewportWidthEpsilon = 0.15f;
144 
145 // In BuildHitTestData we iterate all layers to find all layers that overlap
146 // OOPIFs, but when the number of layers is greater than
147 // |kAssumeOverlapThreshold|, it can be inefficient to accumulate layer bounds
148 // for overlap checking. As a result, we are conservative and make OOPIFs
149 // kHitTestAsk after the threshold is reached.
150 const size_t kAssumeOverlapThreshold = 100;
151 
152 // gfx::DisplayColorSpaces stores up to 3 different color spaces. This should be
153 // updated to match any size changes in DisplayColorSpaces.
154 constexpr size_t kContainsSrgbCacheSize = 3;
155 static_assert(kContainsSrgbCacheSize ==
156                   gfx::DisplayColorSpaces::kConfigCount / 2,
157               "sRGB cache must match the size of DisplayColorSpaces");
158 
HasFixedPageScale(LayerTreeImpl * active_tree)159 bool HasFixedPageScale(LayerTreeImpl* active_tree) {
160   return active_tree->min_page_scale_factor() ==
161          active_tree->max_page_scale_factor();
162 }
163 
HasMobileViewport(LayerTreeImpl * active_tree)164 bool HasMobileViewport(LayerTreeImpl* active_tree) {
165   float window_width_dip = active_tree->current_page_scale_factor() *
166                            active_tree->ScrollableViewportSize().width();
167   float content_width_css = active_tree->ScrollableSize().width();
168   return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
169 }
170 
IsMobileOptimized(LayerTreeImpl * active_tree)171 bool IsMobileOptimized(LayerTreeImpl* active_tree) {
172   bool has_mobile_viewport = HasMobileViewport(active_tree);
173   bool has_fixed_page_scale = HasFixedPageScale(active_tree);
174   return has_fixed_page_scale || has_mobile_viewport;
175 }
176 
TileRasterBufferFormat(const LayerTreeSettings & settings,viz::ContextProvider * context_provider,bool use_gpu_rasterization)177 viz::ResourceFormat TileRasterBufferFormat(
178     const LayerTreeSettings& settings,
179     viz::ContextProvider* context_provider,
180     bool use_gpu_rasterization) {
181   // Software compositing always uses the native skia RGBA N32 format, but we
182   // just call it RGBA_8888 everywhere even though it can be BGRA ordering,
183   // because we don't need to communicate the actual ordering as the code all
184   // assumes the native skia format.
185   if (!context_provider)
186     return viz::RGBA_8888;
187 
188   // RGBA4444 overrides the defaults if specified, but only for gpu compositing.
189   // It is always supported on platforms where it is specified.
190   if (settings.use_rgba_4444)
191     return viz::RGBA_4444;
192   // Otherwise we use BGRA textures if we can but it depends on the context
193   // capabilities, and we have different preferences when rastering to textures
194   // vs uploading textures.
195   const gpu::Capabilities& caps = context_provider->ContextCapabilities();
196   if (use_gpu_rasterization)
197     return viz::PlatformColor::BestSupportedRenderBufferFormat(caps);
198   return viz::PlatformColor::BestSupportedTextureFormat(caps);
199 }
200 
DidVisibilityChange(LayerTreeHostImpl * id,bool visible)201 void DidVisibilityChange(LayerTreeHostImpl* id, bool visible) {
202   if (visible) {
203     TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(
204         "cc,benchmark", "LayerTreeHostImpl::SetVisible", TRACE_ID_LOCAL(id),
205         "LayerTreeHostImpl", id);
206     return;
207   }
208 
209   TRACE_EVENT_NESTABLE_ASYNC_END0(
210       "cc,benchmark", "LayerTreeHostImpl::SetVisible", TRACE_ID_LOCAL(id));
211 }
212 
PopulateMetadataContentColorUsage(const LayerTreeHostImpl::FrameData * frame,viz::CompositorFrameMetadata * metadata)213 void PopulateMetadataContentColorUsage(
214     const LayerTreeHostImpl::FrameData* frame,
215     viz::CompositorFrameMetadata* metadata) {
216   metadata->content_color_usage = gfx::ContentColorUsage::kSRGB;
217   for (const LayerImpl* layer : frame->will_draw_layers) {
218     metadata->content_color_usage =
219         std::max(metadata->content_color_usage, layer->GetContentColorUsage());
220   }
221 }
222 
223 // Registers callbacks, as needed, to track First Scroll Latency.
ApplyFirstScrollTracking(const ui::LatencyInfo * latency,uint32_t frame_token,LayerTreeHostImpl * impl)224 void ApplyFirstScrollTracking(const ui::LatencyInfo* latency,
225                               uint32_t frame_token,
226                               LayerTreeHostImpl* impl) {
227   base::TimeTicks creation_timestamp;
228   // If |latency| isn't tracking a scroll, we don't need to do extra
229   // first-scroll tracking.
230   auto scroll_update_started =
231       ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT;
232   auto scroll_update_continued =
233       ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT;
234   if (!latency->FindLatency(scroll_update_started, &creation_timestamp) &&
235       !latency->FindLatency(scroll_update_continued, &creation_timestamp)) {
236     return;
237   }
238 
239   // Construct a callback that, given presentation feedback, will report the
240   // time span between the scroll input-event creation and the
241   // presentation timestamp.
242   LayerTreeHost::PresentationTimeCallback presentation_callback =
243       base::BindOnce(
244           [](base::TimeTicks event_creation,
245              LayerTreeHostImpl* layer_tree_host_impl,
246              const gfx::PresentationFeedback& feedback) {
247             layer_tree_host_impl->DidObserveScrollDelay(
248                 feedback.timestamp - event_creation, event_creation);
249           },
250           creation_timestamp, impl);
251 
252   // Tell the |LayerTreeHostImpl| to run our callback with the presentation
253   // feedback corresponding to the given |frame_token|.
254   impl->RegisterCompositorPresentationTimeCallback(
255       frame_token, std::move(presentation_callback));
256 }
257 
258 // These values are persisted to logs. Entries should not be renumbered and
259 // numeric values should never be reused.
260 enum class SourceIdConsistency : int {
261   kConsistent = 0,
262   kContainsInvalid = 1,
263   kNonUnique = 2,
264   kInvalidAndNonUnique = 3,
265   kMaxValue = kInvalidAndNonUnique,
266 };
267 
RecordSourceIdConsistency(bool all_valid,bool all_unique)268 void RecordSourceIdConsistency(bool all_valid, bool all_unique) {
269   SourceIdConsistency consistency =
270       all_unique ? (all_valid ? SourceIdConsistency::kConsistent
271                               : SourceIdConsistency::kContainsInvalid)
272                  : (all_valid ? SourceIdConsistency::kNonUnique
273                               : SourceIdConsistency::kInvalidAndNonUnique);
274 
275   // TODO(crbug.com/1062764): we're sometimes seeing unexpected values for the
276   // ukm::SourceId. We'll use this histogram to track how often it happens so
277   // we can properly (de-)prioritize a fix.
278   UMA_HISTOGRAM_ENUMERATION("Event.LatencyInfo.Debug.SourceIdConsistency",
279                             consistency);
280 }
281 
282 }  // namespace
283 
284 DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeRasterDurationHistogramTimer,
285                                   "Scheduling.%s.PendingTreeRasterDuration")
286 
DidUpdateScrollAnimationCurve()287 void LayerTreeHostImpl::DidUpdateScrollAnimationCurve() {
288   // Because we updated the animation target, notify the SwapPromiseMonitor
289   // to tell it that something happened that will cause a swap in the future.
290   // This will happen within the scope of the dispatch of a gesture scroll
291   // update input event. If we don't notify during the handling of the input
292   // event, the LatencyInfo associated with the input event will not be
293   // added as a swap promise and we won't get any swap results.
294   NotifySwapPromiseMonitorsOfSetNeedsRedraw();
295   events_metrics_manager_.SaveActiveEventMetrics();
296 }
297 
AccumulateScrollDeltaForTracing(const gfx::Vector2dF & delta)298 void LayerTreeHostImpl::AccumulateScrollDeltaForTracing(
299     const gfx::Vector2dF& delta) {
300   scroll_accumulated_this_frame_ += delta;
301 }
302 
DidStartPinchZoom()303 void LayerTreeHostImpl::DidStartPinchZoom() {
304   client_->RenewTreePriority();
305   frame_trackers_.StartSequence(FrameSequenceTrackerType::kPinchZoom);
306 }
307 
DidEndPinchZoom()308 void LayerTreeHostImpl::DidEndPinchZoom() {
309   // When a pinch ends, we may be displaying content cached at incorrect scales,
310   // so updating draw properties and drawing will ensure we are using the right
311   // scales that we want when we're not inside a pinch.
312   active_tree_->set_needs_update_draw_properties();
313   SetNeedsRedraw();
314   frame_trackers_.StopSequence(FrameSequenceTrackerType::kPinchZoom);
315 }
316 
DidUpdatePinchZoom()317 void LayerTreeHostImpl::DidUpdatePinchZoom() {
318   SetNeedsRedraw();
319   client_->RenewTreePriority();
320 }
321 
DidStartScroll()322 void LayerTreeHostImpl::DidStartScroll() {
323   scroll_affects_scroll_handler_ = active_tree()->have_scroll_event_handlers();
324   client_->RenewTreePriority();
325 }
326 
DidEndScroll()327 void LayerTreeHostImpl::DidEndScroll() {
328   scroll_affects_scroll_handler_ = false;
329 }
330 
DidMouseLeave()331 void LayerTreeHostImpl::DidMouseLeave() {
332   for (auto& pair : scrollbar_animation_controllers_)
333     pair.second->DidMouseLeave();
334 }
335 
SetNeedsFullViewportRedraw()336 void LayerTreeHostImpl::SetNeedsFullViewportRedraw() {
337   // TODO(bokan): Do these really need to be manually called? (Rather than
338   // damage/redraw being set from scroll offset changes).
339   SetFullViewportDamage();
340   SetNeedsRedraw();
341 }
342 
IsInHighLatencyMode() const343 bool LayerTreeHostImpl::IsInHighLatencyMode() const {
344   return impl_thread_phase_ == ImplThreadPhase::IDLE;
345 }
346 
GetSettings() const347 const LayerTreeSettings& LayerTreeHostImpl::GetSettings() const {
348   return settings();
349 }
350 
GetImplDeprecated()351 LayerTreeHostImpl& LayerTreeHostImpl::GetImplDeprecated() {
352   return *this;
353 }
354 
GetImplDeprecated() const355 const LayerTreeHostImpl& LayerTreeHostImpl::GetImplDeprecated() const {
356   return *this;
357 }
358 
359 LayerTreeHostImpl::FrameData::FrameData() = default;
360 LayerTreeHostImpl::FrameData::~FrameData() = default;
361 LayerTreeHostImpl::UIResourceData::UIResourceData() = default;
362 LayerTreeHostImpl::UIResourceData::~UIResourceData() = default;
363 LayerTreeHostImpl::UIResourceData::UIResourceData(UIResourceData&&) noexcept =
364     default;
365 LayerTreeHostImpl::UIResourceData& LayerTreeHostImpl::UIResourceData::operator=(
366     UIResourceData&&) = default;
367 
Create(const LayerTreeSettings & settings,LayerTreeHostImplClient * client,TaskRunnerProvider * task_runner_provider,RenderingStatsInstrumentation * rendering_stats_instrumentation,TaskGraphRunner * task_graph_runner,std::unique_ptr<MutatorHost> mutator_host,RasterDarkModeFilter * dark_mode_filter,int id,scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,LayerTreeHostSchedulingClient * scheduling_client)368 std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
369     const LayerTreeSettings& settings,
370     LayerTreeHostImplClient* client,
371     TaskRunnerProvider* task_runner_provider,
372     RenderingStatsInstrumentation* rendering_stats_instrumentation,
373     TaskGraphRunner* task_graph_runner,
374     std::unique_ptr<MutatorHost> mutator_host,
375     RasterDarkModeFilter* dark_mode_filter,
376     int id,
377     scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
378     LayerTreeHostSchedulingClient* scheduling_client) {
379   return base::WrapUnique(new LayerTreeHostImpl(
380       settings, client, task_runner_provider, rendering_stats_instrumentation,
381       task_graph_runner, std::move(mutator_host), dark_mode_filter, id,
382       std::move(image_worker_task_runner), scheduling_client));
383 }
384 
LayerTreeHostImpl(const LayerTreeSettings & settings,LayerTreeHostImplClient * client,TaskRunnerProvider * task_runner_provider,RenderingStatsInstrumentation * rendering_stats_instrumentation,TaskGraphRunner * task_graph_runner,std::unique_ptr<MutatorHost> mutator_host,RasterDarkModeFilter * dark_mode_filter,int id,scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,LayerTreeHostSchedulingClient * scheduling_client)385 LayerTreeHostImpl::LayerTreeHostImpl(
386     const LayerTreeSettings& settings,
387     LayerTreeHostImplClient* client,
388     TaskRunnerProvider* task_runner_provider,
389     RenderingStatsInstrumentation* rendering_stats_instrumentation,
390     TaskGraphRunner* task_graph_runner,
391     std::unique_ptr<MutatorHost> mutator_host,
392     RasterDarkModeFilter* dark_mode_filter,
393     int id,
394     scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
395     LayerTreeHostSchedulingClient* scheduling_client)
396     : client_(client),
397       scheduling_client_(scheduling_client),
398       task_runner_provider_(task_runner_provider),
399       current_begin_frame_tracker_(FROM_HERE),
400       compositor_frame_reporting_controller_(
401           std::make_unique<CompositorFrameReportingController>(
402               /*should_report_metrics=*/!settings.single_thread_proxy_scheduler,
403               id)),
404       settings_(settings),
405       is_synchronous_single_threaded_(!task_runner_provider->HasImplThread() &&
406                                       !settings_.single_thread_proxy_scheduler),
407       cached_managed_memory_policy_(settings.memory_policy),
408       // Must be initialized after is_synchronous_single_threaded_ and
409       // task_runner_provider_.
410       tile_manager_(this,
411                     GetTaskRunner(),
412                     std::move(image_worker_task_runner),
413                     is_synchronous_single_threaded_
414                         ? std::numeric_limits<size_t>::max()
415                         : settings.scheduled_raster_task_limit,
416                     settings.ToTileManagerSettings()),
417       memory_history_(MemoryHistory::Create()),
418       debug_rect_history_(DebugRectHistory::Create()),
419       mutator_host_(std::move(mutator_host)),
420       dark_mode_filter_(dark_mode_filter),
421       rendering_stats_instrumentation_(rendering_stats_instrumentation),
422       micro_benchmark_controller_(this),
423       task_graph_runner_(task_graph_runner),
424       id_(id),
425       consecutive_frame_with_damage_count_(settings.damaged_frame_limit),
426       // It is safe to use base::Unretained here since we will outlive the
427       // ImageAnimationController.
428       image_animation_controller_(GetTaskRunner(),
429                                   this,
430                                   settings_.enable_image_animation_resync),
431       paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()),
432       frame_trackers_(settings.single_thread_proxy_scheduler,
433                       compositor_frame_reporting_controller_.get()),
434       lcd_text_metrics_reporter_(LCDTextMetricsReporter::CreateIfNeeded(this)),
435       frame_rate_estimator_(GetTaskRunner()),
436       contains_srgb_cache_(kContainsSrgbCacheSize) {
437   DCHECK(mutator_host_);
438   mutator_host_->SetMutatorHostClient(this);
439   mutator_events_ = mutator_host_->CreateEvents();
440 
441   DCHECK(task_runner_provider_->IsImplThread());
442   DidVisibilityChange(this, visible_);
443 
444   // LTHI always has an active tree.
445   active_tree_ = std::make_unique<LayerTreeImpl>(
446       this, new SyncedProperty<ScaleGroup>, new SyncedBrowserControls,
447       new SyncedBrowserControls, new SyncedElasticOverscroll);
448   active_tree_->property_trees()->is_active = true;
449 
450   viewport_ = Viewport::Create(this);
451 
452   TRACE_EVENT_OBJECT_CREATED_WITH_ID(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
453                                      "cc::LayerTreeHostImpl", id_);
454 
455   browser_controls_offset_manager_ = BrowserControlsOffsetManager::Create(
456       this, settings.top_controls_show_threshold,
457       settings.top_controls_hide_threshold);
458 
459   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
460           switches::kDisableLayerTreeHostMemoryPressure)) {
461     memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
462         FROM_HERE, base::BindRepeating(&LayerTreeHostImpl::OnMemoryPressure,
463                                        base::Unretained(this)));
464   }
465 
466   SetDebugState(settings.initial_debug_state);
467   compositor_frame_reporting_controller_->SetDroppedFrameCounter(
468       &dropped_frame_counter_);
469 
470   dropped_frame_counter_.set_total_counter(&total_frame_counter_);
471   frame_trackers_.set_custom_tracker_results_added_callback(
472       base::BindRepeating(&LayerTreeHostImpl::NotifyThroughputTrackerResults,
473                           weak_factory_.GetWeakPtr()));
474 }
475 
~LayerTreeHostImpl()476 LayerTreeHostImpl::~LayerTreeHostImpl() {
477   DCHECK(task_runner_provider_->IsImplThread());
478   TRACE_EVENT0("cc", "LayerTreeHostImpl::~LayerTreeHostImpl()");
479   TRACE_EVENT_OBJECT_DELETED_WITH_ID(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
480                                      "cc::LayerTreeHostImpl", id_);
481 
482   // The frame sink is released before shutdown, which takes down
483   // all the resource and raster structures.
484   DCHECK(!layer_tree_frame_sink_);
485   DCHECK(!resource_pool_);
486   DCHECK(!image_decode_cache_);
487   DCHECK(!single_thread_synchronous_task_graph_runner_);
488 
489   if (input_delegate_)
490     input_delegate_->WillShutdown();
491 
492   // The layer trees must be destroyed before the LayerTreeHost. Also, if they
493   // are holding onto any resources, destroying them will release them, before
494   // we mark any leftover resources as lost.
495   if (recycle_tree_)
496     recycle_tree_->Shutdown();
497   if (pending_tree_)
498     pending_tree_->Shutdown();
499   active_tree_->Shutdown();
500   recycle_tree_ = nullptr;
501   pending_tree_ = nullptr;
502   active_tree_ = nullptr;
503 
504   // All resources should already be removed, so lose anything still exported.
505   resource_provider_.ShutdownAndReleaseAllResources();
506 
507   mutator_host_->ClearMutators();
508   mutator_host_->SetMutatorHostClient(nullptr);
509 
510   // Clear the UKM Manager so that we do not try to report when the
511   // UKM System has shut down.
512   compositor_frame_reporting_controller_->SetUkmManager(nullptr);
513   compositor_frame_reporting_controller_ = nullptr;
514 }
515 
GetInputHandler()516 ThreadedInputHandler& LayerTreeHostImpl::GetInputHandler() {
517   DCHECK(input_delegate_) << "Requested InputHandler when one wasn't bound. "
518                              "Call BindToInputHandler to bind to one";
519   return static_cast<ThreadedInputHandler&>(*input_delegate_.get());
520 }
521 
GetInputHandler() const522 const ThreadedInputHandler& LayerTreeHostImpl::GetInputHandler() const {
523   DCHECK(input_delegate_) << "Requested InputHandler when one wasn't bound. "
524                              "Call BindToInputHandler to bind to one";
525   return static_cast<const ThreadedInputHandler&>(*input_delegate_.get());
526 }
527 
WillSendBeginMainFrame()528 void LayerTreeHostImpl::WillSendBeginMainFrame() {
529   if (scheduling_client_)
530     scheduling_client_->DidScheduleBeginMainFrame();
531 }
532 
DidSendBeginMainFrame(const viz::BeginFrameArgs & args)533 void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) {
534   frame_trackers_.NotifyBeginMainFrame(args);
535 }
536 
BeginMainFrameAborted(CommitEarlyOutReason reason,std::vector<std::unique_ptr<SwapPromise>> swap_promises,const viz::BeginFrameArgs & args)537 void LayerTreeHostImpl::BeginMainFrameAborted(
538     CommitEarlyOutReason reason,
539     std::vector<std::unique_ptr<SwapPromise>> swap_promises,
540     const viz::BeginFrameArgs& args) {
541   if (reason == CommitEarlyOutReason::ABORTED_NOT_VISIBLE ||
542       reason == CommitEarlyOutReason::FINISHED_NO_UPDATES) {
543     frame_trackers_.NotifyMainFrameCausedNoDamage(args);
544   } else {
545     frame_trackers_.NotifyMainFrameProcessed(args);
546   }
547 
548   // If the begin frame data was handled, then scroll and scale set was applied
549   // by the main thread, so the active tree needs to be updated as if these sent
550   // values were applied and committed.
551   if (CommitEarlyOutHandledCommit(reason)) {
552     active_tree_->ApplySentScrollAndScaleDeltasFromAbortedCommit();
553     if (pending_tree_) {
554       pending_tree_->AppendSwapPromises(std::move(swap_promises));
555     } else {
556       for (const auto& swap_promise : swap_promises)
557         swap_promise->DidNotSwap(SwapPromise::COMMIT_NO_UPDATE);
558     }
559   }
560 }
561 
ReadyToCommit(const viz::BeginFrameArgs & commit_args,const BeginMainFrameMetrics * begin_main_frame_metrics)562 void LayerTreeHostImpl::ReadyToCommit(
563     const viz::BeginFrameArgs& commit_args,
564     const BeginMainFrameMetrics* begin_main_frame_metrics) {
565   frame_trackers_.NotifyMainFrameProcessed(commit_args);
566   if (!is_measuring_smoothness_ && begin_main_frame_metrics &&
567       begin_main_frame_metrics->should_measure_smoothness) {
568     is_measuring_smoothness_ = true;
569     total_frame_counter_.Reset();
570     dropped_frame_counter_.OnFcpReceived();
571   }
572 }
573 
BeginCommit()574 void LayerTreeHostImpl::BeginCommit() {
575   TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit");
576 
577   if (!CommitToActiveTree())
578     CreatePendingTree();
579 }
580 
CommitComplete()581 void LayerTreeHostImpl::CommitComplete() {
582   TRACE_EVENT0("cc", "LayerTreeHostImpl::CommitComplete");
583 
584   if (input_delegate_)
585     input_delegate_->DidCommit();
586 
587   if (CommitToActiveTree()) {
588     active_tree_->HandleScrollbarShowRequestsFromMain();
589 
590     // Property tree nodes have been updated by the commit. Update elements
591     // available on active tree to start/stop ticking animations.
592     UpdateElements(ElementListType::ACTIVE);
593 
594     // We have to activate animations here or "IsActive()" is true on the layers
595     // but the animations aren't activated yet so they get ignored by
596     // UpdateDrawProperties.
597     ActivateAnimations();
598   }
599 
600   // We clear the entries that were never mutated by CC animations from the last
601   // commit until now. Moreover, we reset the values of input properties and
602   // relies on the fact that CC animation will mutate those values when pending
603   // tree is animated below.
604   // With that, when CC finishes animating an input property, the value of that
605   // property stays at finish state until a commit kicks in, which is consistent
606   // with current composited animations.
607   paint_worklet_tracker_.ClearUnusedInputProperties();
608 
609   // Start animations before UpdateDrawProperties and PrepareTiles, as they can
610   // change the results. When doing commit to the active tree, this must happen
611   // after ActivateAnimations() in order for this ticking to be propogated
612   // to layers on the active tree.
613   if (CommitToActiveTree())
614     Animate();
615   else
616     AnimatePendingTreeAfterCommit();
617 
618   UpdateSyncTreeAfterCommitOrImplSideInvalidation();
619   micro_benchmark_controller_.DidCompleteCommit();
620 
621   if (mutator_host_->CurrentFrameHadRAF())
622     frame_trackers_.StartSequence(FrameSequenceTrackerType::kRAF);
623   if (mutator_host_->HasCanvasInvalidation())
624     frame_trackers_.StartSequence(FrameSequenceTrackerType::kCanvasAnimation);
625   if (mutator_host_->HasJSAnimation())
626     frame_trackers_.StartSequence(FrameSequenceTrackerType::kJSAnimation);
627 
628   if (mutator_host_->MainThreadAnimationsCount() > 0) {
629     frame_trackers_.StartSequence(
630         FrameSequenceTrackerType::kMainThreadAnimation);
631   }
632 
633   for (const auto& info : mutator_host_->TakePendingThroughputTrackerInfos()) {
634     const MutatorHost::TrackedAnimationSequenceId sequence_id = info.id;
635     const bool start = info.start;
636     if (start)
637       frame_trackers_.StartCustomSequence(sequence_id);
638     else
639       frame_trackers_.StopCustomSequence(sequence_id);
640   }
641 }
642 
UpdateSyncTreeAfterCommitOrImplSideInvalidation()643 void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() {
644   // LayerTreeHost may have changed the GPU rasterization flags state, which
645   // may require an update of the tree resources.
646   UpdateTreeResourcesForGpuRasterizationIfNeeded();
647   sync_tree()->set_needs_update_draw_properties();
648 
649   // We need an update immediately post-commit to have the opportunity to create
650   // tilings.
651   // We can avoid updating the ImageAnimationController during this
652   // DrawProperties update since it will be done when we animate the controller
653   // below.
654   bool update_image_animation_controller = false;
655   sync_tree()->UpdateDrawProperties(update_image_animation_controller);
656 
657   // Defer invalidating images until UpdateDrawProperties is performed since
658   // that updates whether an image should be animated based on its visibility
659   // and the updated data for the image from the main frame.
660   PaintImageIdFlatSet images_to_invalidate =
661       tile_manager_.TakeImagesToInvalidateOnSyncTree();
662   if (ukm_manager_)
663     ukm_manager_->AddCheckerboardedImages(images_to_invalidate.size());
664 
665   const auto& animated_images =
666       image_animation_controller_.AnimateForSyncTree(CurrentBeginFrameArgs());
667   images_to_invalidate.insert(animated_images.begin(), animated_images.end());
668 
669   // Invalidate cached PaintRecords for worklets whose input properties were
670   // mutated since the last pending tree. We keep requesting invalidations until
671   // the animation is ticking on impl thread. Note that this works since the
672   // animation starts ticking on the pending tree
673   // (AnimatePendingTreeAfterCommit) which committed this animation timeline.
674   // After this the animation may only tick on the active tree for impl-side
675   // invalidations (since AnimatePendingTreeAfterCommit is not done for pending
676   // trees created by impl-side invalidations). But we ensure here that we
677   // request another invalidation if an input property was mutated on the active
678   // tree.
679   if (paint_worklet_tracker_.InvalidatePaintWorkletsOnPendingTree()) {
680     client_->NeedsImplSideInvalidation(
681         true /* needs_first_draw_on_activation */);
682   }
683   PaintImageIdFlatSet dirty_paint_worklet_ids;
684   PaintWorkletJobMap dirty_paint_worklets =
685       GatherDirtyPaintWorklets(&dirty_paint_worklet_ids);
686   images_to_invalidate.insert(dirty_paint_worklet_ids.begin(),
687                               dirty_paint_worklet_ids.end());
688 
689   sync_tree()->InvalidateRegionForImages(images_to_invalidate);
690 
691   // Note that it is important to push the state for checkerboarded and animated
692   // images prior to PrepareTiles here when committing to the active tree. This
693   // is because new tiles on the active tree depend on tree specific state
694   // cached in these components, which must be pushed to active before preparing
695   // tiles for the updated active tree.
696   if (CommitToActiveTree())
697     ActivateStateForImages();
698 
699   if (!paint_worklet_painter_) {
700     // Blink should not send us any PaintWorklet inputs until we have a painter
701     // registered.
702     DCHECK(sync_tree()->picture_layers_with_paint_worklets().empty());
703     pending_tree_fully_painted_ = true;
704     NotifyPendingTreeFullyPainted();
705     return;
706   }
707 
708   if (!dirty_paint_worklets.size()) {
709     pending_tree_fully_painted_ = true;
710     NotifyPendingTreeFullyPainted();
711     return;
712   }
713 
714   client_->NotifyPaintWorkletStateChange(
715       Scheduler::PaintWorkletState::PROCESSING);
716   auto done_callback = base::BindOnce(
717       &LayerTreeHostImpl::OnPaintWorkletResultsReady, base::Unretained(this));
718   paint_worklet_painter_->DispatchWorklets(std::move(dirty_paint_worklets),
719                                            std::move(done_callback));
720 }
721 
GatherDirtyPaintWorklets(PaintImageIdFlatSet * dirty_paint_worklet_ids) const722 PaintWorkletJobMap LayerTreeHostImpl::GatherDirtyPaintWorklets(
723     PaintImageIdFlatSet* dirty_paint_worklet_ids) const {
724   PaintWorkletJobMap dirty_paint_worklets;
725   for (PictureLayerImpl* layer :
726        sync_tree()->picture_layers_with_paint_worklets()) {
727     for (const auto& entry : layer->GetPaintWorkletRecordMap()) {
728       const scoped_refptr<const PaintWorkletInput>& input = entry.first;
729       const PaintImage::Id& paint_image_id = entry.second.first;
730       const sk_sp<PaintRecord>& record = entry.second.second;
731       // If we already have a record we can reuse it and so the
732       // PaintWorkletInput isn't dirty.
733       if (record)
734         continue;
735 
736       // Mark this PaintWorklet as needing invalidation.
737       dirty_paint_worklet_ids->insert(paint_image_id);
738 
739       // Create an entry in the appropriate PaintWorkletJobVector for this dirty
740       // PaintWorklet.
741       int worklet_id = input->WorkletId();
742       auto& job_vector = dirty_paint_worklets[worklet_id];
743       if (!job_vector)
744         job_vector = base::MakeRefCounted<PaintWorkletJobVector>();
745 
746       PaintWorkletJob::AnimatedPropertyValues animated_property_values;
747       for (const auto& element : input->GetPropertyKeys()) {
748         // We should not have multiple property ids with the same name.
749         DCHECK(!animated_property_values.contains(element.first));
750         const PaintWorkletInput::PropertyValue& animated_property_value =
751             paint_worklet_tracker_.GetPropertyAnimationValue(element);
752         // No value indicates that the input property was not mutated by CC
753         // animation.
754         if (animated_property_value.has_value()) {
755           animated_property_values.emplace(element.first,
756                                            animated_property_value);
757         }
758       }
759 
760       job_vector->data.emplace_back(layer->id(), input,
761                                     std::move(animated_property_values));
762     }
763   }
764   return dirty_paint_worklets;
765 }
766 
OnPaintWorkletResultsReady(PaintWorkletJobMap results)767 void LayerTreeHostImpl::OnPaintWorkletResultsReady(PaintWorkletJobMap results) {
768 #if DCHECK_IS_ON()
769   // Nothing else should have painted the PaintWorklets while we were waiting,
770   // and the results should have painted every PaintWorklet, so these should be
771   // the same.
772   PaintImageIdFlatSet dirty_paint_worklet_ids;
773   DCHECK_EQ(results.size(),
774             GatherDirtyPaintWorklets(&dirty_paint_worklet_ids).size());
775 #endif
776 
777   for (const auto& entry : results) {
778     for (const PaintWorkletJob& job : entry.second->data) {
779       LayerImpl* layer_impl =
780           pending_tree_->FindPendingTreeLayerById(job.layer_id());
781       // Painting the pending tree occurs asynchronously but stalls the pending
782       // tree pipeline, so nothing should have changed while we were doing that.
783       DCHECK(layer_impl);
784       static_cast<PictureLayerImpl*>(layer_impl)
785           ->SetPaintWorkletRecord(job.input(), job.output());
786     }
787   }
788 
789   // While the pending tree is being painted by PaintWorklets, we restrict the
790   // tiles the TileManager is able to see. This may cause the TileManager to
791   // believe that it has finished rastering all the necessary tiles. When we
792   // finish painting the tree and release all the tiles, we need to mark the
793   // tile priorities as dirty so that the TileManager logic properly re-runs.
794   tile_priorities_dirty_ = true;
795 
796   // Set the painted state before calling the scheduler, to ensure any callback
797   // running as a result sees the correct painted state.
798   pending_tree_fully_painted_ = true;
799   client_->NotifyPaintWorkletStateChange(Scheduler::PaintWorkletState::IDLE);
800 
801   // The pending tree may have been force activated from the signal to the
802   // scheduler above, in which case there is no longer a tree to paint.
803   if (pending_tree_)
804     NotifyPendingTreeFullyPainted();
805 }
806 
NotifyPendingTreeFullyPainted()807 void LayerTreeHostImpl::NotifyPendingTreeFullyPainted() {
808   // The pending tree must be fully painted at this point.
809   DCHECK(pending_tree_fully_painted_);
810 
811   // Nobody should claim the pending tree is fully painted if there is an
812   // ongoing dispatch.
813   DCHECK(!paint_worklet_painter_ ||
814          !paint_worklet_painter_->HasOngoingDispatch());
815 
816   // Start working on newly created tiles immediately if needed.
817   // TODO(vmpstr): Investigate always having PrepareTiles issue
818   // NotifyReadyToActivate, instead of handling it here.
819   bool did_prepare_tiles = PrepareTiles();
820   if (!did_prepare_tiles) {
821     NotifyReadyToActivate();
822 
823     // Ensure we get ReadyToDraw signal even when PrepareTiles not run. This
824     // is important for SingleThreadProxy and impl-side painting case. For
825     // STP, we commit to active tree and RequiresHighResToDraw, and set
826     // Scheduler to wait for ReadyToDraw signal to avoid Checkerboard.
827     if (CommitToActiveTree())
828       NotifyReadyToDraw();
829   } else if (!CommitToActiveTree()) {
830     DCHECK(!pending_tree_raster_duration_timer_);
831     pending_tree_raster_duration_timer_ =
832         std::make_unique<PendingTreeRasterDurationHistogramTimer>();
833   }
834 }
835 
CanDraw() const836 bool LayerTreeHostImpl::CanDraw() const {
837   // Note: If you are changing this function or any other function that might
838   // affect the result of CanDraw, make sure to call
839   // client_->OnCanDrawStateChanged in the proper places and update the
840   // NotifyIfCanDrawChanged test.
841 
842   if (!layer_tree_frame_sink_) {
843     TRACE_EVENT_INSTANT0("cc",
844                          "LayerTreeHostImpl::CanDraw no LayerTreeFrameSink",
845                          TRACE_EVENT_SCOPE_THREAD);
846     return false;
847   }
848 
849   // TODO(boliu): Make draws without layers work and move this below
850   // |resourceless_software_draw_| check. Tracked in crbug.com/264967.
851   if (active_tree_->LayerListIsEmpty()) {
852     TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw no root layer",
853                          TRACE_EVENT_SCOPE_THREAD);
854     return false;
855   }
856 
857   if (resourceless_software_draw_)
858     return true;
859 
860   if (active_tree_->GetDeviceViewport().IsEmpty()) {
861     TRACE_EVENT_INSTANT0("cc", "LayerTreeHostImpl::CanDraw empty viewport",
862                          TRACE_EVENT_SCOPE_THREAD);
863     return false;
864   }
865   if (EvictedUIResourcesExist()) {
866     TRACE_EVENT_INSTANT0(
867         "cc", "LayerTreeHostImpl::CanDraw UI resources evicted not recreated",
868         TRACE_EVENT_SCOPE_THREAD);
869     return false;
870   }
871   return true;
872 }
873 
AnimatePendingTreeAfterCommit()874 void LayerTreeHostImpl::AnimatePendingTreeAfterCommit() {
875   // Animate the pending tree layer animations to put them at initial positions
876   // and starting state. There is no need to run other animations on pending
877   // tree because they depend on user inputs so the state is identical to what
878   // the active tree has.
879   AnimateLayers(CurrentBeginFrameArgs().frame_time, /* is_active_tree */ false);
880 }
881 
Animate()882 void LayerTreeHostImpl::Animate() {
883   AnimateInternal();
884 }
885 
AnimateInternal()886 void LayerTreeHostImpl::AnimateInternal() {
887   DCHECK(task_runner_provider_->IsImplThread());
888   base::TimeTicks monotonic_time = CurrentBeginFrameArgs().frame_time;
889 
890   // mithro(TODO): Enable these checks.
891   // DCHECK(!current_begin_frame_tracker_.HasFinished());
892   // DCHECK(monotonic_time == current_begin_frame_tracker_.Current().frame_time)
893   //  << "Called animate with unknown frame time!?";
894 
895   bool did_animate = false;
896 
897   // TODO(bokan): This should return did_animate, see TODO in
898   // ElasticOverscrollController::Animate. crbug.com/551138.
899   if (input_delegate_)
900     input_delegate_->TickAnimations(monotonic_time);
901 
902   did_animate |= AnimatePageScale(monotonic_time);
903   did_animate |= AnimateLayers(monotonic_time, /* is_active_tree */ true);
904   did_animate |= AnimateScrollbars(monotonic_time);
905   did_animate |= AnimateBrowserControls(monotonic_time);
906 
907   if (did_animate) {
908     // Animating stuff can change the root scroll offset, so inform the
909     // synchronous input handler.
910     if (input_delegate_)
911       input_delegate_->RootLayerStateMayHaveChanged();
912 
913     // If the tree changed, then we want to draw at the end of the current
914     // frame.
915     SetNeedsRedraw();
916   }
917 }
918 
PrepareTiles()919 bool LayerTreeHostImpl::PrepareTiles() {
920   if (!tile_priorities_dirty_)
921     return false;
922 
923   client_->WillPrepareTiles();
924   bool did_prepare_tiles = tile_manager_.PrepareTiles(global_tile_state_);
925   if (did_prepare_tiles)
926     tile_priorities_dirty_ = false;
927   client_->DidPrepareTiles();
928   return did_prepare_tiles;
929 }
930 
StartPageScaleAnimation(const gfx::Vector2d & target_offset,bool anchor_point,float page_scale,base::TimeDelta duration)931 void LayerTreeHostImpl::StartPageScaleAnimation(
932     const gfx::Vector2d& target_offset,
933     bool anchor_point,
934     float page_scale,
935     base::TimeDelta duration) {
936   // Temporary crash logging for https://crbug.com/845097.
937   static bool has_dumped_without_crashing = false;
938   if (settings().is_layer_tree_for_subframe && !has_dumped_without_crashing) {
939     has_dumped_without_crashing = true;
940     static auto* psf_oopif_animation_error =
941         base::debug::AllocateCrashKeyString("psf_oopif_animation_error",
942                                             base::debug::CrashKeySize::Size32);
943     base::debug::SetCrashKeyString(
944         psf_oopif_animation_error,
945         base::StringPrintf("%p", InnerViewportScrollNode()));
946     base::debug::DumpWithoutCrashing();
947   }
948 
949   if (!InnerViewportScrollNode())
950     return;
951 
952   gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset();
953   gfx::SizeF scrollable_size = active_tree_->ScrollableSize();
954   gfx::SizeF viewport_size(
955       active_tree_->InnerViewportScrollNode()->container_bounds);
956 
957   // TODO(miletus) : Pass in ScrollOffset.
958   page_scale_animation_ =
959       PageScaleAnimation::Create(ScrollOffsetToVector2dF(scroll_total),
960                                  active_tree_->current_page_scale_factor(),
961                                  viewport_size, scrollable_size);
962 
963   if (anchor_point) {
964     gfx::Vector2dF anchor(target_offset);
965     page_scale_animation_->ZoomWithAnchor(anchor, page_scale,
966                                           duration.InSecondsF());
967   } else {
968     gfx::Vector2dF scaled_target_offset = target_offset;
969     page_scale_animation_->ZoomTo(scaled_target_offset, page_scale,
970                                   duration.InSecondsF());
971   }
972 
973   SetNeedsOneBeginImplFrame();
974   client_->SetNeedsCommitOnImplThread();
975   client_->RenewTreePriority();
976 }
977 
SetNeedsAnimateInput()978 void LayerTreeHostImpl::SetNeedsAnimateInput() {
979   SetNeedsOneBeginImplFrame();
980 }
981 
982 std::unique_ptr<SwapPromiseMonitor>
CreateLatencyInfoSwapPromiseMonitor(ui::LatencyInfo * latency)983 LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor(
984     ui::LatencyInfo* latency) {
985   return base::WrapUnique(new LatencyInfoSwapPromiseMonitor(latency, this));
986 }
987 
988 std::unique_ptr<EventsMetricsManager::ScopedMonitor>
GetScopedEventMetricsMonitor(EventsMetricsManager::ScopedMonitor::DoneCallback done_callback)989 LayerTreeHostImpl::GetScopedEventMetricsMonitor(
990     EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) {
991   return events_metrics_manager_.GetScopedMonitor(std::move(done_callback));
992 }
993 
NotifyInputEvent()994 void LayerTreeHostImpl::NotifyInputEvent() {
995   frame_rate_estimator_.NotifyInputEvent();
996 }
997 
QueueSwapPromiseForMainThreadScrollUpdate(std::unique_ptr<SwapPromise> swap_promise)998 void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate(
999     std::unique_ptr<SwapPromise> swap_promise) {
1000   swap_promises_for_main_thread_scroll_update_.push_back(
1001       std::move(swap_promise));
1002 }
1003 
AsValueInto(base::trace_event::TracedValue * value) const1004 void LayerTreeHostImpl::FrameData::AsValueInto(
1005     base::trace_event::TracedValue* value) const {
1006   value->SetBoolean("has_no_damage", has_no_damage);
1007 
1008   // Quad data can be quite large, so only dump render passes if we are
1009   // logging verbosely or viz.quads tracing category is enabled.
1010   bool quads_enabled = VLOG_IS_ON(3);
1011   if (!quads_enabled) {
1012     TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"),
1013                                        &quads_enabled);
1014   }
1015   if (quads_enabled) {
1016     value->BeginArray("render_passes");
1017     for (size_t i = 0; i < render_passes.size(); ++i) {
1018       value->BeginDictionary();
1019       render_passes[i]->AsValueInto(value);
1020       value->EndDictionary();
1021     }
1022     value->EndArray();
1023   }
1024 }
1025 
ToString() const1026 std::string LayerTreeHostImpl::FrameData::ToString() const {
1027   base::trace_event::TracedValueJSON value;
1028   AsValueInto(&value);
1029   return value.ToFormattedJSON();
1030 }
1031 
GetDrawMode() const1032 DrawMode LayerTreeHostImpl::GetDrawMode() const {
1033   if (resourceless_software_draw_) {
1034     return DRAW_MODE_RESOURCELESS_SOFTWARE;
1035   } else if (layer_tree_frame_sink_->context_provider()) {
1036     return DRAW_MODE_HARDWARE;
1037   } else {
1038     return DRAW_MODE_SOFTWARE;
1039   }
1040 }
1041 
AppendQuadsToFillScreen(viz::CompositorRenderPass * target_render_pass,const RenderSurfaceImpl * root_render_surface,SkColor screen_background_color,const Region & fill_region)1042 static void AppendQuadsToFillScreen(
1043     viz::CompositorRenderPass* target_render_pass,
1044     const RenderSurfaceImpl* root_render_surface,
1045     SkColor screen_background_color,
1046     const Region& fill_region) {
1047   if (!root_render_surface || !SkColorGetA(screen_background_color))
1048     return;
1049   if (fill_region.IsEmpty())
1050     return;
1051 
1052   // Manually create the quad state for the gutter quads, as the root layer
1053   // doesn't have any bounds and so can't generate this itself.
1054   // TODO(danakj): Make the gutter quads generated by the solid color layer
1055   // (make it smarter about generating quads to fill unoccluded areas).
1056 
1057   gfx::Rect root_target_rect = root_render_surface->content_rect();
1058   float opacity = 1.f;
1059   int sorting_context_id = 0;
1060   bool are_contents_opaque = SkColorGetA(screen_background_color) == 0xFF;
1061   viz::SharedQuadState* shared_quad_state =
1062       target_render_pass->CreateAndAppendSharedQuadState();
1063   shared_quad_state->SetAll(gfx::Transform(), root_target_rect,
1064                             root_target_rect, gfx::MaskFilterInfo(),
1065                             root_target_rect, false, are_contents_opaque,
1066                             opacity, SkBlendMode::kSrcOver, sorting_context_id);
1067 
1068   for (gfx::Rect screen_space_rect : fill_region) {
1069     gfx::Rect visible_screen_space_rect = screen_space_rect;
1070     // Skip the quad culler and just append the quads directly to avoid
1071     // occlusion checks.
1072     auto* quad =
1073         target_render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>();
1074     quad->SetNew(shared_quad_state, screen_space_rect,
1075                  visible_screen_space_rect, screen_background_color, false);
1076   }
1077 }
1078 
FindRenderPassById(const viz::CompositorRenderPassList & list,viz::CompositorRenderPassId id)1079 static viz::CompositorRenderPass* FindRenderPassById(
1080     const viz::CompositorRenderPassList& list,
1081     viz::CompositorRenderPassId id) {
1082   auto it =
1083       std::find_if(list.begin(), list.end(),
1084                    [id](const std::unique_ptr<viz::CompositorRenderPass>& p) {
1085                      return p->id == id;
1086                    });
1087   return it == list.end() ? nullptr : it->get();
1088 }
1089 
HasDamage() const1090 bool LayerTreeHostImpl::HasDamage() const {
1091   DCHECK(!active_tree()->needs_update_draw_properties());
1092   DCHECK(CanDraw());
1093 
1094   // When touch handle visibility changes there is no visible damage
1095   // because touch handles are composited in the browser. However we
1096   // still want the browser to be notified that the handles changed
1097   // through the |ViewHostMsg_SwapCompositorFrame| IPC so we keep
1098   // track of handle visibility changes here.
1099   if (active_tree()->HandleVisibilityChanged())
1100     return true;
1101 
1102   if (!viewport_damage_rect_.IsEmpty())
1103     return true;
1104 
1105   // If the set of referenced surfaces has changed then we must submit a new
1106   // CompositorFrame to update surface references.
1107   if (last_draw_referenced_surfaces_ != active_tree()->SurfaceRanges())
1108     return true;
1109 
1110   // If we have a new LocalSurfaceId, we must always submit a CompositorFrame
1111   // because the parent is blocking on us.
1112   if (last_draw_local_surface_id_ !=
1113       child_local_surface_id_allocator_.GetCurrentLocalSurfaceId()) {
1114     return true;
1115   }
1116 
1117   const LayerTreeImpl* active_tree = active_tree_.get();
1118 
1119   // If the root render surface has no visible damage, then don't generate a
1120   // frame at all.
1121   const RenderSurfaceImpl* root_surface = active_tree->RootRenderSurface();
1122   bool root_surface_has_visible_damage =
1123       root_surface->GetDamageRect().Intersects(root_surface->content_rect());
1124   bool hud_wants_to_draw_ = active_tree->hud_layer() &&
1125                             active_tree->hud_layer()->IsAnimatingHUDContents();
1126 
1127   return root_surface_has_visible_damage ||
1128          active_tree_->property_trees()->effect_tree.HasCopyRequests() ||
1129          hud_wants_to_draw_;
1130 }
1131 
CalculateRenderPasses(FrameData * frame)1132 DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) {
1133   DCHECK(frame->render_passes.empty());
1134   DCHECK(CanDraw());
1135   DCHECK(!active_tree_->LayerListIsEmpty());
1136 
1137   // For now, we use damage tracking to compute a global scissor. To do this, we
1138   // must compute all damage tracking before drawing anything, so that we know
1139   // the root damage rect. The root damage rect is then used to scissor each
1140   // surface.
1141   DamageTracker::UpdateDamageTracking(active_tree_.get());
1142 
1143   if (HasDamage()) {
1144     consecutive_frame_with_damage_count_++;
1145   } else {
1146     TRACE_EVENT0("cc",
1147                  "LayerTreeHostImpl::CalculateRenderPasses::EmptyDamageRect");
1148     frame->has_no_damage = true;
1149     DCHECK(!resourceless_software_draw_);
1150     consecutive_frame_with_damage_count_ = 0;
1151     return DRAW_SUCCESS;
1152   }
1153 
1154   TRACE_EVENT_BEGIN2("cc,benchmark", "LayerTreeHostImpl::CalculateRenderPasses",
1155                      "render_surface_list.size()",
1156                      static_cast<uint64_t>(frame->render_surface_list->size()),
1157                      "RequiresHighResToDraw", RequiresHighResToDraw());
1158 
1159   // HandleVisibilityChanged contributed to the above damage check, so reset it
1160   // now that we're going to draw.
1161   // TODO(jamwalla): only call this if we are sure the frame draws. Tracked in
1162   // crbug.com/805673.
1163   active_tree_->ResetHandleVisibilityChanged();
1164 
1165   // Create the render passes in dependency order.
1166   size_t render_surface_list_size = frame->render_surface_list->size();
1167   for (size_t i = 0; i < render_surface_list_size; ++i) {
1168     size_t surface_index = render_surface_list_size - 1 - i;
1169     RenderSurfaceImpl* render_surface =
1170         (*frame->render_surface_list)[surface_index];
1171 
1172     bool is_root_surface =
1173         render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId;
1174     bool should_draw_into_render_pass =
1175         is_root_surface || render_surface->contributes_to_drawn_surface() ||
1176         render_surface->HasCopyRequest() ||
1177         render_surface->ShouldCacheRenderSurface();
1178     if (should_draw_into_render_pass)
1179       frame->render_passes.push_back(render_surface->CreateRenderPass());
1180   }
1181 
1182   // Damage rects for non-root passes aren't meaningful, so set them to be
1183   // equal to the output rect.
1184   for (size_t i = 0; i + 1 < frame->render_passes.size(); ++i) {
1185     viz::CompositorRenderPass* pass = frame->render_passes[i].get();
1186     pass->damage_rect = pass->output_rect;
1187   }
1188 
1189   // When we are displaying the HUD, change the root damage rect to cover the
1190   // entire root surface. This will disable partial-swap/scissor optimizations
1191   // that would prevent the HUD from updating, since the HUD does not cause
1192   // damage itself, to prevent it from messing with damage visualizations. Since
1193   // damage visualizations are done off the LayerImpls and RenderSurfaceImpls,
1194   // changing the RenderPass does not affect them.
1195   if (active_tree_->hud_layer()) {
1196     viz::CompositorRenderPass* root_pass = frame->render_passes.back().get();
1197     root_pass->damage_rect = root_pass->output_rect;
1198   }
1199 
1200   // Grab this region here before iterating layers. Taking copy requests from
1201   // the layers while constructing the render passes will dirty the render
1202   // surface layer list and this unoccluded region, flipping the dirty bit to
1203   // true, and making us able to query for it without doing
1204   // UpdateDrawProperties again. The value inside the Region is not actually
1205   // changed until UpdateDrawProperties happens, so a reference to it is safe.
1206   const Region& unoccluded_screen_space_region =
1207       active_tree_->UnoccludedScreenSpaceRegion();
1208 
1209   // Typically when we are missing a texture and use a checkerboard quad, we
1210   // still draw the frame. However when the layer being checkerboarded is moving
1211   // due to an impl-animation, we drop the frame to avoid flashing due to the
1212   // texture suddenly appearing in the future.
1213   DrawResult draw_result = DRAW_SUCCESS;
1214 
1215   const DrawMode draw_mode = GetDrawMode();
1216 
1217   int num_missing_tiles = 0;
1218   int num_incomplete_tiles = 0;
1219   int64_t checkerboarded_no_recording_content_area = 0;
1220   int64_t checkerboarded_needs_raster_content_area = 0;
1221   int64_t total_visible_area = 0;
1222   bool have_copy_request =
1223       active_tree()->property_trees()->effect_tree.HasCopyRequests();
1224   bool have_missing_animated_tiles = false;
1225   int num_of_layers_with_videos = 0;
1226 
1227   // Advance our de-jelly state. This is a no-op if de-jelly is not active.
1228   de_jelly_state_.AdvanceFrame(active_tree_.get());
1229 
1230   for (EffectTreeLayerListIterator it(active_tree());
1231        it.state() != EffectTreeLayerListIterator::State::END; ++it) {
1232     auto target_render_pass_id = it.target_render_surface()->render_pass_id();
1233     viz::CompositorRenderPass* target_render_pass =
1234         FindRenderPassById(frame->render_passes, target_render_pass_id);
1235 
1236     AppendQuadsData append_quads_data;
1237 
1238     if (it.state() == EffectTreeLayerListIterator::State::TARGET_SURFACE) {
1239       RenderSurfaceImpl* render_surface = it.target_render_surface();
1240       if (render_surface->HasCopyRequest()) {
1241         active_tree()
1242             ->property_trees()
1243             ->effect_tree.TakeCopyRequestsAndTransformToSurface(
1244                 render_surface->EffectTreeIndex(),
1245                 &target_render_pass->copy_requests);
1246       }
1247     } else if (it.state() ==
1248                EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) {
1249       RenderSurfaceImpl* render_surface = it.current_render_surface();
1250       if (render_surface->contributes_to_drawn_surface()) {
1251         render_surface->AppendQuads(draw_mode, target_render_pass,
1252                                     &append_quads_data);
1253         if (settings_.allow_de_jelly_effect) {
1254           de_jelly_state_.UpdateSharedQuadState(
1255               active_tree_.get(), render_surface->TransformTreeIndex(),
1256               target_render_pass);
1257         }
1258       }
1259     } else if (it.state() == EffectTreeLayerListIterator::State::LAYER) {
1260       LayerImpl* layer = it.current_layer();
1261       if (layer->WillDraw(draw_mode, &resource_provider_)) {
1262         DCHECK_EQ(active_tree_.get(), layer->layer_tree_impl());
1263 
1264         frame->will_draw_layers.push_back(layer);
1265         if (layer->may_contain_video()) {
1266           num_of_layers_with_videos++;
1267           frame->may_contain_video = true;
1268         }
1269 
1270         layer->AppendQuads(target_render_pass, &append_quads_data);
1271         if (settings_.allow_de_jelly_effect) {
1272           de_jelly_state_.UpdateSharedQuadState(active_tree_.get(),
1273                                                 layer->transform_tree_index(),
1274                                                 target_render_pass);
1275         }
1276       }
1277 
1278       rendering_stats_instrumentation_->AddVisibleContentArea(
1279           append_quads_data.visible_layer_area);
1280       rendering_stats_instrumentation_->AddApproximatedVisibleContentArea(
1281           append_quads_data.approximated_visible_content_area);
1282       rendering_stats_instrumentation_->AddCheckerboardedVisibleContentArea(
1283           append_quads_data.checkerboarded_visible_content_area);
1284       rendering_stats_instrumentation_->AddCheckerboardedNoRecordingContentArea(
1285           append_quads_data.checkerboarded_no_recording_content_area);
1286       rendering_stats_instrumentation_->AddCheckerboardedNeedsRasterContentArea(
1287           append_quads_data.checkerboarded_needs_raster_content_area);
1288 
1289       num_missing_tiles += append_quads_data.num_missing_tiles;
1290       num_incomplete_tiles += append_quads_data.num_incomplete_tiles;
1291       checkerboarded_no_recording_content_area +=
1292           append_quads_data.checkerboarded_no_recording_content_area;
1293       checkerboarded_needs_raster_content_area +=
1294           append_quads_data.checkerboarded_needs_raster_content_area;
1295       total_visible_area += append_quads_data.visible_layer_area;
1296       if (append_quads_data.num_missing_tiles > 0) {
1297         have_missing_animated_tiles |=
1298             layer->screen_space_transform_is_animating();
1299       }
1300     }
1301     frame->activation_dependencies.insert(
1302         frame->activation_dependencies.end(),
1303         append_quads_data.activation_dependencies.begin(),
1304         append_quads_data.activation_dependencies.end());
1305     if (append_quads_data.deadline_in_frames) {
1306       if (!frame->deadline_in_frames) {
1307         frame->deadline_in_frames = append_quads_data.deadline_in_frames;
1308       } else {
1309         frame->deadline_in_frames = std::max(
1310             *frame->deadline_in_frames, *append_quads_data.deadline_in_frames);
1311       }
1312     }
1313     frame->use_default_lower_bound_deadline |=
1314         append_quads_data.use_default_lower_bound_deadline;
1315   }
1316 
1317   // If CommitToActiveTree() is true, then we wait to draw until
1318   // NotifyReadyToDraw. That means we're in as good shape as is possible now,
1319   // so there's no reason to stop the draw now (and this is not supported by
1320   // SingleThreadProxy).
1321   if (have_missing_animated_tiles && !CommitToActiveTree())
1322     draw_result = DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
1323 
1324   // When we require high res to draw, abort the draw (almost) always. This does
1325   // not cause the scheduler to do a main frame, instead it will continue to try
1326   // drawing until we finally complete, so the copy request will not be lost.
1327   // TODO(weiliangc): Remove RequiresHighResToDraw. crbug.com/469175
1328   if (num_incomplete_tiles || num_missing_tiles) {
1329     if (RequiresHighResToDraw())
1330       draw_result = DRAW_ABORTED_MISSING_HIGH_RES_CONTENT;
1331   }
1332 
1333   // Only enable frame rate estimation if it would help lower the composition
1334   // rate for videos.
1335   const bool enable_frame_rate_estimation = num_of_layers_with_videos > 1;
1336   frame_rate_estimator_.SetFrameEstimationEnabled(enable_frame_rate_estimation);
1337 
1338   // When doing a resourceless software draw, we don't have control over the
1339   // surface the compositor draws to, so even though the frame may not be
1340   // complete, the previous frame has already been potentially lost, so an
1341   // incomplete frame is better than nothing, so this takes highest precidence.
1342   if (resourceless_software_draw_)
1343     draw_result = DRAW_SUCCESS;
1344 
1345 #if DCHECK_IS_ON()
1346   for (const auto& render_pass : frame->render_passes) {
1347     for (auto* quad : render_pass->quad_list)
1348       DCHECK(quad->shared_quad_state);
1349   }
1350   DCHECK_EQ(frame->render_passes.back()->output_rect.origin(),
1351             active_tree_->GetDeviceViewport().origin());
1352 #endif
1353   bool has_transparent_background =
1354       SkColorGetA(active_tree_->background_color()) != SK_AlphaOPAQUE;
1355   auto* root_render_surface = active_tree_->RootRenderSurface();
1356   if (root_render_surface && !has_transparent_background) {
1357     frame->render_passes.back()->has_transparent_background = false;
1358 
1359     // If any tiles are missing, then fill behind the entire root render
1360     // surface.  This is a workaround for this edge case, instead of tracking
1361     // individual tiles that are missing.
1362     Region fill_region = unoccluded_screen_space_region;
1363     if (num_missing_tiles > 0)
1364       fill_region = root_render_surface->content_rect();
1365 
1366     AppendQuadsToFillScreen(frame->render_passes.back().get(),
1367                             root_render_surface,
1368                             active_tree_->background_color(), fill_region);
1369   }
1370 
1371   RemoveRenderPasses(frame);
1372   // If we're making a frame to draw, it better have at least one render pass.
1373   DCHECK(!frame->render_passes.empty());
1374 
1375   if (have_copy_request) {
1376     // Any copy requests left in the tree are not going to get serviced, and
1377     // should be aborted.
1378     active_tree()->property_trees()->effect_tree.ClearCopyRequests();
1379 
1380     // Draw properties depend on copy requests.
1381     active_tree()->set_needs_update_draw_properties();
1382   }
1383 
1384   frame->has_missing_content =
1385       num_missing_tiles > 0 || num_incomplete_tiles > 0;
1386 
1387   if (ukm_manager_) {
1388     ukm_manager_->AddCheckerboardStatsForFrame(
1389         checkerboarded_no_recording_content_area +
1390             checkerboarded_needs_raster_content_area,
1391         num_missing_tiles, total_visible_area);
1392   }
1393 
1394   if (active_tree_->has_ever_been_drawn()) {
1395     UMA_HISTOGRAM_COUNTS_100(
1396         "Compositing.RenderPass.AppendQuadData.NumMissingTiles",
1397         num_missing_tiles);
1398     UMA_HISTOGRAM_COUNTS_100(
1399         "Compositing.RenderPass.AppendQuadData.NumIncompleteTiles",
1400         num_incomplete_tiles);
1401     UMA_HISTOGRAM_COUNTS_1M(
1402         "Compositing.RenderPass.AppendQuadData."
1403         "CheckerboardedNoRecordingContentArea",
1404         checkerboarded_no_recording_content_area);
1405     UMA_HISTOGRAM_COUNTS_1M(
1406         "Compositing.RenderPass.AppendQuadData."
1407         "CheckerboardedNeedRasterContentArea",
1408         checkerboarded_needs_raster_content_area);
1409   }
1410 
1411   TRACE_EVENT_END2("cc,benchmark", "LayerTreeHostImpl::CalculateRenderPasses",
1412                    "draw_result", draw_result, "missing tiles",
1413                    num_missing_tiles);
1414 
1415   // Draw has to be successful to not drop the copy request layer.
1416   // When we have a copy request for a layer, we need to draw even if there
1417   // would be animating checkerboards, because failing under those conditions
1418   // triggers a new main frame, which may cause the copy request layer to be
1419   // destroyed.
1420   // TODO(weiliangc): Test copy request w/ LayerTreeFrameSink recreation. Would
1421   // trigger this DCHECK.
1422   DCHECK(!have_copy_request || draw_result == DRAW_SUCCESS);
1423 
1424   // TODO(crbug.com/564832): This workaround to prevent creating unnecessarily
1425   // persistent render passes. When a copy request is made, it may force a
1426   // separate render pass for the layer, which will persist until a new commit
1427   // removes it. Force a commit after copy requests, to remove extra render
1428   // passes.
1429   if (have_copy_request)
1430     client_->SetNeedsCommitOnImplThread();
1431 
1432   return draw_result;
1433 }
1434 
DidAnimateScrollOffset()1435 void LayerTreeHostImpl::DidAnimateScrollOffset() {
1436   client_->SetNeedsCommitOnImplThread();
1437   client_->RenewTreePriority();
1438 }
1439 
SetViewportDamage(const gfx::Rect & damage_rect)1440 void LayerTreeHostImpl::SetViewportDamage(const gfx::Rect& damage_rect) {
1441   viewport_damage_rect_.Union(damage_rect);
1442 }
1443 
SetEnableFrameRateThrottling(bool enable_frame_rate_throttling)1444 void LayerTreeHostImpl::SetEnableFrameRateThrottling(
1445     bool enable_frame_rate_throttling) {
1446   enable_frame_rate_throttling_ = enable_frame_rate_throttling;
1447 }
1448 
UpdateElements(ElementListType changed_list)1449 void LayerTreeHostImpl::UpdateElements(ElementListType changed_list) {
1450   mutator_host()->UpdateRegisteredElementIds(changed_list);
1451 }
1452 
InvalidateContentOnImplSide()1453 void LayerTreeHostImpl::InvalidateContentOnImplSide() {
1454   DCHECK(!pending_tree_);
1455   // Invalidation should never be ran outside the impl frame for non
1456   // synchronous compositor mode. For devices that use synchronous compositor,
1457   // e.g. Android Webview, the assertion is not guaranteed because it may ask
1458   // for a frame at any time.
1459   DCHECK(impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME ||
1460          settings_.using_synchronous_renderer_compositor);
1461 
1462   if (!CommitToActiveTree())
1463     CreatePendingTree();
1464 
1465   UpdateSyncTreeAfterCommitOrImplSideInvalidation();
1466 }
1467 
InvalidateLayerTreeFrameSink(bool needs_redraw)1468 void LayerTreeHostImpl::InvalidateLayerTreeFrameSink(bool needs_redraw) {
1469   DCHECK(layer_tree_frame_sink());
1470 
1471   layer_tree_frame_sink()->Invalidate(needs_redraw);
1472 }
1473 
PrepareToDraw(FrameData * frame)1474 DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) {
1475   TRACE_EVENT1("cc", "LayerTreeHostImpl::PrepareToDraw", "SourceFrameNumber",
1476                active_tree_->source_frame_number());
1477   TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Graphics.Pipeline",
1478                          TRACE_ID_GLOBAL(CurrentBeginFrameArgs().trace_id),
1479                          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
1480                          "step", "GenerateRenderPass");
1481   if (input_delegate_)
1482     input_delegate_->WillDraw();
1483 
1484   // |client_name| is used for various UMA histograms below.
1485   // GetClientNameForMetrics only returns one non-null value over the lifetime
1486   // of the process, so the histogram names are runtime constant.
1487   const char* client_name = GetClientNameForMetrics();
1488   if (client_name) {
1489     size_t total_gpu_memory_for_tilings_in_bytes = 0;
1490     for (const PictureLayerImpl* layer : active_tree()->picture_layers())
1491       total_gpu_memory_for_tilings_in_bytes += layer->GPUMemoryUsageInBytes();
1492 
1493     UMA_HISTOGRAM_CUSTOM_COUNTS(
1494         base::StringPrintf("Compositing.%s.NumActiveLayers", client_name),
1495         base::saturated_cast<int>(active_tree_->NumLayers()), 1, 400, 20);
1496 
1497     UMA_HISTOGRAM_CUSTOM_COUNTS(
1498         base::StringPrintf("Compositing.%s.NumActivePictureLayers",
1499                            client_name),
1500         base::saturated_cast<int>(active_tree_->picture_layers().size()), 1,
1501         400, 20);
1502 
1503     // TODO(pdr): Instead of skipping empty picture layers, maybe we should
1504     // accumulate layer->GetRasterSource()->GetMemoryUsage() above and skip
1505     // recording when the accumulated memory usage is 0.
1506     if (!active_tree()->picture_layers().empty()) {
1507       UMA_HISTOGRAM_CUSTOM_COUNTS(
1508           base::StringPrintf("Compositing.%s.GPUMemoryForTilingsInKb",
1509                              client_name),
1510           base::saturated_cast<int>(total_gpu_memory_for_tilings_in_bytes /
1511                                     1024),
1512           1, kGPUMemoryForTilingsLargestBucketKb,
1513           kGPUMemoryForTilingsBucketCount);
1514     }
1515   }
1516 
1517   // Tick worklet animations here, just before draw, to give animation worklets
1518   // as much time as possible to produce their output for this frame. Note that
1519   // an animation worklet is asked to produce its output at the beginning of the
1520   // frame along side other animations but its output arrives asynchronously so
1521   // we tick worklet animations and apply that output here instead.
1522   mutator_host_->TickWorkletAnimations();
1523 
1524   bool ok = active_tree_->UpdateDrawProperties();
1525   DCHECK(ok) << "UpdateDrawProperties failed during draw";
1526 
1527   // This will cause NotifyTileStateChanged() to be called for any tiles that
1528   // completed, which will add damage for visible tiles to the frame for them so
1529   // they appear as part of the current frame being drawn.
1530   tile_manager_.CheckForCompletedTasks();
1531 
1532   frame->render_surface_list = &active_tree_->GetRenderSurfaceList();
1533   frame->render_passes.clear();
1534   frame->will_draw_layers.clear();
1535   frame->has_no_damage = false;
1536   frame->may_contain_video = false;
1537 
1538   if (active_tree_->RootRenderSurface()) {
1539     active_tree_->RootRenderSurface()->damage_tracker()->AddDamageNextUpdate(
1540         viewport_damage_rect_);
1541     viewport_damage_rect_ = gfx::Rect();
1542   }
1543 
1544   DrawResult draw_result = CalculateRenderPasses(frame);
1545 
1546   // Dump render passes and draw quads if run with:
1547   //   --vmodule=layer_tree_host_impl=3
1548   if (VLOG_IS_ON(3)) {
1549     VLOG(3) << "Prepare to draw ("
1550             << (client_name ? client_name : "<unknown client>") << ")\n"
1551             << frame->ToString();
1552   }
1553 
1554   if (draw_result != DRAW_SUCCESS) {
1555     DCHECK(!resourceless_software_draw_);
1556     return draw_result;
1557   }
1558 
1559   // If we return DRAW_SUCCESS, then we expect DrawLayers() to be called before
1560   // this function is called again.
1561   return DRAW_SUCCESS;
1562 }
1563 
RemoveRenderPasses(FrameData * frame)1564 void LayerTreeHostImpl::RemoveRenderPasses(FrameData* frame) {
1565   // There is always at least a root RenderPass.
1566   DCHECK_GE(frame->render_passes.size(), 1u);
1567 
1568   // A set of RenderPasses that we have seen.
1569   base::flat_set<viz::CompositorRenderPassId> pass_exists;
1570   // A set of viz::RenderPassDrawQuads that we have seen (stored by the
1571   // RenderPasses they refer to).
1572   base::flat_map<viz::CompositorRenderPassId, int> pass_references;
1573 
1574   // Iterate RenderPasses in draw order, removing empty render passes (except
1575   // the root RenderPass).
1576   for (size_t i = 0; i < frame->render_passes.size(); ++i) {
1577     viz::CompositorRenderPass* pass = frame->render_passes[i].get();
1578 
1579     // Remove orphan viz::RenderPassDrawQuads.
1580     for (auto it = pass->quad_list.begin(); it != pass->quad_list.end();) {
1581       if (it->material != viz::DrawQuad::Material::kCompositorRenderPass) {
1582         ++it;
1583         continue;
1584       }
1585       const viz::CompositorRenderPassDrawQuad* quad =
1586           viz::CompositorRenderPassDrawQuad::MaterialCast(*it);
1587       // If the RenderPass doesn't exist, we can remove the quad.
1588       if (pass_exists.count(quad->render_pass_id)) {
1589         // Otherwise, save a reference to the RenderPass so we know there's a
1590         // quad using it.
1591         pass_references[quad->render_pass_id]++;
1592         ++it;
1593       } else {
1594         it = pass->quad_list.EraseAndInvalidateAllPointers(it);
1595       }
1596     }
1597 
1598     if (i == frame->render_passes.size() - 1) {
1599       // Don't remove the root RenderPass.
1600       break;
1601     }
1602 
1603     if (pass->quad_list.empty() && pass->copy_requests.empty() &&
1604         pass->filters.IsEmpty() && pass->backdrop_filters.IsEmpty()) {
1605       // Remove the pass and decrement |i| to counter the for loop's increment,
1606       // so we don't skip the next pass in the loop.
1607       frame->render_passes.erase(frame->render_passes.begin() + i);
1608       --i;
1609       continue;
1610     }
1611 
1612     pass_exists.insert(pass->id);
1613   }
1614 
1615   // Remove RenderPasses that are not referenced by any draw quads or copy
1616   // requests (except the root RenderPass).
1617   for (size_t i = 0; i < frame->render_passes.size() - 1; ++i) {
1618     // Iterating from the back of the list to the front, skipping over the
1619     // back-most (root) pass, in order to remove each qualified RenderPass, and
1620     // drop references to earlier RenderPasses allowing them to be removed to.
1621     viz::CompositorRenderPass* pass =
1622         frame->render_passes[frame->render_passes.size() - 2 - i].get();
1623     if (!pass->copy_requests.empty())
1624       continue;
1625     if (pass_references[pass->id])
1626       continue;
1627 
1628     for (auto it = pass->quad_list.begin(); it != pass->quad_list.end(); ++it) {
1629       if (it->material != viz::DrawQuad::Material::kCompositorRenderPass)
1630         continue;
1631       const viz::CompositorRenderPassDrawQuad* quad =
1632           viz::CompositorRenderPassDrawQuad::MaterialCast(*it);
1633       pass_references[quad->render_pass_id]--;
1634     }
1635 
1636     frame->render_passes.erase(frame->render_passes.end() - 2 - i);
1637     --i;
1638   }
1639 }
1640 
EvictTexturesForTesting()1641 void LayerTreeHostImpl::EvictTexturesForTesting() {
1642   UpdateTileManagerMemoryPolicy(ManagedMemoryPolicy(0));
1643 }
1644 
BlockNotifyReadyToActivateForTesting(bool block)1645 void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) {
1646   NOTREACHED();
1647 }
1648 
BlockImplSideInvalidationRequestsForTesting(bool block)1649 void LayerTreeHostImpl::BlockImplSideInvalidationRequestsForTesting(
1650     bool block) {
1651   NOTREACHED();
1652 }
1653 
ResetTreesForTesting()1654 void LayerTreeHostImpl::ResetTreesForTesting() {
1655   if (active_tree_)
1656     active_tree_->DetachLayers();
1657   active_tree_ = std::make_unique<LayerTreeImpl>(
1658       this, active_tree()->page_scale_factor(),
1659       active_tree()->top_controls_shown_ratio(),
1660       active_tree()->bottom_controls_shown_ratio(),
1661       active_tree()->elastic_overscroll());
1662   active_tree_->property_trees()->is_active = true;
1663   active_tree_->property_trees()->clear();
1664   if (pending_tree_)
1665     pending_tree_->DetachLayers();
1666   pending_tree_ = nullptr;
1667   if (recycle_tree_)
1668     recycle_tree_->DetachLayers();
1669   recycle_tree_ = nullptr;
1670 }
1671 
SourceAnimationFrameNumberForTesting() const1672 size_t LayerTreeHostImpl::SourceAnimationFrameNumberForTesting() const {
1673   return *next_frame_token_;
1674 }
1675 
UpdateTileManagerMemoryPolicy(const ManagedMemoryPolicy & policy)1676 void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy(
1677     const ManagedMemoryPolicy& policy) {
1678   if (!resource_pool_)
1679     return;
1680 
1681   global_tile_state_.hard_memory_limit_in_bytes = 0;
1682   global_tile_state_.soft_memory_limit_in_bytes = 0;
1683   if (visible_ && policy.bytes_limit_when_visible > 0) {
1684     global_tile_state_.hard_memory_limit_in_bytes =
1685         policy.bytes_limit_when_visible;
1686     global_tile_state_.soft_memory_limit_in_bytes =
1687         (static_cast<int64_t>(global_tile_state_.hard_memory_limit_in_bytes) *
1688          settings_.max_memory_for_prepaint_percentage) /
1689         100;
1690   }
1691   global_tile_state_.memory_limit_policy =
1692       ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy(
1693           visible_ ? policy.priority_cutoff_when_visible
1694                    : gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING);
1695   global_tile_state_.num_resources_limit = policy.num_resources_limit;
1696 
1697   if (global_tile_state_.hard_memory_limit_in_bytes > 0) {
1698     // If |global_tile_state_.hard_memory_limit_in_bytes| is greater than 0, we
1699     // consider our contexts visible. Notify the contexts here. We handle
1700     // becoming invisible in NotifyAllTileTasksComplete to avoid interrupting
1701     // running work.
1702     SetContextVisibility(true);
1703 
1704     // If |global_tile_state_.hard_memory_limit_in_bytes| is greater than 0, we
1705     // allow the image decode controller to retain resources. We handle the
1706     // equal to 0 case in NotifyAllTileTasksComplete to avoid interrupting
1707     // running work.
1708     if (image_decode_cache_)
1709       image_decode_cache_->SetShouldAggressivelyFreeResources(false);
1710   } else {
1711     // When the memory policy is set to zero, its important to release any
1712     // decoded images cached by the tracker. But we can not re-checker any
1713     // images that have been displayed since the resources, if held by the
1714     // browser, may be re-used. Which is why its important to maintain the
1715     // decode policy tracking.
1716     bool can_clear_decode_policy_tracking = false;
1717     tile_manager_.ClearCheckerImageTracking(can_clear_decode_policy_tracking);
1718   }
1719 
1720   DCHECK(resource_pool_);
1721   // Soft limit is used for resource pool such that memory returns to soft
1722   // limit after going over.
1723   resource_pool_->SetResourceUsageLimits(
1724       global_tile_state_.soft_memory_limit_in_bytes,
1725       global_tile_state_.num_resources_limit);
1726 
1727   DidModifyTilePriorities();
1728 }
1729 
DidModifyTilePriorities()1730 void LayerTreeHostImpl::DidModifyTilePriorities() {
1731   // Mark priorities as dirty and schedule a PrepareTiles().
1732   tile_priorities_dirty_ = true;
1733   tile_manager_.DidModifyTilePriorities();
1734   client_->SetNeedsPrepareTilesOnImplThread();
1735 }
1736 
BuildRasterQueue(TreePriority tree_priority,RasterTilePriorityQueue::Type type)1737 std::unique_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue(
1738     TreePriority tree_priority,
1739     RasterTilePriorityQueue::Type type) {
1740   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1741                "LayerTreeHostImpl::BuildRasterQueue");
1742 
1743   return RasterTilePriorityQueue::Create(
1744       active_tree_->picture_layers(),
1745       pending_tree_ && pending_tree_fully_painted_
1746           ? pending_tree_->picture_layers()
1747           : std::vector<PictureLayerImpl*>(),
1748       tree_priority, type);
1749 }
1750 
1751 std::unique_ptr<EvictionTilePriorityQueue>
BuildEvictionQueue(TreePriority tree_priority)1752 LayerTreeHostImpl::BuildEvictionQueue(TreePriority tree_priority) {
1753   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
1754                "LayerTreeHostImpl::BuildEvictionQueue");
1755 
1756   std::unique_ptr<EvictionTilePriorityQueue> queue(
1757       new EvictionTilePriorityQueue);
1758   queue->Build(active_tree_->picture_layers(),
1759                pending_tree_ ? pending_tree_->picture_layers()
1760                              : std::vector<PictureLayerImpl*>(),
1761                tree_priority);
1762   return queue;
1763 }
1764 
SetIsLikelyToRequireADraw(bool is_likely_to_require_a_draw)1765 void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
1766     bool is_likely_to_require_a_draw) {
1767   // Proactively tell the scheduler that we expect to draw within each vsync
1768   // until we get all the tiles ready to draw. If we happen to miss a required
1769   // for draw tile here, then we will miss telling the scheduler each frame that
1770   // we intend to draw so it may make worse scheduling decisions.
1771   is_likely_to_require_a_draw_ = is_likely_to_require_a_draw;
1772 }
1773 
GetRasterColorSpace(gfx::ContentColorUsage content_color_usage) const1774 gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
1775     gfx::ContentColorUsage content_color_usage) const {
1776   constexpr gfx::ColorSpace srgb = gfx::ColorSpace::CreateSRGB();
1777 
1778   // If we are likely to software composite the resource, we use sRGB because
1779   // software compositing is unable to perform color conversion.
1780   if (!layer_tree_frame_sink_ || !layer_tree_frame_sink_->context_provider())
1781     return srgb;
1782 
1783   if (settings_.prefer_raster_in_srgb &&
1784       content_color_usage == gfx::ContentColorUsage::kSRGB) {
1785     return srgb;
1786   }
1787 
1788   // The pending tree will has the most recently updated color space, so use it.
1789   gfx::DisplayColorSpaces display_cs;
1790   if (pending_tree_)
1791     display_cs = pending_tree_->display_color_spaces();
1792   else if (active_tree_)
1793     display_cs = active_tree_->display_color_spaces();
1794 
1795   auto result = display_cs.GetOutputColorSpace(gfx::ContentColorUsage::kHDR,
1796                                                /*needs_alpha=*/false);
1797 
1798   // Always specify a color space if color correct rasterization is requested
1799   // (not specifying a color space indicates that no color conversion is
1800   // required).
1801   if (!result.IsValid())
1802     return srgb;
1803 
1804   // It's expensive to rasterize in HDR, so we only want to do so when we know
1805   // we have HDR content to rasterize.
1806   if (result.IsHDR() && content_color_usage != gfx::ContentColorUsage::kHDR)
1807     return gfx::ColorSpace::CreateDisplayP3D65();
1808 
1809   // The raster color space should contain sRGB to avoid artifacts during
1810   // rasterization.
1811   if (!CheckColorSpaceContainsSrgb(result))
1812     return srgb;
1813 
1814   return result;
1815 }
1816 
CheckColorSpaceContainsSrgb(const gfx::ColorSpace & color_space) const1817 bool LayerTreeHostImpl::CheckColorSpaceContainsSrgb(
1818     const gfx::ColorSpace& color_space) const {
1819   constexpr gfx::ColorSpace srgb = gfx::ColorSpace::CreateSRGB();
1820 
1821   // Color spaces without a custom primary matrix are cheap to compute, so the
1822   // cache can be bypassed.
1823   if (color_space.GetPrimaryID() != gfx::ColorSpace::PrimaryID::CUSTOM)
1824     return color_space.Contains(srgb);
1825 
1826   auto it = contains_srgb_cache_.Get(color_space);
1827   if (it != contains_srgb_cache_.end())
1828     return it->second;
1829 
1830   bool result = color_space.Contains(srgb);
1831   contains_srgb_cache_.Put(color_space, result);
1832   return result;
1833 }
1834 
GetSDRWhiteLevel() const1835 float LayerTreeHostImpl::GetSDRWhiteLevel() const {
1836   // If we are likely to software composite the resource, we use sRGB because
1837   // software compositing is unable to perform color conversion.
1838   if (!layer_tree_frame_sink_ || !layer_tree_frame_sink_->context_provider())
1839     return gfx::ColorSpace::kDefaultSDRWhiteLevel;
1840 
1841   // The pending tree will has the most recently updated color space, so use it.
1842   if (pending_tree_)
1843     return pending_tree_->display_color_spaces().GetSDRWhiteLevel();
1844   if (active_tree_)
1845     return active_tree_->display_color_spaces().GetSDRWhiteLevel();
1846   return gfx::ColorSpace::kDefaultSDRWhiteLevel;
1847 }
1848 
RequestImplSideInvalidationForCheckerImagedTiles()1849 void LayerTreeHostImpl::RequestImplSideInvalidationForCheckerImagedTiles() {
1850   // When using impl-side invalidation for checker-imaging, a pending tree does
1851   // not need to be flushed as an independent update through the pipeline.
1852   bool needs_first_draw_on_activation = false;
1853   client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
1854 }
1855 
GetFrameIndexForImage(const PaintImage & paint_image,WhichTree tree) const1856 size_t LayerTreeHostImpl::GetFrameIndexForImage(const PaintImage& paint_image,
1857                                                 WhichTree tree) const {
1858   if (!paint_image.ShouldAnimate())
1859     return PaintImage::kDefaultFrameIndex;
1860 
1861   return image_animation_controller_.GetFrameIndexForImage(
1862       paint_image.stable_id(), tree);
1863 }
1864 
GetMSAASampleCountForRaster(const scoped_refptr<DisplayItemList> & display_list)1865 int LayerTreeHostImpl::GetMSAASampleCountForRaster(
1866     const scoped_refptr<DisplayItemList>& display_list) {
1867   constexpr int kMinNumberOfSlowPathsForMSAA = 6;
1868   if (display_list->NumSlowPaths() < kMinNumberOfSlowPathsForMSAA)
1869     return 0;
1870 
1871   if (!can_use_msaa_)
1872     return 0;
1873 
1874   if (display_list->HasNonAAPaint() && !supports_disable_msaa_)
1875     return 0;
1876 
1877   return RequestedMSAASampleCount();
1878 }
1879 
HasPendingTree()1880 bool LayerTreeHostImpl::HasPendingTree() {
1881   return pending_tree_ != nullptr;
1882 }
1883 
NotifyReadyToActivate()1884 void LayerTreeHostImpl::NotifyReadyToActivate() {
1885   // The TileManager may call this method while the pending tree is still being
1886   // painted, as it isn't aware of the ongoing paint. We shouldn't tell the
1887   // scheduler we are ready to activate in that case, as if we do it will
1888   // immediately activate once we call NotifyPaintWorkletStateChange, rather
1889   // than wait for the TileManager to actually raster the content!
1890   if (!pending_tree_fully_painted_)
1891     return;
1892   pending_tree_raster_duration_timer_.reset();
1893   client_->NotifyReadyToActivate();
1894 }
1895 
NotifyReadyToDraw()1896 void LayerTreeHostImpl::NotifyReadyToDraw() {
1897   // Tiles that are ready will cause NotifyTileStateChanged() to be called so we
1898   // don't need to schedule a draw here. Just stop WillBeginImplFrame() from
1899   // causing optimistic requests to draw a frame.
1900   is_likely_to_require_a_draw_ = false;
1901 
1902   client_->NotifyReadyToDraw();
1903 }
1904 
NotifyAllTileTasksCompleted()1905 void LayerTreeHostImpl::NotifyAllTileTasksCompleted() {
1906   // The tile tasks started by the most recent call to PrepareTiles have
1907   // completed. Now is a good time to free resources if necessary.
1908   if (global_tile_state_.hard_memory_limit_in_bytes == 0) {
1909     // Free image decode controller resources before notifying the
1910     // contexts of visibility change. This ensures that the imaged decode
1911     // controller has released all Skia refs at the time Skia's cleanup
1912     // executes (within worker context's cleanup).
1913     if (image_decode_cache_)
1914       image_decode_cache_->SetShouldAggressivelyFreeResources(true);
1915     SetContextVisibility(false);
1916   }
1917 }
1918 
NotifyTileStateChanged(const Tile * tile)1919 void LayerTreeHostImpl::NotifyTileStateChanged(const Tile* tile) {
1920   TRACE_EVENT0("cc", "LayerTreeHostImpl::NotifyTileStateChanged");
1921 
1922   LayerImpl* layer_impl = nullptr;
1923 
1924   // We must have a pending or active tree layer here, since the layer is
1925   // guaranteed to outlive its tiles.
1926   if (tile->tiling()->tree() == WhichTree::PENDING_TREE)
1927     layer_impl = pending_tree_->FindPendingTreeLayerById(tile->layer_id());
1928   else
1929     layer_impl = active_tree_->FindActiveTreeLayerById(tile->layer_id());
1930 
1931   layer_impl->NotifyTileStateChanged(tile);
1932 
1933   if (!client_->IsInsideDraw() && tile->required_for_draw()) {
1934     // The LayerImpl::NotifyTileStateChanged() should damage the layer, so this
1935     // redraw will make those tiles be displayed.
1936     SetNeedsRedraw();
1937   }
1938 }
1939 
SetMemoryPolicy(const ManagedMemoryPolicy & policy)1940 void LayerTreeHostImpl::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
1941   DCHECK(task_runner_provider_->IsImplThread());
1942 
1943   SetManagedMemoryPolicy(policy);
1944 
1945   // This is short term solution to synchronously drop tile resources when
1946   // using synchronous compositing to avoid memory usage regression.
1947   // TODO(boliu): crbug.com/499004 to track removing this.
1948   if (!policy.bytes_limit_when_visible && resource_pool_ &&
1949       settings_.using_synchronous_renderer_compositor) {
1950     ReleaseTileResources();
1951     CleanUpTileManagerResources();
1952 
1953     // Force a call to NotifyAllTileTasks completed - otherwise this logic may
1954     // be skipped if no work was enqueued at the time the tile manager was
1955     // destroyed.
1956     NotifyAllTileTasksCompleted();
1957 
1958     CreateTileManagerResources();
1959     RecreateTileResources();
1960   }
1961 }
1962 
SetTreeActivationCallback(base::RepeatingClosure callback)1963 void LayerTreeHostImpl::SetTreeActivationCallback(
1964     base::RepeatingClosure callback) {
1965   DCHECK(task_runner_provider_->IsImplThread());
1966   tree_activation_callback_ = std::move(callback);
1967 }
1968 
SetManagedMemoryPolicy(const ManagedMemoryPolicy & policy)1969 void LayerTreeHostImpl::SetManagedMemoryPolicy(
1970     const ManagedMemoryPolicy& policy) {
1971   if (cached_managed_memory_policy_ == policy)
1972     return;
1973 
1974   ManagedMemoryPolicy old_policy = ActualManagedMemoryPolicy();
1975   cached_managed_memory_policy_ = policy;
1976   ManagedMemoryPolicy actual_policy = ActualManagedMemoryPolicy();
1977 
1978   if (old_policy == actual_policy)
1979     return;
1980 
1981   UpdateTileManagerMemoryPolicy(actual_policy);
1982 
1983   // If there is already enough memory to draw everything imaginable and the
1984   // new memory limit does not change this, then do not re-commit. Don't bother
1985   // skipping commits if this is not visible (commits don't happen when not
1986   // visible, there will almost always be a commit when this becomes visible).
1987   bool needs_commit = true;
1988   if (visible() &&
1989       actual_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ &&
1990       old_policy.bytes_limit_when_visible >= max_memory_needed_bytes_ &&
1991       actual_policy.priority_cutoff_when_visible ==
1992           old_policy.priority_cutoff_when_visible) {
1993     needs_commit = false;
1994   }
1995 
1996   if (needs_commit)
1997     client_->SetNeedsCommitOnImplThread();
1998 }
1999 
SetExternalTilePriorityConstraints(const gfx::Rect & viewport_rect,const gfx::Transform & transform)2000 void LayerTreeHostImpl::SetExternalTilePriorityConstraints(
2001     const gfx::Rect& viewport_rect,
2002     const gfx::Transform& transform) {
2003   const bool tile_priority_params_changed =
2004       viewport_rect_for_tile_priority_ != viewport_rect;
2005   viewport_rect_for_tile_priority_ = viewport_rect;
2006 
2007   if (tile_priority_params_changed) {
2008     active_tree_->set_needs_update_draw_properties();
2009     if (pending_tree_)
2010       pending_tree_->set_needs_update_draw_properties();
2011 
2012     // Compositor, not LayerTreeFrameSink, is responsible for setting damage
2013     // and triggering redraw for constraint changes.
2014     SetFullViewportDamage();
2015     SetNeedsRedraw();
2016   }
2017 }
2018 
DidReceiveCompositorFrameAck()2019 void LayerTreeHostImpl::DidReceiveCompositorFrameAck() {
2020   client_->DidReceiveCompositorFrameAckOnImplThread();
2021 }
2022 
DidPresentCompositorFrame(uint32_t frame_token,const viz::FrameTimingDetails & details)2023 void LayerTreeHostImpl::DidPresentCompositorFrame(
2024     uint32_t frame_token,
2025     const viz::FrameTimingDetails& details) {
2026   frame_trackers_.NotifyFramePresented(frame_token,
2027                                        details.presentation_feedback);
2028   PresentationTimeCallbackBuffer::PendingCallbacks activated =
2029       presentation_time_callbacks_.PopPendingCallbacks(frame_token);
2030 
2031   // The callbacks in |compositor_thread_callbacks| expect to be run on the
2032   // compositor thread so we'll run them now.
2033   for (LayerTreeHost::PresentationTimeCallback& callback :
2034        activated.compositor_thread_callbacks) {
2035     std::move(callback).Run(details.presentation_feedback);
2036   }
2037 
2038   // Send all the main-thread callbacks to the client in one batch. The client
2039   // is in charge of posting them to the main thread.
2040   client_->DidPresentCompositorFrameOnImplThread(
2041       frame_token, std::move(activated.main_thread_callbacks), details);
2042 
2043   // Send all pending lag events waiting on the frame pointed by |frame_token|.
2044   // It is posted as a task because LayerTreeHostImpl::DidPresentCompositorFrame
2045   // is in the rendering critical path (it is called by AsyncLayerTreeFrameSink
2046   // ::OnBeginFrame).
2047   GetTaskRunner()->PostTask(
2048       FROM_HERE,
2049       base::BindOnce(&LayerTreeHostImpl::LogAverageLagEvents,
2050                      weak_factory_.GetWeakPtr(), frame_token, details));
2051 }
2052 
LogAverageLagEvents(uint32_t frame_token,const viz::FrameTimingDetails & details)2053 void LayerTreeHostImpl::LogAverageLagEvents(
2054     uint32_t frame_token,
2055     const viz::FrameTimingDetails& details) {
2056   lag_tracking_manager_.DidPresentCompositorFrame(frame_token, details);
2057 }
2058 
NotifyThroughputTrackerResults(const CustomTrackerResults & results)2059 void LayerTreeHostImpl::NotifyThroughputTrackerResults(
2060     const CustomTrackerResults& results) {
2061   client_->NotifyThroughputTrackerResults(results);
2062 }
2063 
DidNotNeedBeginFrame()2064 void LayerTreeHostImpl::DidNotNeedBeginFrame() {
2065   frame_trackers_.NotifyPauseFrameProduction();
2066   if (lcd_text_metrics_reporter_)
2067     lcd_text_metrics_reporter_->NotifyPauseFrameProduction();
2068 }
2069 
ReclaimResources(const std::vector<viz::ReturnedResource> & resources)2070 void LayerTreeHostImpl::ReclaimResources(
2071     const std::vector<viz::ReturnedResource>& resources) {
2072   resource_provider_.ReceiveReturnsFromParent(resources);
2073 
2074   // In OOM, we now might be able to release more resources that were held
2075   // because they were exported.
2076   if (resource_pool_) {
2077     if (resource_pool_->memory_usage_bytes()) {
2078       const size_t kMegabyte = 1024 * 1024;
2079       // This is a good time to log memory usage. A chunk of work has just
2080       // completed but none of the memory used for that work has likely been
2081       // freed.
2082       std::string client_suffix;
2083       if (settings_.commit_to_active_tree) {
2084         client_suffix = "Browser";
2085       } else if (settings_.is_layer_tree_for_subframe) {
2086         client_suffix = "OOPIF";
2087       } else {
2088         client_suffix = "Renderer";
2089       }
2090       base::UmaHistogramMemoryMB(
2091           "Compositing.ResourcePoolMemoryUsage." + client_suffix,
2092           static_cast<int>(resource_pool_->memory_usage_bytes() / kMegabyte));
2093     }
2094     resource_pool_->ReduceResourceUsage();
2095   }
2096 
2097   // If we're not visible, we likely released resources, so we want to
2098   // aggressively flush here to make sure those DeleteTextures make it to the
2099   // GPU process to free up the memory.
2100   if (!visible_ && layer_tree_frame_sink_->context_provider()) {
2101     auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
2102     gl->ShallowFlushCHROMIUM();
2103   }
2104 }
2105 
OnDraw(const gfx::Transform & transform,const gfx::Rect & viewport,bool resourceless_software_draw,bool skip_draw)2106 void LayerTreeHostImpl::OnDraw(const gfx::Transform& transform,
2107                                const gfx::Rect& viewport,
2108                                bool resourceless_software_draw,
2109                                bool skip_draw) {
2110   DCHECK(!resourceless_software_draw_);
2111   // This function is only ever called by Android WebView, in which case we
2112   // expect the device viewport to be at the origin. We never expect an
2113   // external viewport to be set otherwise.
2114   DCHECK(active_tree_->internal_device_viewport().origin().IsOrigin());
2115 
2116 #if DCHECK_IS_ON()
2117   base::AutoReset<bool> reset_sync_draw(&doing_sync_draw_, true);
2118 #endif
2119 
2120   if (skip_draw) {
2121     client_->OnDrawForLayerTreeFrameSink(resourceless_software_draw_, true);
2122     return;
2123   }
2124 
2125   const bool transform_changed = external_transform_ != transform;
2126   const bool viewport_changed = external_viewport_ != viewport;
2127 
2128   external_transform_ = transform;
2129   external_viewport_ = viewport;
2130 
2131   {
2132     base::AutoReset<bool> resourceless_software_draw_reset(
2133         &resourceless_software_draw_, resourceless_software_draw);
2134 
2135     // For resourceless software draw, always set full damage to ensure they
2136     // always swap. Otherwise, need to set redraw for any changes to draw
2137     // parameters.
2138     if (transform_changed || viewport_changed || resourceless_software_draw_) {
2139       SetFullViewportDamage();
2140       SetNeedsRedraw();
2141       active_tree_->set_needs_update_draw_properties();
2142     }
2143 
2144     if (resourceless_software_draw)
2145       client_->OnCanDrawStateChanged(CanDraw());
2146 
2147     client_->OnDrawForLayerTreeFrameSink(resourceless_software_draw_,
2148                                          skip_draw);
2149   }
2150 
2151   if (resourceless_software_draw) {
2152     active_tree_->set_needs_update_draw_properties();
2153     client_->OnCanDrawStateChanged(CanDraw());
2154     // This draw may have reset all damage, which would lead to subsequent
2155     // incorrect hardware draw, so explicitly set damage for next hardware
2156     // draw as well.
2157     SetFullViewportDamage();
2158   }
2159 }
2160 
OnCanDrawStateChangedForTree()2161 void LayerTreeHostImpl::OnCanDrawStateChangedForTree() {
2162   client_->OnCanDrawStateChanged(CanDraw());
2163 }
2164 
MakeCompositorFrameMetadata()2165 viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
2166   viz::CompositorFrameMetadata metadata;
2167   metadata.frame_token = ++next_frame_token_;
2168   metadata.device_scale_factor = active_tree_->painted_device_scale_factor() *
2169                                  active_tree_->device_scale_factor();
2170 
2171   metadata.page_scale_factor = active_tree_->current_page_scale_factor();
2172   metadata.scrollable_viewport_size = active_tree_->ScrollableViewportSize();
2173   metadata.root_background_color = active_tree_->background_color();
2174 
2175   if (active_tree_->has_presentation_callbacks()) {
2176     presentation_time_callbacks_.RegisterMainThreadPresentationCallbacks(
2177         metadata.frame_token, active_tree_->TakePresentationCallbacks());
2178     presentation_time_callbacks_.RegisterFrameTime(
2179         metadata.frame_token, CurrentBeginFrameArgs().frame_time);
2180   }
2181 
2182   if (GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
2183     // TODO(savella) : Change to check for ActivelyScrollingType::kNone
2184     const bool actively_scrolling =
2185         GetActivelyScrollingType() == ActivelyScrollingType::kPrecise;
2186     metadata.is_resourceless_software_draw_with_scroll_or_animation =
2187         actively_scrolling || mutator_host_->NeedsTickAnimations();
2188   }
2189 
2190   const base::flat_set<viz::SurfaceRange>& referenced_surfaces =
2191       active_tree_->SurfaceRanges();
2192   for (auto& surface_range : referenced_surfaces)
2193     metadata.referenced_surfaces.push_back(surface_range);
2194 
2195   if (last_draw_referenced_surfaces_ != referenced_surfaces)
2196     last_draw_referenced_surfaces_ = referenced_surfaces;
2197 
2198   metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
2199 
2200   if (browser_controls_offset_manager_->TopControlsHeight() > 0) {
2201     metadata.top_controls_visible_height.emplace(
2202         browser_controls_offset_manager_->TopControlsHeight() *
2203         browser_controls_offset_manager_->TopControlsShownRatio());
2204   }
2205 
2206   if (InnerViewportScrollNode()) {
2207     // TODO(miletus) : Change the metadata to hold ScrollOffset.
2208     metadata.root_scroll_offset =
2209         gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
2210   }
2211 
2212   metadata.display_transform_hint = active_tree_->display_transform_hint();
2213 
2214   if (std::unique_ptr<viz::DelegatedInkMetadata> delegated_ink_metadata =
2215           active_tree_->take_delegated_ink_metadata()) {
2216     delegated_ink_metadata->set_frame_time(CurrentBeginFrameArgs().frame_time);
2217     TRACE_EVENT_INSTANT1(
2218         "cc", "Delegated Ink Metadata set on compositor frame metadata",
2219         TRACE_EVENT_SCOPE_THREAD, "ink metadata",
2220         delegated_ink_metadata->ToString());
2221     metadata.delegated_ink_metadata = std::move(delegated_ink_metadata);
2222   }
2223 
2224   return metadata;
2225 }
2226 
MakeRenderFrameMetadata(FrameData * frame)2227 RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
2228     FrameData* frame) {
2229   RenderFrameMetadata metadata;
2230   metadata.root_scroll_offset =
2231       gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
2232 
2233   metadata.root_background_color = active_tree_->background_color();
2234   metadata.is_scroll_offset_at_top = active_tree_->TotalScrollOffset().y() == 0;
2235   metadata.device_scale_factor = active_tree_->painted_device_scale_factor() *
2236                                  active_tree_->device_scale_factor();
2237   active_tree_->GetViewportSelection(&metadata.selection);
2238   metadata.is_mobile_optimized = IsMobileOptimized(active_tree_.get());
2239   metadata.viewport_size_in_pixels = active_tree_->GetDeviceViewport().size();
2240 
2241   metadata.page_scale_factor = active_tree_->current_page_scale_factor();
2242   metadata.external_page_scale_factor =
2243       active_tree_->external_page_scale_factor();
2244 
2245   metadata.top_controls_height =
2246       browser_controls_offset_manager_->TopControlsHeight();
2247   metadata.top_controls_shown_ratio =
2248       browser_controls_offset_manager_->TopControlsShownRatio();
2249 #if defined(OS_ANDROID)
2250   metadata.bottom_controls_height =
2251       browser_controls_offset_manager_->BottomControlsHeight();
2252   metadata.bottom_controls_shown_ratio =
2253       browser_controls_offset_manager_->BottomControlsShownRatio();
2254   metadata.top_controls_min_height_offset =
2255       browser_controls_offset_manager_->TopControlsMinHeightOffset();
2256   metadata.bottom_controls_min_height_offset =
2257       browser_controls_offset_manager_->BottomControlsMinHeightOffset();
2258   metadata.scrollable_viewport_size = active_tree_->ScrollableViewportSize();
2259   metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
2260   metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
2261   metadata.root_layer_size = active_tree_->ScrollableSize();
2262   if (InnerViewportScrollNode()) {
2263     DCHECK(OuterViewportScrollNode());
2264     metadata.root_overflow_y_hidden =
2265         !OuterViewportScrollNode()->user_scrollable_vertical ||
2266         !InnerViewportScrollNode()->user_scrollable_vertical;
2267   }
2268   metadata.has_transparent_background =
2269       frame->render_passes.back()->has_transparent_background;
2270 #endif
2271 
2272   if (last_draw_render_frame_metadata_) {
2273     const float last_root_scroll_offset_y =
2274         last_draw_render_frame_metadata_->root_scroll_offset
2275             .value_or(gfx::Vector2dF())
2276             .y();
2277 
2278     const float new_root_scroll_offset_y =
2279         metadata.root_scroll_offset.value().y();
2280 
2281     if (!MathUtil::IsWithinEpsilon(last_root_scroll_offset_y,
2282                                    new_root_scroll_offset_y)) {
2283       viz::VerticalScrollDirection new_vertical_scroll_direction =
2284           (last_root_scroll_offset_y < new_root_scroll_offset_y)
2285               ? viz::VerticalScrollDirection::kDown
2286               : viz::VerticalScrollDirection::kUp;
2287 
2288       // Changes in vertical scroll direction happen instantaneously. This being
2289       // the case, a new vertical scroll direction should only be present in the
2290       // singular metadata for the render frame in which the direction change
2291       // occurred. If the vertical scroll direction detected here matches that
2292       // which we've previously cached, then this frame is not the instant in
2293       // which the direction change occurred and is therefore not propagated.
2294       if (last_vertical_scroll_direction_ != new_vertical_scroll_direction)
2295         metadata.new_vertical_scroll_direction = new_vertical_scroll_direction;
2296     }
2297   }
2298 
2299   bool allocate_new_local_surface_id =
2300 #if !defined(OS_ANDROID)
2301       last_draw_render_frame_metadata_ &&
2302       (last_draw_render_frame_metadata_->top_controls_height !=
2303            metadata.top_controls_height ||
2304        last_draw_render_frame_metadata_->top_controls_shown_ratio !=
2305            metadata.top_controls_shown_ratio);
2306 #else
2307       last_draw_render_frame_metadata_ &&
2308       (last_draw_render_frame_metadata_->top_controls_height !=
2309            metadata.top_controls_height ||
2310        last_draw_render_frame_metadata_->top_controls_shown_ratio !=
2311            metadata.top_controls_shown_ratio ||
2312        last_draw_render_frame_metadata_->bottom_controls_height !=
2313            metadata.bottom_controls_height ||
2314        last_draw_render_frame_metadata_->bottom_controls_shown_ratio !=
2315            metadata.bottom_controls_shown_ratio ||
2316        last_draw_render_frame_metadata_->selection != metadata.selection ||
2317        last_draw_render_frame_metadata_->has_transparent_background !=
2318            metadata.has_transparent_background);
2319 #endif
2320 
2321   if (child_local_surface_id_allocator_.GetCurrentLocalSurfaceId().is_valid()) {
2322     if (allocate_new_local_surface_id)
2323       AllocateLocalSurfaceId();
2324     metadata.local_surface_id =
2325         child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
2326   }
2327 
2328   return metadata;
2329 }
2330 
DrawLayers(FrameData * frame)2331 bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
2332   DCHECK(CanDraw());
2333   DCHECK_EQ(frame->has_no_damage, frame->render_passes.empty());
2334   ResetRequiresHighResToDraw();
2335 
2336   if (frame->has_no_damage) {
2337     DCHECK(!resourceless_software_draw_);
2338 
2339     frame_trackers_.NotifyImplFrameCausedNoDamage(frame->begin_frame_ack);
2340     TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD);
2341     active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
2342     active_tree()->ResetAllChangeTracking();
2343     return false;
2344   }
2345 
2346   layer_tree_frame_sink_->set_source_frame_number(
2347       active_tree_->source_frame_number());
2348 
2349   auto compositor_frame = GenerateCompositorFrame(frame);
2350   const auto frame_token = compositor_frame.metadata.frame_token;
2351   frame->frame_token = frame_token;
2352   const viz::BeginFrameId begin_frame_ack_frame_id =
2353       compositor_frame.metadata.begin_frame_ack.frame_id;
2354 
2355   // Collect |latency_info| information for tracking
2356   lag_tracking_manager_.CollectScrollEventsFromFrame(
2357       frame_token, compositor_frame.metadata.latency_info);
2358   layer_tree_frame_sink_->SubmitCompositorFrame(
2359       std::move(compositor_frame),
2360       /*hit_test_data_changed=*/false, debug_state_.show_hit_test_borders);
2361 
2362 #if DCHECK_IS_ON()
2363   if (!doing_sync_draw_) {
2364     // The throughput computation (in |FrameSequenceTracker|) depends on the
2365     // compositor-frame submission to happen while a BeginFrameArgs is 'active'
2366     // (i.e. between calls to WillBeginImplFrame() and DidFinishImplFrame()).
2367     // Verify that this is the case.
2368     // No begin-frame is available when doing sync draws, so avoid doing this
2369     // check in that case.
2370     const auto& bfargs = current_begin_frame_tracker_.Current();
2371     DCHECK_EQ(bfargs.frame_id, begin_frame_ack_frame_id);
2372   }
2373 #endif
2374 
2375   // In some cases (e.g. for android-webviews), the frame-submission happens
2376   // outside of begin-impl frame pipeline. Avoid notifying the trackers in such
2377   // cases.
2378   if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
2379     frame_trackers_.NotifySubmitFrame(frame_token, frame->has_missing_content,
2380                                       frame->begin_frame_ack,
2381                                       frame->origin_begin_main_frame_args);
2382   }
2383 
2384   if (!mutator_host_->NextFrameHasPendingRAF())
2385     frame_trackers_.StopSequence(FrameSequenceTrackerType::kRAF);
2386   if (!mutator_host_->HasCanvasInvalidation())
2387     frame_trackers_.StopSequence(FrameSequenceTrackerType::kCanvasAnimation);
2388   if (!mutator_host_->HasJSAnimation())
2389     frame_trackers_.StopSequence(FrameSequenceTrackerType::kJSAnimation);
2390 
2391   if (mutator_host_->MainThreadAnimationsCount() == 0) {
2392     frame_trackers_.StopSequence(
2393         FrameSequenceTrackerType::kMainThreadAnimation);
2394   }
2395 
2396   if (lcd_text_metrics_reporter_) {
2397     lcd_text_metrics_reporter_->NotifySubmitFrame(
2398         frame->origin_begin_main_frame_args);
2399   }
2400 
2401   // Clears the list of swap promises after calling DidSwap on each of them to
2402   // signal that the swap is over.
2403   active_tree()->ClearSwapPromises();
2404 
2405   // The next frame should start by assuming nothing has changed, and changes
2406   // are noted as they occur.
2407   // TODO(boliu): If we did a temporary software renderer frame, propogate the
2408   // damage forward to the next frame.
2409   for (size_t i = 0; i < frame->render_surface_list->size(); i++) {
2410     auto* surface = (*frame->render_surface_list)[i];
2411     surface->damage_tracker()->DidDrawDamagedArea();
2412   }
2413   active_tree_->ResetAllChangeTracking();
2414 
2415   active_tree_->set_has_ever_been_drawn(true);
2416   devtools_instrumentation::DidDrawFrame(id_);
2417   benchmark_instrumentation::IssueImplThreadRenderingStatsEvent(
2418       rendering_stats_instrumentation_->TakeImplThreadRenderingStats());
2419   return true;
2420 }
2421 
GenerateCompositorFrame(FrameData * frame)2422 viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
2423     FrameData* frame) {
2424   TRACE_EVENT_WITH_FLOW1("viz,benchmark", "Graphics.Pipeline",
2425                          TRACE_ID_GLOBAL(CurrentBeginFrameArgs().trace_id),
2426                          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
2427                          "step", "GenerateCompositorFrame");
2428   rendering_stats_instrumentation_->IncrementFrameCount(1);
2429 
2430   memory_history_->SaveEntry(tile_manager_.memory_stats_from_last_assign());
2431 
2432   if (debug_state_.ShowHudRects()) {
2433     debug_rect_history_->SaveDebugRectsForCurrentFrame(
2434         active_tree(), active_tree_->hud_layer(), *frame->render_surface_list,
2435         debug_state_);
2436   }
2437 
2438   TRACE_EVENT_INSTANT2("cc", "Scroll Delta This Frame",
2439                        TRACE_EVENT_SCOPE_THREAD, "x",
2440                        scroll_accumulated_this_frame_.x(), "y",
2441                        scroll_accumulated_this_frame_.y());
2442   scroll_accumulated_this_frame_ = gfx::Vector2dF();
2443 
2444   bool is_new_trace;
2445   TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
2446   if (is_new_trace) {
2447     if (pending_tree_) {
2448       for (auto* layer : *pending_tree_)
2449         layer->DidBeginTracing();
2450     }
2451     for (auto* layer : *active_tree_)
2452       layer->DidBeginTracing();
2453   }
2454 
2455   {
2456     TRACE_EVENT0("cc", "DrawLayers.FrameViewerTracing");
2457     TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
2458         frame_viewer_instrumentation::CategoryLayerTree(),
2459         "cc::LayerTreeHostImpl", id_, AsValueWithFrame(frame));
2460   }
2461 
2462   const DrawMode draw_mode = GetDrawMode();
2463 
2464   // Because the contents of the HUD depend on everything else in the frame, the
2465   // contents of its texture are updated as the last thing before the frame is
2466   // drawn.
2467   if (active_tree_->hud_layer()) {
2468     TRACE_EVENT0("cc", "DrawLayers.UpdateHudTexture");
2469     active_tree_->hud_layer()->UpdateHudTexture(
2470         draw_mode, layer_tree_frame_sink_, &resource_provider_,
2471         // The hud uses Gpu rasterization if the device is capable, not related
2472         // to the content of the web page.
2473         gpu_rasterization_status_ != GpuRasterizationStatus::OFF_DEVICE,
2474         frame->render_passes);
2475   }
2476 
2477   viz::CompositorFrameMetadata metadata = MakeCompositorFrameMetadata();
2478   PopulateMetadataContentColorUsage(frame, &metadata);
2479   metadata.may_contain_video = frame->may_contain_video;
2480   metadata.deadline = viz::FrameDeadline(
2481       CurrentBeginFrameArgs().frame_time,
2482       frame->deadline_in_frames.value_or(0u), CurrentBeginFrameArgs().interval,
2483       frame->use_default_lower_bound_deadline);
2484 
2485   frame_rate_estimator_.WillDraw(CurrentBeginFrameArgs().frame_time);
2486 
2487   if (settings_.force_preferred_interval_for_video ||
2488       enable_frame_rate_throttling_) {
2489     metadata.preferred_frame_interval = viz::BeginFrameArgs::MaxInterval();
2490   } else {
2491     metadata.preferred_frame_interval =
2492         frame_rate_estimator_.GetPreferredInterval();
2493   }
2494 
2495   metadata.activation_dependencies = std::move(frame->activation_dependencies);
2496   active_tree()->FinishSwapPromises(&metadata);
2497   // The swap-promises should not change the frame-token.
2498   DCHECK_EQ(metadata.frame_token, *next_frame_token_);
2499 
2500   if (render_frame_metadata_observer_) {
2501     last_draw_render_frame_metadata_ = MakeRenderFrameMetadata(frame);
2502     last_draw_render_frame_metadata_->has_delegated_ink_metadata =
2503         metadata.delegated_ink_metadata.get();
2504 
2505     // We cache the value of any new vertical scroll direction so that we can
2506     // accurately determine when the next change in vertical scroll direction
2507     // occurs. Note that |kNull| is only used to indicate the absence of a
2508     // vertical scroll direction and should therefore be ignored.
2509     if (last_draw_render_frame_metadata_->new_vertical_scroll_direction !=
2510         viz::VerticalScrollDirection::kNull) {
2511       last_vertical_scroll_direction_ =
2512           last_draw_render_frame_metadata_->new_vertical_scroll_direction;
2513     }
2514 
2515     render_frame_metadata_observer_->OnRenderFrameSubmission(
2516         *last_draw_render_frame_metadata_, &metadata,
2517         active_tree()->TakeForceSendMetadataRequest());
2518   }
2519 
2520   if (!CommitToActiveTree() && !metadata.latency_info.empty()) {
2521     base::TimeTicks draw_time = base::TimeTicks::Now();
2522 
2523     ukm::SourceId exemplar = metadata.latency_info.front().ukm_source_id();
2524     ApplyFirstScrollTracking(&metadata.latency_info.front(),
2525                              metadata.frame_token, this);
2526     bool all_valid = true;
2527     bool all_unique = true;
2528     for (auto& latency : metadata.latency_info) {
2529       latency.AddLatencyNumberWithTimestamp(
2530           ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, draw_time);
2531       all_valid &= latency.ukm_source_id() != ukm::kInvalidSourceId;
2532       all_unique &= latency.ukm_source_id() == exemplar;
2533     }
2534 
2535     RecordSourceIdConsistency(all_valid, all_unique);
2536   }
2537   ui::LatencyInfo::TraceIntermediateFlowEvents(
2538       metadata.latency_info,
2539       perfetto::protos::pbzero::ChromeLatencyInfo::STEP_SWAP_BUFFERS);
2540 
2541   // Collect all resource ids in the render passes into a single array.
2542   std::vector<viz::ResourceId> resources;
2543   for (const auto& render_pass : frame->render_passes) {
2544     for (auto* quad : render_pass->quad_list) {
2545       for (viz::ResourceId resource_id : quad->resources)
2546         resources.push_back(resource_id);
2547     }
2548   }
2549 
2550   DCHECK(frame->begin_frame_ack.frame_id.IsSequenceValid());
2551   metadata.begin_frame_ack = frame->begin_frame_ack;
2552 
2553   viz::CompositorFrame compositor_frame;
2554   compositor_frame.metadata = std::move(metadata);
2555   resource_provider_.PrepareSendToParent(
2556       resources, &compositor_frame.resource_list,
2557       layer_tree_frame_sink_->context_provider());
2558   compositor_frame.render_pass_list = std::move(frame->render_passes);
2559 
2560   // We should always have a valid LocalSurfaceId in LayerTreeImpl unless we
2561   // don't have a scheduler because without a scheduler commits are not deferred
2562   // and LayerTrees without valid LocalSurfaceId might slip through, but
2563   // single-thread-without-scheduler mode is only used in tests so it doesn't
2564   // matter.
2565   CHECK(!settings_.single_thread_proxy_scheduler ||
2566         active_tree()->local_surface_id_from_parent().is_valid());
2567   layer_tree_frame_sink_->SetLocalSurfaceId(
2568       child_local_surface_id_allocator_.GetCurrentLocalSurfaceId());
2569 
2570   last_draw_local_surface_id_ =
2571       child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
2572   return compositor_frame;
2573 }
2574 
DidDrawAllLayers(const FrameData & frame)2575 void LayerTreeHostImpl::DidDrawAllLayers(const FrameData& frame) {
2576   // TODO(lethalantidote): LayerImpl::DidDraw can be removed when
2577   // VideoLayerImpl is removed.
2578   for (size_t i = 0; i < frame.will_draw_layers.size(); ++i)
2579     frame.will_draw_layers[i]->DidDraw(&resource_provider_);
2580 
2581   for (auto* it : video_frame_controllers_)
2582     it->DidDrawFrame();
2583 }
2584 
RequestedMSAASampleCount() const2585 int LayerTreeHostImpl::RequestedMSAASampleCount() const {
2586   if (settings_.gpu_rasterization_msaa_sample_count == -1) {
2587     // On "low-end" devices use 4 samples per pixel to save memory.
2588     if (base::SysInfo::IsLowEndDevice())
2589       return 4;
2590 
2591     // Use the most up-to-date version of device_scale_factor that we have.
2592     float device_scale_factor = pending_tree_
2593                                     ? pending_tree_->device_scale_factor()
2594                                     : active_tree_->device_scale_factor();
2595     return device_scale_factor >= 2.0f ? 4 : 8;
2596   }
2597 
2598   return settings_.gpu_rasterization_msaa_sample_count;
2599 }
2600 
GetGpuRasterizationCapabilities(bool * gpu_rasterization_enabled,bool * gpu_rasterization_supported,int * max_msaa_samples,bool * supports_disable_msaa)2601 void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
2602     bool* gpu_rasterization_enabled,
2603     bool* gpu_rasterization_supported,
2604     int* max_msaa_samples,
2605     bool* supports_disable_msaa) {
2606   *gpu_rasterization_enabled = false;
2607   *gpu_rasterization_supported = false;
2608   *max_msaa_samples = 0;
2609   *supports_disable_msaa = false;
2610 
2611   if (settings_.gpu_rasterization_disabled)
2612     return;
2613 
2614   if (!(layer_tree_frame_sink_ && layer_tree_frame_sink_->context_provider() &&
2615         layer_tree_frame_sink_->worker_context_provider())) {
2616     return;
2617   }
2618 
2619   viz::RasterContextProvider* context_provider =
2620       layer_tree_frame_sink_->worker_context_provider();
2621   viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
2622       context_provider);
2623 
2624   const auto& caps = context_provider->ContextCapabilities();
2625   *gpu_rasterization_enabled = caps.gpu_rasterization;
2626   if (!*gpu_rasterization_enabled)
2627     return;
2628 
2629   bool use_msaa = !caps.msaa_is_slow && !caps.avoid_stencil_buffers;
2630 
2631   if (can_use_oop_rasterization_) {
2632     *gpu_rasterization_supported = true;
2633     *supports_disable_msaa = caps.multisample_compatibility;
2634     // For OOP raster, the gpu service side will disable msaa if the
2635     // requested samples are not enough.  GPU raster does this same
2636     // logic below client side.
2637     if (use_msaa)
2638       *max_msaa_samples = RequestedMSAASampleCount();
2639     return;
2640   }
2641 
2642   if (!context_provider->ContextSupport()->HasGrContextSupport())
2643     return;
2644 
2645   // Do not check GrContext above. It is lazy-created, and we only want to
2646   // create it if it might be used.
2647   GrDirectContext* gr_context = context_provider->GrContext();
2648   *gpu_rasterization_supported = !!gr_context;
2649   if (!*gpu_rasterization_supported)
2650     return;
2651 
2652   *supports_disable_msaa = caps.multisample_compatibility;
2653   if (use_msaa) {
2654     // Skia may block MSAA independently of Chrome. Query Skia for its max
2655     // supported sample count. Assume gpu compositing + gpu raster for this, as
2656     // that is what we are hoping to use.
2657     viz::ResourceFormat tile_format = TileRasterBufferFormat(
2658         settings_, layer_tree_frame_sink_->context_provider(),
2659         /*use_gpu_rasterization=*/true);
2660     SkColorType color_type = ResourceFormatToClosestSkColorType(
2661         /*gpu_compositing=*/true, tile_format);
2662     *max_msaa_samples =
2663         gr_context->maxSurfaceSampleCountForColorType(color_type);
2664   }
2665 }
2666 
UpdateGpuRasterizationStatus()2667 bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() {
2668   if (!need_update_gpu_rasterization_status_)
2669     return false;
2670   need_update_gpu_rasterization_status_ = false;
2671 
2672   // TODO(danakj): Can we avoid having this run when there's no
2673   // LayerTreeFrameSink?
2674   // For now just early out and leave things unchanged, we'll come back here
2675   // when we get a LayerTreeFrameSink.
2676   if (!layer_tree_frame_sink_)
2677     return false;
2678 
2679   int requested_msaa_samples = RequestedMSAASampleCount();
2680   int max_msaa_samples = 0;
2681   bool gpu_rasterization_enabled = false;
2682   bool gpu_rasterization_supported = false;
2683   bool supports_disable_msaa = false;
2684   GetGpuRasterizationCapabilities(&gpu_rasterization_enabled,
2685                                   &gpu_rasterization_supported,
2686                                   &max_msaa_samples, &supports_disable_msaa);
2687 
2688   bool use_gpu = false;
2689   bool can_use_msaa =
2690       requested_msaa_samples > 0 && max_msaa_samples >= requested_msaa_samples;
2691 
2692   if (!gpu_rasterization_enabled) {
2693     if (gpu_rasterization_supported)
2694       gpu_rasterization_status_ = GpuRasterizationStatus::OFF_FORCED;
2695     else
2696       gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE;
2697   } else {
2698     use_gpu = true;
2699     gpu_rasterization_status_ = GpuRasterizationStatus::ON;
2700   }
2701 
2702   if (use_gpu && !use_gpu_rasterization_) {
2703     if (!gpu_rasterization_supported) {
2704       // If GPU rasterization is unusable, e.g. if GlContext could not
2705       // be created due to losing the GL context, force use of software
2706       // raster.
2707       use_gpu = false;
2708       can_use_msaa_ = false;
2709       supports_disable_msaa_ = false;
2710       gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE;
2711     }
2712   }
2713 
2714   // Changes in MSAA settings require that we re-raster resources for the
2715   // settings to take effect. But we don't need to trigger any raster
2716   // invalidation in this case since these settings change only if the context
2717   // changed. In this case we already re-allocate and re-raster all resources.
2718   if (use_gpu == use_gpu_rasterization_ && can_use_msaa == can_use_msaa_ &&
2719       supports_disable_msaa == supports_disable_msaa_) {
2720     return false;
2721   }
2722 
2723   use_gpu_rasterization_ = use_gpu;
2724   can_use_msaa_ = can_use_msaa;
2725   supports_disable_msaa_ = supports_disable_msaa;
2726   return true;
2727 }
2728 
UpdateTreeResourcesForGpuRasterizationIfNeeded()2729 void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() {
2730   if (!UpdateGpuRasterizationStatus())
2731     return;
2732 
2733   // Clean up and replace existing tile manager with another one that uses
2734   // appropriate rasterizer. Only do this however if we already have a
2735   // resource pool, since otherwise we might not be able to create a new
2736   // one.
2737   ReleaseTileResources();
2738   if (resource_pool_) {
2739     CleanUpTileManagerResources();
2740     CreateTileManagerResources();
2741   }
2742   RecreateTileResources();
2743 
2744   // We have released tilings for both active and pending tree.
2745   // We would not have any content to draw until the pending tree is activated.
2746   // Prevent the active tree from drawing until activation.
2747   // TODO(crbug.com/469175): Replace with RequiresHighResToDraw.
2748   SetRequiresHighResToDraw();
2749 }
2750 
RegisterMainThreadPresentationTimeCallback(uint32_t frame_token,LayerTreeHost::PresentationTimeCallback callback)2751 void LayerTreeHostImpl::RegisterMainThreadPresentationTimeCallback(
2752     uint32_t frame_token,
2753     LayerTreeHost::PresentationTimeCallback callback) {
2754   std::vector<LayerTreeHost::PresentationTimeCallback> as_vector;
2755   as_vector.emplace_back(std::move(callback));
2756   presentation_time_callbacks_.RegisterMainThreadPresentationCallbacks(
2757       frame_token, std::move(as_vector));
2758 }
2759 
RegisterCompositorPresentationTimeCallback(uint32_t frame_token,LayerTreeHost::PresentationTimeCallback callback)2760 void LayerTreeHostImpl::RegisterCompositorPresentationTimeCallback(
2761     uint32_t frame_token,
2762     LayerTreeHost::PresentationTimeCallback callback) {
2763   std::vector<LayerTreeHost::PresentationTimeCallback> as_vector;
2764   as_vector.emplace_back(std::move(callback));
2765   presentation_time_callbacks_.RegisterCompositorPresentationCallbacks(
2766       frame_token, std::move(as_vector));
2767 }
2768 
WillBeginImplFrame(const viz::BeginFrameArgs & args)2769 bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) {
2770   impl_thread_phase_ = ImplThreadPhase::INSIDE_IMPL_FRAME;
2771   current_begin_frame_tracker_.Start(args);
2772   frame_trackers_.NotifyBeginImplFrame(args);
2773   total_frame_counter_.OnBeginFrame(args);
2774 
2775   if (is_likely_to_require_a_draw_) {
2776     // Optimistically schedule a draw. This will let us expect the tile manager
2777     // to complete its work so that we can draw new tiles within the impl frame
2778     // we are beginning now.
2779     SetNeedsRedraw();
2780   }
2781 
2782   if (input_delegate_)
2783     input_delegate_->WillBeginImplFrame(args);
2784 
2785   Animate();
2786 
2787   image_animation_controller_.WillBeginImplFrame(args);
2788 
2789   for (auto* it : video_frame_controllers_)
2790     it->OnBeginFrame(args);
2791 
2792   bool recent_frame_had_no_damage =
2793       consecutive_frame_with_damage_count_ < settings_.damaged_frame_limit;
2794   // Check damage early if the setting is enabled and a recent frame had no
2795   // damage. HasDamage() expects CanDraw to be true. If we can't check damage,
2796   // return true to indicate that there might be damage in this frame.
2797   if (settings_.enable_early_damage_check && recent_frame_had_no_damage &&
2798       CanDraw()) {
2799     bool ok = active_tree()->UpdateDrawProperties();
2800     DCHECK(ok);
2801     DamageTracker::UpdateDamageTracking(active_tree_.get());
2802     bool has_damage = HasDamage();
2803     // Animations are updated after we attempt to draw. If the frame is aborted,
2804     // update animations now.
2805     if (!has_damage)
2806       UpdateAnimationState(true);
2807     return has_damage;
2808   }
2809   // Assume there is damage if we cannot check for damage.
2810   return true;
2811 }
2812 
DidFinishImplFrame(const viz::BeginFrameArgs & args)2813 void LayerTreeHostImpl::DidFinishImplFrame(const viz::BeginFrameArgs& args) {
2814   frame_trackers_.NotifyFrameEnd(current_begin_frame_tracker_.Current(), args);
2815   impl_thread_phase_ = ImplThreadPhase::IDLE;
2816   current_begin_frame_tracker_.Finish();
2817 }
2818 
DidNotProduceFrame(const viz::BeginFrameAck & ack,FrameSkippedReason reason)2819 void LayerTreeHostImpl::DidNotProduceFrame(const viz::BeginFrameAck& ack,
2820                                            FrameSkippedReason reason) {
2821   if (layer_tree_frame_sink_)
2822     layer_tree_frame_sink_->DidNotProduceFrame(ack);
2823 
2824   // If a frame was not submitted because there was no damage, or the scheduler
2825   // hit the frame-deadline while waiting for the main-thread, notify the
2826   // trackers.
2827   if (reason != FrameSkippedReason::kRecoverLatency &&
2828       impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
2829     // It is possible that |ack| is for a 'future frame', i.e. for the next
2830     // frame from the one currently being handled by the compositor (represented
2831     // by the BeginFrameArgs instance in |current_begin_frame_tracker_|). This
2832     // can happen, for example, when a frame is skipped early for
2833     // latency-recovery, while the previous frame is still being processed.
2834     // Notify the trackers only when this is *not* the case (since the trackers
2835     // are not notified about the start of the future frame either).
2836     const auto& args = current_begin_frame_tracker_.Current();
2837     if (args.frame_id == ack.frame_id) {
2838       frame_trackers_.NotifyImplFrameCausedNoDamage(ack);
2839     }
2840   }
2841 }
2842 
SynchronouslyInitializeAllTiles()2843 void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() {
2844   // Only valid for the single-threaded non-scheduled/synchronous case
2845   // using the zero copy raster worker pool.
2846   single_thread_synchronous_task_graph_runner_->RunUntilIdle();
2847 }
2848 
GetFlagsForSurfaceLayer(const SurfaceLayerImpl * layer)2849 static uint32_t GetFlagsForSurfaceLayer(const SurfaceLayerImpl* layer) {
2850   uint32_t flags = viz::HitTestRegionFlags::kHitTestMouse |
2851                    viz::HitTestRegionFlags::kHitTestTouch;
2852   if (layer->range().IsValid()) {
2853     flags |= viz::HitTestRegionFlags::kHitTestChildSurface;
2854   } else {
2855     flags |= viz::HitTestRegionFlags::kHitTestMine;
2856   }
2857   return flags;
2858 }
2859 
PopulateHitTestRegion(viz::HitTestRegion * hit_test_region,const LayerImpl * layer,uint32_t flags,uint32_t async_hit_test_reasons,const gfx::Rect & rect,const viz::SurfaceId & surface_id,float device_scale_factor)2860 static void PopulateHitTestRegion(viz::HitTestRegion* hit_test_region,
2861                                   const LayerImpl* layer,
2862                                   uint32_t flags,
2863                                   uint32_t async_hit_test_reasons,
2864                                   const gfx::Rect& rect,
2865                                   const viz::SurfaceId& surface_id,
2866                                   float device_scale_factor) {
2867   hit_test_region->frame_sink_id = surface_id.frame_sink_id();
2868   hit_test_region->flags = flags;
2869   hit_test_region->async_hit_test_reasons = async_hit_test_reasons;
2870   DCHECK_EQ(!!async_hit_test_reasons,
2871             !!(flags & viz::HitTestRegionFlags::kHitTestAsk));
2872 
2873   hit_test_region->rect = rect;
2874   // The transform of hit test region maps a point from parent hit test region
2875   // to the local space. This is the inverse of screen space transform. Because
2876   // hit test query wants the point in target to be in Pixel space, we
2877   // counterscale the transform here. Note that the rect is scaled by dsf, so
2878   // the point and the rect are still in the same space.
2879   gfx::Transform surface_to_root_transform = layer->ScreenSpaceTransform();
2880   surface_to_root_transform.Scale(SK_Scalar1 / device_scale_factor,
2881                                   SK_Scalar1 / device_scale_factor);
2882   surface_to_root_transform.FlattenTo2d();
2883   // TODO(sunxd): Avoid losing precision by not using inverse if possible.
2884   bool ok = surface_to_root_transform.GetInverse(&hit_test_region->transform);
2885   // Note: If |ok| is false, the |transform| is set to the identity before
2886   // returning, which is what we want.
2887   ALLOW_UNUSED_LOCAL(ok);
2888 }
2889 
BuildHitTestData()2890 base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
2891   TRACE_EVENT0("cc", "LayerTreeHostImpl::BuildHitTestData");
2892 
2893   base::Optional<viz::HitTestRegionList> hit_test_region_list(base::in_place);
2894   hit_test_region_list->flags = viz::HitTestRegionFlags::kHitTestMine |
2895                                 viz::HitTestRegionFlags::kHitTestMouse |
2896                                 viz::HitTestRegionFlags::kHitTestTouch;
2897   hit_test_region_list->bounds = active_tree_->GetDeviceViewport();
2898   hit_test_region_list->transform = DrawTransform();
2899 
2900   float device_scale_factor = active_tree()->device_scale_factor();
2901 
2902   Region overlapping_region;
2903   size_t num_iterated_layers = 0;
2904   // If the layer tree contains more than 100 layers, we stop accumulating
2905   // layers in |overlapping_region| to save compositor frame submitting time, as
2906   // a result we do async hit test on any surface layers that
2907   bool assume_overlap = false;
2908   for (const auto* layer : base::Reversed(*active_tree())) {
2909     // Viz hit test needs to collect information for pointer-events: none OOPIFs
2910     // as well. Now Layer::HitTestable ignores pointer-events property, but this
2911     // early out will not work correctly if we integrate has_pointer_events_none
2912     // into Layer::HitTestable, so we make sure we don't skip surface layers
2913     // that draws content but has pointer-events: none property.
2914     if (!(layer->HitTestable() ||
2915           (layer->is_surface_layer() && layer->DrawsContent())))
2916       continue;
2917 
2918     if (layer->is_surface_layer()) {
2919       const auto* surface_layer = static_cast<const SurfaceLayerImpl*>(layer);
2920       // If a surface layer is created not by child frame compositor or the
2921       // frame owner has pointer-events: none property, the surface layer
2922       // becomes not hit testable. We should not generate data for it.
2923       if (!surface_layer->surface_hit_testable() ||
2924           !surface_layer->range().IsValid()) {
2925         // We collect any overlapped regions that does not have pointer-events:
2926         // none.
2927         if (!surface_layer->has_pointer_events_none() && !assume_overlap) {
2928           overlapping_region.Union(MathUtil::MapEnclosingClippedRect(
2929               layer->ScreenSpaceTransform(),
2930               gfx::Rect(surface_layer->bounds())));
2931         }
2932         continue;
2933       }
2934 
2935       gfx::Rect content_rect(
2936           gfx::ScaleToEnclosingRect(gfx::Rect(surface_layer->bounds()),
2937                                     device_scale_factor, device_scale_factor));
2938 
2939       gfx::Rect layer_screen_space_rect = MathUtil::MapEnclosingClippedRect(
2940           surface_layer->ScreenSpaceTransform(),
2941           gfx::Rect(surface_layer->bounds()));
2942       auto flag = GetFlagsForSurfaceLayer(surface_layer);
2943       uint32_t async_hit_test_reasons =
2944           viz::AsyncHitTestReasons::kNotAsyncHitTest;
2945       if (surface_layer->has_pointer_events_none())
2946         flag |= viz::HitTestRegionFlags::kHitTestIgnore;
2947       if (assume_overlap ||
2948           overlapping_region.Intersects(layer_screen_space_rect)) {
2949         flag |= viz::HitTestRegionFlags::kHitTestAsk;
2950         async_hit_test_reasons |= viz::AsyncHitTestReasons::kOverlappedRegion;
2951       }
2952       bool layer_hit_test_region_is_masked =
2953           active_tree()
2954               ->property_trees()
2955               ->effect_tree.HitTestMayBeAffectedByMask(
2956                   surface_layer->effect_tree_index());
2957       if (surface_layer->is_clipped() || layer_hit_test_region_is_masked) {
2958         bool layer_hit_test_region_is_rectangle =
2959             !layer_hit_test_region_is_masked &&
2960             surface_layer->ScreenSpaceTransform().Preserves2dAxisAlignment() &&
2961             active_tree()
2962                 ->property_trees()
2963                 ->effect_tree.ClippedHitTestRegionIsRectangle(
2964                     surface_layer->effect_tree_index());
2965         content_rect =
2966             gfx::ScaleToEnclosingRect(surface_layer->visible_layer_rect(),
2967                                       device_scale_factor, device_scale_factor);
2968         if (!layer_hit_test_region_is_rectangle) {
2969           flag |= viz::HitTestRegionFlags::kHitTestAsk;
2970           async_hit_test_reasons |= viz::AsyncHitTestReasons::kIrregularClip;
2971         }
2972       }
2973       const auto& surface_id = surface_layer->range().end();
2974       hit_test_region_list->regions.emplace_back();
2975       PopulateHitTestRegion(&hit_test_region_list->regions.back(), layer, flag,
2976                             async_hit_test_reasons, content_rect, surface_id,
2977                             device_scale_factor);
2978       continue;
2979     }
2980     // TODO(sunxd): Submit all overlapping layer bounds as hit test regions.
2981     // Also investigate if we can use visible layer rect as overlapping regions.
2982     num_iterated_layers++;
2983     if (num_iterated_layers > kAssumeOverlapThreshold)
2984       assume_overlap = true;
2985     if (!assume_overlap) {
2986       overlapping_region.Union(MathUtil::MapEnclosingClippedRect(
2987           layer->ScreenSpaceTransform(), gfx::Rect(layer->bounds())));
2988     }
2989   }
2990 
2991   return hit_test_region_list;
2992 }
2993 
DidLoseLayerTreeFrameSink()2994 void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() {
2995   // Check that we haven't already detected context loss because we get it via
2996   // two paths: compositor context loss on the compositor thread and worker
2997   // context loss posted from main thread to compositor thread. We do not want
2998   // to reset the context recovery state in the scheduler.
2999   if (!has_valid_layer_tree_frame_sink_)
3000     return;
3001   has_valid_layer_tree_frame_sink_ = false;
3002   client_->DidLoseLayerTreeFrameSinkOnImplThread();
3003   lag_tracking_manager_.Clear();
3004 
3005   dropped_frame_counter_.ResetFrameSorter();
3006 }
3007 
OnlyExpandTopControlsAtPageTop() const3008 bool LayerTreeHostImpl::OnlyExpandTopControlsAtPageTop() const {
3009   return active_tree_->only_expand_top_controls_at_page_top();
3010 }
3011 
HaveRootScrollNode() const3012 bool LayerTreeHostImpl::HaveRootScrollNode() const {
3013   return InnerViewportScrollNode();
3014 }
3015 
SetNeedsCommit()3016 void LayerTreeHostImpl::SetNeedsCommit() {
3017   client_->SetNeedsCommitOnImplThread();
3018 }
3019 
InnerViewportScrollNode() const3020 ScrollNode* LayerTreeHostImpl::InnerViewportScrollNode() const {
3021   return active_tree_->InnerViewportScrollNode();
3022 }
3023 
OuterViewportScrollNode() const3024 ScrollNode* LayerTreeHostImpl::OuterViewportScrollNode() const {
3025   return active_tree_->OuterViewportScrollNode();
3026 }
3027 
CurrentlyScrollingNode()3028 ScrollNode* LayerTreeHostImpl::CurrentlyScrollingNode() {
3029   return active_tree()->CurrentlyScrollingNode();
3030 }
3031 
CurrentlyScrollingNode() const3032 const ScrollNode* LayerTreeHostImpl::CurrentlyScrollingNode() const {
3033   return active_tree()->CurrentlyScrollingNode();
3034 }
3035 
IsPinchGestureActive() const3036 bool LayerTreeHostImpl::IsPinchGestureActive() const {
3037   if (!input_delegate_)
3038     return false;
3039   return GetInputHandler().pinch_gesture_active();
3040 }
3041 
GetActivelyScrollingType() const3042 ActivelyScrollingType LayerTreeHostImpl::GetActivelyScrollingType() const {
3043   if (!input_delegate_)
3044     return ActivelyScrollingType::kNone;
3045   return input_delegate_->GetActivelyScrollingType();
3046 }
3047 
ScrollAffectsScrollHandler() const3048 bool LayerTreeHostImpl::ScrollAffectsScrollHandler() const {
3049   if (!input_delegate_)
3050     return false;
3051   return settings_.enable_synchronized_scrolling &&
3052          scroll_affects_scroll_handler_;
3053 }
3054 
SetExternalPinchGestureActive(bool active)3055 void LayerTreeHostImpl::SetExternalPinchGestureActive(bool active) {
3056   DCHECK(input_delegate_ || !active);
3057   if (input_delegate_)
3058     GetInputHandler().set_external_pinch_gesture_active(active);
3059 }
3060 
CreatePendingTree()3061 void LayerTreeHostImpl::CreatePendingTree() {
3062   CHECK(!pending_tree_);
3063   if (recycle_tree_) {
3064     recycle_tree_.swap(pending_tree_);
3065   } else {
3066     pending_tree_ = std::make_unique<LayerTreeImpl>(
3067         this, active_tree()->page_scale_factor(),
3068         active_tree()->top_controls_shown_ratio(),
3069         active_tree()->bottom_controls_shown_ratio(),
3070         active_tree()->elastic_overscroll());
3071   }
3072   pending_tree_fully_painted_ = false;
3073 
3074   client_->OnCanDrawStateChanged(CanDraw());
3075   TRACE_EVENT_NESTABLE_ASYNC_BEGIN0("cc", "PendingTree:waiting",
3076                                     TRACE_ID_LOCAL(pending_tree_.get()));
3077 }
3078 
PushScrollbarOpacitiesFromActiveToPending()3079 void LayerTreeHostImpl::PushScrollbarOpacitiesFromActiveToPending() {
3080   if (!active_tree())
3081     return;
3082   for (auto& pair : scrollbar_animation_controllers_) {
3083     for (auto* scrollbar : pair.second->Scrollbars()) {
3084       if (const EffectNode* source_effect_node =
3085               active_tree()
3086                   ->property_trees()
3087                   ->effect_tree.FindNodeFromElementId(
3088                       scrollbar->element_id())) {
3089         if (EffectNode* target_effect_node =
3090                 pending_tree()
3091                     ->property_trees()
3092                     ->effect_tree.FindNodeFromElementId(
3093                         scrollbar->element_id())) {
3094           DCHECK(target_effect_node);
3095           float source_opacity = source_effect_node->opacity;
3096           float target_opacity = target_effect_node->opacity;
3097           if (source_opacity == target_opacity)
3098             continue;
3099           target_effect_node->opacity = source_opacity;
3100           pending_tree()->property_trees()->effect_tree.set_needs_update(true);
3101         }
3102       }
3103     }
3104   }
3105 }
3106 
ActivateSyncTree()3107 void LayerTreeHostImpl::ActivateSyncTree() {
3108   TRACE_EVENT0("cc,benchmark", "LayerTreeHostImpl::ActivateSyncTree()");
3109   if (pending_tree_) {
3110     TRACE_EVENT_NESTABLE_ASYNC_END0("cc", "PendingTree:waiting",
3111                                     TRACE_ID_LOCAL(pending_tree_.get()));
3112     active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync);
3113 
3114     // In most cases, this will be reset in NotifyReadyToActivate, since we
3115     // activate the pending tree only when its ready. But an activation may be
3116     // forced, in the case of a context loss for instance, so reset it here as
3117     // well.
3118     pending_tree_raster_duration_timer_.reset();
3119 
3120     // Process any requests in the UI resource queue.  The request queue is
3121     // given in LayerTreeHost::FinishCommitOnImplThread.  This must take place
3122     // before the swap.
3123     pending_tree_->ProcessUIResourceRequestQueue();
3124 
3125     if (pending_tree_->needs_full_tree_sync()) {
3126       TreeSynchronizer::SynchronizeTrees(pending_tree_.get(),
3127                                          active_tree_.get());
3128     }
3129 
3130     PushScrollbarOpacitiesFromActiveToPending();
3131     pending_tree_->PushPropertyTreesTo(active_tree_.get());
3132     active_tree_->lifecycle().AdvanceTo(
3133         LayerTreeLifecycle::kSyncedPropertyTrees);
3134 
3135     TreeSynchronizer::PushLayerProperties(pending_tree(), active_tree());
3136 
3137     active_tree_->lifecycle().AdvanceTo(
3138         LayerTreeLifecycle::kSyncedLayerProperties);
3139 
3140     pending_tree_->PushPropertiesTo(active_tree_.get());
3141     if (!pending_tree_->LayerListIsEmpty())
3142       pending_tree_->property_trees()->ResetAllChangeTracking();
3143 
3144     // Property tree nodes have been updated by PushLayerProperties. Update
3145     // elements available on active tree to start/stop ticking animations.
3146     UpdateElements(ElementListType::ACTIVE);
3147 
3148     active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing);
3149 
3150     // Now that we've synced everything from the pending tree to the active
3151     // tree, rename the pending tree the recycle tree so we can reuse it on the
3152     // next sync.
3153     DCHECK(!recycle_tree_);
3154     pending_tree_.swap(recycle_tree_);
3155 
3156     // ScrollTimelines track a scroll source (i.e. a scroll node in the scroll
3157     // tree), whose ElementId may change between the active and pending trees.
3158     // Therefore we must inform all ScrollTimelines when the pending tree is
3159     // promoted to active.
3160     mutator_host_->PromoteScrollTimelinesPendingToActive();
3161 
3162     // If we commit to the active tree directly, this is already done during
3163     // commit.
3164     ActivateAnimations();
3165 
3166     // Update the state for images in ImageAnimationController and TileManager
3167     // before dirtying tile priorities. Since these components cache tree
3168     // specific state, these should be updated before DidModifyTilePriorities
3169     // which can synchronously issue a PrepareTiles. Note that if we commit to
3170     // the active tree directly, this is already done during commit.
3171     ActivateStateForImages();
3172   } else {
3173     active_tree_->ProcessUIResourceRequestQueue();
3174   }
3175 
3176   active_tree_->UpdateViewportContainerSizes();
3177 
3178   if (InnerViewportScrollNode()) {
3179     active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset(
3180         *InnerViewportScrollNode(), active_tree_.get());
3181 
3182     DCHECK(OuterViewportScrollNode());
3183     active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset(
3184         *OuterViewportScrollNode(), active_tree_.get());
3185   }
3186 
3187   active_tree_->DidBecomeActive();
3188   client_->RenewTreePriority();
3189 
3190   // If we have any picture layers, then by activating we also modified tile
3191   // priorities.
3192   if (!active_tree_->picture_layers().empty())
3193     DidModifyTilePriorities();
3194 
3195   client_->OnCanDrawStateChanged(CanDraw());
3196   client_->DidActivateSyncTree();
3197   if (!tree_activation_callback_.is_null())
3198     tree_activation_callback_.Run();
3199 
3200   std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation =
3201       active_tree_->TakePendingPageScaleAnimation();
3202   if (pending_page_scale_animation) {
3203     StartPageScaleAnimation(pending_page_scale_animation->target_offset,
3204                             pending_page_scale_animation->use_anchor,
3205                             pending_page_scale_animation->scale,
3206                             pending_page_scale_animation->duration);
3207   }
3208 
3209   if (input_delegate_)
3210     input_delegate_->DidActivatePendingTree();
3211 
3212   // Update the child's LocalSurfaceId.
3213   if (active_tree()->local_surface_id_from_parent().is_valid()) {
3214     child_local_surface_id_allocator_.UpdateFromParent(
3215         active_tree()->local_surface_id_from_parent());
3216     if (active_tree()->TakeNewLocalSurfaceIdRequest())
3217       AllocateLocalSurfaceId();
3218   }
3219 
3220   // Dump property trees and layers if run with:
3221   //   --vmodule=layer_tree_host_impl=3
3222   if (VLOG_IS_ON(3)) {
3223     const char* client_name = GetClientNameForMetrics();
3224     if (!client_name)
3225       client_name = "<unknown client>";
3226     VLOG(3) << "After activating (" << client_name
3227             << ") sync tree, the active tree:"
3228             << "\nproperty_trees:\n"
3229             << active_tree_->property_trees()->ToString() << "\n"
3230             << "cc::LayerImpls:\n"
3231             << active_tree_->LayerListAsJson();
3232   }
3233 }
3234 
ActivateStateForImages()3235 void LayerTreeHostImpl::ActivateStateForImages() {
3236   image_animation_controller_.DidActivate();
3237   tile_manager_.DidActivateSyncTree();
3238 }
3239 
OnMemoryPressure(base::MemoryPressureListener::MemoryPressureLevel level)3240 void LayerTreeHostImpl::OnMemoryPressure(
3241     base::MemoryPressureListener::MemoryPressureLevel level) {
3242   // Only work for low-end devices for now.
3243   if (!base::SysInfo::IsLowEndDevice())
3244     return;
3245 
3246   if (level != base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL)
3247     return;
3248 
3249   ReleaseTileResources();
3250   active_tree_->OnPurgeMemory();
3251   if (pending_tree_)
3252     pending_tree_->OnPurgeMemory();
3253   if (recycle_tree_)
3254     recycle_tree_->OnPurgeMemory();
3255 
3256   EvictAllUIResources();
3257   if (image_decode_cache_) {
3258     image_decode_cache_->SetShouldAggressivelyFreeResources(true);
3259     image_decode_cache_->SetShouldAggressivelyFreeResources(false);
3260   }
3261   if (resource_pool_)
3262     resource_pool_->OnMemoryPressure(level);
3263   tile_manager_.decoded_image_tracker().UnlockAllImages();
3264 }
3265 
SetVisible(bool visible)3266 void LayerTreeHostImpl::SetVisible(bool visible) {
3267   DCHECK(task_runner_provider_->IsImplThread());
3268 
3269   if (visible_ == visible)
3270     return;
3271   visible_ = visible;
3272   if (visible_)
3273     total_frame_counter_.OnShow(base::TimeTicks::Now());
3274   else
3275     total_frame_counter_.OnHide(base::TimeTicks::Now());
3276   DidVisibilityChange(this, visible_);
3277   UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
3278 
3279   // If we just became visible, we have to ensure that we draw high res tiles,
3280   // to prevent checkerboard/low res flashes.
3281   if (visible_) {
3282     // TODO(crbug.com/469175): Replace with RequiresHighResToDraw.
3283     SetRequiresHighResToDraw();
3284     // Prior CompositorFrame may have been discarded and thus we need to ensure
3285     // that we submit a new one, even if there are no tiles. Therefore, force a
3286     // full viewport redraw. However, this is unnecessary when we become visible
3287     // for the first time (before the first commit) as there is no prior
3288     // CompositorFrame to replace. We can safely use |!active_tree_->
3289     // LayerListIsEmpty()| as a proxy for this, because we wouldn't be able to
3290     // draw anything even if this is not the first time we become visible.
3291     if (!active_tree_->LayerListIsEmpty()) {
3292       SetFullViewportDamage();
3293       SetNeedsRedraw();
3294     }
3295   } else {
3296     EvictAllUIResources();
3297     // Call PrepareTiles to evict tiles when we become invisible.
3298     PrepareTiles();
3299     tile_manager_.decoded_image_tracker().UnlockAllImages();
3300   }
3301 }
3302 
SetNeedsOneBeginImplFrame()3303 void LayerTreeHostImpl::SetNeedsOneBeginImplFrame() {
3304   // TODO(miletus): This is just the compositor-thread-side call to the
3305   // SwapPromiseMonitor to say something happened that may cause a swap in the
3306   // future. The name should not refer to SetNeedsRedraw but it does for now.
3307   NotifySwapPromiseMonitorsOfSetNeedsRedraw();
3308   events_metrics_manager_.SaveActiveEventMetrics();
3309   client_->SetNeedsOneBeginImplFrameOnImplThread();
3310 }
3311 
SetNeedsRedraw()3312 void LayerTreeHostImpl::SetNeedsRedraw() {
3313   NotifySwapPromiseMonitorsOfSetNeedsRedraw();
3314   events_metrics_manager_.SaveActiveEventMetrics();
3315   client_->SetNeedsRedrawOnImplThread();
3316 }
3317 
ActualManagedMemoryPolicy() const3318 ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const {
3319   ManagedMemoryPolicy actual = cached_managed_memory_policy_;
3320   if (debug_state_.rasterize_only_visible_content) {
3321     actual.priority_cutoff_when_visible =
3322         gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY;
3323   } else if (use_gpu_rasterization()) {
3324     actual.priority_cutoff_when_visible =
3325         gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
3326   }
3327   return actual;
3328 }
3329 
ReleaseTreeResources()3330 void LayerTreeHostImpl::ReleaseTreeResources() {
3331   active_tree_->ReleaseResources();
3332   if (pending_tree_)
3333     pending_tree_->ReleaseResources();
3334   if (recycle_tree_)
3335     recycle_tree_->ReleaseResources();
3336 
3337   EvictAllUIResources();
3338 }
3339 
ReleaseTileResources()3340 void LayerTreeHostImpl::ReleaseTileResources() {
3341   active_tree_->ReleaseTileResources();
3342   if (pending_tree_)
3343     pending_tree_->ReleaseTileResources();
3344   if (recycle_tree_)
3345     recycle_tree_->ReleaseTileResources();
3346 
3347   // Need to update tiles again in order to kick of raster work for all the
3348   // tiles that are dropped here.
3349   active_tree_->set_needs_update_draw_properties();
3350 }
3351 
RecreateTileResources()3352 void LayerTreeHostImpl::RecreateTileResources() {
3353   active_tree_->RecreateTileResources();
3354   if (pending_tree_)
3355     pending_tree_->RecreateTileResources();
3356   if (recycle_tree_)
3357     recycle_tree_->RecreateTileResources();
3358 }
3359 
CreateTileManagerResources()3360 void LayerTreeHostImpl::CreateTileManagerResources() {
3361   raster_buffer_provider_ = CreateRasterBufferProvider();
3362 
3363   viz::ResourceFormat tile_format = TileRasterBufferFormat(
3364       settings_, layer_tree_frame_sink_->context_provider(),
3365       use_gpu_rasterization_);
3366 
3367   if (use_gpu_rasterization_) {
3368     image_decode_cache_ = std::make_unique<GpuImageDecodeCache>(
3369         layer_tree_frame_sink_->worker_context_provider(),
3370         can_use_oop_rasterization_,
3371         viz::ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true,
3372                                                 tile_format),
3373         settings_.decoded_image_working_set_budget_bytes, max_texture_size_,
3374         paint_image_generator_client_id_, dark_mode_filter_);
3375   } else {
3376     bool gpu_compositing = !!layer_tree_frame_sink_->context_provider();
3377     image_decode_cache_ = std::make_unique<SoftwareImageDecodeCache>(
3378         viz::ResourceFormatToClosestSkColorType(gpu_compositing, tile_format),
3379         settings_.decoded_image_working_set_budget_bytes,
3380         paint_image_generator_client_id_);
3381   }
3382 
3383   // Pass the single-threaded synchronous task graph runner to the worker pool
3384   // if we're in synchronous single-threaded mode.
3385   TaskGraphRunner* task_graph_runner = task_graph_runner_;
3386   if (is_synchronous_single_threaded_) {
3387     DCHECK(!single_thread_synchronous_task_graph_runner_);
3388     single_thread_synchronous_task_graph_runner_.reset(
3389         new SynchronousTaskGraphRunner);
3390     task_graph_runner = single_thread_synchronous_task_graph_runner_.get();
3391   }
3392 
3393   tile_manager_.SetResources(resource_pool_.get(), image_decode_cache_.get(),
3394                              task_graph_runner, raster_buffer_provider_.get(),
3395                              use_gpu_rasterization_, use_oop_rasterization());
3396   tile_manager_.SetCheckerImagingForceDisabled(
3397       settings_.only_checker_images_with_gpu_raster && !use_gpu_rasterization_);
3398   UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
3399 }
3400 
3401 std::unique_ptr<RasterBufferProvider>
CreateRasterBufferProvider()3402 LayerTreeHostImpl::CreateRasterBufferProvider() {
3403   DCHECK(GetTaskRunner());
3404 
3405   viz::ContextProvider* compositor_context_provider =
3406       layer_tree_frame_sink_->context_provider();
3407   if (!compositor_context_provider)
3408     return std::make_unique<BitmapRasterBufferProvider>(layer_tree_frame_sink_);
3409 
3410   const gpu::Capabilities& caps =
3411       compositor_context_provider->ContextCapabilities();
3412   viz::RasterContextProvider* worker_context_provider =
3413       layer_tree_frame_sink_->worker_context_provider();
3414 
3415   viz::ResourceFormat tile_format = TileRasterBufferFormat(
3416       settings_, compositor_context_provider, use_gpu_rasterization_);
3417 
3418   if (use_gpu_rasterization_) {
3419     DCHECK(worker_context_provider);
3420 
3421     return std::make_unique<GpuRasterBufferProvider>(
3422         compositor_context_provider, worker_context_provider,
3423         settings_.resource_settings.use_gpu_memory_buffer_resources,
3424         tile_format, settings_.max_gpu_raster_tile_size,
3425         settings_.unpremultiply_and_dither_low_bit_depth_tiles,
3426         can_use_oop_rasterization_);
3427   }
3428 
3429   bool use_zero_copy = settings_.use_zero_copy;
3430   // TODO(reveman): Remove this when mojo supports worker contexts.
3431   // crbug.com/522440
3432   if (!use_zero_copy && !worker_context_provider) {
3433     LOG(ERROR)
3434         << "Forcing zero-copy tile initialization as worker context is missing";
3435     use_zero_copy = true;
3436   }
3437 
3438   if (use_zero_copy) {
3439     return std::make_unique<ZeroCopyRasterBufferProvider>(
3440         layer_tree_frame_sink_->gpu_memory_buffer_manager(),
3441         compositor_context_provider, tile_format);
3442   }
3443 
3444   const int max_copy_texture_chromium_size =
3445       caps.max_copy_texture_chromium_size;
3446   return std::make_unique<OneCopyRasterBufferProvider>(
3447       GetTaskRunner(), compositor_context_provider, worker_context_provider,
3448       layer_tree_frame_sink_->gpu_memory_buffer_manager(),
3449       max_copy_texture_chromium_size, settings_.use_partial_raster,
3450       settings_.resource_settings.use_gpu_memory_buffer_resources,
3451       settings_.max_staging_buffer_usage_in_bytes, tile_format);
3452 }
3453 
SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator)3454 void LayerTreeHostImpl::SetLayerTreeMutator(
3455     std::unique_ptr<LayerTreeMutator> mutator) {
3456   mutator_host_->SetLayerTreeMutator(std::move(mutator));
3457 }
3458 
SetPaintWorkletLayerPainter(std::unique_ptr<PaintWorkletLayerPainter> painter)3459 void LayerTreeHostImpl::SetPaintWorkletLayerPainter(
3460     std::unique_ptr<PaintWorkletLayerPainter> painter) {
3461   paint_worklet_painter_ = std::move(painter);
3462 }
3463 
QueueImageDecode(int request_id,const PaintImage & image)3464 void LayerTreeHostImpl::QueueImageDecode(int request_id,
3465                                          const PaintImage& image) {
3466   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
3467                "LayerTreeHostImpl::QueueImageDecode", "frame_key",
3468                image.GetKeyForFrame(PaintImage::kDefaultFrameIndex).ToString());
3469   // Optimistically specify the current raster color space, since we assume that
3470   // it won't change.
3471   auto content_color_usage = image.GetContentColorUsage();
3472   tile_manager_.decoded_image_tracker().QueueImageDecode(
3473       image, GetRasterColorSpace(content_color_usage),
3474       base::BindOnce(&LayerTreeHostImpl::ImageDecodeFinished,
3475                      weak_factory_.GetWeakPtr(), request_id));
3476   tile_manager_.checker_image_tracker().DisallowCheckeringForImage(image);
3477 }
3478 
ImageDecodeFinished(int request_id,bool decode_succeeded)3479 void LayerTreeHostImpl::ImageDecodeFinished(int request_id,
3480                                             bool decode_succeeded) {
3481   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
3482                "LayerTreeHostImpl::ImageDecodeFinished");
3483   completed_image_decode_requests_.emplace_back(request_id, decode_succeeded);
3484   client_->NotifyImageDecodeRequestFinished();
3485 }
3486 
3487 std::vector<std::pair<int, bool>>
TakeCompletedImageDecodeRequests()3488 LayerTreeHostImpl::TakeCompletedImageDecodeRequests() {
3489   auto result = std::move(completed_image_decode_requests_);
3490   completed_image_decode_requests_.clear();
3491   return result;
3492 }
3493 
TakeMutatorEvents()3494 std::unique_ptr<MutatorEvents> LayerTreeHostImpl::TakeMutatorEvents() {
3495   std::unique_ptr<MutatorEvents> events = mutator_host_->CreateEvents();
3496   std::swap(events, mutator_events_);
3497   mutator_host_->TakeTimeUpdatedEvents(events.get());
3498   return events;
3499 }
3500 
ClearCaches()3501 void LayerTreeHostImpl::ClearCaches() {
3502   // It is safe to clear the decode policy tracking on navigations since it
3503   // comes with an invalidation and the image ids are never re-used.
3504   bool can_clear_decode_policy_tracking = true;
3505   tile_manager_.ClearCheckerImageTracking(can_clear_decode_policy_tracking);
3506   if (image_decode_cache_)
3507     image_decode_cache_->ClearCache();
3508   image_animation_controller_.set_did_navigate();
3509 }
3510 
DidChangeScrollbarVisibility()3511 void LayerTreeHostImpl::DidChangeScrollbarVisibility() {
3512   // Need a commit since input handling for scrollbars is handled in Blink so
3513   // we need to communicate to Blink when the compositor shows/hides the
3514   // scrollbars.
3515   client_->SetNeedsCommitOnImplThread();
3516 }
3517 
CleanUpTileManagerResources()3518 void LayerTreeHostImpl::CleanUpTileManagerResources() {
3519   tile_manager_.FinishTasksAndCleanUp();
3520   single_thread_synchronous_task_graph_runner_ = nullptr;
3521   image_decode_cache_ = nullptr;
3522   raster_buffer_provider_ = nullptr;
3523   // Any resources that were allocated previously should be considered not good
3524   // for reuse, as the RasterBufferProvider will be replaced and it may choose
3525   // to allocate future resources differently.
3526   resource_pool_->InvalidateResources();
3527 
3528   // We've potentially just freed a large number of resources on our various
3529   // contexts. Flushing now helps ensure these are cleaned up quickly
3530   // preventing driver cache growth. See crbug.com/643251
3531   if (layer_tree_frame_sink_) {
3532     if (auto* compositor_context = layer_tree_frame_sink_->context_provider()) {
3533       // TODO(ericrk): Remove ordering barrier once |compositor_context| no
3534       // longer uses GL.
3535       compositor_context->ContextGL()->OrderingBarrierCHROMIUM();
3536       compositor_context->ContextSupport()->FlushPendingWork();
3537     }
3538     if (auto* worker_context =
3539             layer_tree_frame_sink_->worker_context_provider()) {
3540       viz::RasterContextProvider::ScopedRasterContextLock hold(worker_context);
3541       hold.RasterInterface()->ShallowFlushCHROMIUM();
3542     }
3543   }
3544 }
3545 
ReleaseLayerTreeFrameSink()3546 void LayerTreeHostImpl::ReleaseLayerTreeFrameSink() {
3547   TRACE_EVENT0("cc", "LayerTreeHostImpl::ReleaseLayerTreeFrameSink");
3548 
3549   if (!layer_tree_frame_sink_) {
3550     DCHECK(!has_valid_layer_tree_frame_sink_);
3551     return;
3552   }
3553 
3554   has_valid_layer_tree_frame_sink_ = false;
3555 
3556   ReleaseTreeResources();
3557   CleanUpTileManagerResources();
3558   resource_pool_ = nullptr;
3559   ClearUIResources();
3560 
3561   if (layer_tree_frame_sink_->context_provider()) {
3562     // TODO(ericrk): Remove this once all uses of ContextGL from LTFS are
3563     // removed.
3564     auto* gl = layer_tree_frame_sink_->context_provider()->ContextGL();
3565     gl->Finish();
3566   }
3567 
3568   // Release any context visibility before we destroy the LayerTreeFrameSink.
3569   SetContextVisibility(false);
3570 
3571   bool all_resources_are_lost = layer_tree_frame_sink_->context_provider();
3572 
3573   // Destroy the submit-frame trackers before destroying the frame sink.
3574   frame_trackers_.ClearAll();
3575 
3576   // Detach from the old LayerTreeFrameSink and reset |layer_tree_frame_sink_|
3577   // pointer as this surface is going to be destroyed independent of if binding
3578   // the new LayerTreeFrameSink succeeds or not.
3579   layer_tree_frame_sink_->DetachFromClient();
3580   layer_tree_frame_sink_ = nullptr;
3581 
3582   // If gpu compositing, then any resources created with the gpu context in the
3583   // LayerTreeFrameSink were exported to the display compositor may be modified
3584   // by it, and thus we would be unable to determine what state they are in, in
3585   // order to reuse them, so they must be lost. Note that this includes
3586   // resources created using the gpu context associated with
3587   // |layer_tree_frame_sink_| internally by the compositor and any resources
3588   // received from an external source (for instance, TextureLayers). This is
3589   // because the API contract for releasing these external resources requires
3590   // that the compositor return them with a valid sync token and no
3591   // modifications to their GL state. Since that can not be guaranteed, these
3592   // must also be marked lost.
3593   //
3594   // In software compositing, the resources are not modified by the display
3595   // compositor (there is no stateful metadata for shared memory), so we do not
3596   // need to consider them lost.
3597   //
3598   // In both cases, the resources that are exported to the display compositor
3599   // will have no means of being returned to this client without the
3600   // LayerTreeFrameSink, so they should no longer be considered as exported. Do
3601   // this *after* any interactions with the |layer_tree_frame_sink_| in case it
3602   // tries to return resources during destruction.
3603   //
3604   // The assumption being made here is that the display compositor WILL NOT use
3605   // any resources previously exported when the CompositorFrameSink is closed.
3606   // This should be true as the connection is closed when the display compositor
3607   // shuts down/crashes, or when it believes we are a malicious client in which
3608   // case it will not display content from the previous CompositorFrameSink. If
3609   // this assumption is violated, we may modify resources no longer considered
3610   // as exported while the display compositor is still making use of them,
3611   // leading to visual mistakes.
3612   resource_provider_.ReleaseAllExportedResources(all_resources_are_lost);
3613 
3614   // We don't know if the next LayerTreeFrameSink will support GPU
3615   // rasterization. Make sure to clear the flag so that we force a
3616   // re-computation.
3617   use_gpu_rasterization_ = false;
3618 }
3619 
InitializeFrameSink(LayerTreeFrameSink * layer_tree_frame_sink)3620 bool LayerTreeHostImpl::InitializeFrameSink(
3621     LayerTreeFrameSink* layer_tree_frame_sink) {
3622   TRACE_EVENT0("cc", "LayerTreeHostImpl::InitializeFrameSink");
3623 
3624   ReleaseLayerTreeFrameSink();
3625   if (!layer_tree_frame_sink->BindToClient(this)) {
3626     // Avoid recreating tree resources because we might not have enough
3627     // information to do this yet (eg. we don't have a TileManager at this
3628     // point).
3629     return false;
3630   }
3631 
3632   layer_tree_frame_sink_ = layer_tree_frame_sink;
3633   has_valid_layer_tree_frame_sink_ = true;
3634 
3635   auto* context_provider = layer_tree_frame_sink_->context_provider();
3636 
3637   if (context_provider) {
3638     max_texture_size_ =
3639         context_provider->ContextCapabilities().max_texture_size;
3640   } else {
3641     // Pick an arbitrary limit here similar to what hardware might.
3642     max_texture_size_ = 16 * 1024;
3643   }
3644 
3645   resource_pool_ = std::make_unique<ResourcePool>(
3646       &resource_provider_, context_provider, GetTaskRunner(),
3647       ResourcePool::kDefaultExpirationDelay,
3648       settings_.disallow_non_exact_resource_reuse);
3649 
3650   auto* context = layer_tree_frame_sink_->worker_context_provider();
3651   if (context) {
3652     viz::RasterContextProvider::ScopedRasterContextLock hold(context);
3653     can_use_oop_rasterization_ =
3654         context->ContextCapabilities().supports_oop_raster;
3655   } else {
3656     can_use_oop_rasterization_ = false;
3657   }
3658 
3659   // Since the new context may support GPU raster or be capable of MSAA, update
3660   // status here. We don't need to check the return value since we are
3661   // recreating all resources already.
3662   SetNeedUpdateGpuRasterizationStatus();
3663   UpdateGpuRasterizationStatus();
3664 
3665   // See note in LayerTreeImpl::UpdateDrawProperties, new LayerTreeFrameSink
3666   // means a new max texture size which affects draw properties. Also, if the
3667   // draw properties were up to date, layers still lost resources and we need to
3668   // UpdateDrawProperties() after calling RecreateTreeResources().
3669   active_tree_->set_needs_update_draw_properties();
3670   if (pending_tree_)
3671     pending_tree_->set_needs_update_draw_properties();
3672 
3673   CreateTileManagerResources();
3674   RecreateTileResources();
3675 
3676   client_->OnCanDrawStateChanged(CanDraw());
3677   SetFullViewportDamage();
3678   // There will not be anything to draw here, so set high res
3679   // to avoid checkerboards, typically when we are recovering
3680   // from lost context.
3681   // TODO(crbug.com/469175): Replace with RequiresHighResToDraw.
3682   SetRequiresHighResToDraw();
3683 
3684   // Always allocate a new viz::LocalSurfaceId when we get a new
3685   // LayerTreeFrameSink to ensure that we do not reuse the same surface after
3686   // it might have been garbage collected.
3687   const viz::LocalSurfaceId& local_surface_id =
3688       child_local_surface_id_allocator_.GetCurrentLocalSurfaceId();
3689   if (local_surface_id.is_valid())
3690     AllocateLocalSurfaceId();
3691 
3692   return true;
3693 }
3694 
SetBeginFrameSource(viz::BeginFrameSource * source)3695 void LayerTreeHostImpl::SetBeginFrameSource(viz::BeginFrameSource* source) {
3696   client_->SetBeginFrameSource(source);
3697 }
3698 
DrawTransform() const3699 const gfx::Transform& LayerTreeHostImpl::DrawTransform() const {
3700   return external_transform_;
3701 }
3702 
DidChangeBrowserControlsPosition()3703 void LayerTreeHostImpl::DidChangeBrowserControlsPosition() {
3704   active_tree_->UpdateViewportContainerSizes();
3705   if (pending_tree_)
3706     pending_tree_->UpdateViewportContainerSizes();
3707   SetNeedsRedraw();
3708   SetNeedsOneBeginImplFrame();
3709   SetFullViewportDamage();
3710 }
3711 
DidObserveScrollDelay(base::TimeDelta scroll_delay,base::TimeTicks scroll_timestamp)3712 void LayerTreeHostImpl::DidObserveScrollDelay(
3713     base::TimeDelta scroll_delay,
3714     base::TimeTicks scroll_timestamp) {
3715   // Record First Scroll Delay.
3716   if (!has_observed_first_scroll_delay_) {
3717     client_->DidObserveFirstScrollDelay(scroll_delay, scroll_timestamp);
3718     has_observed_first_scroll_delay_ = true;
3719   }
3720 }
3721 
TopControlsHeight() const3722 float LayerTreeHostImpl::TopControlsHeight() const {
3723   return active_tree_->top_controls_height();
3724 }
3725 
TopControlsMinHeight() const3726 float LayerTreeHostImpl::TopControlsMinHeight() const {
3727   return active_tree_->top_controls_min_height();
3728 }
3729 
BottomControlsHeight() const3730 float LayerTreeHostImpl::BottomControlsHeight() const {
3731   return active_tree_->bottom_controls_height();
3732 }
3733 
BottomControlsMinHeight() const3734 float LayerTreeHostImpl::BottomControlsMinHeight() const {
3735   return active_tree_->bottom_controls_min_height();
3736 }
3737 
SetCurrentBrowserControlsShownRatio(float top_ratio,float bottom_ratio)3738 void LayerTreeHostImpl::SetCurrentBrowserControlsShownRatio(
3739     float top_ratio,
3740     float bottom_ratio) {
3741   if (active_tree_->SetCurrentBrowserControlsShownRatio(top_ratio,
3742                                                         bottom_ratio))
3743     DidChangeBrowserControlsPosition();
3744 }
3745 
CurrentTopControlsShownRatio() const3746 float LayerTreeHostImpl::CurrentTopControlsShownRatio() const {
3747   return active_tree_->CurrentTopControlsShownRatio();
3748 }
3749 
CurrentBottomControlsShownRatio() const3750 float LayerTreeHostImpl::CurrentBottomControlsShownRatio() const {
3751   return active_tree_->CurrentBottomControlsShownRatio();
3752 }
3753 
ViewportScrollOffset() const3754 gfx::ScrollOffset LayerTreeHostImpl::ViewportScrollOffset() const {
3755   return viewport_->TotalScrollOffset();
3756 }
3757 
AutoScrollAnimationCreate(const ScrollNode & scroll_node,const gfx::Vector2dF & delta,float autoscroll_velocity)3758 bool LayerTreeHostImpl::AutoScrollAnimationCreate(const ScrollNode& scroll_node,
3759                                                   const gfx::Vector2dF& delta,
3760                                                   float autoscroll_velocity) {
3761   return ScrollAnimationCreateInternal(scroll_node, delta, base::TimeDelta(),
3762                                        autoscroll_velocity);
3763 }
3764 
ScrollAnimationCreate(const ScrollNode & scroll_node,const gfx::Vector2dF & delta,base::TimeDelta delayed_by)3765 bool LayerTreeHostImpl::ScrollAnimationCreate(const ScrollNode& scroll_node,
3766                                               const gfx::Vector2dF& delta,
3767                                               base::TimeDelta delayed_by) {
3768   return ScrollAnimationCreateInternal(scroll_node, delta, delayed_by,
3769                                        base::nullopt);
3770 }
3771 
ScrollAnimationCreateInternal(const ScrollNode & scroll_node,const gfx::Vector2dF & delta,base::TimeDelta delayed_by,base::Optional<float> autoscroll_velocity)3772 bool LayerTreeHostImpl::ScrollAnimationCreateInternal(
3773     const ScrollNode& scroll_node,
3774     const gfx::Vector2dF& delta,
3775     base::TimeDelta delayed_by,
3776     base::Optional<float> autoscroll_velocity) {
3777   ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
3778 
3779   const float kEpsilon = 0.1f;
3780   bool scroll_animated =
3781       (std::abs(delta.x()) > kEpsilon || std::abs(delta.y()) > kEpsilon) ||
3782       autoscroll_velocity;
3783   if (!scroll_animated) {
3784     scroll_tree.ScrollBy(scroll_node, delta, active_tree());
3785     TRACE_EVENT_INSTANT0("cc", "no scroll animation due to small delta",
3786                          TRACE_EVENT_SCOPE_THREAD);
3787     return false;
3788   }
3789 
3790   gfx::ScrollOffset current_offset =
3791       scroll_tree.current_scroll_offset(scroll_node.element_id);
3792   gfx::ScrollOffset target_offset = scroll_tree.ClampScrollOffsetToLimits(
3793       current_offset + gfx::ScrollOffset(delta), scroll_node);
3794 
3795   // Start the animation one full frame in. Without any offset, the animation
3796   // doesn't start until next frame, increasing latency, and preventing our
3797   // input latency tracking architecture from working.
3798   base::TimeDelta animation_start_offset = CurrentBeginFrameArgs().interval;
3799 
3800   if (autoscroll_velocity) {
3801     mutator_host_->ImplOnlyAutoScrollAnimationCreate(
3802         scroll_node.element_id, gfx::ScrollOffset(delta), current_offset,
3803         autoscroll_velocity.value(), animation_start_offset);
3804   } else {
3805     mutator_host_->ImplOnlyScrollAnimationCreate(
3806         scroll_node.element_id, target_offset, current_offset, delayed_by,
3807         animation_start_offset);
3808   }
3809 
3810   SetNeedsOneBeginImplFrame();
3811 
3812   return true;
3813 }
3814 
3815 
UpdateImageDecodingHints(base::flat_map<PaintImage::Id,PaintImage::DecodingMode> decoding_mode_map)3816 void LayerTreeHostImpl::UpdateImageDecodingHints(
3817     base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
3818         decoding_mode_map) {
3819   tile_manager_.checker_image_tracker().UpdateImageDecodingHints(
3820       std::move(decoding_mode_map));
3821 }
3822 
SetRenderFrameObserver(std::unique_ptr<RenderFrameMetadataObserver> observer)3823 void LayerTreeHostImpl::SetRenderFrameObserver(
3824     std::unique_ptr<RenderFrameMetadataObserver> observer) {
3825   render_frame_metadata_observer_ = std::move(observer);
3826   render_frame_metadata_observer_->BindToCurrentThread();
3827 }
3828 
WillScrollContent(ElementId element_id)3829 void LayerTreeHostImpl::WillScrollContent(ElementId element_id) {
3830   // Flash the overlay scrollbar even if the scroll delta is 0.
3831   if (settings().scrollbar_flash_after_any_scroll_update) {
3832     FlashAllScrollbars(false);
3833   } else {
3834     if (ScrollbarAnimationController* animation_controller =
3835             ScrollbarAnimationControllerForElementId(element_id))
3836       animation_controller->WillUpdateScroll();
3837   }
3838 }
3839 
DidScrollContent(ElementId element_id,bool animated)3840 void LayerTreeHostImpl::DidScrollContent(ElementId element_id, bool animated) {
3841   if (settings().scrollbar_flash_after_any_scroll_update) {
3842     FlashAllScrollbars(true);
3843   } else {
3844     if (ScrollbarAnimationController* animation_controller =
3845             ScrollbarAnimationControllerForElementId(element_id))
3846       animation_controller->DidScrollUpdate();
3847   }
3848 
3849   // We may wish to prioritize smoothness over raster when the user is
3850   // interacting with content, but this needs to be evaluated only for direct
3851   // user scrolls, not for programmatic scrolls.
3852   if (input_delegate_->IsCurrentlyScrolling())
3853     client_->RenewTreePriority();
3854 
3855   if (!animated) {
3856     // SetNeedsRedraw is only called in non-animated cases since an animation
3857     // won't actually update any scroll offsets until a frame produces a
3858     // tick. Scheduling a redraw here before ticking means the draw gets
3859     // aborted due to no damage and the swap promises broken so a LatencyInfo
3860     // won't be recorded.
3861     SetNeedsRedraw();
3862   }
3863 }
3864 
DeviceScaleFactor() const3865 float LayerTreeHostImpl::DeviceScaleFactor() const {
3866   return active_tree_->device_scale_factor();
3867 }
3868 
PageScaleFactor() const3869 float LayerTreeHostImpl::PageScaleFactor() const {
3870   return active_tree_->page_scale_factor_for_scroll();
3871 }
3872 
BindToInputHandler(std::unique_ptr<InputDelegateForCompositor> delegate)3873 void LayerTreeHostImpl::BindToInputHandler(
3874     std::unique_ptr<InputDelegateForCompositor> delegate) {
3875   input_delegate_ = std::move(delegate);
3876 }
3877 
GetScrollTree() const3878 ScrollTree& LayerTreeHostImpl::GetScrollTree() const {
3879   return active_tree_->property_trees()->scroll_tree;
3880 }
3881 
HasAnimatedScrollbars() const3882 bool LayerTreeHostImpl::HasAnimatedScrollbars() const {
3883   return !scrollbar_animation_controllers_.empty();
3884 }
3885 
CollectScrollbarUpdatesForCommit(CompositorCommitData * commit_data) const3886 void LayerTreeHostImpl::CollectScrollbarUpdatesForCommit(
3887     CompositorCommitData* commit_data) const {
3888   commit_data->scrollbars.reserve(scrollbar_animation_controllers_.size());
3889   for (auto& pair : scrollbar_animation_controllers_) {
3890     commit_data->scrollbars.push_back(
3891         {pair.first, pair.second->ScrollbarsHidden()});
3892   }
3893 }
3894 
3895 std::unique_ptr<CompositorCommitData>
ProcessCompositorDeltas()3896 LayerTreeHostImpl::ProcessCompositorDeltas() {
3897   auto commit_data = std::make_unique<CompositorCommitData>();
3898 
3899   if (input_delegate_)
3900     input_delegate_->ProcessCommitDeltas(commit_data.get());
3901   CollectScrollbarUpdatesForCommit(commit_data.get());
3902 
3903   commit_data->page_scale_delta =
3904       active_tree_->page_scale_factor()->PullDeltaForMainThread();
3905   commit_data->is_pinch_gesture_active = active_tree_->PinchGestureActive();
3906   // We should never process non-unit page_scale_delta for an OOPIF subframe.
3907   // TODO(wjmaclean): Remove this DCHECK as a pre-condition to closing the bug.
3908   // https://crbug.com/845097
3909   DCHECK(!settings().is_layer_tree_for_subframe ||
3910          commit_data->page_scale_delta == 1.f);
3911   commit_data->top_controls_delta =
3912       active_tree()->top_controls_shown_ratio()->PullDeltaForMainThread();
3913   commit_data->bottom_controls_delta =
3914       active_tree()->bottom_controls_shown_ratio()->PullDeltaForMainThread();
3915   commit_data->elastic_overscroll_delta =
3916       active_tree_->elastic_overscroll()->PullDeltaForMainThread();
3917   commit_data->swap_promises.swap(swap_promises_for_main_thread_scroll_update_);
3918 
3919   commit_data->ongoing_scroll_animation =
3920       !!mutator_host_->ImplOnlyScrollAnimatingElement();
3921 
3922   if (browser_controls_manager()) {
3923     commit_data->browser_controls_constraint =
3924         browser_controls_manager()->PullConstraintForMainThread(
3925             &commit_data->browser_controls_constraint_changed);
3926   }
3927 
3928   return commit_data;
3929 }
3930 
SetFullViewportDamage()3931 void LayerTreeHostImpl::SetFullViewportDamage() {
3932   // In non-Android-WebView cases, we expect GetDeviceViewport() to be the same
3933   // as internal_device_viewport(), so the full-viewport damage rect is just
3934   // the internal viewport rect. In the case of Android WebView,
3935   // GetDeviceViewport returns the external viewport, but we still want to use
3936   // the internal viewport's origin for setting the damage.
3937   // See https://chromium-review.googlesource.com/c/chromium/src/+/1257555.
3938   SetViewportDamage(gfx::Rect(active_tree_->internal_device_viewport().origin(),
3939                               active_tree_->GetDeviceViewport().size()));
3940 }
3941 
AnimatePageScale(base::TimeTicks monotonic_time)3942 bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
3943   if (!page_scale_animation_)
3944     return false;
3945 
3946   gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset();
3947 
3948   if (!page_scale_animation_->IsAnimationStarted())
3949     page_scale_animation_->StartAnimation(monotonic_time);
3950 
3951   active_tree_->SetPageScaleOnActiveTree(
3952       page_scale_animation_->PageScaleFactorAtTime(monotonic_time));
3953   gfx::ScrollOffset next_scroll = gfx::ScrollOffset(
3954       page_scale_animation_->ScrollOffsetAtTime(monotonic_time));
3955 
3956   viewport().ScrollByInnerFirst(next_scroll.DeltaFrom(scroll_total));
3957 
3958   if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
3959     page_scale_animation_ = nullptr;
3960     client_->SetNeedsCommitOnImplThread();
3961     client_->RenewTreePriority();
3962     client_->DidCompletePageScaleAnimationOnImplThread();
3963   } else {
3964     SetNeedsOneBeginImplFrame();
3965   }
3966   return true;
3967 }
3968 
AnimateBrowserControls(base::TimeTicks time)3969 bool LayerTreeHostImpl::AnimateBrowserControls(base::TimeTicks time) {
3970   if (!browser_controls_offset_manager_->HasAnimation())
3971     return false;
3972 
3973   gfx::Vector2dF scroll_delta = browser_controls_offset_manager_->Animate(time);
3974 
3975   if (browser_controls_offset_manager_->HasAnimation())
3976     SetNeedsOneBeginImplFrame();
3977 
3978   if (active_tree_->TotalScrollOffset().y() == 0.f ||
3979       OnlyExpandTopControlsAtPageTop()) {
3980     return false;
3981   }
3982 
3983   if (scroll_delta.IsZero())
3984     return false;
3985 
3986   // This counter-scrolls the page to keep the appearance of the page content
3987   // being fixed while the browser controls animate.
3988   viewport().ScrollBy(scroll_delta,
3989                       /*viewport_point=*/gfx::Point(),
3990                       /*is_wheel_scroll=*/false,
3991                       /*affect_browser_controls=*/false,
3992                       /*scroll_outer_viewport=*/true);
3993   client_->SetNeedsCommitOnImplThread();
3994   client_->RenewTreePriority();
3995   return true;
3996 }
3997 
AnimateScrollbars(base::TimeTicks monotonic_time)3998 bool LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks monotonic_time) {
3999   bool animated = false;
4000   for (auto& pair : scrollbar_animation_controllers_)
4001     animated |= pair.second->Animate(monotonic_time);
4002   return animated;
4003 }
4004 
AnimateLayers(base::TimeTicks monotonic_time,bool is_active_tree)4005 bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time,
4006                                       bool is_active_tree) {
4007   const ScrollTree& scroll_tree =
4008       is_active_tree ? active_tree_->property_trees()->scroll_tree
4009                      : pending_tree_->property_trees()->scroll_tree;
4010   const bool animated = mutator_host_->TickAnimations(
4011       monotonic_time, scroll_tree, is_active_tree);
4012 
4013   // TODO(crbug.com/551134): Only do this if the animations are on the active
4014   // tree, or if they are on the pending tree waiting for some future time to
4015   // start.
4016   // TODO(crbug.com/551138): We currently have a single signal from the
4017   // animation_host, so on the last frame of an animation we will
4018   // still request an extra SetNeedsAnimate here.
4019   if (animated) {
4020     // TODO(crbug.com/1039750): If only scroll animations present, schedule a
4021     // frame only if scroll changes.
4022     SetNeedsOneBeginImplFrame();
4023     frame_trackers_.StartSequence(
4024         FrameSequenceTrackerType::kCompositorAnimation);
4025   } else {
4026     frame_trackers_.StopSequence(
4027         FrameSequenceTrackerType::kCompositorAnimation);
4028   }
4029 
4030   // TODO(crbug.com/551138): We could return true only if the animations are on
4031   // the active tree. There's no need to cause a draw to take place from
4032   // animations starting/ticking on the pending tree.
4033   return animated;
4034 }
4035 
UpdateAnimationState(bool start_ready_animations)4036 void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
4037   const bool has_active_animations = mutator_host_->UpdateAnimationState(
4038       start_ready_animations, mutator_events_.get());
4039 
4040   if (has_active_animations) {
4041     SetNeedsOneBeginImplFrame();
4042     if (!mutator_events_->IsEmpty())
4043       SetNeedsCommit();
4044   }
4045 }
4046 
ActivateAnimations()4047 void LayerTreeHostImpl::ActivateAnimations() {
4048   const bool activated =
4049       mutator_host_->ActivateAnimations(mutator_events_.get());
4050   if (activated) {
4051     // Activating an animation changes layer draw properties, such as
4052     // screen_space_transform_is_animating. So when we see a new animation get
4053     // activated, we need to update the draw properties on the active tree.
4054     active_tree()->set_needs_update_draw_properties();
4055     // Request another frame to run the next tick of the animation.
4056     SetNeedsOneBeginImplFrame();
4057     if (!mutator_events_->IsEmpty())
4058       SetNeedsCommit();
4059   }
4060 }
4061 
RegisterScrollbarAnimationController(ElementId scroll_element_id,float scrollbar_opacity)4062 void LayerTreeHostImpl::RegisterScrollbarAnimationController(
4063     ElementId scroll_element_id,
4064     float scrollbar_opacity) {
4065   if (ScrollbarAnimationControllerForElementId(scroll_element_id))
4066     return;
4067 
4068   scrollbar_animation_controllers_[scroll_element_id] =
4069       active_tree_->CreateScrollbarAnimationController(scroll_element_id,
4070                                                        scrollbar_opacity);
4071 }
4072 
DidUnregisterScrollbarLayer(ElementId scroll_element_id,ScrollbarOrientation orientation)4073 void LayerTreeHostImpl::DidUnregisterScrollbarLayer(
4074     ElementId scroll_element_id,
4075     ScrollbarOrientation orientation) {
4076   if (ScrollbarsFor(scroll_element_id).empty())
4077     scrollbar_animation_controllers_.erase(scroll_element_id);
4078   if (input_delegate_)
4079     input_delegate_->DidUnregisterScrollbar(scroll_element_id, orientation);
4080 }
4081 
4082 ScrollbarAnimationController*
ScrollbarAnimationControllerForElementId(ElementId scroll_element_id) const4083 LayerTreeHostImpl::ScrollbarAnimationControllerForElementId(
4084     ElementId scroll_element_id) const {
4085   // The viewport layers have only one set of scrollbars. On Android, these are
4086   // registered with the inner viewport, otherwise they're registered with the
4087   // outer viewport. If a controller for one exists, the other shouldn't.
4088   if (InnerViewportScrollNode()) {
4089     DCHECK(OuterViewportScrollNode());
4090     if (scroll_element_id == InnerViewportScrollNode()->element_id ||
4091         scroll_element_id == OuterViewportScrollNode()->element_id) {
4092       auto itr = scrollbar_animation_controllers_.find(
4093           InnerViewportScrollNode()->element_id);
4094       if (itr != scrollbar_animation_controllers_.end())
4095         return itr->second.get();
4096 
4097       itr = scrollbar_animation_controllers_.find(
4098           OuterViewportScrollNode()->element_id);
4099       if (itr != scrollbar_animation_controllers_.end())
4100         return itr->second.get();
4101 
4102       return nullptr;
4103     }
4104   }
4105 
4106   auto i = scrollbar_animation_controllers_.find(scroll_element_id);
4107   if (i == scrollbar_animation_controllers_.end())
4108     return nullptr;
4109   return i->second.get();
4110 }
4111 
FlashAllScrollbars(bool did_scroll)4112 void LayerTreeHostImpl::FlashAllScrollbars(bool did_scroll) {
4113   for (auto& pair : scrollbar_animation_controllers_) {
4114     if (did_scroll)
4115       pair.second->DidScrollUpdate();
4116     else
4117       pair.second->WillUpdateScroll();
4118   }
4119 }
4120 
PostDelayedScrollbarAnimationTask(base::OnceClosure task,base::TimeDelta delay)4121 void LayerTreeHostImpl::PostDelayedScrollbarAnimationTask(
4122     base::OnceClosure task,
4123     base::TimeDelta delay) {
4124   client_->PostDelayedAnimationTaskOnImplThread(std::move(task), delay);
4125 }
4126 
4127 // TODO(danakj): Make this a return value from the Animate() call instead of an
4128 // interface on LTHI. (Also, crbug.com/551138.)
SetNeedsAnimateForScrollbarAnimation()4129 void LayerTreeHostImpl::SetNeedsAnimateForScrollbarAnimation() {
4130   TRACE_EVENT0("cc", "LayerTreeHostImpl::SetNeedsAnimateForScrollbarAnimation");
4131   SetNeedsOneBeginImplFrame();
4132 }
4133 
4134 // TODO(danakj): Make this a return value from the Animate() call instead of an
4135 // interface on LTHI. (Also, crbug.com/551138.)
SetNeedsRedrawForScrollbarAnimation()4136 void LayerTreeHostImpl::SetNeedsRedrawForScrollbarAnimation() {
4137   SetNeedsRedraw();
4138 }
4139 
ScrollbarsFor(ElementId id) const4140 ScrollbarSet LayerTreeHostImpl::ScrollbarsFor(ElementId id) const {
4141   return active_tree_->ScrollbarsFor(id);
4142 }
4143 
AddVideoFrameController(VideoFrameController * controller)4144 void LayerTreeHostImpl::AddVideoFrameController(
4145     VideoFrameController* controller) {
4146   bool was_empty = video_frame_controllers_.empty();
4147   video_frame_controllers_.insert(controller);
4148   if (current_begin_frame_tracker_.DangerousMethodHasStarted() &&
4149       !current_begin_frame_tracker_.DangerousMethodHasFinished())
4150     controller->OnBeginFrame(current_begin_frame_tracker_.Current());
4151   if (was_empty)
4152     client_->SetVideoNeedsBeginFrames(true);
4153 }
4154 
RemoveVideoFrameController(VideoFrameController * controller)4155 void LayerTreeHostImpl::RemoveVideoFrameController(
4156     VideoFrameController* controller) {
4157   video_frame_controllers_.erase(controller);
4158   if (video_frame_controllers_.empty())
4159     client_->SetVideoNeedsBeginFrames(false);
4160 }
4161 
SetTreePriority(TreePriority priority)4162 void LayerTreeHostImpl::SetTreePriority(TreePriority priority) {
4163   if (global_tile_state_.tree_priority == priority)
4164     return;
4165   global_tile_state_.tree_priority = priority;
4166   DidModifyTilePriorities();
4167 }
4168 
GetTreePriority() const4169 TreePriority LayerTreeHostImpl::GetTreePriority() const {
4170   return global_tile_state_.tree_priority;
4171 }
4172 
CurrentBeginFrameArgs() const4173 const viz::BeginFrameArgs& LayerTreeHostImpl::CurrentBeginFrameArgs() const {
4174   // TODO(mithro): Replace call with current_begin_frame_tracker_.Current()
4175   // once all calls which happens outside impl frames are fixed.
4176   return current_begin_frame_tracker_.DangerousMethodCurrentOrLast();
4177 }
4178 
CurrentBeginFrameInterval() const4179 base::TimeDelta LayerTreeHostImpl::CurrentBeginFrameInterval() const {
4180   return current_begin_frame_tracker_.Interval();
4181 }
4182 
4183 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
AsValueWithFrame(FrameData * frame) const4184 LayerTreeHostImpl::AsValueWithFrame(FrameData* frame) const {
4185   std::unique_ptr<base::trace_event::TracedValue> state(
4186       new base::trace_event::TracedValue());
4187   AsValueWithFrameInto(frame, state.get());
4188   return std::move(state);
4189 }
4190 
AsValueWithFrameInto(FrameData * frame,base::trace_event::TracedValue * state) const4191 void LayerTreeHostImpl::AsValueWithFrameInto(
4192     FrameData* frame,
4193     base::trace_event::TracedValue* state) const {
4194   if (this->pending_tree_) {
4195     state->BeginDictionary("activation_state");
4196     ActivationStateAsValueInto(state);
4197     state->EndDictionary();
4198   }
4199   MathUtil::AddToTracedValue("device_viewport_size",
4200                              active_tree_->GetDeviceViewport().size(), state);
4201 
4202   std::vector<PrioritizedTile> prioritized_tiles;
4203   active_tree_->GetAllPrioritizedTilesForTracing(&prioritized_tiles);
4204   if (pending_tree_)
4205     pending_tree_->GetAllPrioritizedTilesForTracing(&prioritized_tiles);
4206 
4207   state->BeginArray("active_tiles");
4208   for (const auto& prioritized_tile : prioritized_tiles) {
4209     state->BeginDictionary();
4210     prioritized_tile.AsValueInto(state);
4211     state->EndDictionary();
4212   }
4213   state->EndArray();
4214 
4215   state->BeginDictionary("tile_manager_basic_state");
4216   tile_manager_.BasicStateAsValueInto(state);
4217   state->EndDictionary();
4218 
4219   state->BeginDictionary("active_tree");
4220   active_tree_->AsValueInto(state);
4221   state->EndDictionary();
4222   if (pending_tree_) {
4223     state->BeginDictionary("pending_tree");
4224     pending_tree_->AsValueInto(state);
4225     state->EndDictionary();
4226   }
4227   if (frame) {
4228     state->BeginDictionary("frame");
4229     frame->AsValueInto(state);
4230     state->EndDictionary();
4231   }
4232 }
4233 
ActivationStateAsValueInto(base::trace_event::TracedValue * state) const4234 void LayerTreeHostImpl::ActivationStateAsValueInto(
4235     base::trace_event::TracedValue* state) const {
4236   viz::TracedValue::SetIDRef(this, state, "lthi");
4237   state->BeginDictionary("tile_manager");
4238   tile_manager_.BasicStateAsValueInto(state);
4239   state->EndDictionary();
4240 }
4241 
SetDebugState(const LayerTreeDebugState & new_debug_state)4242 void LayerTreeHostImpl::SetDebugState(
4243     const LayerTreeDebugState& new_debug_state) {
4244   if (LayerTreeDebugState::Equal(debug_state_, new_debug_state))
4245     return;
4246 
4247   debug_state_ = new_debug_state;
4248   UpdateTileManagerMemoryPolicy(ActualManagedMemoryPolicy());
4249   SetFullViewportDamage();
4250 }
4251 
CreateUIResource(UIResourceId uid,const UIResourceBitmap & bitmap)4252 void LayerTreeHostImpl::CreateUIResource(UIResourceId uid,
4253                                          const UIResourceBitmap& bitmap) {
4254   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
4255                "LayerTreeHostImpl::CreateUIResource");
4256   DCHECK_GT(uid, 0);
4257 
4258   // Allow for multiple creation requests with the same UIResourceId.  The
4259   // previous resource is simply deleted.
4260   viz::ResourceId id = ResourceIdForUIResource(uid);
4261   if (id)
4262     DeleteUIResource(uid);
4263 
4264   if (!has_valid_layer_tree_frame_sink_) {
4265     evicted_ui_resources_.insert(uid);
4266     return;
4267   }
4268 
4269   viz::ResourceFormat format;
4270   switch (bitmap.GetFormat()) {
4271     case UIResourceBitmap::RGBA8:
4272       if (layer_tree_frame_sink_->context_provider()) {
4273         const gpu::Capabilities& caps =
4274             layer_tree_frame_sink_->context_provider()->ContextCapabilities();
4275         format = viz::PlatformColor::BestSupportedTextureFormat(caps);
4276       } else {
4277         format = viz::RGBA_8888;
4278       }
4279       break;
4280     case UIResourceBitmap::ALPHA_8:
4281       format = viz::ALPHA_8;
4282       break;
4283     case UIResourceBitmap::ETC1:
4284       format = viz::ETC1;
4285       break;
4286   }
4287 
4288   const gfx::Size source_size = bitmap.GetSize();
4289   gfx::Size upload_size = bitmap.GetSize();
4290   bool scaled = false;
4291   // UIResources are assumed to be rastered in SRGB.
4292   const gfx::ColorSpace& color_space = gfx::ColorSpace::CreateSRGB();
4293 
4294   if (source_size.width() > max_texture_size_ ||
4295       source_size.height() > max_texture_size_) {
4296     // Must resize the bitmap to fit within the max texture size.
4297     scaled = true;
4298     int edge = std::max(source_size.width(), source_size.height());
4299     float scale = static_cast<float>(max_texture_size_ - 1) / edge;
4300     DCHECK_LT(scale, 1.f);
4301     upload_size = gfx::ScaleToCeiledSize(source_size, scale, scale);
4302   }
4303 
4304   // For gpu compositing, a SharedImage mailbox will be allocated and the
4305   // UIResource will be uploaded into it.
4306   gpu::Mailbox mailbox;
4307   uint32_t shared_image_usage = gpu::SHARED_IMAGE_USAGE_DISPLAY;
4308   // For gpu compositing, we also calculate the GL texture target.
4309   // TODO(ericrk): Remove references to GL from this code.
4310   GLenum texture_target = GL_TEXTURE_2D;
4311   // For software compositing, shared memory will be allocated and the
4312   // UIResource will be copied into it.
4313   base::MappedReadOnlyRegion shm;
4314   viz::SharedBitmapId shared_bitmap_id;
4315   bool overlay_candidate = false;
4316 
4317   if (layer_tree_frame_sink_->context_provider()) {
4318     viz::ContextProvider* context_provider =
4319         layer_tree_frame_sink_->context_provider();
4320     const auto& caps = context_provider->ContextCapabilities();
4321     overlay_candidate =
4322         settings_.resource_settings.use_gpu_memory_buffer_resources &&
4323         caps.texture_storage_image &&
4324         viz::IsGpuMemoryBufferFormatSupported(format);
4325     if (overlay_candidate) {
4326       shared_image_usage |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
4327       texture_target = gpu::GetBufferTextureTarget(gfx::BufferUsage::SCANOUT,
4328                                                    BufferFormat(format), caps);
4329     }
4330   } else {
4331     shm = viz::bitmap_allocation::AllocateSharedBitmap(upload_size, format);
4332     shared_bitmap_id = viz::SharedBitmap::GenerateId();
4333   }
4334 
4335   if (!scaled) {
4336     // If not scaled, we can copy the pixels 1:1 from the source bitmap to our
4337     // destination backing of a texture or shared bitmap.
4338     if (layer_tree_frame_sink_->context_provider()) {
4339       viz::ContextProvider* context_provider =
4340           layer_tree_frame_sink_->context_provider();
4341       auto* sii = context_provider->SharedImageInterface();
4342       mailbox = sii->CreateSharedImage(
4343           format, upload_size, color_space, kTopLeft_GrSurfaceOrigin,
4344           kPremul_SkAlphaType, shared_image_usage,
4345           base::span<const uint8_t>(bitmap.GetPixels(), bitmap.SizeInBytes()));
4346     } else {
4347       DCHECK_EQ(bitmap.GetFormat(), UIResourceBitmap::RGBA8);
4348       SkImageInfo src_info =
4349           SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(source_size));
4350       SkImageInfo dst_info =
4351           SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
4352 
4353       sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(
4354           dst_info, shm.mapping.memory(), dst_info.minRowBytes());
4355       surface->getCanvas()->writePixels(
4356           src_info, const_cast<uint8_t*>(bitmap.GetPixels()),
4357           bitmap.row_bytes(), 0, 0);
4358     }
4359   } else {
4360     // Only support auto-resizing for N32 textures (since this is primarily for
4361     // scrollbars). Users of other types need to ensure they are not too big.
4362     DCHECK_EQ(bitmap.GetFormat(), UIResourceBitmap::RGBA8);
4363 
4364     float canvas_scale_x =
4365         upload_size.width() / static_cast<float>(source_size.width());
4366     float canvas_scale_y =
4367         upload_size.height() / static_cast<float>(source_size.height());
4368 
4369     // Uses N32Premul since that is what SkBitmap's allocN32Pixels makes, and we
4370     // only support the RGBA8 format here.
4371     SkImageInfo info =
4372         SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(source_size));
4373 
4374     SkBitmap source_bitmap;
4375     source_bitmap.setInfo(info, bitmap.row_bytes());
4376     source_bitmap.setPixels(const_cast<uint8_t*>(bitmap.GetPixels()));
4377 
4378     // This applies the scale to draw the |bitmap| into |scaled_surface|. For
4379     // gpu compositing, we scale into a software bitmap-backed SkSurface here,
4380     // then upload from there into a texture. For software compositing, we scale
4381     // directly into the shared memory backing.
4382     sk_sp<SkSurface> scaled_surface;
4383     if (layer_tree_frame_sink_->context_provider()) {
4384       scaled_surface = SkSurface::MakeRasterN32Premul(upload_size.width(),
4385                                                       upload_size.height());
4386     } else {
4387       SkImageInfo dst_info =
4388           SkImageInfo::MakeN32Premul(gfx::SizeToSkISize(upload_size));
4389       scaled_surface = SkSurface::MakeRasterDirect(
4390           dst_info, shm.mapping.memory(), dst_info.minRowBytes());
4391     }
4392     SkCanvas* scaled_canvas = scaled_surface->getCanvas();
4393     scaled_canvas->scale(canvas_scale_x, canvas_scale_y);
4394     // The |canvas_scale_x| and |canvas_scale_y| may have some floating point
4395     // error for large enough values, causing pixels on the edge to be not
4396     // fully filled by drawBitmap(), so we ensure they start empty. (See
4397     // crbug.com/642011 for an example.)
4398     scaled_canvas->clear(SK_ColorTRANSPARENT);
4399     scaled_canvas->drawBitmap(source_bitmap, 0, 0);
4400 
4401     if (layer_tree_frame_sink_->context_provider()) {
4402       SkPixmap pixmap;
4403       scaled_surface->peekPixels(&pixmap);
4404       viz::ContextProvider* context_provider =
4405           layer_tree_frame_sink_->context_provider();
4406       auto* sii = context_provider->SharedImageInterface();
4407       mailbox = sii->CreateSharedImage(
4408           format, upload_size, color_space, kTopLeft_GrSurfaceOrigin,
4409           kPremul_SkAlphaType, shared_image_usage,
4410           base::span<const uint8_t>(
4411               reinterpret_cast<const uint8_t*>(pixmap.addr()),
4412               pixmap.computeByteSize()));
4413     }
4414   }
4415 
4416   // Once the backing has the UIResource inside it, we have to prepare it for
4417   // export to the display compositor via ImportResource(). For gpu compositing,
4418   // this requires a Mailbox+SyncToken as well. For software compositing, the
4419   // SharedBitmapId must be notified to the LayerTreeFrameSink. The
4420   // OnUIResourceReleased() method will be called once the resource is deleted
4421   // and the display compositor is no longer using it, to free the memory
4422   // allocated in this method above.
4423   viz::TransferableResource transferable;
4424   if (layer_tree_frame_sink_->context_provider()) {
4425     gpu::SyncToken sync_token = layer_tree_frame_sink_->context_provider()
4426                                     ->SharedImageInterface()
4427                                     ->GenUnverifiedSyncToken();
4428 
4429     transferable = viz::TransferableResource::MakeGL(
4430         mailbox, GL_LINEAR, texture_target, sync_token, upload_size,
4431         overlay_candidate);
4432     transferable.format = format;
4433   } else {
4434     layer_tree_frame_sink_->DidAllocateSharedBitmap(std::move(shm.region),
4435                                                     shared_bitmap_id);
4436     transferable = viz::TransferableResource::MakeSoftware(shared_bitmap_id,
4437                                                            upload_size, format);
4438   }
4439   transferable.color_space = color_space;
4440   id = resource_provider_.ImportResource(
4441       transferable,
4442       // The OnUIResourceReleased method is bound with a WeakPtr, but the
4443       // resource backing will be deleted when the LayerTreeFrameSink is
4444       // removed before shutdown, so nothing leaks if the WeakPtr is
4445       // invalidated.
4446       viz::SingleReleaseCallback::Create(base::BindOnce(
4447           &LayerTreeHostImpl::OnUIResourceReleased, AsWeakPtr(), uid)));
4448 
4449   UIResourceData data;
4450   data.opaque = bitmap.GetOpaque();
4451   data.format = format;
4452   data.shared_bitmap_id = shared_bitmap_id;
4453   data.shared_mapping = std::move(shm.mapping);
4454   data.mailbox = mailbox;
4455   data.resource_id_for_export = id;
4456   ui_resource_map_[uid] = std::move(data);
4457 
4458   MarkUIResourceNotEvicted(uid);
4459 }
4460 
DeleteUIResource(UIResourceId uid)4461 void LayerTreeHostImpl::DeleteUIResource(UIResourceId uid) {
4462   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
4463                "LayerTreeHostImpl::DeleteUIResource");
4464   auto it = ui_resource_map_.find(uid);
4465   if (it != ui_resource_map_.end()) {
4466     UIResourceData& data = it->second;
4467     viz::ResourceId id = data.resource_id_for_export;
4468     // Move the |data| to |deleted_ui_resources_| before removing it from the
4469     // viz::ClientResourceProvider, so that the ReleaseCallback can see it
4470     // there.
4471     deleted_ui_resources_[uid] = std::move(data);
4472     ui_resource_map_.erase(it);
4473 
4474     resource_provider_.RemoveImportedResource(id);
4475   }
4476   MarkUIResourceNotEvicted(uid);
4477 }
4478 
DeleteUIResourceBacking(UIResourceData data,const gpu::SyncToken & sync_token)4479 void LayerTreeHostImpl::DeleteUIResourceBacking(
4480     UIResourceData data,
4481     const gpu::SyncToken& sync_token) {
4482   // Resources are either software or gpu backed, not both.
4483   DCHECK(!(data.shared_mapping.IsValid() && !data.mailbox.IsZero()));
4484   if (data.shared_mapping.IsValid())
4485     layer_tree_frame_sink_->DidDeleteSharedBitmap(data.shared_bitmap_id);
4486   if (!data.mailbox.IsZero()) {
4487     auto* sii =
4488         layer_tree_frame_sink_->context_provider()->SharedImageInterface();
4489     sii->DestroySharedImage(sync_token, data.mailbox);
4490   }
4491   // |data| goes out of scope and deletes anything it owned.
4492 }
4493 
OnUIResourceReleased(UIResourceId uid,const gpu::SyncToken & sync_token,bool lost)4494 void LayerTreeHostImpl::OnUIResourceReleased(UIResourceId uid,
4495                                              const gpu::SyncToken& sync_token,
4496                                              bool lost) {
4497   auto it = deleted_ui_resources_.find(uid);
4498   if (it == deleted_ui_resources_.end()) {
4499     // Backing was already deleted, eg if the context was lost.
4500     return;
4501   }
4502   UIResourceData& data = it->second;
4503   // We don't recycle backings here, so |lost| is not relevant, we always delete
4504   // them.
4505   DeleteUIResourceBacking(std::move(data), sync_token);
4506   deleted_ui_resources_.erase(it);
4507 }
4508 
ClearUIResources()4509 void LayerTreeHostImpl::ClearUIResources() {
4510   for (auto& pair : ui_resource_map_) {
4511     UIResourceId uid = pair.first;
4512     UIResourceData& data = pair.second;
4513     resource_provider_.RemoveImportedResource(data.resource_id_for_export);
4514     // Immediately drop the backing instead of waiting for the resource to be
4515     // returned from the ResourceProvider, as this is called in cases where the
4516     // ability to clean up the backings will go away (context loss, shutdown).
4517     DeleteUIResourceBacking(std::move(data), gpu::SyncToken());
4518     // This resource is not deleted, and its |uid| is still valid, so it moves
4519     // to the evicted list, not the |deleted_ui_resources_| set. Also, its
4520     // backing is gone, so it would not belong in |deleted_ui_resources_|.
4521     evicted_ui_resources_.insert(uid);
4522   }
4523   ui_resource_map_.clear();
4524   for (auto& pair : deleted_ui_resources_) {
4525     UIResourceData& data = pair.second;
4526     // Immediately drop the backing instead of waiting for the resource to be
4527     // returned from the ResourceProvider, as this is called in cases where the
4528     // ability to clean up the backings will go away (context loss, shutdown).
4529     DeleteUIResourceBacking(std::move(data), gpu::SyncToken());
4530   }
4531   deleted_ui_resources_.clear();
4532 }
4533 
EvictAllUIResources()4534 void LayerTreeHostImpl::EvictAllUIResources() {
4535   if (ui_resource_map_.empty())
4536     return;
4537   while (!ui_resource_map_.empty()) {
4538     UIResourceId uid = ui_resource_map_.begin()->first;
4539     DeleteUIResource(uid);
4540     evicted_ui_resources_.insert(uid);
4541   }
4542   client_->SetNeedsCommitOnImplThread();
4543   client_->OnCanDrawStateChanged(CanDraw());
4544   client_->RenewTreePriority();
4545 }
4546 
ResourceIdForUIResource(UIResourceId uid) const4547 viz::ResourceId LayerTreeHostImpl::ResourceIdForUIResource(
4548     UIResourceId uid) const {
4549   auto iter = ui_resource_map_.find(uid);
4550   if (iter != ui_resource_map_.end())
4551     return iter->second.resource_id_for_export;
4552   return viz::kInvalidResourceId;
4553 }
4554 
IsUIResourceOpaque(UIResourceId uid) const4555 bool LayerTreeHostImpl::IsUIResourceOpaque(UIResourceId uid) const {
4556   auto iter = ui_resource_map_.find(uid);
4557   DCHECK(iter != ui_resource_map_.end());
4558   return iter->second.opaque;
4559 }
4560 
EvictedUIResourcesExist() const4561 bool LayerTreeHostImpl::EvictedUIResourcesExist() const {
4562   return !evicted_ui_resources_.empty();
4563 }
4564 
MarkUIResourceNotEvicted(UIResourceId uid)4565 void LayerTreeHostImpl::MarkUIResourceNotEvicted(UIResourceId uid) {
4566   auto found_in_evicted = evicted_ui_resources_.find(uid);
4567   if (found_in_evicted == evicted_ui_resources_.end())
4568     return;
4569   evicted_ui_resources_.erase(found_in_evicted);
4570   if (evicted_ui_resources_.empty())
4571     client_->OnCanDrawStateChanged(CanDraw());
4572 }
4573 
ScheduleMicroBenchmark(std::unique_ptr<MicroBenchmarkImpl> benchmark)4574 void LayerTreeHostImpl::ScheduleMicroBenchmark(
4575     std::unique_ptr<MicroBenchmarkImpl> benchmark) {
4576   micro_benchmark_controller_.ScheduleRun(std::move(benchmark));
4577 }
4578 
InsertSwapPromiseMonitor(SwapPromiseMonitor * monitor)4579 void LayerTreeHostImpl::InsertSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
4580   swap_promise_monitor_.insert(monitor);
4581 }
4582 
RemoveSwapPromiseMonitor(SwapPromiseMonitor * monitor)4583 void LayerTreeHostImpl::RemoveSwapPromiseMonitor(SwapPromiseMonitor* monitor) {
4584   swap_promise_monitor_.erase(monitor);
4585 }
4586 
NotifySwapPromiseMonitorsOfSetNeedsRedraw()4587 void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfSetNeedsRedraw() {
4588   auto it = swap_promise_monitor_.begin();
4589   for (; it != swap_promise_monitor_.end(); it++)
4590     (*it)->OnSetNeedsRedrawOnImpl();
4591 }
4592 
IsElementInPropertyTrees(ElementId element_id,ElementListType list_type) const4593 bool LayerTreeHostImpl::IsElementInPropertyTrees(
4594     ElementId element_id,
4595     ElementListType list_type) const {
4596   if (list_type == ElementListType::ACTIVE)
4597     return active_tree() && active_tree()->IsElementInPropertyTree(element_id);
4598 
4599   return (pending_tree() &&
4600           pending_tree()->IsElementInPropertyTree(element_id)) ||
4601          (recycle_tree() &&
4602           recycle_tree()->IsElementInPropertyTree(element_id));
4603 }
4604 
SetMutatorsNeedCommit()4605 void LayerTreeHostImpl::SetMutatorsNeedCommit() {}
4606 
SetMutatorsNeedRebuildPropertyTrees()4607 void LayerTreeHostImpl::SetMutatorsNeedRebuildPropertyTrees() {}
4608 
SetTreeLayerScrollOffsetMutated(ElementId element_id,LayerTreeImpl * tree,const gfx::ScrollOffset & scroll_offset)4609 void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated(
4610     ElementId element_id,
4611     LayerTreeImpl* tree,
4612     const gfx::ScrollOffset& scroll_offset) {
4613   if (!tree)
4614     return;
4615 
4616   PropertyTrees* property_trees = tree->property_trees();
4617   DCHECK_EQ(1u,
4618             property_trees->element_id_to_scroll_node_index.count(element_id));
4619   const int scroll_node_index =
4620       property_trees->element_id_to_scroll_node_index[element_id];
4621   property_trees->scroll_tree.OnScrollOffsetAnimated(
4622       element_id, scroll_node_index, scroll_offset, tree);
4623 }
4624 
SetNeedUpdateGpuRasterizationStatus()4625 void LayerTreeHostImpl::SetNeedUpdateGpuRasterizationStatus() {
4626   need_update_gpu_rasterization_status_ = true;
4627 }
4628 
SetElementFilterMutated(ElementId element_id,ElementListType list_type,const FilterOperations & filters)4629 void LayerTreeHostImpl::SetElementFilterMutated(
4630     ElementId element_id,
4631     ElementListType list_type,
4632     const FilterOperations& filters) {
4633   if (list_type == ElementListType::ACTIVE) {
4634     active_tree()->SetFilterMutated(element_id, filters);
4635   } else {
4636     if (pending_tree())
4637       pending_tree()->SetFilterMutated(element_id, filters);
4638     if (recycle_tree())
4639       recycle_tree()->SetFilterMutated(element_id, filters);
4640   }
4641 }
4642 
OnCustomPropertyMutated(ElementId element_id,const std::string & custom_property_name,PaintWorkletInput::PropertyValue custom_property_value)4643 void LayerTreeHostImpl::OnCustomPropertyMutated(
4644     ElementId element_id,
4645     const std::string& custom_property_name,
4646     PaintWorkletInput::PropertyValue custom_property_value) {
4647   paint_worklet_tracker_.OnCustomPropertyMutated(
4648       element_id, custom_property_name, std::move(custom_property_value));
4649 }
4650 
SetElementBackdropFilterMutated(ElementId element_id,ElementListType list_type,const FilterOperations & backdrop_filters)4651 void LayerTreeHostImpl::SetElementBackdropFilterMutated(
4652     ElementId element_id,
4653     ElementListType list_type,
4654     const FilterOperations& backdrop_filters) {
4655   if (list_type == ElementListType::ACTIVE) {
4656     active_tree()->SetBackdropFilterMutated(element_id, backdrop_filters);
4657   } else {
4658     if (pending_tree())
4659       pending_tree()->SetBackdropFilterMutated(element_id, backdrop_filters);
4660     if (recycle_tree())
4661       recycle_tree()->SetBackdropFilterMutated(element_id, backdrop_filters);
4662   }
4663 }
4664 
SetElementOpacityMutated(ElementId element_id,ElementListType list_type,float opacity)4665 void LayerTreeHostImpl::SetElementOpacityMutated(ElementId element_id,
4666                                                  ElementListType list_type,
4667                                                  float opacity) {
4668   if (list_type == ElementListType::ACTIVE) {
4669     active_tree()->SetOpacityMutated(element_id, opacity);
4670   } else {
4671     if (pending_tree())
4672       pending_tree()->SetOpacityMutated(element_id, opacity);
4673     if (recycle_tree())
4674       recycle_tree()->SetOpacityMutated(element_id, opacity);
4675   }
4676 }
4677 
SetElementTransformMutated(ElementId element_id,ElementListType list_type,const gfx::Transform & transform)4678 void LayerTreeHostImpl::SetElementTransformMutated(
4679     ElementId element_id,
4680     ElementListType list_type,
4681     const gfx::Transform& transform) {
4682   if (list_type == ElementListType::ACTIVE) {
4683     active_tree()->SetTransformMutated(element_id, transform);
4684   } else {
4685     if (pending_tree())
4686       pending_tree()->SetTransformMutated(element_id, transform);
4687     if (recycle_tree())
4688       recycle_tree()->SetTransformMutated(element_id, transform);
4689   }
4690 }
4691 
SetElementScrollOffsetMutated(ElementId element_id,ElementListType list_type,const gfx::ScrollOffset & scroll_offset)4692 void LayerTreeHostImpl::SetElementScrollOffsetMutated(
4693     ElementId element_id,
4694     ElementListType list_type,
4695     const gfx::ScrollOffset& scroll_offset) {
4696   if (list_type == ElementListType::ACTIVE) {
4697     SetTreeLayerScrollOffsetMutated(element_id, active_tree(), scroll_offset);
4698     ShowScrollbarsForImplScroll(element_id);
4699   } else {
4700     SetTreeLayerScrollOffsetMutated(element_id, pending_tree(), scroll_offset);
4701     SetTreeLayerScrollOffsetMutated(element_id, recycle_tree(), scroll_offset);
4702   }
4703 }
4704 
ElementIsAnimatingChanged(const PropertyToElementIdMap & element_id_map,ElementListType list_type,const PropertyAnimationState & mask,const PropertyAnimationState & state)4705 void LayerTreeHostImpl::ElementIsAnimatingChanged(
4706     const PropertyToElementIdMap& element_id_map,
4707     ElementListType list_type,
4708     const PropertyAnimationState& mask,
4709     const PropertyAnimationState& state) {
4710   LayerTreeImpl* tree =
4711       list_type == ElementListType::ACTIVE ? active_tree() : pending_tree();
4712   // TODO(wkorman): Explore enabling DCHECK in ElementIsAnimatingChanged()
4713   // below. Currently enabling causes batch of unit test failures.
4714   if (tree && tree->property_trees()->ElementIsAnimatingChanged(
4715                   element_id_map, mask, state, false))
4716     tree->set_needs_update_draw_properties();
4717 }
4718 
AnimationScalesChanged(ElementId element_id,ElementListType list_type,float maximum_scale,float starting_scale)4719 void LayerTreeHostImpl::AnimationScalesChanged(ElementId element_id,
4720                                                ElementListType list_type,
4721                                                float maximum_scale,
4722                                                float starting_scale) {
4723   if (LayerTreeImpl* tree = list_type == ElementListType::ACTIVE
4724                                 ? active_tree()
4725                                 : pending_tree()) {
4726     tree->property_trees()->AnimationScalesChanged(element_id, maximum_scale,
4727                                                    starting_scale);
4728   }
4729 }
4730 
ScrollOffsetAnimationFinished()4731 void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
4732   if (input_delegate_)
4733     input_delegate_->ScrollOffsetAnimationFinished();
4734 }
4735 
NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,ElementListType tree_type)4736 void LayerTreeHostImpl::NotifyAnimationWorkletStateChange(
4737     AnimationWorkletMutationState state,
4738     ElementListType tree_type) {
4739   client_->NotifyAnimationWorkletStateChange(state, tree_type);
4740   if (state != AnimationWorkletMutationState::CANCELED) {
4741     // We have at least one active worklet animation. We need to request a new
4742     // frame to keep the animation ticking.
4743     SetNeedsOneBeginImplFrame();
4744     if (state == AnimationWorkletMutationState::COMPLETED_WITH_UPDATE &&
4745         tree_type == ElementListType::ACTIVE) {
4746       SetNeedsRedraw();
4747     }
4748   }
4749 }
4750 
GetScrollOffsetForAnimation(ElementId element_id) const4751 gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation(
4752     ElementId element_id) const {
4753   if (active_tree()) {
4754     return active_tree()->property_trees()->scroll_tree.current_scroll_offset(
4755         element_id);
4756   }
4757 
4758   return gfx::ScrollOffset();
4759 }
4760 
SupportsImplScrolling() const4761 bool LayerTreeHostImpl::SupportsImplScrolling() const {
4762   // Supported in threaded mode.
4763   return task_runner_provider_->HasImplThread();
4764 }
4765 
CommitToActiveTree() const4766 bool LayerTreeHostImpl::CommitToActiveTree() const {
4767   return settings_.commit_to_active_tree;
4768 }
4769 
SetContextVisibility(bool is_visible)4770 void LayerTreeHostImpl::SetContextVisibility(bool is_visible) {
4771   if (!layer_tree_frame_sink_)
4772     return;
4773 
4774   // Update the compositor context. If we are already in the correct visibility
4775   // state, skip. This can happen if we transition invisible/visible rapidly,
4776   // before we get a chance to go invisible in NotifyAllTileTasksComplete.
4777   auto* compositor_context = layer_tree_frame_sink_->context_provider();
4778   if (compositor_context && is_visible != !!compositor_context_visibility_) {
4779     if (is_visible) {
4780       compositor_context_visibility_ =
4781           compositor_context->CacheController()->ClientBecameVisible();
4782     } else {
4783       compositor_context->CacheController()->ClientBecameNotVisible(
4784           std::move(compositor_context_visibility_));
4785     }
4786   }
4787 
4788   // Update the worker context. If we are already in the correct visibility
4789   // state, skip. This can happen if we transition invisible/visible rapidly,
4790   // before we get a chance to go invisible in NotifyAllTileTasksComplete.
4791   auto* worker_context = layer_tree_frame_sink_->worker_context_provider();
4792   if (worker_context && is_visible != !!worker_context_visibility_) {
4793     viz::RasterContextProvider::ScopedRasterContextLock hold(worker_context);
4794     if (is_visible) {
4795       worker_context_visibility_ =
4796           worker_context->CacheController()->ClientBecameVisible();
4797     } else {
4798       worker_context->CacheController()->ClientBecameNotVisible(
4799           std::move(worker_context_visibility_));
4800     }
4801   }
4802 }
4803 
ShowScrollbarsForImplScroll(ElementId element_id)4804 void LayerTreeHostImpl::ShowScrollbarsForImplScroll(ElementId element_id) {
4805   if (settings_.scrollbar_flash_after_any_scroll_update) {
4806     FlashAllScrollbars(true);
4807     return;
4808   }
4809   if (!element_id)
4810     return;
4811   if (ScrollbarAnimationController* animation_controller =
4812           ScrollbarAnimationControllerForElementId(element_id))
4813     animation_controller->DidScrollUpdate();
4814 }
4815 
InitializeUkm(std::unique_ptr<ukm::UkmRecorder> recorder)4816 void LayerTreeHostImpl::InitializeUkm(
4817     std::unique_ptr<ukm::UkmRecorder> recorder) {
4818   DCHECK(!ukm_manager_);
4819   ukm_manager_ = std::make_unique<UkmManager>(std::move(recorder));
4820   frame_trackers_.SetUkmManager(ukm_manager_.get());
4821   compositor_frame_reporting_controller_->SetUkmManager(ukm_manager_.get());
4822 }
4823 
SetActiveURL(const GURL & url,ukm::SourceId source_id)4824 void LayerTreeHostImpl::SetActiveURL(const GURL& url, ukm::SourceId source_id) {
4825   tile_manager_.set_active_url(url);
4826   has_observed_first_scroll_delay_ = false;
4827   // The active tree might still be from content for the previous page when the
4828   // recorder is updated here, since new content will be pushed with the next
4829   // main frame. But we should only get a few impl frames wrong here in that
4830   // case. Also, since checkerboard stats are only recorded with user
4831   // interaction, it must be in progress when the navigation commits for this
4832   // case to occur.
4833   if (ukm_manager_) {
4834     // The source id has already been associated to the URL.
4835     ukm_manager_->SetSourceId(source_id);
4836   }
4837   total_frame_counter_.Reset();
4838   dropped_frame_counter_.Reset();
4839   is_measuring_smoothness_ = false;
4840 }
4841 
SetUkmSmoothnessDestination(base::WritableSharedMemoryMapping ukm_smoothness_data)4842 void LayerTreeHostImpl::SetUkmSmoothnessDestination(
4843     base::WritableSharedMemoryMapping ukm_smoothness_data) {
4844   ukm_smoothness_mapping_ = std::move(ukm_smoothness_data);
4845   dropped_frame_counter_.SetUkmSmoothnessDestination(
4846       ukm_smoothness_mapping_.GetMemoryAs<UkmSmoothnessDataShared>());
4847 }
4848 
AllocateLocalSurfaceId()4849 void LayerTreeHostImpl::AllocateLocalSurfaceId() {
4850   child_local_surface_id_allocator_.GenerateId();
4851 }
4852 
RequestBeginFrameForAnimatedImages()4853 void LayerTreeHostImpl::RequestBeginFrameForAnimatedImages() {
4854   SetNeedsOneBeginImplFrame();
4855 }
4856 
RequestInvalidationForAnimatedImages()4857 void LayerTreeHostImpl::RequestInvalidationForAnimatedImages() {
4858   DCHECK_EQ(impl_thread_phase_, ImplThreadPhase::INSIDE_IMPL_FRAME);
4859 
4860   // If we are animating an image, we want at least one draw of the active tree
4861   // before a new tree is activated.
4862   bool needs_first_draw_on_activation = true;
4863   client_->NeedsImplSideInvalidation(needs_first_draw_on_activation);
4864 }
4865 
TakeEventsMetrics()4866 EventMetricsSet LayerTreeHostImpl::TakeEventsMetrics() {
4867   return EventMetricsSet(active_tree()->TakeEventsMetrics(),
4868                          events_metrics_manager_.TakeSavedEventsMetrics());
4869 }
4870 
AsWeakPtr()4871 base::WeakPtr<LayerTreeHostImpl> LayerTreeHostImpl::AsWeakPtr() {
4872   return weak_factory_.GetWeakPtr();
4873 }
4874 
4875 }  // namespace cc
4876