Bug 1677293 - Enable Software WebRender on Linux nightly for small/medium screens. r=jrmuizel
authorAndrew Osmond <aosmond@mozilla.com>
Fri, 20 Nov 2020 17:38:53 +0000 (2020-11-20)
changeset 558238 fded65adecd4639ac0f1db0cf11d6092c9e55a51
parent 558237 5bf85f5f74c1262d2dad3283b111b2e388e9c2ca
child 558239 f9537fedd47d8dbb27dfb19446a9d0de642edae4
push id131477
push useraosmond@mozilla.com
push dateFri, 20 Nov 2020 19:28:12 +0000 (2020-11-20)
treeherderautoland@fded65adecd4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1677293
milestone85.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1677293 - Enable Software WebRender on Linux nightly for small/medium screens. r=jrmuizel This patch enables Software WebRender for all Linux users. If their configuration is also allowlisted for (accelerated) WebRender, then they will default to that over Software WebRender. Differential Revision: https://phabricator.services.mozilla.com/D97156
gfx/config/gfxConfigManager.cpp
gfx/config/gfxConfigManager.h
gfx/tests/gtest/TestConfigManager.cpp
widget/GfxDriverInfo.cpp
widget/GfxDriverInfo.h
widget/GfxInfoX11.cpp
--- a/gfx/config/gfxConfigManager.cpp
+++ b/gfx/config/gfxConfigManager.cpp
@@ -25,16 +25,17 @@ namespace mozilla {
 namespace gfx {
 
 void gfxConfigManager::Init() {
   MOZ_ASSERT(XRE_IsParentProcess());
 
   EmplaceUserPref("gfx.webrender.compositor", mWrCompositorEnabled);
   mWrForceEnabled = gfxPlatform::WebRenderPrefEnabled();
   mWrForceDisabled = StaticPrefs::gfx_webrender_force_disabled_AtStartup();
+  mWrSoftwareForceEnabled = StaticPrefs::gfx_webrender_software_AtStartup();
   mWrCompositorForceEnabled =
       StaticPrefs::gfx_webrender_compositor_force_enabled_AtStartup();
   mGPUProcessAllowSoftware =
       StaticPrefs::layers_gpu_process_allow_software_AtStartup();
   mWrPartialPresent =
       StaticPrefs::gfx_webrender_max_partial_present_rects_AtStartup() > 0;
 #ifdef XP_WIN
   mWrForceAngle = StaticPrefs::gfx_webrender_force_angle_AtStartup();
@@ -108,18 +109,31 @@ void gfxConfigManager::ConfigureFromBloc
   }
 }
 
 void gfxConfigManager::ConfigureWebRenderSoftware() {
   MOZ_ASSERT(mFeatureWrSoftware);
 
   mFeatureWrSoftware->EnableByDefault();
 
-  if (StaticPrefs::gfx_webrender_software_AtStartup()) {
+  // Note that for testing in CI, software WebRender uses gfx.webrender.software
+  // to force enable WebRender Software. As a result, we need to prefer that
+  // over the MOZ_WEBRENDER envvar which is used to otherwise force on WebRender
+  // (hardware). See bug 1656811.
+  if (mWrSoftwareForceEnabled) {
     mFeatureWrSoftware->UserForceEnable("Force enabled by pref");
+  } else if (mWrEnvForceEnabled) {
+    mFeatureWrSoftware->UserDisable(
+        "User force-enabled full WR",
+        "FEATURE_FAILURE_USER_FORCE_ENABLED_FULL_WR"_ns);
+  } else if (mWrForceDisabled || mWrEnvForceDisabled) {
+    // If the user set the pref to force-disable, let's do that. This
+    // will override all the other enabling prefs
+    mFeatureWrSoftware->UserDisable("User force-disabled WR",
+                                    "FEATURE_FAILURE_USER_FORCE_DISABLED"_ns);
   }
 
   nsCString failureId;
   int32_t status;
   if (NS_FAILED(mGfxInfo->GetFeatureStatus(
           nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE, failureId, &status))) {
     mFeatureWrSoftware->Disable(FeatureStatus::BlockedNoGfxInfo,
                                 "gfxInfo is broken",
--- a/gfx/config/gfxConfigManager.h
+++ b/gfx/config/gfxConfigManager.h
@@ -24,16 +24,17 @@ class gfxConfigManager {
         mFeatureWrDComp(nullptr),
         mFeatureWrPartial(nullptr),
         mFeatureWrSoftware(nullptr),
         mFeatureHwCompositing(nullptr),
         mFeatureD3D11HwAngle(nullptr),
         mFeatureGPUProcess(nullptr),
         mWrForceEnabled(false),
         mWrForceDisabled(false),
+        mWrSoftwareForceEnabled(false),
         mWrCompositorForceEnabled(false),
         mWrForceAngle(false),
         mWrForceAngleNoGPUProcess(false),
         mWrDCompWinEnabled(false),
         mWrCompositorDCompRequired(false),
         mWrPartialPresent(false),
         mGPUProcessAllowSoftware(false),
         mXRenderEnabled(false),
@@ -70,16 +71,17 @@ class gfxConfigManager {
   FeatureState* mFeatureGPUProcess;
 
   /**
    * Prefs
    */
   Maybe<bool> mWrCompositorEnabled;
   bool mWrForceEnabled;
   bool mWrForceDisabled;
+  bool mWrSoftwareForceEnabled;
   bool mWrCompositorForceEnabled;
   bool mWrForceAngle;
   bool mWrForceAngleNoGPUProcess;
   bool mWrDCompWinEnabled;
   bool mWrCompositorDCompRequired;
   bool mWrPartialPresent;
   bool mGPUProcessAllowSoftware;
   bool mXRenderEnabled;
--- a/gfx/tests/gtest/TestConfigManager.cpp
+++ b/gfx/tests/gtest/TestConfigManager.cpp
@@ -772,8 +772,111 @@ TEST_F(GfxConfigManager, WebRenderSofwar
   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());
 }
+
+TEST_F(GfxConfigManager, WebRenderForceDisabledEnvvar) {
+  mWrEnvForceDisabled = true;
+  ConfigureWebRender();
+
+  EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWr.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
+  EXPECT_FALSE(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, WebRenderSoftwareAllowedForceDisabledEnvvar) {
+  mWrEnvForceDisabled = true;
+  mMockGfxInfo->mStatusWrSoftware = nsIGfxInfo::FEATURE_ALLOW_ALWAYS;
+  ConfigureWebRender();
+
+  EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWr.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
+  EXPECT_FALSE(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, WebRenderForceSoftwareForceDisabledEnvvar) {
+  mWrEnvForceDisabled = true;
+  mWrSoftwareForceEnabled = true;
+  ConfigureWebRender();
+
+  EXPECT_TRUE(mFeatures.mWrQualified.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWr.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrCompositor.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrAngle.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrDComp.IsEnabled());
+  EXPECT_FALSE(mFeatures.mWrPartial.IsEnabled());
+  EXPECT_TRUE(mFeatures.mHwCompositing.IsEnabled());
+  EXPECT_TRUE(mFeatures.mGPUProcess.IsEnabled());
+  EXPECT_TRUE(mFeatures.mD3D11HwAngle.IsEnabled());
+  EXPECT_TRUE(mFeatures.mWrSoftware.IsEnabled());
+}
+
+TEST_F(GfxConfigManager, WebRenderForceEnabledEnvvar) {
+  mWrEnvForceEnabled = true;
+  mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_DENIED;
+  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_FALSE(mFeatures.mWrSoftware.IsEnabled());
+}
+
+TEST_F(GfxConfigManager, WebRenderSoftwareAllowedForceEnabledEnvvar) {
+  mWrEnvForceEnabled = true;
+  mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_DENIED;
+  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_FALSE(mFeatures.mWrSoftware.IsEnabled());
+}
+
+TEST_F(GfxConfigManager, WebRenderForceSoftwareForceEnabledEnvvar) {
+  mWrEnvForceEnabled = true;
+  mWrSoftwareForceEnabled = true;
+  mMockGfxInfo->mStatusWr = nsIGfxInfo::FEATURE_DENIED;
+  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());
+}
--- a/widget/GfxDriverInfo.cpp
+++ b/widget/GfxDriverInfo.cpp
@@ -996,14 +996,16 @@ const nsAString& GfxDriverInfo::GetDrive
   switch (id) {
     DECLARE_DRIVER_VENDOR_ID(MesaAll, "mesa/all");
     DECLARE_DRIVER_VENDOR_ID(MesaLLVMPipe, "mesa/llvmpipe");
     DECLARE_DRIVER_VENDOR_ID(MesaSoftPipe, "mesa/softpipe");
     DECLARE_DRIVER_VENDOR_ID(MesaSWRast, "mesa/swrast");
     DECLARE_DRIVER_VENDOR_ID(MesaUnknown, "mesa/unknown");
     DECLARE_DRIVER_VENDOR_ID(MesaNouveau, "mesa/nouveau");
     DECLARE_DRIVER_VENDOR_ID(NonMesaAll, "non-mesa/all");
+    DECLARE_DRIVER_VENDOR_ID(HardwareMesaAll, "mesa/hw-all");
+    DECLARE_DRIVER_VENDOR_ID(SoftwareMesaAll, "mesa/sw-all");
     case DriverVendor::Max:  // Suppress a warning.
       DECLARE_DRIVER_VENDOR_ID(All, "");
   }
 
   return *sDriverVendors[idx];
 }
--- a/widget/GfxDriverInfo.h
+++ b/widget/GfxDriverInfo.h
@@ -231,16 +231,20 @@ enum DriverVendor : uint8_t {
   MesaSoftPipe,
   MesaSWRast,
   // Nouveau: Open-source nvidia
   MesaNouveau,
   // A generic ID to be provided when we can't determine the DRI driver on Mesa.
   MesaUnknown,
   // Wildcard for all non-Mesa drivers.
   NonMesaAll,
+  // Wildcard for all hardware Mesa drivers.
+  HardwareMesaAll,
+  // Wildcard for all software Mesa drivers.
+  SoftwareMesaAll,
 
   Max
 };
 
 enum class DesktopEnvironment : uint8_t {
   All,  // There is an assumption that this is the first enum
   GNOME,
   KDE,
--- a/widget/GfxInfoX11.cpp
+++ b/widget/GfxInfoX11.cpp
@@ -718,16 +718,38 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
         OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
         DesktopEnvironment::All, WindowProtocol::All, DriverVendor::MesaAll,
         DeviceFamily::AtiRolloutWebRender, nsIGfxInfo::FEATURE_WEBRENDER,
         nsIGfxInfo::FEATURE_ALLOW_QUALIFIED, DRIVER_GREATER_THAN_OR_EQUAL,
         V(18, 0, 0, 0), "FEATURE_ROLLOUT_NIGHTLY_ATI_MESA", "Mesa 18.0.0.0");
 #endif
 
     ////////////////////////////////////
+    // FEATURE_WEBRENDER_SOFTWARE - ALLOWLIST
+#ifdef NIGHTLY_BUILD
+    APPEND_TO_DRIVER_BLOCKLIST_EXT(
+        OperatingSystem::Linux, ScreenSizeStatus::SmallAndMedium,
+        BatteryStatus::All, DesktopEnvironment::All, WindowProtocol::All,
+        DriverVendor::NonMesaAll, DeviceFamily::All,
+        nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE,
+        nsIGfxInfo::FEATURE_ALLOW_ALWAYS, DRIVER_COMPARISON_IGNORED,
+        V(0, 0, 0, 0), "FEATURE_ROLLOUT_NIGHTLY_SOFTWARE_WR_NON_MESA_S_M_SCRN",
+        "");
+
+    APPEND_TO_DRIVER_BLOCKLIST_EXT(
+        OperatingSystem::Linux, ScreenSizeStatus::SmallAndMedium,
+        BatteryStatus::All, DesktopEnvironment::All, WindowProtocol::All,
+        DriverVendor::HardwareMesaAll, DeviceFamily::All,
+        nsIGfxInfo::FEATURE_WEBRENDER_SOFTWARE,
+        nsIGfxInfo::FEATURE_ALLOW_ALWAYS, DRIVER_COMPARISON_IGNORED,
+        V(0, 0, 0, 0), "FEATURE_ROLLOUT_NIGHTLY_SOFTWARE_WR_HW_MESA_S_M_SCRN",
+        "");
+#endif
+
+    ////////////////////////////////////
 
     APPEND_TO_DRIVER_BLOCKLIST_EXT(
         OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All,
         DesktopEnvironment::All, WindowProtocol::All, DriverVendor::MesaNouveau,
         DeviceFamily::All, nsIGfxInfo::FEATURE_THREADSAFE_GL,
         nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
         V(0, 0, 0, 0), "FEATURE_FAILURE_THREADSAFE_GL", "");
   }
@@ -749,20 +771,34 @@ bool GfxInfo::DoesWindowProtocolMatch(co
     return true;
   }
   return GfxInfoBase::DoesWindowProtocolMatch(aBlocklistWindowProtocol,
                                               aWindowProtocol);
 }
 
 bool GfxInfo::DoesDriverVendorMatch(const nsAString& aBlocklistVendor,
                                     const nsAString& aDriverVendor) {
-  if (mIsMesa && aBlocklistVendor.Equals(
-                     GfxDriverInfo::GetDriverVendor(DriverVendor::MesaAll),
-                     nsCaseInsensitiveStringComparator)) {
-    return true;
+  if (mIsMesa) {
+    if (aBlocklistVendor.Equals(
+            GfxDriverInfo::GetDriverVendor(DriverVendor::MesaAll),
+            nsCaseInsensitiveStringComparator)) {
+      return true;
+    }
+    if (mIsAccelerated &&
+        aBlocklistVendor.Equals(
+            GfxDriverInfo::GetDriverVendor(DriverVendor::HardwareMesaAll),
+            nsCaseInsensitiveStringComparator)) {
+      return true;
+    }
+    if (!mIsAccelerated &&
+        aBlocklistVendor.Equals(
+            GfxDriverInfo::GetDriverVendor(DriverVendor::SoftwareMesaAll),
+            nsCaseInsensitiveStringComparator)) {
+      return true;
+    }
   }
   if (!mIsMesa && aBlocklistVendor.Equals(
                       GfxDriverInfo::GetDriverVendor(DriverVendor::NonMesaAll),
                       nsCaseInsensitiveStringComparator)) {
     return true;
   }
   return GfxInfoBase::DoesDriverVendorMatch(aBlocklistVendor, aDriverVendor);
 }