compositor.cc 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911
  1. // Copyright (c) 2012 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. #include "ui/compositor/compositor.h"
  5. #include <stddef.h>
  6. #include <algorithm>
  7. #include <memory>
  8. #include <utility>
  9. #include <vector>
  10. #include "base/bind.h"
  11. #include "base/command_line.h"
  12. #include "base/containers/contains.h"
  13. #include "base/metrics/histogram_macros.h"
  14. #include "base/observer_list.h"
  15. #include "base/power_monitor/power_monitor.h"
  16. #include "base/strings/string_number_conversions.h"
  17. #include "base/strings/string_split.h"
  18. #include "base/strings/string_util.h"
  19. #include "base/system/sys_info.h"
  20. #include "base/trace_event/trace_event.h"
  21. #include "build/build_config.h"
  22. #include "build/chromeos_buildflags.h"
  23. #include "cc/animation/animation_host.h"
  24. #include "cc/animation/animation_id_provider.h"
  25. #include "cc/animation/animation_timeline.h"
  26. #include "cc/base/features.h"
  27. #include "cc/base/switches.h"
  28. #include "cc/input/input_handler.h"
  29. #include "cc/layers/layer.h"
  30. #include "cc/metrics/begin_main_frame_metrics.h"
  31. #include "cc/metrics/frame_sequence_tracker.h"
  32. #include "cc/metrics/web_vital_metrics.h"
  33. #include "cc/trees/layer_tree_host.h"
  34. #include "cc/trees/layer_tree_settings.h"
  35. #include "components/viz/common/features.h"
  36. #include "components/viz/common/frame_sinks/begin_frame_args.h"
  37. #include "components/viz/common/frame_sinks/begin_frame_source.h"
  38. #include "components/viz/common/gpu/context_provider.h"
  39. #include "components/viz/common/resources/resource_format.h"
  40. #include "components/viz/common/resources/resource_settings.h"
  41. #include "components/viz/common/switches.h"
  42. #include "components/viz/host/host_frame_sink_manager.h"
  43. #include "components/viz/host/renderer_settings_creation.h"
  44. #include "services/viz/privileged/mojom/compositing/display_private.mojom.h"
  45. #include "services/viz/privileged/mojom/compositing/external_begin_frame_controller.mojom.h"
  46. #include "services/viz/privileged/mojom/compositing/vsync_parameter_observer.mojom.h"
  47. #include "third_party/skia/include/core/SkBitmap.h"
  48. #include "ui/base/ui_base_features.h"
  49. #include "ui/base/ui_base_switches.h"
  50. #include "ui/compositor/compositor_observer.h"
  51. #include "ui/compositor/compositor_switches.h"
  52. #include "ui/compositor/layer.h"
  53. #include "ui/compositor/layer_animator_collection.h"
  54. #include "ui/compositor/overscroll/scroll_input_handler.h"
  55. #include "ui/compositor/scoped_animation_duration_scale_mode.h"
  56. #include "ui/display/display_switches.h"
  57. #include "ui/gfx/icc_profile.h"
  58. #include "ui/gfx/presentation_feedback.h"
  59. #include "ui/gfx/switches.h"
  60. #include "ui/gl/gl_switches.h"
  61. #if BUILDFLAG(IS_WIN)
  62. #include "mojo/public/cpp/bindings/sync_call_restrictions.h"
  63. #endif
  64. namespace ui {
  65. // Used to hold on to IssueExternalBeginFrame arguments if
  66. // |external_begin_frame_controller_| isn't ready yet.
  67. struct PendingBeginFrameArgs {
  68. PendingBeginFrameArgs(
  69. const viz::BeginFrameArgs& args,
  70. bool force,
  71. base::OnceCallback<void(const viz::BeginFrameAck&)> callback)
  72. : args(args), force(force), callback(std::move(callback)) {}
  73. viz::BeginFrameArgs args;
  74. bool force;
  75. base::OnceCallback<void(const viz::BeginFrameAck&)> callback;
  76. };
  77. Compositor::Compositor(const viz::FrameSinkId& frame_sink_id,
  78. ui::ContextFactory* context_factory,
  79. scoped_refptr<base::SingleThreadTaskRunner> task_runner,
  80. bool enable_pixel_canvas,
  81. bool use_external_begin_frame_control,
  82. bool force_software_compositor,
  83. bool enable_compositing_based_throttling,
  84. size_t memory_limit_when_visible_mb)
  85. : context_factory_(context_factory),
  86. frame_sink_id_(frame_sink_id),
  87. task_runner_(task_runner),
  88. use_external_begin_frame_control_(use_external_begin_frame_control),
  89. force_software_compositor_(force_software_compositor),
  90. layer_animator_collection_(this),
  91. is_pixel_canvas_(enable_pixel_canvas),
  92. lock_manager_(task_runner) {
  93. DCHECK(context_factory_);
  94. auto* host_frame_sink_manager = context_factory_->GetHostFrameSinkManager();
  95. host_frame_sink_manager->RegisterFrameSinkId(
  96. frame_sink_id_, this, viz::ReportFirstSurfaceActivation::kNo);
  97. host_frame_sink_manager->SetFrameSinkDebugLabel(frame_sink_id_, "Compositor");
  98. root_web_layer_ = cc::Layer::Create();
  99. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  100. cc::LayerTreeSettings settings;
  101. // This will ensure PictureLayers always can have LCD text, to match the
  102. // previous behaviour with ContentLayers, where LCD-not-allowed notifications
  103. // were ignored.
  104. settings.layers_always_allowed_lcd_text = true;
  105. // Use occlusion to allow more overlapping windows to take less memory.
  106. settings.use_occlusion_for_tile_prioritization = true;
  107. settings.main_frame_before_activation_enabled = false;
  108. settings.release_tile_resources_for_hidden_layers =
  109. base::FeatureList::IsEnabled(
  110. features::kUiCompositorReleaseTileResourcesForHiddenLayers);
  111. // Disable edge anti-aliasing in order to increase support for HW overlays.
  112. settings.enable_edge_anti_aliasing = false;
  113. // GPU rasterization in the UI compositor is controlled by a feature.
  114. settings.gpu_rasterization_disabled =
  115. !features::IsUiGpuRasterizationEnabled();
  116. if (command_line->HasSwitch(cc::switches::kUIShowCompositedLayerBorders)) {
  117. std::string layer_borders_string = command_line->GetSwitchValueASCII(
  118. cc::switches::kUIShowCompositedLayerBorders);
  119. std::vector<base::StringPiece> entries = base::SplitStringPiece(
  120. layer_borders_string, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  121. if (entries.empty()) {
  122. settings.initial_debug_state.show_debug_borders.set();
  123. } else {
  124. for (const auto& entry : entries) {
  125. const struct {
  126. const char* name;
  127. cc::DebugBorderType type;
  128. } kBorders[] = {{cc::switches::kCompositedRenderPassBorders,
  129. cc::DebugBorderType::RENDERPASS},
  130. {cc::switches::kCompositedSurfaceBorders,
  131. cc::DebugBorderType::SURFACE},
  132. {cc::switches::kCompositedLayerBorders,
  133. cc::DebugBorderType::LAYER}};
  134. for (const auto& border : kBorders) {
  135. if (border.name == entry) {
  136. settings.initial_debug_state.show_debug_borders.set(border.type);
  137. break;
  138. }
  139. }
  140. }
  141. }
  142. }
  143. settings.initial_debug_state.show_fps_counter =
  144. command_line->HasSwitch(cc::switches::kUIShowFPSCounter);
  145. settings.initial_debug_state.show_layer_animation_bounds_rects =
  146. command_line->HasSwitch(cc::switches::kUIShowLayerAnimationBounds);
  147. settings.initial_debug_state.show_paint_rects =
  148. command_line->HasSwitch(switches::kUIShowPaintRects);
  149. settings.initial_debug_state.show_property_changed_rects =
  150. command_line->HasSwitch(cc::switches::kUIShowPropertyChangedRects);
  151. settings.initial_debug_state.show_surface_damage_rects =
  152. command_line->HasSwitch(cc::switches::kUIShowSurfaceDamageRects);
  153. settings.initial_debug_state.show_screen_space_rects =
  154. command_line->HasSwitch(cc::switches::kUIShowScreenSpaceRects);
  155. settings.initial_debug_state.SetRecordRenderingStats(
  156. command_line->HasSwitch(cc::switches::kEnableGpuBenchmarking));
  157. settings.use_zero_copy = IsUIZeroCopyEnabled() && !features::IsUsingRawDraw();
  158. settings.use_layer_lists =
  159. command_line->HasSwitch(cc::switches::kUIEnableLayerLists);
  160. // UI compositor always uses partial raster if not using zero-copy. Zero copy
  161. // doesn't currently support partial raster.
  162. // RawDraw doesn't support partial raster.
  163. settings.use_partial_raster =
  164. !(settings.use_zero_copy || features::IsUsingRawDraw());
  165. settings.use_rgba_4444 =
  166. command_line->HasSwitch(switches::kUIEnableRGBA4444Textures);
  167. #if BUILDFLAG(IS_APPLE)
  168. // Using CoreAnimation to composite requires using GpuMemoryBuffers, which
  169. // require zero copy.
  170. settings.resource_settings.use_gpu_memory_buffer_resources =
  171. settings.use_zero_copy;
  172. settings.enable_elastic_overscroll = true;
  173. #endif
  174. #if BUILDFLAG(IS_CHROMEOS_LACROS)
  175. // Rasterized tiles must be overlay candidates to be forwarded.
  176. // This is very similar to the line above for Apple.
  177. settings.resource_settings.use_gpu_memory_buffer_resources =
  178. features::IsDelegatedCompositingEnabled();
  179. #endif
  180. // Set use_gpu_memory_buffer_resources to false to disable delegated
  181. // compositing, if RawDraw is enabled.
  182. if (settings.resource_settings.use_gpu_memory_buffer_resources &&
  183. features::IsUsingRawDraw()) {
  184. settings.resource_settings.use_gpu_memory_buffer_resources = false;
  185. }
  186. settings.memory_policy.bytes_limit_when_visible =
  187. (memory_limit_when_visible_mb > 0 ? memory_limit_when_visible_mb : 512) *
  188. 1024 * 1024;
  189. if (base::FeatureList::IsEnabled(features::kUiCompositorRequiredTilesOnly)) {
  190. settings.memory_policy.priority_cutoff_when_visible =
  191. gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY;
  192. } else {
  193. settings.memory_policy.priority_cutoff_when_visible =
  194. gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE;
  195. }
  196. settings.disallow_non_exact_resource_reuse =
  197. command_line->HasSwitch(switches::kDisallowNonExactResourceReuse);
  198. settings.wait_for_all_pipeline_stages_before_draw =
  199. command_line->HasSwitch(switches::kRunAllCompositorStagesBeforeDraw);
  200. if (base::FeatureList::IsEnabled(
  201. features::kCompositorThreadedScrollbarScrolling)) {
  202. settings.compositor_threaded_scrollbar_scrolling = true;
  203. }
  204. if (features::IsPercentBasedScrollingEnabled()) {
  205. settings.percent_based_scrolling = true;
  206. }
  207. settings.enable_compositing_based_throttling =
  208. enable_compositing_based_throttling;
  209. settings.is_layer_tree_for_ui = true;
  210. #if DCHECK_IS_ON()
  211. if (command_line->HasSwitch(cc::switches::kLogOnUIDoubleBackgroundBlur))
  212. settings.log_on_ui_double_background_blur = true;
  213. #endif
  214. animation_host_ = cc::AnimationHost::CreateMainInstance();
  215. cc::LayerTreeHost::InitParams params;
  216. params.client = this;
  217. params.task_graph_runner = context_factory_->GetTaskGraphRunner();
  218. params.settings = &settings;
  219. params.main_task_runner = task_runner_;
  220. params.mutator_host = animation_host_.get();
  221. host_ = cc::LayerTreeHost::CreateSingleThreaded(this, std::move(params));
  222. const base::WeakPtr<cc::CompositorDelegateForInput>& compositor_delegate =
  223. host_->GetDelegateForInput();
  224. if (base::FeatureList::IsEnabled(features::kUiCompositorScrollWithLayers) &&
  225. compositor_delegate) {
  226. input_handler_weak_ = cc::InputHandler::Create(*compositor_delegate);
  227. scroll_input_handler_ =
  228. std::make_unique<ScrollInputHandler>(input_handler_weak_);
  229. }
  230. animation_timeline_ =
  231. cc::AnimationTimeline::Create(cc::AnimationIdProvider::NextTimelineId());
  232. animation_host_->AddAnimationTimeline(animation_timeline_.get());
  233. host_->SetRootLayer(root_web_layer_);
  234. // This shouldn't be done in the constructor in order to match Widget.
  235. // See: http://crbug.com/956264.
  236. host_->SetVisible(true);
  237. if (base::PowerMonitor::IsInitialized())
  238. base::PowerMonitor::AddPowerSuspendObserver(this);
  239. if (command_line->HasSwitch(switches::kUISlowAnimations)) {
  240. slow_animations_ = std::make_unique<ScopedAnimationDurationScaleMode>(
  241. ScopedAnimationDurationScaleMode::SLOW_DURATION);
  242. }
  243. }
  244. Compositor::~Compositor() {
  245. TRACE_EVENT0("shutdown,viz", "Compositor::destructor");
  246. if (base::PowerMonitor::IsInitialized())
  247. base::PowerMonitor::RemovePowerSuspendObserver(this);
  248. for (auto& observer : observer_list_)
  249. observer.OnCompositingShuttingDown(this);
  250. for (auto& observer : animation_observer_list_)
  251. observer.OnCompositingShuttingDown(this);
  252. if (root_layer_)
  253. root_layer_->ResetCompositor();
  254. if (animation_timeline_)
  255. animation_host_->RemoveAnimationTimeline(animation_timeline_.get());
  256. // Stop all outstanding draws before telling the ContextFactory to tear
  257. // down any contexts that the |host_| may rely upon.
  258. host_.reset();
  259. context_factory_->RemoveCompositor(this);
  260. auto* host_frame_sink_manager = context_factory_->GetHostFrameSinkManager();
  261. for (auto& client : child_frame_sinks_) {
  262. DCHECK(client.is_valid());
  263. host_frame_sink_manager->UnregisterFrameSinkHierarchy(frame_sink_id_,
  264. client);
  265. }
  266. host_frame_sink_manager->InvalidateFrameSinkId(frame_sink_id_);
  267. }
  268. void Compositor::AddChildFrameSink(const viz::FrameSinkId& frame_sink_id) {
  269. context_factory_->GetHostFrameSinkManager()->RegisterFrameSinkHierarchy(
  270. frame_sink_id_, frame_sink_id);
  271. auto result = child_frame_sinks_.insert(frame_sink_id);
  272. DCHECK(result.second);
  273. }
  274. void Compositor::RemoveChildFrameSink(const viz::FrameSinkId& frame_sink_id) {
  275. auto it = child_frame_sinks_.find(frame_sink_id);
  276. DCHECK(it != child_frame_sinks_.end());
  277. DCHECK(it->is_valid());
  278. context_factory_->GetHostFrameSinkManager()->UnregisterFrameSinkHierarchy(
  279. frame_sink_id_, *it);
  280. child_frame_sinks_.erase(it);
  281. }
  282. void Compositor::SetLayerTreeFrameSink(
  283. std::unique_ptr<cc::LayerTreeFrameSink> layer_tree_frame_sink,
  284. viz::mojom::DisplayPrivate* display_private) {
  285. layer_tree_frame_sink_requested_ = false;
  286. display_private_ = display_private;
  287. host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
  288. // Display properties are reset when the output surface is lost, so update it
  289. // to match the Compositor's.
  290. if (display_private_) {
  291. disabled_swap_until_resize_ = false;
  292. display_private_->Resize(size());
  293. display_private_->SetDisplayVisible(host_->IsVisible());
  294. display_private_->SetDisplayColorSpaces(display_color_spaces_);
  295. display_private_->SetDisplayColorMatrix(
  296. gfx::Transform(display_color_matrix_));
  297. display_private_->SetOutputIsSecure(output_is_secure_);
  298. if (has_vsync_params_)
  299. display_private_->SetDisplayVSyncParameters(vsync_timebase_,
  300. vsync_interval_);
  301. }
  302. }
  303. void Compositor::SetExternalBeginFrameController(
  304. viz::mojom::ExternalBeginFrameController* external_begin_frame_controller) {
  305. DCHECK(use_external_begin_frame_control());
  306. external_begin_frame_controller_ = external_begin_frame_controller;
  307. if (pending_begin_frame_args_) {
  308. external_begin_frame_controller_->IssueExternalBeginFrame(
  309. pending_begin_frame_args_->args, pending_begin_frame_args_->force,
  310. std::move(pending_begin_frame_args_->callback));
  311. pending_begin_frame_args_.reset();
  312. }
  313. }
  314. void Compositor::OnChildResizing() {
  315. for (auto& observer : observer_list_)
  316. observer.OnCompositingChildResizing(this);
  317. }
  318. void Compositor::ScheduleDraw() {
  319. host_->SetNeedsCommit();
  320. }
  321. void Compositor::SetRootLayer(Layer* root_layer) {
  322. if (root_layer_ == root_layer)
  323. return;
  324. if (root_layer_)
  325. root_layer_->ResetCompositor();
  326. root_layer_ = root_layer;
  327. root_web_layer_->RemoveAllChildren();
  328. if (root_layer_)
  329. root_layer_->SetCompositor(this, root_web_layer_);
  330. }
  331. void Compositor::DisableAnimations() {
  332. DCHECK(animations_are_enabled_);
  333. animations_are_enabled_ = false;
  334. root_layer_->ResetCompositorForAnimatorsInTree(this);
  335. }
  336. void Compositor::EnableAnimations() {
  337. DCHECK(!animations_are_enabled_);
  338. animations_are_enabled_ = true;
  339. root_layer_->SetCompositorForAnimatorsInTree(this);
  340. }
  341. cc::AnimationTimeline* Compositor::GetAnimationTimeline() const {
  342. return animation_timeline_.get();
  343. }
  344. void Compositor::SetDisplayColorMatrix(const SkM44& matrix) {
  345. display_color_matrix_ = matrix;
  346. if (display_private_)
  347. display_private_->SetDisplayColorMatrix(gfx::Transform(matrix));
  348. }
  349. void Compositor::ScheduleFullRedraw() {
  350. // TODO(enne): Some callers (mac) call this function expecting that it
  351. // will also commit. This should probably just redraw the screen
  352. // from damage and not commit. ScheduleDraw/ScheduleRedraw need
  353. // better names.
  354. host_->SetNeedsRedrawRect(host_->device_viewport_rect());
  355. host_->SetNeedsCommit();
  356. }
  357. void Compositor::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
  358. // TODO(enne): Make this not commit. See ScheduleFullRedraw.
  359. host_->SetNeedsRedrawRect(damage_rect);
  360. host_->SetNeedsCommit();
  361. }
  362. #if BUILDFLAG(IS_WIN)
  363. void Compositor::SetShouldDisableSwapUntilResize(bool should) {
  364. should_disable_swap_until_resize_ = should;
  365. }
  366. void Compositor::DisableSwapUntilResize() {
  367. if (should_disable_swap_until_resize_ && display_private_) {
  368. // Browser needs to block for Viz to receive and process this message.
  369. // Otherwise when we return from WM_WINDOWPOSCHANGING message handler and
  370. // receive a WM_WINDOWPOSCHANGED the resize is finalized and any swaps of
  371. // wrong size by Viz can cause the swapped content to get scaled.
  372. // TODO(crbug.com/859168): Investigate nonblocking ways for solving.
  373. TRACE_EVENT0("viz", "Blocked UI for DisableSwapUntilResize");
  374. mojo::SyncCallRestrictions::ScopedAllowSyncCall scoped_allow_sync_call;
  375. display_private_->DisableSwapUntilResize();
  376. disabled_swap_until_resize_ = true;
  377. }
  378. }
  379. void Compositor::ReenableSwap() {
  380. if (should_disable_swap_until_resize_ && display_private_)
  381. display_private_->Resize(size_);
  382. }
  383. #endif
  384. void Compositor::SetScaleAndSize(float scale,
  385. const gfx::Size& size_in_pixel,
  386. const viz::LocalSurfaceId& local_surface_id) {
  387. DCHECK_GT(scale, 0);
  388. bool device_scale_factor_changed = device_scale_factor_ != scale;
  389. device_scale_factor_ = scale;
  390. // cc requires the size to be non-empty (meaning DCHECKs if size is empty).
  391. if (!size_in_pixel.IsEmpty()) {
  392. bool size_changed = size_ != size_in_pixel;
  393. size_ = size_in_pixel;
  394. host_->SetViewportRectAndScale(gfx::Rect(size_in_pixel), scale,
  395. local_surface_id);
  396. root_web_layer_->SetBounds(size_in_pixel);
  397. if (display_private_ && (size_changed || disabled_swap_until_resize_)) {
  398. display_private_->Resize(size_in_pixel);
  399. disabled_swap_until_resize_ = false;
  400. }
  401. }
  402. if (device_scale_factor_changed) {
  403. if (is_pixel_canvas())
  404. host_->SetRecordingScaleFactor(scale);
  405. if (root_layer_)
  406. root_layer_->OnDeviceScaleFactorChanged(scale);
  407. }
  408. }
  409. void Compositor::SetDisplayColorSpaces(
  410. const gfx::DisplayColorSpaces& display_color_spaces) {
  411. if (display_color_spaces_ == display_color_spaces)
  412. return;
  413. display_color_spaces_ = display_color_spaces;
  414. host_->SetDisplayColorSpaces(display_color_spaces_);
  415. // Always force the ui::Compositor to re-draw all layers, because damage
  416. // tracking bugs result in black flashes.
  417. // https://crbug.com/804430
  418. // TODO(ccameron): Remove this when the above bug is fixed.
  419. host_->SetNeedsDisplayOnAllLayers();
  420. // Color space is reset when the output surface is lost, so this must also be
  421. // updated then.
  422. if (display_private_)
  423. display_private_->SetDisplayColorSpaces(display_color_spaces_);
  424. }
  425. void Compositor::SetDisplayTransformHint(gfx::OverlayTransform hint) {
  426. host_->set_display_transform_hint(hint);
  427. }
  428. void Compositor::SetBackgroundColor(SkColor color) {
  429. // TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
  430. host_->set_background_color(SkColor4f::FromColor(color));
  431. ScheduleDraw();
  432. }
  433. void Compositor::SetVisible(bool visible) {
  434. host_->SetVisible(visible);
  435. // Visibility is reset when the output surface is lost, so this must also be
  436. // updated then.
  437. if (display_private_)
  438. display_private_->SetDisplayVisible(visible);
  439. }
  440. bool Compositor::IsVisible() {
  441. return host_->IsVisible();
  442. }
  443. // TODO(bokan): These calls should be delegated through the
  444. // scroll_input_handler_ so that we don't have to keep a pointer to the
  445. // cc::InputHandler in this class.
  446. bool Compositor::ScrollLayerTo(cc::ElementId element_id,
  447. const gfx::PointF& offset) {
  448. return input_handler_weak_ &&
  449. input_handler_weak_->ScrollLayerTo(element_id, offset);
  450. }
  451. bool Compositor::GetScrollOffsetForLayer(cc::ElementId element_id,
  452. gfx::PointF* offset) const {
  453. return input_handler_weak_ &&
  454. input_handler_weak_->GetScrollOffsetForLayer(element_id, offset);
  455. }
  456. void Compositor::SetDisplayVSyncParameters(base::TimeTicks timebase,
  457. base::TimeDelta interval) {
  458. static bool is_frame_rate_limit_disabled =
  459. base::CommandLine::ForCurrentProcess()->HasSwitch(
  460. switches::kDisableFrameRateLimit);
  461. if (is_frame_rate_limit_disabled)
  462. return;
  463. if (interval.is_zero()) {
  464. // TODO(brianderson): We should not be receiving 0 intervals.
  465. interval = viz::BeginFrameArgs::DefaultInterval();
  466. }
  467. DCHECK_GT(interval.InMillisecondsF(), 0);
  468. // This is called at high frequenty on macOS, so early-out of redundant
  469. // updates here.
  470. if (vsync_timebase_ == timebase && vsync_interval_ == interval)
  471. return;
  472. if (interval != vsync_interval_)
  473. has_vsync_params_ = true;
  474. vsync_timebase_ = timebase;
  475. vsync_interval_ = interval;
  476. if (display_private_)
  477. display_private_->SetDisplayVSyncParameters(timebase, interval);
  478. }
  479. void Compositor::AddVSyncParameterObserver(
  480. mojo::PendingRemote<viz::mojom::VSyncParameterObserver> observer) {
  481. if (display_private_)
  482. display_private_->AddVSyncParameterObserver(std::move(observer));
  483. }
  484. void Compositor::SetAcceleratedWidget(gfx::AcceleratedWidget widget) {
  485. // This function should only get called once.
  486. DCHECK(!widget_valid_);
  487. widget_ = widget;
  488. widget_valid_ = true;
  489. if (layer_tree_frame_sink_requested_) {
  490. context_factory_->CreateLayerTreeFrameSink(
  491. context_creation_weak_ptr_factory_.GetWeakPtr());
  492. }
  493. }
  494. gfx::AcceleratedWidget Compositor::ReleaseAcceleratedWidget() {
  495. DCHECK(!IsVisible());
  496. host_->ReleaseLayerTreeFrameSink();
  497. display_private_ = nullptr;
  498. external_begin_frame_controller_ = nullptr;
  499. context_factory_->RemoveCompositor(this);
  500. context_creation_weak_ptr_factory_.InvalidateWeakPtrs();
  501. widget_valid_ = false;
  502. gfx::AcceleratedWidget widget = widget_;
  503. widget_ = gfx::kNullAcceleratedWidget;
  504. return widget;
  505. }
  506. gfx::AcceleratedWidget Compositor::widget() const {
  507. DCHECK(widget_valid_);
  508. return widget_;
  509. }
  510. void Compositor::AddObserver(CompositorObserver* observer) {
  511. observer_list_.AddObserver(observer);
  512. }
  513. void Compositor::RemoveObserver(CompositorObserver* observer) {
  514. observer_list_.RemoveObserver(observer);
  515. }
  516. bool Compositor::HasObserver(const CompositorObserver* observer) const {
  517. return observer_list_.HasObserver(observer);
  518. }
  519. void Compositor::AddAnimationObserver(CompositorAnimationObserver* observer) {
  520. if (animation_observer_list_.empty()) {
  521. for (auto& obs : observer_list_)
  522. obs.OnFirstAnimationStarted(this);
  523. }
  524. observer->Start();
  525. animation_observer_list_.AddObserver(observer);
  526. host_->SetNeedsAnimate();
  527. }
  528. void Compositor::RemoveAnimationObserver(
  529. CompositorAnimationObserver* observer) {
  530. if (!animation_observer_list_.HasObserver(observer))
  531. return;
  532. for (auto& aobs : animation_observer_list_)
  533. aobs.Check();
  534. animation_observer_list_.RemoveObserver(observer);
  535. if (animation_observer_list_.empty()) {
  536. for (auto& obs : observer_list_)
  537. obs.OnLastAnimationEnded(this);
  538. }
  539. }
  540. bool Compositor::HasAnimationObserver(
  541. const CompositorAnimationObserver* observer) const {
  542. return animation_observer_list_.HasObserver(observer);
  543. }
  544. void Compositor::IssueExternalBeginFrame(
  545. const viz::BeginFrameArgs& args,
  546. bool force,
  547. base::OnceCallback<void(const viz::BeginFrameAck&)> callback) {
  548. if (!external_begin_frame_controller_) {
  549. // IssueExternalBeginFrame() shouldn't be called again before the previous
  550. // begin frame is acknowledged.
  551. DCHECK(!pending_begin_frame_args_);
  552. pending_begin_frame_args_ = std::make_unique<PendingBeginFrameArgs>(
  553. args, force, std::move(callback));
  554. return;
  555. }
  556. external_begin_frame_controller_->IssueExternalBeginFrame(
  557. args, force, std::move(callback));
  558. }
  559. ThroughputTracker Compositor::RequestNewThroughputTracker() {
  560. return ThroughputTracker(next_throughput_tracker_id_++,
  561. weak_ptr_factory_.GetWeakPtr());
  562. }
  563. double Compositor::GetPercentDroppedFrames() const {
  564. return host_->GetPercentDroppedFrames();
  565. }
  566. std::unique_ptr<cc::EventsMetricsManager::ScopedMonitor>
  567. Compositor::GetScopedEventMetricsMonitor(
  568. cc::EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) {
  569. return host_->GetScopedEventMetricsMonitor(std::move(done_callback));
  570. }
  571. void Compositor::DidUpdateLayers() {
  572. // Dump property trees and layers if run with:
  573. // --vmodule=*ui/compositor*=3
  574. VLOG(3) << "After updating layers:\n"
  575. << "property trees:\n"
  576. << host_->property_trees()->ToString() << "\n"
  577. << "cc::Layers:\n"
  578. << host_->LayersAsString();
  579. }
  580. void Compositor::BeginMainFrame(const viz::BeginFrameArgs& args) {
  581. DCHECK(!IsLocked());
  582. for (auto& observer : animation_observer_list_)
  583. observer.OnAnimationStep(args.frame_time);
  584. if (!animation_observer_list_.empty())
  585. host_->SetNeedsAnimate();
  586. }
  587. void Compositor::BeginMainFrameNotExpectedSoon() {
  588. }
  589. void Compositor::BeginMainFrameNotExpectedUntil(base::TimeTicks time) {}
  590. static void SendDamagedRectsRecursive(ui::Layer* layer) {
  591. layer->SendDamagedRects();
  592. // Iterate using the size for the case of mutation during sending damaged
  593. // regions. https://crbug.com/1242257.
  594. for (size_t i = 0; i < layer->children().size(); ++i)
  595. SendDamagedRectsRecursive(layer->children()[i]);
  596. }
  597. void Compositor::UpdateLayerTreeHost() {
  598. if (!root_layer())
  599. return;
  600. SendDamagedRectsRecursive(root_layer());
  601. }
  602. void Compositor::RequestNewLayerTreeFrameSink() {
  603. DCHECK(!layer_tree_frame_sink_requested_);
  604. layer_tree_frame_sink_requested_ = true;
  605. if (widget_valid_) {
  606. context_factory_->CreateLayerTreeFrameSink(
  607. context_creation_weak_ptr_factory_.GetWeakPtr());
  608. }
  609. }
  610. void Compositor::DidFailToInitializeLayerTreeFrameSink() {
  611. task_runner_->PostTask(
  612. FROM_HERE,
  613. base::BindOnce(&Compositor::RequestNewLayerTreeFrameSink,
  614. context_creation_weak_ptr_factory_.GetWeakPtr()));
  615. }
  616. void Compositor::DidCommit(base::TimeTicks, base::TimeTicks) {
  617. DCHECK(!IsLocked());
  618. for (auto& observer : observer_list_)
  619. observer.OnCompositingDidCommit(this);
  620. }
  621. std::unique_ptr<cc::BeginMainFrameMetrics>
  622. Compositor::GetBeginMainFrameMetrics() {
  623. #if BUILDFLAG(IS_CHROMEOS)
  624. auto metrics_data = std::make_unique<cc::BeginMainFrameMetrics>();
  625. metrics_data->should_measure_smoothness = true;
  626. return metrics_data;
  627. #else
  628. return nullptr;
  629. #endif
  630. }
  631. std::unique_ptr<cc::WebVitalMetrics> Compositor::GetWebVitalMetrics() {
  632. return nullptr;
  633. }
  634. void Compositor::NotifyThroughputTrackerResults(
  635. cc::CustomTrackerResults results) {
  636. for (auto& pair : results)
  637. ReportMetricsForTracker(pair.first, std::move(pair.second));
  638. }
  639. void Compositor::ReportEventLatency(
  640. std::vector<cc::EventLatencyTracker::LatencyData> latencies) {
  641. // TODO(crbug.com/1321193): Report EventLatency as appropriate.
  642. }
  643. void Compositor::DidReceiveCompositorFrameAck() {
  644. ++activated_frame_count_;
  645. for (auto& observer : observer_list_)
  646. observer.OnCompositingEnded(this);
  647. }
  648. void Compositor::DidPresentCompositorFrame(
  649. uint32_t frame_token,
  650. const gfx::PresentationFeedback& feedback) {
  651. TRACE_EVENT_MARK_WITH_TIMESTAMP1("cc,benchmark", "FramePresented",
  652. feedback.timestamp, "environment",
  653. "browser");
  654. for (auto& observer : observer_list_)
  655. observer.OnDidPresentCompositorFrame(frame_token, feedback);
  656. }
  657. void Compositor::DidSubmitCompositorFrame() {
  658. base::TimeTicks start_time = base::TimeTicks::Now();
  659. for (auto& observer : observer_list_)
  660. observer.OnCompositingStarted(this, start_time);
  661. }
  662. void Compositor::FrameIntervalUpdated(base::TimeDelta interval) {
  663. refresh_rate_ = interval.ToHz();
  664. }
  665. void Compositor::FrameSinksToThrottleUpdated(
  666. const base::flat_set<viz::FrameSinkId>& ids) {
  667. for (auto& observer : observer_list_) {
  668. observer.OnFrameSinksToThrottleUpdated(ids);
  669. }
  670. }
  671. void Compositor::OnFirstSurfaceActivation(
  672. const viz::SurfaceInfo& surface_info) {
  673. NOTREACHED();
  674. }
  675. void Compositor::OnFrameTokenChanged(uint32_t frame_token,
  676. base::TimeTicks activation_time) {
  677. // TODO(yiyix, fsamuel): Implement frame token propagation for Compositor.
  678. NOTREACHED();
  679. }
  680. Compositor::TrackerState::TrackerState() = default;
  681. Compositor::TrackerState::TrackerState(TrackerState&&) = default;
  682. Compositor::TrackerState& Compositor::TrackerState::operator=(TrackerState&&) =
  683. default;
  684. Compositor::TrackerState::~TrackerState() = default;
  685. void Compositor::StartThroughputTracker(
  686. TrackerId tracker_id,
  687. ThroughputTrackerHost::ReportCallback callback) {
  688. DCHECK(!base::Contains(throughput_tracker_map_, tracker_id));
  689. auto& tracker_state = throughput_tracker_map_[tracker_id];
  690. tracker_state.report_callback = std::move(callback);
  691. animation_host_->StartThroughputTracking(tracker_id);
  692. }
  693. bool Compositor::StopThroughtputTracker(TrackerId tracker_id) {
  694. auto it = throughput_tracker_map_.find(tracker_id);
  695. DCHECK(it != throughput_tracker_map_.end());
  696. // Clean up if report has happened since StopThroughputTracking would
  697. // not trigger report in this case.
  698. if (it->second.report_attempted) {
  699. throughput_tracker_map_.erase(it);
  700. return false;
  701. }
  702. it->second.should_report = true;
  703. animation_host_->StopThroughputTracking(tracker_id);
  704. return true;
  705. }
  706. void Compositor::CancelThroughtputTracker(TrackerId tracker_id) {
  707. auto it = throughput_tracker_map_.find(tracker_id);
  708. DCHECK(it != throughput_tracker_map_.end());
  709. const bool should_stop = !it->second.report_attempted;
  710. throughput_tracker_map_.erase(it);
  711. if (should_stop)
  712. animation_host_->StopThroughputTracking(tracker_id);
  713. }
  714. void Compositor::OnResume() {
  715. // Restart the time upon resume.
  716. for (auto& obs : animation_observer_list_)
  717. obs.ResetIfActive();
  718. }
  719. // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
  720. // of lacros-chrome is complete.
  721. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
  722. void Compositor::OnCompleteSwapWithNewSize(const gfx::Size& size) {
  723. for (auto& observer : observer_list_)
  724. observer.OnCompositingCompleteSwapWithNewSize(this, size);
  725. }
  726. #endif
  727. void Compositor::SetOutputIsSecure(bool output_is_secure) {
  728. output_is_secure_ = output_is_secure;
  729. if (display_private_)
  730. display_private_->SetOutputIsSecure(output_is_secure);
  731. }
  732. const cc::LayerTreeDebugState& Compositor::GetLayerTreeDebugState() const {
  733. return host_->GetDebugState();
  734. }
  735. void Compositor::SetLayerTreeDebugState(
  736. const cc::LayerTreeDebugState& debug_state) {
  737. host_->SetDebugState(debug_state);
  738. }
  739. void Compositor::RequestPresentationTimeForNextFrame(
  740. PresentationTimeCallback callback) {
  741. host_->RequestPresentationTimeForNextFrame(std::move(callback));
  742. }
  743. void Compositor::ReportMetricsForTracker(
  744. int tracker_id,
  745. const cc::FrameSequenceMetrics::CustomReportData& data) {
  746. auto it = throughput_tracker_map_.find(tracker_id);
  747. if (it == throughput_tracker_map_.end())
  748. return;
  749. // Set `report_attempted` but not reporting if relevant ThroughputTrackers
  750. // are not stopped and waiting for reports.
  751. if (!it->second.should_report) {
  752. it->second.report_attempted = true;
  753. return;
  754. }
  755. // Callback may modify `throughput_tracker_map_` so update the map first.
  756. // See https://crbug.com/1193382.
  757. auto callback = std::move(it->second.report_callback);
  758. throughput_tracker_map_.erase(it);
  759. std::move(callback).Run(data);
  760. }
  761. void Compositor::SetDelegatedInkPointRenderer(
  762. mojo::PendingReceiver<gfx::mojom::DelegatedInkPointRenderer> receiver) {
  763. if (display_private_)
  764. display_private_->SetDelegatedInkPointRenderer(std::move(receiver));
  765. }
  766. const cc::LayerTreeSettings& Compositor::GetLayerTreeSettings() const {
  767. return host_->GetSettings();
  768. }
  769. } // namespace ui