diff --git a/gfx/config/gfxConfigManager.cpp b/gfx/config/gfxConfigManager.cpp index 1b48c5fd92e1..b4b7bb23d3b5 100644 --- a/gfx/config/gfxConfigManager.cpp +++ b/gfx/config/gfxConfigManager.cpp @@ -80,6 +80,7 @@ void gfxConfigManager::Init() { mFeatureWrAngle = &gfxConfig::GetFeature(Feature::WEBRENDER_ANGLE); mFeatureWrDComp = &gfxConfig::GetFeature(Feature::WEBRENDER_DCOMP_PRESENT); mFeatureWrPartial = &gfxConfig::GetFeature(Feature::WEBRENDER_PARTIAL); + mFeatureWrSoftware = &gfxConfig::GetFeature(Feature::WEBRENDER_SOFTWARE); mFeatureHwCompositing = &gfxConfig::GetFeature(Feature::HW_COMPOSITING); #ifdef XP_WIN @@ -113,6 +114,45 @@ void gfxConfigManager::ConfigureFromBlocklist(long aFeature, } } +void gfxConfigManager::ConfigureWebRenderSoftware() { + MOZ_ASSERT(mFeatureWrSoftware); + + mFeatureWrSoftware->EnableByDefault(); + + if (StaticPrefs::gfx_webrender_software_AtStartup()) { + mFeatureWrSoftware->UserForceEnable("Force enabled by pref"); + } + + nsCString failureId; + int32_t status; + if (NS_FAILED(mGfxInfo->GetFeatureStatus( + nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE, failureId, &status))) { + mFeatureWrSoftware->Disable(FeatureStatus::BlockedNoGfxInfo, + "gfxInfo is broken", + "FEATURE_FAILURE_WR_NO_GFX_INFO"_ns); + return; + } + + switch (status) { + case nsIGfxInfo::FEATURE_ALLOW_ALWAYS: + case nsIGfxInfo::FEATURE_ALLOW_QUALIFIED: + break; + case nsIGfxInfo::FEATURE_DENIED: + mFeatureWrSoftware->Disable(FeatureStatus::Denied, "Not on allowlist", + failureId); + break; + default: + mFeatureWrSoftware->Disable(FeatureStatus::Blocklisted, + "No qualified hardware", failureId); + break; + case nsIGfxInfo::FEATURE_STATUS_OK: + MOZ_ASSERT_UNREACHABLE("We should still be rolling out WebRender!"); + mFeatureWrSoftware->Disable(FeatureStatus::Blocked, + "Not controlled by rollout", failureId); + break; + } +} + bool gfxConfigManager::ConfigureWebRenderQualified() { MOZ_ASSERT(mFeatureWrQualified); MOZ_ASSERT(mFeatureWrCompositor); @@ -197,6 +237,7 @@ void gfxConfigManager::ConfigureWebRender() { MOZ_ASSERT(mFeatureWrAngle); MOZ_ASSERT(mFeatureWrDComp); MOZ_ASSERT(mFeatureWrPartial); + MOZ_ASSERT(mFeatureWrSoftware); MOZ_ASSERT(mFeatureHwCompositing); MOZ_ASSERT(mFeatureGPUProcess); @@ -224,6 +265,8 @@ void gfxConfigManager::ConfigureWebRender() { "No hardware stretching support", failureId); } + ConfigureWebRenderSoftware(); + bool guardedByQualifiedPref = ConfigureWebRenderQualified(); mFeatureWr->EnableByDefault(); @@ -247,19 +290,29 @@ void gfxConfigManager::ConfigureWebRender() { } if (!mFeatureWrQualified->IsEnabled()) { - mFeatureWr->Disable(FeatureStatus::Disabled, "Not qualified", - "FEATURE_FAILURE_NOT_QUALIFIED"_ns); + // No qualified hardware. If we haven't allowed software fallback, + // then we need to disable WR. + if (!mFeatureWrSoftware->IsEnabled()) { + mFeatureWr->Disable(FeatureStatus::Disabled, "Not qualified", + "FEATURE_FAILURE_NOT_QUALIFIED"_ns); + } } else if (guardedByQualifiedPref && !mWrQualified) { // If the HW is qualified, we enable if either the HW has been qualified // on the release channel (i.e. it's no longer guarded by the qualified // pref), or if the qualified pref is enabled. mFeatureWr->Disable(FeatureStatus::Disabled, "Control group for experiment", "FEATURE_FAILURE_IN_EXPERIMENT"_ns); + } else { + // Otherwise we have qualified hardware, so we can disable the software + // feature. Note that this doesn't override the force-enabled state set by + // the pref, so the pref will still enable software. + mFeatureWrSoftware->Disable(FeatureStatus::Disabled, + "Overriden by qualified hardware", + "FEATURE_FAILURE_OVERRIDEN"_ns); } // HW_COMPOSITING being disabled implies interfacing with the GPU might break - if (!mFeatureHwCompositing->IsEnabled() && - !StaticPrefs::gfx_webrender_software_AtStartup()) { + if (!mFeatureHwCompositing->IsEnabled() && !mFeatureWrSoftware->IsEnabled()) { mFeatureWr->ForceDisable(FeatureStatus::UnavailableNoHwCompositing, "Hardware compositing is disabled", "FEATURE_FAILURE_WEBRENDER_NEED_HWCOMP"_ns); diff --git a/gfx/config/gfxConfigManager.h b/gfx/config/gfxConfigManager.h index 4166f655a019..bacd5fcaff05 100644 --- a/gfx/config/gfxConfigManager.h +++ b/gfx/config/gfxConfigManager.h @@ -21,6 +21,7 @@ class gfxConfigManager { mFeatureWrAngle(nullptr), mFeatureWrDComp(nullptr), mFeatureWrPartial(nullptr), + mFeatureWrSoftware(nullptr), mFeatureHwCompositing(nullptr), mFeatureD3D11HwAngle(nullptr), mFeatureGPUProcess(nullptr), @@ -51,6 +52,7 @@ class gfxConfigManager { protected: void EmplaceUserPref(const char* aPrefName, Maybe& aValue); bool ConfigureWebRenderQualified(); + void ConfigureWebRenderSoftware(); nsCOMPtr mGfxInfo; @@ -60,6 +62,7 @@ class gfxConfigManager { FeatureState* mFeatureWrAngle; FeatureState* mFeatureWrDComp; FeatureState* mFeatureWrPartial; + FeatureState* mFeatureWrSoftware; FeatureState* mFeatureHwCompositing; FeatureState* mFeatureD3D11HwAngle; diff --git a/gfx/config/gfxFeature.h b/gfx/config/gfxFeature.h index 0e738b0ea8a7..9c295a089dc8 100644 --- a/gfx/config/gfxFeature.h +++ b/gfx/config/gfxFeature.h @@ -31,6 +31,7 @@ namespace gfx { _(WEBRENDER_PARTIAL, Feature, "WebRender partial present") \ _(WEBRENDER_ANGLE, Feature, "WebRender ANGLE") \ _(WEBRENDER_DCOMP_PRESENT, Feature, "WebRender DirectComposition") \ + _(WEBRENDER_SOFTWARE, Feature, "WebRender software fallback") \ _(OMTP, Feature, "Off Main Thread Painting") \ _(ADVANCED_LAYERS, Feature, "Advanced Layers") \ _(WEBGPU, Feature, "WebGPU") \ diff --git a/gfx/tests/gtest/TestConfigManager.cpp b/gfx/tests/gtest/TestConfigManager.cpp index 34a0c5ab293f..f0854cd9c2ab 100644 --- a/gfx/tests/gtest/TestConfigManager.cpp +++ b/gfx/tests/gtest/TestConfigManager.cpp @@ -21,6 +21,7 @@ class MockGfxInfo final : public nsIGfxInfo { int32_t mStatusWr; int32_t mStatusWrCompositor; + int32_t mStatusWrSoftware; int32_t mMaxRefreshRate; bool mHasMixedRefreshRate; Maybe mHasBattery; @@ -30,6 +31,7 @@ class MockGfxInfo final : public nsIGfxInfo { MockGfxInfo() : mStatusWr(nsIGfxInfo::FEATURE_ALLOW_ALWAYS), mStatusWrCompositor(nsIGfxInfo::FEATURE_STATUS_OK), + mStatusWrSoftware(nsIGfxInfo::FEATURE_DENIED), mMaxRefreshRate(-1), mHasMixedRefreshRate(false), mHasBattery(Some(false)), @@ -44,6 +46,9 @@ class MockGfxInfo final : public nsIGfxInfo { case nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR: *_retval = mStatusWrCompositor; break; + case nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE: + *_retval = mStatusWrSoftware; + break; default: return NS_ERROR_NOT_IMPLEMENTED; } @@ -242,6 +247,7 @@ class GfxConfigManager : public ::testing::Test, public gfxConfigManager { mFeatureHwCompositing = &mFeatures.mHwCompositing; mFeatureD3D11HwAngle = &mFeatures.mD3D11HwAngle; mFeatureGPUProcess = &mFeatures.mGPUProcess; + mFeatureWrSoftware = &mFeatures.mWrSoftware; } void SetUp() override { @@ -275,6 +281,7 @@ class GfxConfigManager : public ::testing::Test, public gfxConfigManager { mFeatures.mHwCompositing.Reset(); mFeatures.mD3D11HwAngle.Reset(); mFeatures.mGPUProcess.Reset(); + mFeatures.mWrSoftware.Reset(); } struct { @@ -287,6 +294,7 @@ class GfxConfigManager : public ::testing::Test, public gfxConfigManager { FeatureState mHwCompositing; FeatureState mD3D11HwAngle; FeatureState mGPUProcess; + FeatureState mWrSoftware; } mFeatures; RefPtr mMockGfxInfo; @@ -307,6 +315,7 @@ TEST_F(GfxConfigManager, WebRenderDefault) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNoPartialPresent) { @@ -322,6 +331,7 @@ TEST_F(GfxConfigManager, WebRenderNoPartialPresent) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderScaledResolutionWithHwStretching) { @@ -337,6 +347,7 @@ TEST_F(GfxConfigManager, WebRenderScaledResolutionWithHwStretching) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderScaledResolutionNoHwStretching) { @@ -353,6 +364,7 @@ TEST_F(GfxConfigManager, WebRenderScaledResolutionNoHwStretching) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderEnabledWithDisableHwCompositingNoWr) { @@ -368,6 +380,7 @@ TEST_F(GfxConfigManager, WebRenderEnabledWithDisableHwCompositingNoWr) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderDisabledWithDisableHwCompositingNoWr) { @@ -384,6 +397,7 @@ TEST_F(GfxConfigManager, WebRenderDisabledWithDisableHwCompositingNoWr) { EXPECT_FALSE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_FALSE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderDisabledWithAllowSoftwareGPUProcess) { @@ -401,6 +415,7 @@ TEST_F(GfxConfigManager, WebRenderDisabledWithAllowSoftwareGPUProcess) { EXPECT_FALSE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderQualifiedOverrideDisabled) { @@ -416,6 +431,7 @@ TEST_F(GfxConfigManager, WebRenderQualifiedOverrideDisabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderSafeMode) { @@ -431,6 +447,7 @@ TEST_F(GfxConfigManager, WebRenderSafeMode) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderEarlierThanWindows10) { @@ -446,6 +463,7 @@ TEST_F(GfxConfigManager, WebRenderEarlierThanWindows10) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderDCompDisabled) { @@ -461,6 +479,7 @@ TEST_F(GfxConfigManager, WebRenderDCompDisabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderDCompNotRequired) { @@ -477,6 +496,7 @@ TEST_F(GfxConfigManager, WebRenderDCompNotRequired) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderForceAngleDisabled) { @@ -492,6 +512,7 @@ TEST_F(GfxConfigManager, WebRenderForceAngleDisabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderD3D11HwAngleDisabled) { @@ -507,6 +528,7 @@ TEST_F(GfxConfigManager, WebRenderD3D11HwAngleDisabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_FALSE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderD3D11HwAngleAndForceAngleDisabled) { @@ -523,6 +545,7 @@ TEST_F(GfxConfigManager, WebRenderD3D11HwAngleAndForceAngleDisabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_FALSE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderGPUProcessDisabled) { @@ -538,6 +561,7 @@ TEST_F(GfxConfigManager, WebRenderGPUProcessDisabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_FALSE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderQualifiedAndBlocklistAllowQualified) { @@ -553,6 +577,7 @@ TEST_F(GfxConfigManager, WebRenderQualifiedAndBlocklistAllowQualified) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderQualifiedAndBlocklistAllowAlways) { @@ -569,6 +594,7 @@ TEST_F(GfxConfigManager, WebRenderQualifiedAndBlocklistAllowAlways) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNotQualifiedAndBlocklistAllowQualified) { @@ -585,6 +611,7 @@ TEST_F(GfxConfigManager, WebRenderNotQualifiedAndBlocklistAllowQualified) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNotQualifiedAndBlocklistAllowAlways) { @@ -602,6 +629,7 @@ TEST_F(GfxConfigManager, WebRenderNotQualifiedAndBlocklistAllowAlways) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderIntelBatteryNoHwStretchingNotNightly) { @@ -621,6 +649,7 @@ TEST_F(GfxConfigManager, WebRenderIntelBatteryNoHwStretchingNotNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderIntelHighRefreshRateNightly) { @@ -638,6 +667,7 @@ TEST_F(GfxConfigManager, WebRenderIntelHighRefreshRateNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderIntelHighRefreshRateNotNightly) { @@ -655,6 +685,7 @@ TEST_F(GfxConfigManager, WebRenderIntelHighRefreshRateNotNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderIntelAtRefreshRateThreshold) { @@ -672,6 +703,7 @@ TEST_F(GfxConfigManager, WebRenderIntelAtRefreshRateThreshold) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNvidiaHighMixedRefreshRateNightly) { @@ -689,6 +721,7 @@ TEST_F(GfxConfigManager, WebRenderNvidiaHighMixedRefreshRateNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNvidiaHighMixedRefreshRateNotNightly) { @@ -706,6 +739,7 @@ TEST_F(GfxConfigManager, WebRenderNvidiaHighMixedRefreshRateNotNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNvidiaHighRefreshRateNotNightly) { @@ -721,6 +755,7 @@ TEST_F(GfxConfigManager, WebRenderNvidiaHighRefreshRateNotNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderNvidiaLowMixedRefreshRateNotNightly) { @@ -737,6 +772,7 @@ TEST_F(GfxConfigManager, WebRenderNvidiaLowMixedRefreshRateNotNightly) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); } TEST_F(GfxConfigManager, WebRenderWhenXRenderEnabled) { @@ -752,4 +788,44 @@ TEST_F(GfxConfigManager, WebRenderWhenXRenderEnabled) { EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); +} + +TEST_F(GfxConfigManager, WebRenderSofwareAndQualified) { + // Enabling software in gfxInfo gives the same results + // as the default configuration, since qualified hardware + // takes precedence and we won't enable the software + // feature. + mMockGfxInfo->mStatusWrSoftware = nsIGfxInfo::FEATURE_ALLOW_ALWAYS; + ConfigureWebRender(); + + EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled()); + EXPECT_TRUE(mFeatures.mWr.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled()); + EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); + EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); + EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_FALSE(mFeatures.mWrSoftware.IsEnabled()); +} + +TEST_F(GfxConfigManager, WebRenderSofwareAndNotQualified) { + // Enabling software in gfxInfo when we're not qualified + // results in WR software being enabled instead. + mWrQualifiedOverride.emplace(false); + mMockGfxInfo->mStatusWrSoftware = nsIGfxInfo::FEATURE_ALLOW_ALWAYS; + ConfigureWebRender(); + + EXPECT_FALSE(mFeatures.mWrQualified.IsEnabled()); + EXPECT_TRUE(mFeatures.mWr.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrCompositor.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrAngle.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrDComp.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrPartial.IsEnabled()); + EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled()); + EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled()); + EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled()); + EXPECT_TRUE(mFeatures.mWrSoftware.IsEnabled()); } diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index b6ef09031998..c2f84e6a6ee9 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -2734,9 +2734,9 @@ void gfxPlatform::InitWebRenderConfig() { gfxConfig::IsEnabled(Feature::WEBRENDER)); } - if (StaticPrefs::gfx_webrender_software_AtStartup()) { - gfxVars::SetUseSoftwareWebRender(gfxConfig::IsEnabled(Feature::WEBRENDER)); - } + gfxVars::SetUseSoftwareWebRender( + gfxConfig::IsEnabled(Feature::WEBRENDER) && + gfxConfig::IsEnabled(Feature::WEBRENDER_SOFTWARE)); // gfxFeature is not usable in the GPU process, so we use gfxVars to transmit // this feature diff --git a/toolkit/components/telemetry/docs/data/environment.rst b/toolkit/components/telemetry/docs/data/environment.rst index 96dc4cc4876c..fe1a69351864 100644 --- a/toolkit/components/telemetry/docs/data/environment.rst +++ b/toolkit/components/telemetry/docs/data/environment.rst @@ -243,6 +243,9 @@ Structure: wrCompositor: { // native OS compositor (CA, DComp, etc.) status: } + wrSoftware: { // Software backend for WebRender, only computed when 'compositor' is 'webrender' + status: + } openglCompositing: { // OpenGL compositing. status: } diff --git a/widget/GfxInfoBase.cpp b/widget/GfxInfoBase.cpp index aa91bc3aa94f..2824a49d3147 100644 --- a/widget/GfxInfoBase.cpp +++ b/widget/GfxInfoBase.cpp @@ -228,6 +228,9 @@ static const char* GetPrefNameForFeature(int32_t aFeature) { case nsIGfxInfo::FEATURE_THREADSAFE_GL: name = BLOCKLIST_PREF_BRANCH "gl.threadsafe"; break; + case nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE: + name = BLOCKLIST_PREF_BRANCH "webrender.software"; + break; default: MOZ_ASSERT_UNREACHABLE("Unexpected nsIGfxInfo feature?!"); break; @@ -421,6 +424,8 @@ static int32_t BlocklistFeatureToGfxFeature(const nsAString& aFeature) { return nsIGfxInfo::FEATURE_ALLOW_WEBGL_OUT_OF_PROCESS; else if (aFeature.EqualsLiteral("THREADSAFE_GL")) return nsIGfxInfo::FEATURE_THREADSAFE_GL; + else if (aFeature.EqualsLiteral("WEBRENDER_SOFTWARE")) + return nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE; // If we don't recognize the feature, it may be new, and something // this version doesn't understand. So, nothing to do. This is @@ -1147,7 +1152,8 @@ bool GfxInfoBase::DoesDriverVendorMatch(const nsAString& aBlocklistVendor, } bool GfxInfoBase::IsFeatureAllowlisted(int32_t aFeature) const { - return aFeature == nsIGfxInfo::FEATURE_WEBRENDER; + return aFeature == nsIGfxInfo::FEATURE_WEBRENDER || + aFeature == nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE; } nsresult GfxInfoBase::GetFeatureStatusImpl( @@ -1281,6 +1287,7 @@ void GfxInfoBase::EvaluateDownloadedBlocklist( nsIGfxInfo::FEATURE_D3D11_KEYED_MUTEX, nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_WEBRENDER_COMPOSITOR, + nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE, nsIGfxInfo::FEATURE_DX_NV12, nsIGfxInfo::FEATURE_DX_P010, nsIGfxInfo::FEATURE_DX_P016, @@ -1642,6 +1649,10 @@ void GfxInfoBase::DescribeFeatures(JSContext* aCx, JS::Handle aObj) { gfxConfig::GetFeature(gfx::Feature::WEBRENDER_COMPOSITOR); InitFeatureObject(aCx, aObj, "wrCompositor", wrCompositor, &obj); + gfx::FeatureState& wrSoftware = + gfxConfig::GetFeature(gfx::Feature::WEBRENDER_SOFTWARE); + InitFeatureObject(aCx, aObj, "wrSoftware", wrSoftware, &obj); + gfx::FeatureState& openglCompositing = gfxConfig::GetFeature(gfx::Feature::OPENGL_COMPOSITING); InitFeatureObject(aCx, aObj, "openglCompositing", openglCompositing, &obj); diff --git a/widget/nsIGfxInfo.idl b/widget/nsIGfxInfo.idl index 4606a6ceb3b4..34269dc93ec7 100644 --- a/widget/nsIGfxInfo.idl +++ b/widget/nsIGfxInfo.idl @@ -166,8 +166,10 @@ interface nsIGfxInfo : nsISupports const long FEATURE_ALLOW_WEBGL_OUT_OF_PROCESS = 31; /* Is OpenGL threadsafe (starting in 83) */ const long FEATURE_THREADSAFE_GL = 32; + /* Support running WebRender using the software backend, starting in 84. */ + const long FEATURE_WEBRENDER_SOFTWARE = 33; /* the maximum feature value. */ - const long FEATURE_MAX_VALUE = FEATURE_THREADSAFE_GL; + const long FEATURE_MAX_VALUE = FEATURE_WEBRENDER_SOFTWARE; /* * A set of return values from GetFeatureStatus