From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: reito <cnschwarzer@qq.com>
Date: Thu, 15 Aug 2024 14:05:52 +0800
Subject: Remove DXGI GMB keyed-mutex

This patch removes the keyed mutex of the d3d11 texture only when the texture is requested by offscreen rendering and on Windows.

The keyed mutex introduce extra performance cost and spikes. However, at offscreen rendering scenario, the shared resources will not be simultaneously read from & written to, typically just one reader, so it doesn't need such exclusive guarantee, and it's safe to remove this mutex for extra performance gain.

For resolving complex conflict please pin @reitowo
For more reason please see: https://crrev.com/c/5465148

diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
index 31543b5b018313d2e5890f599109bd48d7bc5e64..2f4003b0557ae275ee3697062fafb6428f5da010 100644
--- a/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
+++ b/gpu/ipc/service/gpu_memory_buffer_factory_dxgi.cc
@@ -166,7 +166,8 @@ gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateNativeGmbHandle(
   // so make sure that the usage is one that we support.
   DCHECK(usage == gfx::BufferUsage::GPU_READ ||
          usage == gfx::BufferUsage::SCANOUT ||
-         usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE)
+         usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE ||
+         usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ)
       << "Incorrect usage, usage=" << gfx::BufferUsageToString(usage);
 
   D3D11_TEXTURE2D_DESC desc = {
@@ -180,7 +181,9 @@ gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateNativeGmbHandle(
       D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET,
       0,
       D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
-          D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX};
+          static_cast<UINT>(usage == gfx::BufferUsage::SCANOUT_VEA_CPU_READ
+                                ? D3D11_RESOURCE_MISC_SHARED
+                                : D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)};
 
   Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture;
 
diff --git a/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc b/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
index 46c48aa7d08b336f577f81163bf4cc0596a0b2fb..c1098fbc5ea57031f2e153379ae0baaddd3bbe5f 100644
--- a/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
+++ b/media/video/renderable_gpu_memory_buffer_video_frame_pool.cc
@@ -182,7 +182,7 @@ bool FrameResources::Initialize(VideoPixelFormat format,
 
   auto* context = pool_->GetContext();
 
-  constexpr gfx::BufferUsage kBufferUsage =
+  gfx::BufferUsage buffer_usage =
 #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
       gfx::BufferUsage::SCANOUT_VEA_CPU_READ
 #else
@@ -193,6 +193,23 @@ bool FrameResources::Initialize(VideoPixelFormat format,
   const gfx::Size coded_size =
       GetCodedSizeForVideoPixelFormat(format, visible_size_);
 
+#if BUILDFLAG(IS_WIN)
+  // For CEF OSR feature, currently there's no other place in chromium use RGBA.
+  // If the format is RGBA, currently CEF do not write to the texture anymore
+  // once the GMB is returned from CopyRequest. So there will be no race
+  // condition on that texture. We can request a GMB without a keyed mutex to
+  // accelerate and probably prevent some driver deadlock.
+  if (format == PIXEL_FORMAT_ARGB || format == PIXEL_FORMAT_ABGR) {
+    // This value is 'borrowed', SCANOUT_VEA_CPU_READ is probably invalid
+    // cause there's no real SCANOUT on Windows. We simply use this enum as a
+    // flag to disable mutex in the GMBFactoryDXGI because this enum is also
+    // used above in macOS and CrOS for similar usage (claim no other one will
+    // concurrently use the resource).
+    // https://chromium-review.googlesource.com/c/chromium/src/+/5302103
+    buffer_usage = gfx::BufferUsage::SCANOUT_VEA_CPU_READ;
+  }
+#endif
+
   gpu::SharedImageUsageSet usage =
 #if BUILDFLAG(IS_MAC)
       gpu::SHARED_IMAGE_USAGE_MACOS_VIDEO_TOOLBOX |
@@ -230,7 +247,7 @@ bool FrameResources::Initialize(VideoPixelFormat format,
       VideoPixelFormatToSharedImageFormat(format).value();
 
   shared_image_ = context->CreateSharedImage(
-      coded_size, kBufferUsage, si_format, color_space, usage, sync_token_);
+      coded_size, buffer_usage, si_format, color_space, usage, sync_token_);
   if (!shared_image_) {
     DLOG(ERROR) << "Failed to allocate shared image for frame: visible_size="
                 << visible_size_.ToString()
