Skip to content

Commit

Permalink
Add checking for RGB10A2 overlay support
Browse files Browse the repository at this point in the history
RGB10A2 overlay could be used for displaying HDR content. In some latest
Intel platform, RGB10A2 overlay is supported.

This CL adds caps checking, displays related info. in chrome://gpu

Bug: 1062184
Change-Id: I4f5d5e22ca3088c4ba3ae2a0c099fab4651a7ce7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2242971
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Maggie Chen <magchen@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Richard Li <richard.li@intel.com>
Cr-Commit-Position: refs/heads/master@{#781696}
  • Loading branch information
RRRichardLi authored and Commit Bot committed Jun 24, 2020
1 parent d94b35c commit 53909ca
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 16 deletions.
8 changes: 8 additions & 0 deletions content/browser/gpu/gpu_internals_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ std::unique_ptr<base::ListValue> BasicGpuInfoAsListValue(
basic_info->Append(NewDescriptionValuePair(
"NV12 overlay support",
gpu::OverlaySupportToString(gpu_info.overlay_info.nv12_overlay_support)));
basic_info->Append(NewDescriptionValuePair(
"BGRA8 overlay support",
gpu::OverlaySupportToString(
gpu_info.overlay_info.bgra8_overlay_support)));
basic_info->Append(NewDescriptionValuePair(
"RGB10A2 overlay support",
gpu::OverlaySupportToString(
gpu_info.overlay_info.rgb10a2_overlay_support)));

std::vector<gfx::PhysicalDisplaySize> display_sizes =
gfx::GetPhysicalSizeForDisplays();
Expand Down
6 changes: 5 additions & 1 deletion gpu/config/gpu_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ struct GPU_EXPORT OverlayInfo {
return direct_composition == other.direct_composition &&
supports_overlays == other.supports_overlays &&
yuy2_overlay_support == other.yuy2_overlay_support &&
nv12_overlay_support == other.nv12_overlay_support;
nv12_overlay_support == other.nv12_overlay_support &&
bgra8_overlay_support == other.bgra8_overlay_support &&
rgb10a2_overlay_support == other.rgb10a2_overlay_support;
}
bool operator!=(const OverlayInfo& other) const { return !(*this == other); }

Expand All @@ -208,6 +210,8 @@ struct GPU_EXPORT OverlayInfo {
bool supports_overlays = false;
OverlaySupport yuy2_overlay_support = OverlaySupport::kNone;
OverlaySupport nv12_overlay_support = OverlaySupport::kNone;
OverlaySupport bgra8_overlay_support = OverlaySupport::kNone;
OverlaySupport rgb10a2_overlay_support = OverlaySupport::kNone;
};

#endif
Expand Down
8 changes: 8 additions & 0 deletions gpu/config/gpu_info_collector_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ void CollectHardwareOverlayInfo(OverlayInfo* overlay_info) {
overlay_info->supports_overlays,
gl::DirectCompositionSurfaceWin::GetOverlaySupportFlags(
DXGI_FORMAT_YUY2));
overlay_info->bgra8_overlay_support = FlagsToOverlaySupport(
overlay_info->supports_overlays,
gl::DirectCompositionSurfaceWin::GetOverlaySupportFlags(
DXGI_FORMAT_B8G8R8A8_UNORM));
overlay_info->rgb10a2_overlay_support = FlagsToOverlaySupport(
overlay_info->supports_overlays,
gl::DirectCompositionSurfaceWin::GetOverlaySupportFlags(
DXGI_FORMAT_R10G10B10A2_UNORM));
}
}

Expand Down
2 changes: 2 additions & 0 deletions gpu/ipc/common/gpu_info.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ struct OverlayInfo {
bool supports_overlays;
OverlaySupport yuy2_overlay_support;
OverlaySupport nv12_overlay_support;
OverlaySupport bgra8_overlay_support;
OverlaySupport rgb10a2_overlay_support;
};

// Corresponds to |gpu::GPUInfo| in gpu/config/gpu_info.h
Expand Down
4 changes: 3 additions & 1 deletion gpu/ipc/common/gpu_info_mojom_traits.cc
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,9 @@ bool StructTraits<gpu::mojom::OverlayInfoDataView, gpu::OverlayInfo>::Read(
out->direct_composition = data.direct_composition();
out->supports_overlays = data.supports_overlays();
return data.ReadYuy2OverlaySupport(&out->yuy2_overlay_support) &&
data.ReadNv12OverlaySupport(&out->nv12_overlay_support);
data.ReadNv12OverlaySupport(&out->nv12_overlay_support) &&
data.ReadBgra8OverlaySupport(&out->bgra8_overlay_support) &&
data.ReadRgb10a2OverlaySupport(&out->rgb10a2_overlay_support);
}
#endif

Expand Down
10 changes: 10 additions & 0 deletions gpu/ipc/common/gpu_info_mojom_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,16 @@ struct StructTraits<gpu::mojom::OverlayInfoDataView, gpu::OverlayInfo> {
const gpu::OverlayInfo& input) {
return input.nv12_overlay_support;
}

static gpu::OverlaySupport bgra8_overlay_support(
const gpu::OverlayInfo& input) {
return input.bgra8_overlay_support;
}

static gpu::OverlaySupport rgb10a2_overlay_support(
const gpu::OverlayInfo& input) {
return input.rgb10a2_overlay_support;
}
};

#endif
Expand Down
91 changes: 77 additions & 14 deletions ui/gl/direct_composition_surface_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ void SetOverlayCapsValid(bool valid) {
base::AutoLock auto_lock(GetOverlayLock());
g_overlay_caps_valid = valid;
}
// A warpper of IDXGIOutput4::CheckOverlayColorSpaceSupport()
bool CheckOverlayColorSpaceSupport(
DXGI_FORMAT dxgi_format,
DXGI_COLOR_SPACE_TYPE dxgi_color_space,
Microsoft::WRL::ComPtr<IDXGIOutput> output,
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device) {
UINT color_space_support_flags = 0;
Microsoft::WRL::ComPtr<IDXGIOutput4> output4;
if (FAILED(output.As(&output4)) ||
FAILED(output4->CheckOverlayColorSpaceSupport(
dxgi_format, dxgi_color_space, d3d11_device.Get(),
&color_space_support_flags)))
return false;
return (color_space_support_flags &
DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG_PRESENT);
}

// Used for workaround limiting overlay size to monitor size.
gfx::Size g_overlay_monitor_size;
Expand All @@ -74,11 +90,14 @@ DirectCompositionSurfaceWin::OverlayHDRInfoUpdateCallback
// initialization. Set to NV12 by default so that it's used when enabling
// overlays using command line flags.
DXGI_FORMAT g_overlay_format_used = DXGI_FORMAT_NV12;
DXGI_FORMAT g_overlay_format_used_hdr = DXGI_FORMAT_UNKNOWN;

// These are the raw support info, which shouldn't depend on field trial state,
// or command line flags.
UINT g_nv12_overlay_support_flags = 0;
UINT g_yuy2_overlay_support_flags = 0;
UINT g_bgra8_overlay_support_flags = 0;
UINT g_rgb10a2_overlay_support_flags = 0;

bool FlagsSupportsOverlays(UINT flags) {
return (flags & (DXGI_OVERLAY_SUPPORT_FLAG_DIRECT |
Expand All @@ -87,14 +106,20 @@ bool FlagsSupportsOverlays(UINT flags) {

void GetGpuDriverOverlayInfo(bool* supports_overlays,
DXGI_FORMAT* overlay_format_used,
DXGI_FORMAT* overlay_format_used_hdr,
UINT* nv12_overlay_support_flags,
UINT* yuy2_overlay_support_flags,
UINT* bgra8_overlay_support_flags,
UINT* rgb10a2_overlay_support_flags,
gfx::Size* overlay_monitor_size) {
// Initialization
*supports_overlays = false;
*overlay_format_used = DXGI_FORMAT_NV12;
*overlay_format_used_hdr = DXGI_FORMAT_R10G10B10A2_UNORM;
*nv12_overlay_support_flags = 0;
*yuy2_overlay_support_flags = 0;
*bgra8_overlay_support_flags = 0;
*rgb10a2_overlay_support_flags = 0;
*overlay_monitor_size = gfx::Size();

// Check for DirectComposition support first to prevent likely crashes.
Expand Down Expand Up @@ -146,6 +171,13 @@ void GetGpuDriverOverlayInfo(bool* supports_overlays,
nv12_overlay_support_flags);
output3->CheckOverlaySupport(DXGI_FORMAT_YUY2, d3d11_device.Get(),
yuy2_overlay_support_flags);
output3->CheckOverlaySupport(DXGI_FORMAT_B8G8R8A8_UNORM, d3d11_device.Get(),
bgra8_overlay_support_flags);
// Today it still returns false, which blocks Chrome from using HDR
// overlays.
output3->CheckOverlaySupport(DXGI_FORMAT_R10G10B10A2_UNORM,
d3d11_device.Get(),
rgb10a2_overlay_support_flags);
if (FlagsSupportsOverlays(*nv12_overlay_support_flags) &&
base::FeatureList::IsEnabled(
features::kDirectCompositionPreferNV12Overlays)) {
Expand All @@ -155,14 +187,9 @@ void GetGpuDriverOverlayInfo(bool* supports_overlays,
// COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709 is also supported. Rec 709 is
// commonly used for H.264 and HEVC. At least one Intel Gen9 SKU will not
// support NV12 overlays.
UINT color_space_support_flags = 0;
Microsoft::WRL::ComPtr<IDXGIOutput4> output4;
if (SUCCEEDED(output.As(&output4)) &&
SUCCEEDED(output4->CheckOverlayColorSpaceSupport(
if (CheckOverlayColorSpaceSupport(
DXGI_FORMAT_NV12, DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709,
d3d11_device.Get(), &color_space_support_flags)) &&
(color_space_support_flags &
DXGI_OVERLAY_COLOR_SPACE_SUPPORT_FLAG_PRESENT)) {
output, d3d11_device)) {
// Some new Intel drivers only claim to support unscaled overlays, but
// scaled overlays still work. It's possible DWM works around it by
// performing an extra scaling Blt before calling the driver. Even when
Expand All @@ -185,6 +212,15 @@ void GetGpuDriverOverlayInfo(bool* supports_overlays,
gfx::Rect(monitor_desc.DesktopCoordinates).size();
}
}
// RGB10A2 overlay is used for displaying HDR content. In Intel's
// platform, RGB10A2 overlay is enabled only when
// DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 is supported.
if (FlagsSupportsOverlays(*rgb10a2_overlay_support_flags)) {
if (!CheckOverlayColorSpaceSupport(
DXGI_FORMAT_R10G10B10A2_UNORM,
DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020, output, d3d11_device))
*rgb10a2_overlay_support_flags = 0;
}

// Early out after the first output that reports overlay support. All
// outputs are expected to report the same overlay support according to
Expand All @@ -205,6 +241,8 @@ void GetGpuDriverOverlayInfo(bool* supports_overlays,
*supports_overlays = true;
*nv12_overlay_support_flags = 0;
*yuy2_overlay_support_flags = 0;
*bgra8_overlay_support_flags = 0;
*rgb10a2_overlay_support_flags = 0;

// Software overlays always use NV12 because it's slightly more efficient and
// YUY2 was only used because Skylake doesn't support NV12 hardware overlays.
Expand All @@ -222,13 +260,18 @@ void UpdateOverlaySupport() {

bool supports_overlays = false;
DXGI_FORMAT overlay_format_used = DXGI_FORMAT_NV12;
DXGI_FORMAT overlay_format_used_hdr = DXGI_FORMAT_R10G10B10A2_UNORM;
UINT nv12_overlay_support_flags = 0;
UINT yuy2_overlay_support_flags = 0;
UINT bgra8_overlay_support_flags = 0;
UINT rgb10a2_overlay_support_flags = 0;
gfx::Size overlay_monitor_size = gfx::Size();

GetGpuDriverOverlayInfo(&supports_overlays, &overlay_format_used,
&nv12_overlay_support_flags,
&yuy2_overlay_support_flags, &overlay_monitor_size);
GetGpuDriverOverlayInfo(
&supports_overlays, &overlay_format_used, &overlay_format_used_hdr,
&nv12_overlay_support_flags, &yuy2_overlay_support_flags,
&bgra8_overlay_support_flags, &rgb10a2_overlay_support_flags,
&overlay_monitor_size);

if (supports_overlays != SupportsOverlays() ||
overlay_format_used != g_overlay_format_used) {
Expand All @@ -244,8 +287,11 @@ void UpdateOverlaySupport() {
// Update global caps
SetSupportsOverlays(supports_overlays);
g_overlay_format_used = overlay_format_used;
g_overlay_format_used_hdr = overlay_format_used_hdr;
g_nv12_overlay_support_flags = nv12_overlay_support_flags;
g_yuy2_overlay_support_flags = yuy2_overlay_support_flags;
g_bgra8_overlay_support_flags = bgra8_overlay_support_flags;
g_rgb10a2_overlay_support_flags = rgb10a2_overlay_support_flags;
g_overlay_monitor_size = overlay_monitor_size;
}

Expand Down Expand Up @@ -417,10 +463,25 @@ bool DirectCompositionSurfaceWin::AreScaledOverlaysSupported() {
// static
UINT DirectCompositionSurfaceWin::GetOverlaySupportFlags(DXGI_FORMAT format) {
UpdateOverlaySupport();
if (format == DXGI_FORMAT_NV12)
return g_nv12_overlay_support_flags;
DCHECK_EQ(DXGI_FORMAT_YUY2, format);
return g_yuy2_overlay_support_flags;
UINT support_flag = 0;
switch (format) {
case DXGI_FORMAT_NV12:
support_flag = g_nv12_overlay_support_flags;
break;
case DXGI_FORMAT_YUY2:
support_flag = g_yuy2_overlay_support_flags;
break;
case DXGI_FORMAT_B8G8R8A8_UNORM:
support_flag = g_bgra8_overlay_support_flags;
break;
case DXGI_FORMAT_R10G10B10A2_UNORM:
support_flag = g_rgb10a2_overlay_support_flags;
break;
default:
NOTREACHED();
break;
}
return support_flag;
}

// static
Expand All @@ -440,9 +501,11 @@ void DirectCompositionSurfaceWin::SetScaledOverlaysSupportedForTesting(
if (supported) {
g_nv12_overlay_support_flags |= DXGI_OVERLAY_SUPPORT_FLAG_SCALING;
g_yuy2_overlay_support_flags |= DXGI_OVERLAY_SUPPORT_FLAG_SCALING;
g_rgb10a2_overlay_support_flags |= DXGI_OVERLAY_SUPPORT_FLAG_SCALING;
} else {
g_nv12_overlay_support_flags &= ~DXGI_OVERLAY_SUPPORT_FLAG_SCALING;
g_yuy2_overlay_support_flags &= ~DXGI_OVERLAY_SUPPORT_FLAG_SCALING;
g_rgb10a2_overlay_support_flags &= ~DXGI_OVERLAY_SUPPORT_FLAG_SCALING;
}
DCHECK_EQ(supported, AreScaledOverlaysSupported());
}
Expand Down

0 comments on commit 53909ca

Please sign in to comment.