Bug 1593725 - cache gfx information so we don't re-read prefs and re-search blocklists for each content process, r=jrmuizel
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Sat, 09 Nov 2019 02:21:18 +0000
changeset 501415 a1901e1e614fc9773275cbc683cb77ea53ea1c7a
parent 501414 74ae5427c21f848b01a2e72fd81f339ba2a5b7a3
child 501416 453108aa1e96fe97b264ba921740aec0a7ef4884
push id36791
push usercsabou@mozilla.com
push dateSun, 10 Nov 2019 09:53:30 +0000
treeherdermozilla-central@72c52c0101cf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1593725
milestone72.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 1593725 - cache gfx information so we don't re-read prefs and re-search blocklists for each content process, r=jrmuizel Differential Revision: https://phabricator.services.mozilla.com/D51644
dom/ipc/ContentParent.cpp
widget/GfxInfoBase.cpp
widget/GfxInfoBase.h
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -205,16 +205,17 @@
 #include "SourceSurfaceRawData.h"
 #include "BrowserParent.h"
 #include "URIUtils.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsIDocShell.h"
 #include "nsDocShell.h"
 #include "nsOpenURIInFrameParams.h"
 #include "mozilla/net/NeckoMessageUtils.h"
+#include "GfxInfoBase.h"
 #include "gfxPlatform.h"
 #include "gfxPlatformFontList.h"
 #include "prio.h"
 #include "private/pprio.h"
 #include "ContentProcessManager.h"
 #include "mozilla/dom/BlobURLProtocolHandler.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/PerformanceMetricsCollector.h"
@@ -2493,26 +2494,18 @@ bool ContentParent::InitInternal(Process
       &xpcomInit.contentDeviceData());
   // 2. Gather non-default gfxVars.
   xpcomInit.gfxNonDefaultVarUpdates() = gfxVars::FetchNonDefaultVars();
   // 3. Start listening for gfxVars updates, to notify content process later on.
   gfxVars::AddReceiver(this);
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
   if (gfxInfo) {
-    for (int32_t i = 1; i <= nsIGfxInfo::FEATURE_MAX_VALUE; ++i) {
-      int32_t status = 0;
-      nsAutoCString failureId;
-      gfxInfo->GetFeatureStatus(i, failureId, &status);
-      dom::GfxInfoFeatureStatus gfxFeatureStatus;
-      gfxFeatureStatus.feature() = i;
-      gfxFeatureStatus.status() = status;
-      gfxFeatureStatus.failureId() = failureId;
-      xpcomInit.gfxFeatureStatus().AppendElement(gfxFeatureStatus);
-    }
+    GfxInfoBase* gfxInfoRaw = static_cast<GfxInfoBase*>(gfxInfo.get());
+    gfxInfoRaw->GetAllFeatures(xpcomInit);
   }
 
   DataStorage::GetAllChildProcessData(xpcomInit.dataStorage());
 
   // Send the dynamic scalar definitions to the new process.
   TelemetryIPC::GetDynamicScalarDefinitions(xpcomInit.dynamicScalarDefs());
 
   // Must send screen info before send initialData
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -229,29 +229,37 @@ static bool GetPrefValueForFeature(int32
 
   return true;
 }
 
 static void SetPrefValueForFeature(int32_t aFeature, int32_t aValue,
                                    const nsACString& aFailureId) {
   const char* prefname = GetPrefNameForFeature(aFeature);
   if (!prefname) return;
+  if (XRE_IsParentProcess()) {
+    delete GfxInfoBase::sFeatureStatus;
+    GfxInfoBase::sFeatureStatus = nullptr;
+  }
 
   Preferences::SetInt(prefname, aValue);
   if (!aFailureId.IsEmpty()) {
     nsCString failureprefname(prefname);
     failureprefname += ".failureid";
     Preferences::SetCString(failureprefname.get(), aFailureId);
   }
 }
 
 static void RemovePrefForFeature(int32_t aFeature) {
   const char* prefname = GetPrefNameForFeature(aFeature);
   if (!prefname) return;
 
+  if (XRE_IsParentProcess()) {
+    delete GfxInfoBase::sFeatureStatus;
+    GfxInfoBase::sFeatureStatus = nullptr;
+  }
   Preferences::ClearUser(prefname);
 }
 
 static bool GetPrefValueForDriverVersion(nsCString& aVersion) {
   return NS_SUCCEEDED(
       Preferences::GetCString(SUGGESTED_VERSION_PREF, aVersion));
 }
 
@@ -650,16 +658,37 @@ GfxInfoBase::GetFeatureStatus(int32_t aF
 
   nsString version;
   nsTArray<GfxDriverInfo> driverInfo;
   nsresult rv =
       GetFeatureStatusImpl(aFeature, aStatus, version, driverInfo, aFailureId);
   return rv;
 }
 
+void GfxInfoBase::GetAllFeatures(dom::XPCOMInitData& xpcomInit) {
+  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
+  if (!sFeatureStatus) {
+    sFeatureStatus = new nsTArray<dom::GfxInfoFeatureStatus>();
+    for (int32_t i = 1; i <= nsIGfxInfo::FEATURE_MAX_VALUE; ++i) {
+      int32_t status = 0;
+      nsAutoCString failureId;
+      GetFeatureStatus(i, failureId, &status);
+      dom::GfxInfoFeatureStatus gfxFeatureStatus;
+      gfxFeatureStatus.feature() = i;
+      gfxFeatureStatus.status() = status;
+      gfxFeatureStatus.failureId() = failureId;
+      sFeatureStatus->AppendElement(gfxFeatureStatus);
+    }
+  }
+  for (const auto& status : *sFeatureStatus) {
+    dom::GfxInfoFeatureStatus copy = status;
+    xpcomInit.gfxFeatureStatus().AppendElement(copy);
+  }
+}
+
 // Matching OS go somewhat beyond the simple equality check because of the
 // "All Windows" and "All OS X" variations.
 //
 // aBlockedOS is describing the system(s) we are trying to block.
 // aSystemOS is describing the system we are running on.
 //
 // aSystemOS should not be "Windows" or "OSX" - it should be set to
 // a particular version instead.
--- a/widget/GfxInfoBase.h
+++ b/widget/GfxInfoBase.h
@@ -70,16 +70,19 @@ class GfxInfoBase : public nsIGfxInfo,
   NS_IMETHOD GetUsesTiling(bool* aUsesTiling) override;
   NS_IMETHOD GetContentUsesTiling(bool* aUsesTiling) override;
   NS_IMETHOD GetOffMainThreadPaintEnabled(
       bool* aOffMainThreadPaintEnabled) override;
   NS_IMETHOD GetOffMainThreadPaintWorkerCount(
       int32_t* aOffMainThreadPaintWorkerCount) override;
   NS_IMETHOD GetTargetFrameRate(uint32_t* aTargetFrameRate) override;
 
+  // Non-XPCOM method to get IPC data:
+  void GetAllFeatures(dom::XPCOMInitData& xpcomInit);
+
   // Initialization function. If you override this, you must call this class's
   // version of Init first.
   // We need Init to be called separately from the constructor so we can
   // register as an observer after all derived classes have been constructed
   // and we know we have a non-zero refcount.
   // Ideally, Init() would be void-return, but the rules of
   // NS_GENERIC_FACTORY_CONSTRUCTOR_INIT require it be nsresult return.
   virtual nsresult Init();