From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Michal Pichlinski <michal.pichlinski@openfin.co>
Date: Thu, 15 Jun 2023 23:04:48 +0200
Subject: allow disabling throttling in the `viz::DisplayScheduler` per
 `ui::Compositor`

In Chromium when the `viz::DisplayScheduler` is invisible it throttles
its work by dropping frame draws and swaps.

This patch allows disbling this throttling by preventing transition to
invisible state of the `viz::DisplayScheduler` owned
by the `ui::Compositor`.

diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index 1cb8ea92e46ad45cd8bf9e99f38889964b16768f..3e80241add13eeeb3b5970932f23acec0d91fd4e 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -358,7 +358,8 @@ void Compositor::SetLayerTreeFrameSink(
   if (display_private_) {
     disabled_swap_until_resize_ = false;
     display_private_->Resize(size());
-    display_private_->SetDisplayVisible(host_->IsVisible());
+    // Invisible display is throttling itself.
+    display_private_->SetDisplayVisible(background_throttling_ ? host_->IsVisible() : true);
     display_private_->SetDisplayColorSpaces(display_color_spaces_);
     display_private_->SetDisplayColorMatrix(
         gfx::SkM44ToTransform(display_color_matrix_));
@@ -609,7 +610,9 @@ void Compositor::SetVisible(bool visible) {
   // updated then. We need to call this even if the visibility hasn't changed,
   // for the same reason.
   if (display_private_)
-    display_private_->SetDisplayVisible(visible);
+    // Invisible display is throttling itself.
+    display_private_->SetDisplayVisible(
+        background_throttling_ ? visible : true);
 
   if (changed) {
     observer_list_.Notify(&CompositorObserver::OnCompositorVisibilityChanged,
@@ -1073,6 +1076,15 @@ void Compositor::MaybeUpdateObserveBeginFrame() {
       host_begin_frame_observer_->GetBoundRemote());
 }
 
+void Compositor::SetBackgroundThrottling(bool background_throttling_enabled) {
+  background_throttling_ = background_throttling_enabled;
+  if (display_private_) {
+    // Invisible display is throttling itself.
+    display_private_->SetDisplayVisible(
+        background_throttling_ ? host_->IsVisible() : true);
+  }
+}
+
 #if BUILDFLAG(IS_CHROMEOS)
 void Compositor::SetSeamlessRefreshRates(
     const std::vector<float>& seamless_refresh_rates) {
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index 682b23f083eff17bc36cdc4698e35d853beb90cc..df9e598b65594748d59284e1e91d61233eef83a0 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -514,6 +514,10 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
 
   const cc::LayerTreeSettings& GetLayerTreeSettings() const;
 
+  // Sets |background_throttling_| responsible for suspending drawing
+  // and switching frames.
+  void SetBackgroundThrottling(bool background_throttling_enabled);
+
   size_t saved_events_metrics_count_for_testing() const {
     return host_->saved_events_metrics_count_for_testing();
   }
@@ -724,6 +728,12 @@ class COMPOSITOR_EXPORT Compositor : public base::PowerSuspendObserver,
   // See go/report-ux-metrics-at-painting for details.
   bool animation_started_ = false;
 
+  // Background throttling is a default Chromium behaviour. It occurs
+  // when the |display_private_| is not visible by prevent drawing and swapping
+  // frames. When it is disabled we are keeping |display_private_| always
+  // visible in order to keep generating frames.
+  bool background_throttling_ = true;
+
   TrackerId next_compositor_metrics_tracker_id_ = 1u;
   struct TrackerState {
     TrackerState();
