Bug 1543217 - Allow qualified Linux machines to get WebRender. r=jrmuizel
☠☠ backed out by a9b425b08d83 ☠ ☠
authorAndrew Osmond <aosmond@mozilla.com>
Tue, 09 Apr 2019 15:27:16 -0400
changeset 468829 34e912d9305a292318edc31931bf354c5221ec6a
parent 468828 1664505ad313eff325d6dbc62bce5357fac19b90
child 468830 a9b425b08d83faff89a8eb609a144b0aff93e395
push id35851
push userdvarga@mozilla.com
push dateWed, 10 Apr 2019 21:56:12 +0000
treeherdermozilla-central@30ca3c3abfe6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1543217
milestone68.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 1543217 - Allow qualified Linux machines to get WebRender. r=jrmuizel Linux machines using Intel graphics with Mesa drivers being at least 18.2.8.0 and not 4k displays should be able to run WebRender well, given this is a common configuration used for testing already by Mozilla. This patch allows users meeting said requirements to join the WebRender experiments on nightly. WebRender will remain disabled by default for other configurations/devices. Differential Revision: https://phabricator.services.mozilla.com/D26796
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxPlatformGtk.cpp
widget/GfxInfoX11.cpp
widget/windows/GfxInfo.cpp
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -918,16 +918,17 @@ void gfxPlatform::Init() {
   gPlatform = new gfxPlatformMac;
 #elif defined(MOZ_WIDGET_GTK)
   gPlatform = new gfxPlatformGtk;
 #elif defined(ANDROID)
   gPlatform = new gfxAndroidPlatform;
 #else
 #  error "No gfxPlatform implementation available"
 #endif
+  gPlatform->PopulateScreenInfo();
   gPlatform->InitAcceleration();
   gPlatform->InitWebRenderConfig();
   // When using WebRender, we defer initialization of the D3D11 devices until
   // the (rare) cases where they're used. Note that the GPU process where
   // WebRender runs doesn't initialize gfxPlatform and performs explicit
   // initialization of the bits it needs.
   if (!gfxVars::UseWebRender()) {
     gPlatform->EnsureDevicesInitialized();
@@ -955,17 +956,16 @@ void gfxPlatform::Init() {
   SkGraphics::Init();
 #  ifdef MOZ_ENABLE_FREETYPE
   SkInitCairoFT(gPlatform->FontHintingEnabled());
 #  endif
 #endif
 
   InitLayersIPC();
 
-  gPlatform->PopulateScreenInfo();
   gPlatform->ComputeTileSize();
 
 #ifdef MOZ_ENABLE_FREETYPE
   Factory::SetFTLibrary(gPlatform->GetFTLibrary());
 #endif
 
   gPlatform->mHasVariationFontSupport = gPlatform->CheckVariationFontSupport();
 
@@ -2506,17 +2506,17 @@ static bool CalculateWrQualifiedPrefValu
   // rollout pref enabled" case.
   if (Preferences::HasUserValue(WR_ROLLOUT_PREF_OVERRIDE)) {
     return Preferences::GetBool(WR_ROLLOUT_PREF_OVERRIDE);
   }
   return gfxPrefs::WebRenderAllQualified();
 }
 
 static FeatureState& WebRenderHardwareQualificationStatus(
-    bool aHasBattery, nsCString& aOutFailureId) {
+    const IntSize& aScreenSize, bool aHasBattery, nsCString& aOutFailureId) {
   FeatureState& featureWebRenderQualified =
       gfxConfig::GetFeature(Feature::WEBRENDER_QUALIFIED);
   featureWebRenderQualified.EnableByDefault();
 
   if (Preferences::HasUserValue(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
     if (!Preferences::GetBool(WR_ROLLOUT_HW_QUALIFIED_OVERRIDE)) {
       featureWebRenderQualified.Disable(
           FeatureStatus::Blocked, "HW qualification pref override",
@@ -2571,17 +2571,18 @@ static FeatureState& WebRenderHardwareQu
               (deviceID >= 0x9830 && deviceID < 0x9870) ||
               (deviceID >= 0x9900 && deviceID < 0x9a00)) {
             // we have a desktop CAYMAN, SI, CIK, VI, or GFX9 device
           } else {
             featureWebRenderQualified.Disable(
                 FeatureStatus::Blocked, "Device too old",
                 NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
           }
-        } else if (adapterVendorID == u"0x8086") {  // Intel
+        } else if (adapterVendorID == u"0x8086" ||
+                   adapterVendorID == u"mesa/i965") {  // Intel
           const uint16_t supportedDevices[] = {
               0x191d,  // HD Graphics P530
               0x192d,  // Iris Pro Graphics P555
               0x1912,  // HD Graphics 530
               0x5912,  // HD Graphics 630
               0x3e92,  // UHD Graphics 630
               // HD Graphics 4600
               0x0412,
@@ -2600,16 +2601,28 @@ static FeatureState& WebRenderHardwareQu
             if (deviceID == id) {
               supported = true;
             }
           }
           if (!supported) {
             featureWebRenderQualified.Disable(
                 FeatureStatus::Blocked, "Device too old",
                 NS_LITERAL_CSTRING("FEATURE_FAILURE_DEVICE_TOO_OLD"));
+          } else if (adapterVendorID == u"mesa/i965") {
+            const int32_t maxPixels = 3440 * 1440;  // UWQHD
+            int32_t pixels = aScreenSize.width * aScreenSize.height;
+            if (pixels > maxPixels) {
+              featureWebRenderQualified.Disable(
+                  FeatureStatus::Blocked, "Screen size too large",
+                  NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_TOO_LARGE"));
+            } else if (pixels <= 0) {
+              featureWebRenderQualified.Disable(
+                  FeatureStatus::Blocked, "Screen size unknown",
+                  NS_LITERAL_CSTRING("FEATURE_FAILURE_SCREEN_SIZE_UNKNOWN"));
+            }
           }
 #endif
         } else {
           featureWebRenderQualified.Disable(
               FeatureStatus::Blocked, "Unsupported vendor",
               NS_LITERAL_CSTRING("FEATURE_FAILURE_UNSUPPORTED_VENDOR"));
         }
       }
@@ -2648,17 +2661,18 @@ void gfxPlatform::InitWebRenderConfig() 
     if (gfxVars::UseWebRender()) {
       reporter.SetSuccessful();
     }
     return;
   }
 
   nsCString failureId;
   FeatureState& featureWebRenderQualified =
-      WebRenderHardwareQualificationStatus(HasBattery(), failureId);
+      WebRenderHardwareQualificationStatus(GetScreenSize(), HasBattery(),
+                                           failureId);
   FeatureState& featureWebRender = gfxConfig::GetFeature(Feature::WEBRENDER);
 
   featureWebRender.DisableByDefault(
       FeatureStatus::OptIn, "WebRender is an opt-in feature",
       NS_LITERAL_CSTRING("FEATURE_FAILURE_DEFAULT_OFF"));
 
   const bool wrQualifiedAll = CalculateWrQualifiedPrefValue();
 
@@ -2743,16 +2757,24 @@ void gfxPlatform::InitWebRenderConfig() 
     gfxVars::SetUseWebRender(true);
     reporter.SetSuccessful();
 
     if (XRE_IsParentProcess()) {
       Preferences::RegisterPrefixCallbackAndCall(
           WebRenderDebugPrefChangeCallback, WR_DEBUG_PREF);
     }
   }
+#ifdef XP_LINUX
+  else {
+    // Hardware compositing should be disabled by default if we aren't using
+    // WebRender, but may still have been enabled by prefs.
+    gfxConfig::Disable(Feature::HW_COMPOSITING, FeatureStatus::Blocked,
+                       "Acceleration blocked by platform");
+  }
+#endif
 
 #ifdef XP_WIN
   if (Preferences::GetBool("gfx.webrender.dcomp-win.enabled", false)) {
     // XXX relax win version to windows 8.
     if (IsWin10OrLater() && gfxVars::UseWebRender() &&
         gfxVars::UseWebRenderANGLE()) {
       gfxVars::SetUseWebRenderDCompWin(true);
     }
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -731,17 +731,17 @@ class gfxPlatform : public mozilla::laye
   virtual bool DevicesInitialized() { return true; };
 
   static uint32_t TargetFrameRate();
 
  protected:
   gfxPlatform();
   virtual ~gfxPlatform();
 
-  virtual bool HasBattery() { return true; }
+  virtual bool HasBattery() { return false; }
 
   virtual void InitAcceleration();
   virtual void InitWebRenderConfig();
 
   /**
    * Called immediately before deleting the gfxPlatform object.
    */
   virtual void WillShutdown();
--- a/gfx/thebes/gfxPlatformGtk.cpp
+++ b/gfx/thebes/gfxPlatformGtk.cpp
@@ -325,17 +325,17 @@ uint32_t gfxPlatformGtk::MaxGenericSubst
       mMaxGenericSubstitutions = 3;
     }
   }
 
   return uint32_t(mMaxGenericSubstitutions);
 }
 
 bool gfxPlatformGtk::AccelerateLayersByDefault() {
-  return gfxPrefs::WebRenderAll();
+  return true;
 }
 
 void gfxPlatformGtk::GetPlatformCMSOutputProfile(void*& mem, size_t& size) {
   mem = nullptr;
   size = 0;
 
 #ifdef MOZ_X11
   GdkDisplay* display = gdk_display_get_default();
--- a/widget/GfxInfoX11.cpp
+++ b/widget/GfxInfoX11.cpp
@@ -302,16 +302,44 @@ const nsTArray<GfxDriverInfo> &GfxInfo::
 
     // fglrx baseline (chosen arbitrarily as 2013-07-22 release).
     APPEND_TO_DRIVER_BLOCKLIST(
         OperatingSystem::Linux,
         (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorATI),
         GfxDriverInfo::allDevices, GfxDriverInfo::allFeatures,
         nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN,
         V(13, 15, 100, 1), "FEATURE_FAILURE_OLD_FGLRX", "fglrx 13.15.100.1");
+
+    ////////////////////////////////////
+    // FEATURE_WEBRENDER
+
+    // Mesa baseline (chosen arbitrarily as that which ships with
+    // Ubuntu 18.04 LTS).
+    APPEND_TO_DRIVER_BLOCKLIST(
+        OperatingSystem::Linux,
+        (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorMesaAll),
+        GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_WEBRENDER,
+        nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN,
+        V(18, 2, 8, 0), "FEATURE_FAILURE_WEBRENDER_OLD_MESA", "Mesa 18.2.8.0");
+
+    // Disable on all NVIDIA devices for now.
+    APPEND_TO_DRIVER_BLOCKLIST(
+        OperatingSystem::Linux,
+        (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorNVIDIA),
+        GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_WEBRENDER,
+        nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
+        V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_NVIDIA", "");
+
+    // Disable on all ATI devices for now.
+    APPEND_TO_DRIVER_BLOCKLIST(
+        OperatingSystem::Linux,
+        (nsAString &)GfxDriverInfo::GetDeviceVendor(VendorATI),
+        GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_WEBRENDER,
+        nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_COMPARISON_IGNORED,
+        V(0, 0, 0, 0), "FEATURE_FAILURE_WEBRENDER_NO_LINUX_ATI", "");
   }
   return *sDriverInfo;
 }
 
 bool GfxInfo::DoesVendorMatch(const nsAString &aBlocklistVendor,
                               const nsAString &aAdapterVendor) {
   if (mIsMesa &&
       aBlocklistVendor.Equals(GfxDriverInfo::GetDeviceVendor(VendorMesaAll),
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -1597,19 +1597,19 @@ const nsTArray<GfxDriverInfo>& GfxInfo::
         (nsAString&)GfxDriverInfo::GetDeviceVendor(VendorNVIDIA),
         GfxDriverInfo::allDevices, nsIGfxInfo::FEATURE_DX_P010,
         nsIGfxInfo::FEATURE_BLOCKED_DEVICE, DRIVER_LESS_THAN,
         GfxDriverInfo::allDriverVersions, "FEATURE_UNQUALIFIED_P010_NVIDIA");
 
     ////////////////////////////////////
     // FEATURE_WEBRENDER
 
-    // We are blocking all non-Nvidia cards in gfxPlatform.cpp where we check
-    // for the WEBRENDER_QUALIFIED feature. However we also want to block some
-    // specific Nvidia cards for being too low-powered, so we do that here.
+    // We are blocking most hardware explicitly in gfxPlatform.cpp where we
+    // check for the WEBRENDER_QUALIFIED feature. However we also want to block
+    // some specific Nvidia cards for being too low-powered, so we do that here.
     APPEND_TO_DRIVER_BLOCKLIST2(
         OperatingSystem::Windows10,
         (nsAString&)GfxDriverInfo::GetDeviceVendor(VendorNVIDIA),
         (GfxDeviceFamily*)GfxDriverInfo::GetDeviceFamily(NvidiaBlockWebRender),
         nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_BLOCKED_DEVICE,
         DRIVER_LESS_THAN, GfxDriverInfo::allDriverVersions,
         "FEATURE_UNQUALIFIED_WEBRENDER_NVIDIA_BLOCKED");