Add support for updating the browser with the latest HDR and Overlay status

Add an info-update callback function to DirectCompositionSurfaceWin so
the status change of HDR, direct composition or overlay can be
propagated to the browser. The status change could be a result of swap
chain creation failure.

Bug:1089998

Change-Id: If3ca647cf73edbb776b35775dcc7df46ea8b5ba4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2225144
Reviewed-by: Bo <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Zhenyao Mo <[email protected]>
Reviewed-by: ccameron <[email protected]>
Commit-Queue: Maggie Chen <[email protected]>
Cr-Commit-Position: refs/heads/master@{#774541}
diff --git a/components/viz/host/gpu_host_impl.cc b/components/viz/host/gpu_host_impl.cc
index 414ba48b..fc1ab7b 100644
--- a/components/viz/host/gpu_host_impl.cc
+++ b/components/viz/host/gpu_host_impl.cc
@@ -512,6 +512,10 @@
   delegate_->DidUpdateOverlayInfo(overlay_info);
 }
 
+void GpuHostImpl::DidUpdateHDRStatus(bool hdr_enabled) {
+  delegate_->DidUpdateHDRStatus(hdr_enabled);
+}
+
 void GpuHostImpl::SetChildSurface(gpu::SurfaceHandle parent,
                                   gpu::SurfaceHandle child) {
   if (pid_ != base::kNullProcessId) {
diff --git a/components/viz/host/gpu_host_impl.h b/components/viz/host/gpu_host_impl.h
index 6481e8f0e..640814e 100644
--- a/components/viz/host/gpu_host_impl.h
+++ b/components/viz/host/gpu_host_impl.h
@@ -73,6 +73,7 @@
     virtual void MaybeShutdownGpuProcess() = 0;
 #if defined(OS_WIN)
     virtual void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) = 0;
+    virtual void DidUpdateHDRStatus(bool hdr_enabled) = 0;
 #endif
     virtual void BlockDomainFrom3DAPIs(const GURL& url,
                                        gpu::DomainGuilt guilt) = 0;
@@ -231,6 +232,7 @@
   void DisableGpuCompositing() override;
 #if defined(OS_WIN)
   void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) override;
+  void DidUpdateHDRStatus(bool hdr_enabled) override;
   void SetChildSurface(gpu::SurfaceHandle parent,
                        gpu::SurfaceHandle child) override;
 #endif
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index df961f12..98cdbff9 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -405,6 +405,13 @@
   }
 #endif
 
+#if defined(OS_WIN)
+  auto info_callback = base::BindRepeating(
+      &GpuServiceImpl::UpdateOverlayAndHDRInfo, weak_ptr_factory_.GetWeakPtr());
+  gl::DirectCompositionSurfaceWin::SetOverlayHDRGpuInfoUpdateCallback(
+      info_callback);
+#endif
+
   gpu_memory_buffer_factory_ =
       gpu::GpuMemoryBufferFactory::CreateNativeType(vulkan_context_provider());
 
@@ -768,12 +775,12 @@
 void GpuServiceImpl::RequestHDRStatusOnMainThread(
     RequestHDRStatusCallback callback) {
   DCHECK(main_runner_->BelongsToCurrentThread());
-  bool hdr_enabled = false;
+
 #if defined(OS_WIN)
-  hdr_enabled = gl::DirectCompositionSurfaceWin::IsHDRSupported();
+  hdr_enabled_ = gl::DirectCompositionSurfaceWin::IsHDRSupported();
 #endif
   io_runner_->PostTask(FROM_HERE,
-                       base::BindOnce(std::move(callback), hdr_enabled));
+                       base::BindOnce(std::move(callback), hdr_enabled_));
 }
 
 void GpuServiceImpl::RegisterDisplayContext(
@@ -837,6 +844,10 @@
     const gpu::OverlayInfo& overlay_info) {
   gpu_host_->DidUpdateOverlayInfo(gpu_info_.overlay_info);
 }
+
+void GpuServiceImpl::DidUpdateHDRStatus(bool hdr_enabled) {
+  gpu_host_->DidUpdateHDRStatus(hdr_enabled);
+}
 #endif
 
 void GpuServiceImpl::StoreShaderToDisk(int client_id,
@@ -968,12 +979,6 @@
 
   if (!in_host_process())
     ui::GpuSwitchingManager::GetInstance()->NotifyDisplayAdded();
-
-#if defined(OS_WIN)
-  // Update overlay info in the GPU process and send the updated data back to
-  // the GPU host in the Browser process through mojom if the info has changed.
-  UpdateOverlayInfo();
-#endif
 }
 
 void GpuServiceImpl::DisplayRemoved() {
@@ -986,12 +991,6 @@
 
   if (!in_host_process())
     ui::GpuSwitchingManager::GetInstance()->NotifyDisplayRemoved();
-
-#if defined(OS_WIN)
-  // Update overlay info in the GPU process and send the updated data back to
-  // the GPU host in the Browser process through mojom if the info has changed.
-  UpdateOverlayInfo();
-#endif
 }
 
 void GpuServiceImpl::DestroyAllChannels() {
@@ -1141,12 +1140,20 @@
 }
 
 #if defined(OS_WIN)
-void GpuServiceImpl::UpdateOverlayInfo() {
+void GpuServiceImpl::UpdateOverlayAndHDRInfo() {
   gpu::OverlayInfo old_overlay_info = gpu_info_.overlay_info;
   gpu::CollectHardwareOverlayInfo(&gpu_info_.overlay_info);
 
+  // Update overlay info in the GPU process and send the updated data back to
+  // the GPU host in the Browser process through mojom if the info has changed.
   if (old_overlay_info != gpu_info_.overlay_info)
     DidUpdateOverlayInfo(gpu_info_.overlay_info);
+
+  // Update HDR status in the GPU process through the GPU host mojom.
+  bool old_hdr_enabled_status = hdr_enabled_;
+  hdr_enabled_ = gl::DirectCompositionSurfaceWin::IsHDRSupported();
+  if (old_hdr_enabled_status != hdr_enabled_)
+    DidUpdateHDRStatus(hdr_enabled_);
 }
 #endif
 
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h
index 018be6ac..90d68b3 100644
--- a/components/viz/service/gl/gpu_service_impl.h
+++ b/components/viz/service/gl/gpu_service_impl.h
@@ -210,6 +210,7 @@
                       const GURL& active_url) override;
 #if defined(OS_WIN)
   void DidUpdateOverlayInfo(const gpu::OverlayInfo& overlay_info) override;
+  void DidUpdateHDRStatus(bool hdr_enabled) override;
 #endif
   void StoreShaderToDisk(int client_id,
                          const std::string& key,
@@ -342,10 +343,10 @@
   // process. If |for_context_loss| is true an error message will be logged.
   void MaybeExit(bool for_context_loss);
 
-  // Update overlay info on the GPU process and send the updated info back
-  // to the browser process if there is a change.
+  // Update overlay info and HDR status on the GPU process and send the updated
+  // info back to the browser process if there is a change.
 #if defined(OS_WIN)
-  void UpdateOverlayInfo();
+  void UpdateOverlayAndHDRInfo();
 #endif
 
   scoped_refptr<base::SingleThreadTaskRunner> main_runner_;
@@ -363,6 +364,8 @@
   // Information about general chrome feature support for the GPU.
   gpu::GpuFeatureInfo gpu_feature_info_;
 
+  bool hdr_enabled_ = false;
+
   // What we would have gotten if we haven't fallen back to SwiftShader or
   // pure software (in the viz case).
   base::Optional<gpu::GPUInfo> gpu_info_for_hardware_gpu_;