Bug 1764201 Part 2: Make Gecko_MediaFeatures_VideoDynamicRange check per-screen HDR. r=emilio

This makes all platforms report video-dynamic-range:high if the screen
most closely associated with the document (according to the logic of
nsDeviceContext::FindScreen) is HDR capable.

This removes the LookAndFeel id for VideoDynamicRange, since it is only
used by Gecko_MediaFeatures_VideoDynamicRange, which is being modified
here to use the nsDeviceContext instead.

It also removes gfxPlatform::supportsHDR and its implementations, as it
is no longer used.

Differential Revision: https://phabricator.services.mozilla.com/D203329
This commit is contained in:
Brad Werth 2024-03-22 00:55:47 +00:00
Родитель 2f4d447f5f
Коммит 8f132a9e95
14 изменённых файлов: 42 добавлений и 102 удалений

Просмотреть файл

@ -208,6 +208,16 @@ uint16_t nsDeviceContext::GetScreenOrientationAngle() {
return screen->GetOrientationAngle();
}
bool nsDeviceContext::GetScreenIsHDR() {
RefPtr<widget::Screen> screen = FindScreen();
if (!screen) {
auto& screenManager = ScreenManager::GetSingleton();
screen = screenManager.GetPrimaryScreen();
MOZ_ASSERT(screen);
}
return screen->GetIsHDR();
}
nsresult nsDeviceContext::GetDeviceSurfaceDimensions(nscoord& aWidth,
nscoord& aHeight) {
if (IsPrinterContext()) {

Просмотреть файл

@ -149,6 +149,11 @@ class nsDeviceContext final {
*/
uint16_t GetScreenOrientationAngle();
/**
* Get the status of HDR support of the associated screen.
*/
bool GetScreenIsHDR();
/**
* Get the size of the displayable area of the output device
* in app units.

Просмотреть файл

@ -1064,6 +1064,13 @@ void gfxPlatform::ReportTelemetry() {
mozilla::glean::gfx_display::count.Set(screenCount);
mozilla::glean::gfx_display::primary_height.Set(rect.Height());
mozilla::glean::gfx_display::primary_width.Set(rect.Width());
// Check if any screen known by screenManager supports HDR.
bool supportsHDR = false;
for (const auto& screen : screenManager.CurrentScreenList()) {
supportsHDR |= screen->GetIsHDR();
}
Telemetry::ScalarSet(Telemetry::ScalarID::GFX_SUPPORTS_HDR, supportsHDR);
}
nsString adapterDesc;
@ -1120,10 +1127,6 @@ void gfxPlatform::ReportTelemetry() {
NS_ConvertUTF16toUTF8(adapterDriverDate));
mozilla::glean::gfx_status::headless.Set(IsHeadless());
MOZ_ASSERT(gPlatform, "Need gPlatform to generate some telemetry.");
Telemetry::ScalarSet(Telemetry::ScalarID::GFX_SUPPORTS_HDR,
gPlatform->SupportsHDR());
}
static bool IsFeatureSupported(long aFeature, bool aDefault) {

Просмотреть файл

@ -811,8 +811,6 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
static bool UseDesktopZoomingScrollbars();
virtual bool SupportsHDR() { return false; }
protected:
gfxPlatform();
virtual ~gfxPlatform();

Просмотреть файл

@ -965,27 +965,6 @@ gfxPlatformMac::CreateGlobalHardwareVsyncSource() {
#endif
}
bool gfxPlatformMac::SupportsHDR() {
// HDR has 3 requirements:
// 1) high peak brightness
// 2) high contrast ratio
// 3) color depth > 24
if (GetScreenDepth() <= 24) {
return false;
}
#ifdef MOZ_WIDGET_UIKIT
return false;
#elif defined(EARLY_BETA_OR_EARLIER)
// Screen is capable. Is the OS capable?
// More-or-less supported in Catalina.
return true;
#else
// Definitely supported in Big Sur.
return nsCocoaFeatures::OnBigSurOrLater();
#endif
}
nsTArray<uint8_t> gfxPlatformMac::GetPlatformCMSOutputProfileData() {
nsTArray<uint8_t> prefProfileData = GetPrefCMSOutputProfileData();
if (!prefProfileData.IsEmpty()) {

Просмотреть файл

@ -76,8 +76,6 @@ class gfxPlatformMac : public gfxPlatform {
static bool CheckVariationFontSupport();
bool SupportsHDR() override;
protected:
bool AccelerateLayersByDefault() override;

Просмотреть файл

@ -259,8 +259,7 @@ class D3DSharedTexturesReporter final : public nsIMemoryReporter {
NS_IMPL_ISUPPORTS(D3DSharedTexturesReporter, nsIMemoryReporter)
gfxWindowsPlatform::gfxWindowsPlatform()
: mRenderMode(RENDER_GDI), mSupportsHDR(false) {
gfxWindowsPlatform::gfxWindowsPlatform() : mRenderMode(RENDER_GDI) {
// If win32k is locked down then we can't use COM STA and shouldn't need it.
// Also, we won't be using any GPU memory in this process.
if (!IsWin32kLockedDown()) {
@ -401,7 +400,6 @@ void gfxWindowsPlatform::InitAcceleration() {
// CanUseHardwareVideoDecoding depends on DeviceManagerDx state,
// so update the cached value now.
UpdateCanUseHardwareVideoDecoding();
UpdateSupportsHDR();
// Our ScreenHelperWin also depends on DeviceManagerDx state.
if (XRE_IsParentProcess() && !gfxPlatform::IsHeadless()) {
@ -537,53 +535,6 @@ void gfxWindowsPlatform::UpdateRenderMode() {
}
}
void gfxWindowsPlatform::UpdateSupportsHDR() {
// TODO: This function crashes content processes, for reasons that are not
// obvious from the crash reports. For now, this function can only be executed
// by the parent process. Therefore SupportsHDR() will always return false for
// content processes, as noted in the header.
if (!XRE_IsParentProcess()) {
return;
}
// Set mSupportsHDR to true if any of the DeviceManager outputs have a BT2020
// colorspace with EOTF2084 gamma curve, this indicates the system is sending
// an HDR format to at least one monitor. The colorspace returned by DXGI is
// very vague - we only see DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 for HDR
// and DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 for SDR modes, even if the
// monitor is using something like YCbCr444 according to Settings
// (System -> Display Settings -> Advanced Display). To get more specific
// info we would need to query the DISPLAYCONFIG values in WinGDI.
//
// Note that the bit depth used to be checked here, but as of Windows 11 22H2,
// HDR is supported with 8bpc for lower bandwidth, where DWM converts to
// dithered RGB8 rather than RGB10, which doesn't really matter here.
//
// This only returns true if there is an HDR display connected at app start,
// if the user switches to HDR to watch a video, we won't know that here, and
// if no displays are connected we return false (e.g. if Windows Update
// restarted a laptop with its lid closed and no external displays, we will
// see zero outputs here when the app is restarted automatically).
//
// It would be better to track if HDR is ever used and report that telemetry
// so we know if HDR matters, not just when it is detected at app start.
//
// Further reading:
// https://learn.microsoft.com/en-us/windows/win32/direct3darticles/high-dynamic-range
// https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-displayconfig_sdr_white_level
DeviceManagerDx* dx = DeviceManagerDx::Get();
nsTArray<DXGI_OUTPUT_DESC1> outputs = dx->EnumerateOutputs();
for (auto& output : outputs) {
if (output.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) {
mSupportsHDR = true;
return;
}
}
mSupportsHDR = false;
}
mozilla::gfx::BackendType gfxWindowsPlatform::GetContentBackendFor(
mozilla::layers::LayersBackend aLayers) {
mozilla::gfx::BackendType defaultBackend =

Просмотреть файл

@ -193,9 +193,6 @@ class gfxWindowsPlatform final : public gfxPlatform {
static bool CheckVariationFontSupport();
// Always false for content processes.
bool SupportsHDR() override { return mSupportsHDR; }
protected:
bool AccelerateLayersByDefault() override { return true; }
@ -214,10 +211,7 @@ class gfxWindowsPlatform final : public gfxPlatform {
BackendPrefsData GetBackendPrefs() const override;
void UpdateSupportsHDR();
RenderMode mRenderMode;
bool mSupportsHDR;
private:
void Init();

Просмотреть файл

@ -336,18 +336,20 @@ StyleDynamicRange Gecko_MediaFeatures_DynamicRange(const Document* aDocument) {
StyleDynamicRange Gecko_MediaFeatures_VideoDynamicRange(
const Document* aDocument) {
if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSVideoDynamicRange)) {
if (aDocument->ShouldResistFingerprinting(RFPTarget::CSSVideoDynamicRange) ||
!StaticPrefs::layout_css_video_dynamic_range_allows_high()) {
return StyleDynamicRange::Standard;
}
// video-dynamic-range: high has 3 requirements:
// 1) high peak brightness
// 2) high contrast ratio
// 3) color depth > 24
// We check the color depth requirement before asking the LookAndFeel
// if it is HDR capable.
// As a proxy for those requirements, return 'High' if the screen associated
// with the device context claims to be HDR capable.
if (nsDeviceContext* dx = GetDeviceContextFor(aDocument)) {
if (dx->GetDepth() > 24 &&
LookAndFeel::GetInt(LookAndFeel::IntID::VideoDynamicRange)) {
if (dx->GetScreenIsHDR()) {
// bjw
return StyleDynamicRange::High;
}
}

Просмотреть файл

@ -9396,6 +9396,16 @@
mirror: always
rust: true
# Is matching video-dynamic-range: high allowed?
- name: layout.css.video-dynamic-range.allows-high
type: RelaxedAtomicBool
#if defined(XP_MACOSX) || defined(NIGHTLY_BUILD)
value: true
#else
value: false
#endif
mirror: always
# Whether frame visibility tracking is enabled globally.
- name: layout.framevisibility.enabled
type: bool

Просмотреть файл

@ -57,8 +57,6 @@ int MaxTouchPoints() {
// ==================================================================
void PopulateCSSProperties() {
glean::characteristics::video_dynamic_range.Set(
LookAndFeel::GetInt(LookAndFeel::IntID::VideoDynamicRange));
glean::characteristics::prefers_reduced_transparency.Set(
LookAndFeel::GetInt(LookAndFeel::IntID::PrefersReducedTransparency));
glean::characteristics::prefers_reduced_motion.Set(
@ -110,6 +108,8 @@ void PopulateScreenProperties() {
const LayoutDeviceIntRect rect = screen->GetRect();
glean::characteristics::screen_height.Set(rect.Height());
glean::characteristics::screen_width.Set(rect.Width());
glean::characteristics::video_dynamic_range.Set(screen->GetIsHDR());
}
void PopulateMissingFonts() {

Просмотреть файл

@ -300,7 +300,6 @@ class LookAndFeel {
* 1: High
*/
DynamicRange,
VideoDynamicRange,
/** Whether XUL panel animations are enabled. */
PanelAnimations,

Просмотреть файл

@ -469,14 +469,6 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
aResult = NSWorkspace.sharedWorkspace
.accessibilityDisplayShouldIncreaseContrast;
break;
case IntID::VideoDynamicRange: {
// If the platform says it supports HDR, then we claim to support
// video-dynamic-range.
gfxPlatform* platform = gfxPlatform::GetPlatform();
MOZ_ASSERT(platform);
aResult = platform->SupportsHDR();
break;
}
case IntID::PanelAnimations:
aResult = 1;
break;

Просмотреть файл

@ -187,7 +187,6 @@ static const char sIntPrefs[][45] = {
"ui.titlebarRadius",
"ui.titlebarButtonSpacing",
"ui.dynamicRange",
"ui.videoDynamicRange",
"ui.panelAnimations",
"ui.hideCursorWhileTyping",
"ui.gtkThemeFamily",