Bug 1543217 - Allow qualified Linux machines to get WebRender. r=jrmuizel
authorAndrew Osmond <aosmond@mozilla.com>
Tue, 09 Apr 2019 15:27:16 -0400
changeset 468831 f3fcf307ee8091d8d3c03af13818099a90c2db21
parent 468830 a9b425b08d83faff89a8eb609a144b0aff93e395
child 468832 30ca3c3abfe63d2d5923e28dcc565972ea4cf811
child 468884 399822369a16cd4eb5ad06f644aeb25db88eecd0
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,26 @@ void gfxPlatform::InitWebRenderConfig() 
     gfxVars::SetUseWebRender(true);
     reporter.SetSuccessful();
 
     if (XRE_IsParentProcess()) {
       Preferences::RegisterPrefixCallbackAndCall(
           WebRenderDebugPrefChangeCallback, WR_DEBUG_PREF);
     }
   }
+#if defined(XP_LINUX) && !defined(MOZ_WIDGET_ANDROID)
+  else if (gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
+    // Hardware compositing should be disabled by default if we aren't using
+    // WebRender. We had to check if it is enabled at all, because it may
+    // already have been forced disabled (e.g. safe mode, headless). It may
+    // still be forced on by the user, and if so, this should have no effect.
+    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");