Backed out 4 changesets (bug 1280822) for leaking nsTArray_base
authorWes Kocher <wkocher@mozilla.com>
Fri, 24 Jun 2016 14:43:41 -0700
changeset 342662 c6bb3db5e1b837a3caa622d673bdc326b171e566
parent 342661 80884ad1ee27b41ef871d5357e95a1d812176702
child 342663 2bc819d1feda178cfb89336c2f29fa8282447339
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1280822
milestone50.0a1
backs outb9a0567cd7c1161a8fd4ec075ec9f9883552d802
93d483583ffa60face65bdd2ccd01bee0284b87e
91715d8e468fdaecf7f3f334527e8508d9d576c5
3db77f57cef49c606cb82f0ee28748bb7e1ca838
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
Backed out 4 changesets (bug 1280822) for leaking nsTArray_base Backed out changeset b9a0567cd7c1 (bug 1280822) Backed out changeset 93d483583ffa (bug 1280822) Backed out changeset 91715d8e468f (bug 1280822) Backed out changeset 3db77f57cef4 (bug 1280822)
gfx/2d/Factory.cpp
gfx/2d/Logging.h
gfx/2d/LoggingConstants.h
gfx/2d/Preferences.cpp
gfx/2d/Preferences.h
gfx/2d/moz.build
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUChild.h
gfx/ipc/GPUParent.cpp
gfx/ipc/GPUParent.h
gfx/ipc/GPUProcessHost.cpp
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/ipc/PGPU.ipdl
gfx/thebes/gfxPrefs.cpp
gfx/thebes/gfxPrefs.h
modules/libpref/Preferences.cpp
modules/libpref/Preferences.h
--- a/gfx/2d/Factory.cpp
+++ b/gfx/2d/Factory.cpp
@@ -45,16 +45,17 @@
 #include "DrawTargetDual.h"
 #include "DrawTargetTiled.h"
 #include "DrawTargetRecording.h"
 
 #include "SourceSurfaceRawData.h"
 
 #include "DrawEventRecorder.h"
 
+#include "Preferences.h"
 #include "Logging.h"
 
 #include "mozilla/CheckedInt.h"
 
 #if defined(MOZ_LOGGING)
 GFX2D_API mozilla::LogModule*
 GetGFX2DLog()
 {
@@ -148,18 +149,19 @@ HasCPUIDBit(unsigned int level, CPUIDReg
   return !!(unsigned(regs[reg]) & bit);
 }
 #endif
 #endif
 
 namespace mozilla {
 namespace gfx {
 
-// In Gecko, this value is managed by gfx.logging.level in gfxPrefs.
-int32_t LoggingPrefs::sGfxLogLevel = LOG_DEFAULT;
+int32_t LoggingPrefs::sGfxLogLevel =
+  PreferenceAccess::RegisterLivePref("gfx.logging.level", &sGfxLogLevel,
+                                     LOG_DEFAULT);
 
 #ifdef WIN32
 ID3D11Device *Factory::mD3D11Device;
 ID2D1Device *Factory::mD2D1Device;
 #endif
 
 DrawEventRecorder *Factory::mRecorder;
 
--- a/gfx/2d/Logging.h
+++ b/gfx/2d/Logging.h
@@ -17,25 +17,39 @@
 #include "mozilla/Tuple.h"
 
 #if defined(MOZ_WIDGET_GONK) || defined(MOZ_WIDGET_ANDROID)
 #include "nsDebug.h"
 #endif
 #include "Point.h"
 #include "BaseRect.h"
 #include "Matrix.h"
-#include "LoggingConstants.h"
 
 #if defined(MOZ_LOGGING)
 extern GFX2D_API mozilla::LogModule* GetGFX2DLog();
 #endif
 
 namespace mozilla {
 namespace gfx {
 
+// Attempting to be consistent with prlog values, but that isn't critical
+// (and note that 5 has a special meaning - see the description
+// with sGfxLogLevel)
+const int LOG_CRITICAL = 1;
+const int LOG_WARNING = 2;
+const int LOG_DEBUG = 3;
+const int LOG_DEBUG_PRLOG = 4;
+const int LOG_EVERYTHING = 5; // This needs to be the highest value
+
+#if defined(DEBUG)
+const int LOG_DEFAULT = LOG_EVERYTHING;
+#else
+const int LOG_DEFAULT = LOG_CRITICAL;
+#endif
+
 #if defined(MOZ_LOGGING)
 inline mozilla::LogLevel PRLogLevelForLevel(int aLevel) {
   switch (aLevel) {
   case LOG_CRITICAL:
     return LogLevel::Error;
   case LOG_WARNING:
     return LogLevel::Warning;
   case LOG_DEBUG:
deleted file mode 100644
--- a/gfx/2d/LoggingConstants.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef MOZILLA_GFX_LOGGING_CONSTANTS_H_
-#define MOZILLA_GFX_LOGGING_CONSTANTS_H_
-
-namespace mozilla {
-namespace gfx {
-
-// Attempting to be consistent with prlog values, but that isn't critical
-// (and note that 5 has a special meaning - see the description
-// with LoggingPrefs::sGfxLogLevel)
-const int LOG_CRITICAL = 1;
-const int LOG_WARNING = 2;
-const int LOG_DEBUG = 3;
-const int LOG_DEBUG_PRLOG = 4;
-const int LOG_EVERYTHING = 5; // This needs to be the highest value
-
-#if defined(DEBUG)
-const int LOG_DEFAULT = LOG_EVERYTHING;
-#else
-const int LOG_DEFAULT = LOG_CRITICAL;
-#endif
-
-} // namespace gfx
-} // namespace mozilla
-
-#endif /* MOZILLA_GFX_LOGGING_CONSTANTS_H_ */
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Preferences.cpp
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "Preferences.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/Vector.h"
+
+namespace mozilla {
+namespace gfx {
+
+static PreferenceAccess* sAccess = nullptr;
+
+struct Int32Pref
+{
+  const char* name;
+  int32_t* varPtr;
+};
+
+static Vector<Int32Pref>& Int32Prefs()
+{
+  static Vector<Int32Pref>* sInt32Prefs = new Vector<Int32Pref>();
+  return *sInt32Prefs;
+}
+
+/* static */
+int32_t
+PreferenceAccess::RegisterLivePref(const char* aName, int32_t* aVar,
+                                   int32_t aDefault)
+{
+  if (!Int32Prefs().append(Int32Pref{ aName, aVar })) {
+    MOZ_CRASH("GFX: RegisterLivePref failure");
+  }
+  return aDefault;
+}
+
+/* static */
+void
+PreferenceAccess::SetAccess(PreferenceAccess* aAccess)
+{
+  sAccess = aAccess;
+  if (!sAccess) {
+    return;
+  }
+
+#if defined(DEBUG)
+  static uint32_t sProvideAccessCount;
+  MOZ_ASSERT(!sProvideAccessCount++,
+             "ProvideAccess must only be called with non-nullptr once.");
+#endif
+
+  for (Int32Pref pref : Int32Prefs()) {
+    sAccess->LivePref(pref.name, pref.varPtr, *pref.varPtr);
+  }
+  Int32Prefs().clearAndFree();
+}
+
+} // namespace gfx
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Preferences.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_gfx_Preferences_h
+#define mozilla_gfx_Preferences_h
+
+namespace mozilla {
+namespace gfx {
+
+class PreferenceAccess
+{
+public:
+  virtual ~PreferenceAccess() {};
+
+  // This will be called with the derived class, so we will can register the
+  // callbacks with it.
+  static void SetAccess(PreferenceAccess* aAccess);
+
+  static int32_t RegisterLivePref(const char* aName, int32_t* aVar,
+                                  int32_t aDefault);
+protected:
+  // This should connect the variable aVar to be updated whenever a preference
+  // aName is modified.  aDefault would be used if the preference is undefined,
+  // so that we always get the valid value for aVar.
+  virtual void LivePref(const char* aName, int32_t* aVar, int32_t aDefault) = 0;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif // mozilla_gfx_Preferences_h
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -28,23 +28,23 @@ EXPORTS.mozilla.gfx += [
     'Filters.h',
     'Helpers.h',
     'HelpersCairo.h',
     'IterableArena.h',
     'JobScheduler.h',
     'JobScheduler_posix.h',
     'JobScheduler_win32.h',
     'Logging.h',
-    'LoggingConstants.h',
     'Matrix.h',
     'MatrixFwd.h',
     'NumericTools.h',
     'PathHelpers.h',
     'PatternHelpers.h',
     'Point.h',
+    'Preferences.h',
     'Quaternion.h',
     'RecordedEvent.h',
     'RecordingTypes.h',
     'Rect.h',
     'Scale.h',
     'ScaleFactor.h',
     'ScaleFactors2D.h',
     'SourceSurfaceCairo.h',
@@ -156,16 +156,17 @@ UNIFIED_SOURCES += [
     'FilterProcessingScalar.cpp',
     'ImageScaling.cpp',
     'JobScheduler.cpp',
     'Matrix.cpp',
     'Path.cpp',
     'PathCairo.cpp',
     'PathHelpers.cpp',
     'PathRecording.cpp',
+    'Preferences.cpp',
     'Quaternion.cpp',
     'RecordedEvent.cpp',
     'Scale.cpp',
     'ScaledFontBase.cpp',
     'ScaledFontCairo.cpp',
     'SFNTData.cpp',
     'SFNTNameTable.cpp',
     'SourceSurfaceCairo.cpp',
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "GPUChild.h"
-#include "gfxPrefs.h"
 #include "GPUProcessHost.h"
 
 namespace mozilla {
 namespace gfx {
 
 GPUChild::GPUChild(GPUProcessHost* aHost)
  : mHost(aHost)
 {
@@ -17,38 +16,16 @@ GPUChild::GPUChild(GPUProcessHost* aHost
 }
 
 GPUChild::~GPUChild()
 {
   MOZ_COUNT_DTOR(GPUChild);
 }
 
 void
-GPUChild::Init()
-{
-  // Build a list of prefs the GPU process will need. Note that because we
-  // limit the GPU process to prefs contained in gfxPrefs, we can simplify
-  // the message in two ways: one, we only need to send its index in gfxPrefs
-  // rather than its name, and two, we only need to send prefs that don't
-  // have their default value.
-  nsTArray<GfxPrefSetting> prefs;
-  for (auto pref : gfxPrefs::all()) {
-    if (pref->HasDefaultValue()) {
-      return;
-    }
-
-    GfxPrefValue value;
-    pref->GetCachedValue(&value);
-    prefs.AppendElement(GfxPrefSetting(pref->Index(), value));
-  }
-
-  SendInit(prefs);
-}
-
-void
 GPUChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   mHost->OnChannelClosed();
 }
 
 class DeferredDeleteGPUChild : public Runnable
 {
 public:
--- a/gfx/ipc/GPUChild.h
+++ b/gfx/ipc/GPUChild.h
@@ -15,18 +15,16 @@ namespace gfx {
 class GPUProcessHost;
 
 class GPUChild final : public PGPUChild
 {
 public:
   explicit GPUChild(GPUProcessHost* aHost);
   ~GPUChild();
 
-  void Init();
-
   static void Destroy(UniquePtr<GPUChild>&& aChild);
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
 private:
   GPUProcessHost* mHost;
 };
 
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -1,16 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=99: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #include "GPUParent.h"
 #include "gfxConfig.h"
-#include "gfxPrefs.h"
 #include "GPUProcessHost.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/ipc/ProcessChild.h"
 
 namespace mozilla {
 namespace gfx {
 
 using namespace ipc;
@@ -27,38 +26,22 @@ bool
 GPUParent::Init(base::ProcessId aParentPid,
                 MessageLoop* aIOLoop,
                 IPC::Channel* aChannel)
 {
   if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
     return false;
   }
 
-  // Ensure gfxPrefs are initialized.
-  gfxPrefs::GetSingleton();
-
   return true;
 }
 
 bool
-GPUParent::RecvInit(nsTArray<GfxPrefSetting>&& prefs)
+GPUParent::RecvNothing()
 {
-  for (auto setting : prefs) {
-    gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()];
-    pref->SetCachedValue(setting.value());
-  }
-
-  return true;
-}
-
-bool
-GPUParent::RecvUpdatePref(const GfxPrefSetting& setting)
-{
-  gfxPrefs::Pref* pref = gfxPrefs::all()[setting.index()];
-  pref->SetCachedValue(setting.value());
   return true;
 }
 
 void
 GPUParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (AbnormalShutdown == aWhy) {
     NS_WARNING("Shutting down GPU process early due to a crash!");
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -16,18 +16,17 @@ class GPUParent final : public PGPUParen
 public:
   GPUParent();
   ~GPUParent();
 
   bool Init(base::ProcessId aParentPid,
             MessageLoop* aIOLoop,
             IPC::Channel* aChannel);
 
-  bool RecvInit(nsTArray<GfxPrefSetting>&& prefs) override;
-  bool RecvUpdatePref(const GfxPrefSetting& pref) override;
+  bool RecvNothing() override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif // _include_gfx_ipc_GPUParent_h__
--- a/gfx/ipc/GPUProcessHost.cpp
+++ b/gfx/ipc/GPUProcessHost.cpp
@@ -117,18 +117,16 @@ GPUProcessHost::InitAfterConnect(bool aS
 
   mLaunchPhase = LaunchPhase::Complete;
 
   if (aSucceeded) {
     mGPUChild = MakeUnique<GPUChild>(this);
     DebugOnly<bool> rv =
       mGPUChild->Open(GetChannel(), base::GetProcId(GetChildProcessHandle()));
     MOZ_ASSERT(rv);
-
-    mGPUChild->Init();
   }
 
   if (mListener) {
     mListener->OnProcessLaunchComplete(this);
   }
 }
 
 void
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -14,23 +14,23 @@ namespace gfx {
 
 using namespace mozilla::layers;
 
 static StaticAutoPtr<GPUProcessManager> sSingleton;
 
 GPUProcessManager*
 GPUProcessManager::Get()
 {
+  MOZ_ASSERT(sSingleton);
   return sSingleton;
 }
 
 void
 GPUProcessManager::Initialize()
 {
-  MOZ_ASSERT(XRE_IsParentProcess());
   sSingleton = new GPUProcessManager();
 }
 
 void
 GPUProcessManager::Shutdown()
 {
   sSingleton = nullptr;
 }
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -101,21 +101,16 @@ public:
   bool UpdateRemoteContentController(uint64_t aLayersId,
                                      dom::ContentParent* aContentParent,
                                      const dom::TabId& aTabId,
                                      dom::TabParent* aBrowserParent);
 
   void OnProcessLaunchComplete(GPUProcessHost* aHost) override;
   void OnProcessUnexpectedShutdown(GPUProcessHost* aHost) override;
 
-  // Returns access to the PGPU protocol if a GPU process is present.
-  GPUChild* GetGPUChild() {
-    return mGPUChild;
-  }
-
 private:
   // Called from our xpcom-shutdown observer.
   void OnXPCOMShutdown();
 
 private:
   GPUProcessManager();
 
   // Permanently disable the GPU process and record a message why.
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -1,34 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-include protocol PContent;
-
 namespace mozilla {
 namespace gfx {
 
-union GfxPrefValue {
-  bool;
-  int32_t;
-  uint32_t;
-  float;
-};
-
-struct GfxPrefSetting {
-  int32_t index;
-  GfxPrefValue value;
-};
-
 sync protocol PGPU
 {
 parent:
-  // Sent by the UI process to initiate core settings.
-  async Init(GfxPrefSetting[] prefs);
-
-  // Called to update a gfx preference.
-  async UpdatePref(GfxPrefSetting pref);
+  // Sent by the UI process to initiate shutdown.
+  async Nothing();
 };
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/thebes/gfxPrefs.cpp
+++ b/gfx/thebes/gfxPrefs.cpp
@@ -1,29 +1,42 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "gfxPrefs.h"
 
+#include "mozilla/Preferences.h"
 #include "MainThreadUtils.h"
-#include "nsXULAppAPI.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/unused.h"
-#include "mozilla/gfx/Logging.h"
-#include "mozilla/gfx/GPUChild.h"
-#include "mozilla/gfx/GPUProcessManager.h"
+#include "mozilla/gfx/Preferences.h"
 
 using namespace mozilla;
 
-nsTArray<gfxPrefs::Pref*> gfxPrefs::sGfxPrefList;
 gfxPrefs* gfxPrefs::sInstance = nullptr;
 bool gfxPrefs::sInstanceHasBeenDestroyed = false;
 
+class PreferenceAccessImpl : public mozilla::gfx::PreferenceAccess
+{
+public:
+  virtual ~PreferenceAccessImpl();
+  virtual void LivePref(const char* aName, int32_t* aVar, int32_t aDefault) override;
+};
+
+PreferenceAccessImpl::~PreferenceAccessImpl()
+{
+}
+
+void PreferenceAccessImpl::LivePref(const char* aName,
+                                    int32_t* aVar,
+                                    int32_t aDefault)
+{
+  Preferences::AddIntVarCache(aVar, aName, aDefault);
+}
+
 void
 gfxPrefs::DestroySingleton()
 {
   if (sInstance) {
     delete sInstance;
     sInstance = nullptr;
     sInstanceHasBeenDestroyed = true;
   }
@@ -33,234 +46,97 @@ gfxPrefs::DestroySingleton()
 bool
 gfxPrefs::SingletonExists()
 {
   return sInstance != nullptr;
 }
 
 gfxPrefs::gfxPrefs()
 {
-  // UI, content, and plugin processes use XPCOM and should have prefs
-  // ready by the time we initialize gfxPrefs.
-  MOZ_ASSERT_IF(XRE_IsContentProcess() ||
-                XRE_IsParentProcess() ||
-                XRE_GetProcessType() == GeckoProcessType_Plugin,
-                Preferences::IsServiceAvailable());
-
   gfxPrefs::AssertMainThread();
-}
-
-void
-gfxPrefs::Init()
-{
-  // Set up Moz2D prefs.
-  mPrefGfxLoggingLevel.SetChangeCallback([]() -> void {
-    mozilla::gfx::LoggingPrefs::sGfxLogLevel = GetSingleton().mPrefGfxLoggingLevel.GetLiveValue();
-  });
+  mMoz2DPrefAccess = new PreferenceAccessImpl;
+  mozilla::gfx::PreferenceAccess::SetAccess(mMoz2DPrefAccess);
 }
 
 gfxPrefs::~gfxPrefs()
 {
   gfxPrefs::AssertMainThread();
-  mPrefGfxLoggingLevel.SetChangeCallback(nullptr);
-  sGfxPrefList.Clear();
+
+  // gfxPrefs is a singleton, we can reset this to null once
+  // it goes away.
+  mozilla::gfx::PreferenceAccess::SetAccess(nullptr);
+  delete mMoz2DPrefAccess;
+  mMoz2DPrefAccess = nullptr;
 }
 
 void gfxPrefs::AssertMainThread()
 {
   MOZ_ASSERT(NS_IsMainThread(), "this code must be run on the main thread");
 }
 
-void
-gfxPrefs::Pref::OnChange()
-{
-  if (auto gpm = gfx::GPUProcessManager::Get()) {
-    if (gfx::GPUChild* gpu = gpm->GetGPUChild()) {
-      GfxPrefValue value;
-      GetCachedValue(&value);
-      Unused << gpu->SendUpdatePref(gfx::GfxPrefSetting(mIndex, value));
-    }
-  }
-  FireChangeCallback();
-}
-
-void
-gfxPrefs::Pref::FireChangeCallback()
-{
-  if (mChangeCallback) {
-    mChangeCallback();
-  }
-}
-
-void
-gfxPrefs::Pref::SetChangeCallback(ChangeCallback aCallback)
-{
-  mChangeCallback = aCallback;
-
-  if (!IsParentProcess() && IsPrefsServiceAvailable()) {
-    // If we're in the parent process, we watch prefs by default so we can
-    // send changes over to the GPU process. Otherwise, we need to add or
-    // remove a watch for the pref now.
-    if (aCallback) {
-      WatchChanges(Name(), this);
-    } else {
-      UnwatchChanges(Name(), this);
-    }
-  }
-
-  // Fire the callback once to make initialization easier for the caller.
-  FireChangeCallback();
-}
-
-// On lightweight processes such as for GMP and GPU, XPCOM is not initialized,
-// and therefore we don't have access to Preferences. When XPCOM is not
-// available we rely on manual synchronization of gfxPrefs values over IPC.
-/* static */ bool
-gfxPrefs::IsPrefsServiceAvailable()
-{
-  return Preferences::IsServiceAvailable();
-}
-
-/* static */ bool
-gfxPrefs::IsParentProcess()
-{
-  return XRE_IsParentProcess();
-}
-
 void gfxPrefs::PrefAddVarCache(bool* aVariable,
                                const char* aPref,
                                bool aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::AddBoolVarCache(aVariable, aPref, aDefault);
 }
 
 void gfxPrefs::PrefAddVarCache(int32_t* aVariable,
                                const char* aPref,
                                int32_t aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::AddIntVarCache(aVariable, aPref, aDefault);
 }
 
 void gfxPrefs::PrefAddVarCache(uint32_t* aVariable,
                                const char* aPref,
                                uint32_t aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::AddUintVarCache(aVariable, aPref, aDefault);
 }
 
 void gfxPrefs::PrefAddVarCache(float* aVariable,
                                const char* aPref,
                                float aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::AddFloatVarCache(aVariable, aPref, aDefault);
 }
 
 bool gfxPrefs::PrefGet(const char* aPref, bool aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   return Preferences::GetBool(aPref, aDefault);
 }
 
 int32_t gfxPrefs::PrefGet(const char* aPref, int32_t aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   return Preferences::GetInt(aPref, aDefault);
 }
 
 uint32_t gfxPrefs::PrefGet(const char* aPref, uint32_t aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   return Preferences::GetUint(aPref, aDefault);
 }
 
 float gfxPrefs::PrefGet(const char* aPref, float aDefault)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   return Preferences::GetFloat(aPref, aDefault);
 }
 
 void gfxPrefs::PrefSet(const char* aPref, bool aValue)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::SetBool(aPref, aValue);
 }
 
 void gfxPrefs::PrefSet(const char* aPref, int32_t aValue)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::SetInt(aPref, aValue);
 }
 
 void gfxPrefs::PrefSet(const char* aPref, uint32_t aValue)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::SetUint(aPref, aValue);
 }
 
 void gfxPrefs::PrefSet(const char* aPref, float aValue)
 {
-  MOZ_ASSERT(IsPrefsServiceAvailable());
   Preferences::SetFloat(aPref, aValue);
 }
 
-static void
-OnGfxPrefChanged(const char* aPrefname, void* aClosure)
-{
-  reinterpret_cast<gfxPrefs::Pref*>(aClosure)->OnChange();
-}
-
-void gfxPrefs::WatchChanges(const char* aPrefname, Pref* aPref)
-{
-  MOZ_ASSERT(IsPrefsServiceAvailable());
-  Preferences::RegisterCallback(OnGfxPrefChanged, aPrefname, aPref, Preferences::ExactMatch);
-}
-
-void gfxPrefs::UnwatchChanges(const char* aPrefname, Pref* aPref)
-{
-  // The Preferences service can go offline before gfxPrefs is destroyed.
-  if (IsPrefsServiceAvailable()) {
-    Preferences::UnregisterCallback(OnGfxPrefChanged, aPrefname, aPref, Preferences::ExactMatch);
-  }
-}
-
-void gfxPrefs::CopyPrefValue(const bool* aValue, GfxPrefValue* aOutValue)
-{
-  *aOutValue = *aValue;
-}
-
-void gfxPrefs::CopyPrefValue(const int32_t* aValue, GfxPrefValue* aOutValue)
-{
-  *aOutValue = *aValue;
-}
-
-void gfxPrefs::CopyPrefValue(const uint32_t* aValue, GfxPrefValue* aOutValue)
-{
-  *aOutValue = *aValue;
-}
-
-void gfxPrefs::CopyPrefValue(const float* aValue, GfxPrefValue* aOutValue)
-{
-  *aOutValue = *aValue;
-}
-
-void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, bool* aOutValue)
-{
-  *aOutValue = aValue->get_bool();
-}
-
-void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, int32_t* aOutValue)
-{
-  *aOutValue = aValue->get_int32_t();
-}
-
-void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, uint32_t* aOutValue)
-{
-  *aOutValue = aValue->get_uint32_t();
-}
-
-void gfxPrefs::CopyPrefValue(const GfxPrefValue* aValue, float* aOutValue)
-{
-  *aOutValue = aValue->get_float();
-}
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -4,19 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_PREFS_H
 #define GFX_PREFS_H
 
 #include <cmath>                 // for M_PI
 #include <stdint.h>
 #include "mozilla/Assertions.h"
-#include "mozilla/Function.h"
-#include "mozilla/gfx/LoggingConstants.h"
-#include "nsTArray.h"
 
 // First time gfxPrefs::GetSingleton() needs to be called on the main thread,
 // before any of the methods accessing the values are used, but after
 // the Preferences system has been initialized.
 
 // The static methods to access the preference value are safe to call
 // from any thread after that first call.
 
@@ -53,125 +50,65 @@
 // in the first place, so be careful.  You need to be ready for the
 // values changing mid execution, and if you're using those preferences
 // in any setup and initialization, you may need to do extra work.
 
 // Note 2: Prefs can be set by using the corresponding Set method. For
 // example, if the accessor is Foo() then calling SetFoo(...) will update
 // the preference and also change the return value of subsequent Foo() calls.
 // This is true even for 'Once' prefs which otherwise do not change if the
-// pref is updated after initialization. Changing gfxPrefs values in content
-// processes will not affect the result in other processes. Changing gfxPrefs
-// values in the GPU process is not supported at all.
+// pref is updated after initialization.
 
-#define DECL_GFX_PREF(Update, Prefname, Name, Type, Default)                  \
+#define DECL_GFX_PREF(Update, Pref, Name, Type, Default)                     \
 public:                                                                       \
 static Type Name() { MOZ_ASSERT(SingletonExists()); return GetSingleton().mPref##Name.mValue; } \
-static void Set##Name(Type aVal) { MOZ_ASSERT(SingletonExists());             \
+static void Set##Name(Type aVal) { MOZ_ASSERT(SingletonExists()); \
     GetSingleton().mPref##Name.Set(UpdatePolicy::Update, Get##Name##PrefName(), aVal); } \
-static const char* Get##Name##PrefName() { return Prefname; }                 \
+static const char* Get##Name##PrefName() { return Pref; }                     \
 static Type Get##Name##PrefDefault() { return Default; }                      \
 private:                                                                      \
-static Pref* Get##Name##PrefPtr() { return &GetSingleton().mPref##Name; }     \
 PrefTemplate<UpdatePolicy::Update, Type, Get##Name##PrefDefault, Get##Name##PrefName> mPref##Name
 
-namespace mozilla {
-namespace gfx {
-class GfxPrefValue;   // defined in PGPU.ipdl
-} // namespace gfx
-} // namespace mozilla
-
+class PreferenceAccessImpl;
 class gfxPrefs;
 class gfxPrefs final
 {
-  typedef mozilla::gfx::GfxPrefValue GfxPrefValue;
+private:
+  /// See Logging.h.  This lets Moz2D access preference values it owns.
+  PreferenceAccessImpl* mMoz2DPrefAccess;
 
 private:
   // Enums for the update policy.
   enum class UpdatePolicy {
     Skip, // Set the value to default, skip any Preferences calls
     Once, // Evaluate the preference once, unchanged during the session
     Live  // Evaluate the preference and set callback so it stays current/live
   };
 
-public:
-  class Pref
-  {
-  public:
-    Pref() : mChangeCallback(nullptr)
-    {
-      mIndex = sGfxPrefList.Length();
-      sGfxPrefList.AppendElement(this);
-    }
-
-    size_t Index() const { return mIndex; }
-    void OnChange();
-
-    typedef void (*ChangeCallback)();
-    void SetChangeCallback(ChangeCallback aCallback);
-
-    virtual const char* Name() const = 0;
-
-    // Returns true if the value is default, false if changed.
-    virtual bool HasDefaultValue() const = 0;
-
-    // Returns the pref value as a discriminated union.
-    virtual void GetCachedValue(GfxPrefValue* aOutValue) const = 0;
-
-    // Change the cached value. GfxPrefValue must be a compatible type.
-    virtual void SetCachedValue(const GfxPrefValue& aOutValue) = 0;
-
-  protected:
-    void FireChangeCallback();
-
-  private:
-    size_t mIndex;
-    ChangeCallback mChangeCallback;
-  };
-
-  static const nsTArray<Pref*>& all() {
-    return sGfxPrefList;
-  }
-
-private:
   // Since we cannot use const char*, use a function that returns it.
-  template <UpdatePolicy Update, class T, T Default(void), const char* Prefname(void)>
-  class PrefTemplate : public Pref
+  template <UpdatePolicy Update, class T, T Default(void), const char* Pref(void)>
+  class PrefTemplate
   {
   public:
     PrefTemplate()
     : mValue(Default())
     {
-      // If not using the Preferences service, values are synced over IPC, so
-      // there's no need to register us as a Preferences observer.
-      if (IsPrefsServiceAvailable()) {
-        Register(Update, Prefname());
-      }
-      // By default we only watch changes in the parent process, to communicate
-      // changes to the GPU process.
-      if (IsParentProcess() && Update == UpdatePolicy::Live) {
-        WatchChanges(Prefname(), this);
-      }
-    }
-    ~PrefTemplate() {
-      if (IsParentProcess() && Update == UpdatePolicy::Live) {
-        UnwatchChanges(Prefname(), this);
-      }
+      Register(Update, Pref());
     }
     void Register(UpdatePolicy aUpdate, const char* aPreference)
     {
       AssertMainThread();
-      switch (aUpdate) {
+      switch(aUpdate) {
         case UpdatePolicy::Skip:
           break;
         case UpdatePolicy::Once:
           mValue = PrefGet(aPreference, mValue);
           break;
         case UpdatePolicy::Live:
-          PrefAddVarCache(&mValue, aPreference, mValue);
+          PrefAddVarCache(&mValue,aPreference, mValue);
           break;
         default:
           MOZ_CRASH("Incomplete switch");
       }
     }
     void Set(UpdatePolicy aUpdate, const char* aPref, T aValue)
     {
       AssertMainThread();
@@ -182,46 +119,16 @@ private:
           break;
         case UpdatePolicy::Once:
           mValue = PrefGet(aPref, mValue);
           break;
         default:
           MOZ_CRASH("Incomplete switch");
       }
     }
-    const char *Name() const override {
-      return Prefname();
-    }
-    // When using the Preferences service, the change callback can be triggered
-    // *before* our cached value is updated, so we expose a method to grab the
-    // true live value.
-    T GetLiveValue() const {
-      if (IsPrefsServiceAvailable()) {
-        return PrefGet(Prefname(), mValue);
-      }
-      return mValue;
-    }
-    bool HasDefaultValue() const override {
-      return mValue == Default();
-    }
-    void GetCachedValue(GfxPrefValue* aOutValue) const override {
-      CopyPrefValue(&mValue, aOutValue);
-    }
-    void SetCachedValue(const GfxPrefValue& aOutValue) override {
-      // This is only used in non-XPCOM processes.
-      MOZ_ASSERT(!IsPrefsServiceAvailable());
-
-      T newValue;
-      CopyPrefValue(&aOutValue, &newValue);
-
-      if (mValue != newValue) {
-        mValue = newValue;
-        FireChangeCallback();
-      }
-    }
     T mValue;
   };
 
   // This is where DECL_GFX_PREF for each of the preferences should go.
   // We will keep these in an alphabetical order to make it easier to see if
   // a method accessing a pref already exists. Just add yours in the list.
 
   // The apz prefs are explained in AsyncPanZoomController.cpp
@@ -349,18 +256,17 @@ private:
   DECL_GFX_PREF(Once, "gfx.direct2d.disabled",                 Direct2DDisabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.direct2d.force-enabled",            Direct2DForceEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.draw-color-bars",                   CompositorDrawColorBars, bool, false);
   DECL_GFX_PREF(Once, "gfx.e10s.hide-plugins-for-scroll",      HidePluginsForScroll, bool, true);
   DECL_GFX_PREF(Once, "gfx.font_rendering.directwrite.force-enabled", DirectWriteFontRenderingForceEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels",     GrallocFenceWithReadPixels, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.enabled",                LayerScopeEnabled, bool, false);
   DECL_GFX_PREF(Live, "gfx.layerscope.port",                   LayerScopePort, int32_t, 23456);
-  // Note that        "gfx.logging.level" is defined in Logging.h.
-  DECL_GFX_PREF(Live, "gfx.logging.level",                     GfxLoggingLevel, int32_t, mozilla::gfx::LOG_DEFAULT);
+  // Note that        "gfx.logging.level" is defined in Logging.h
   DECL_GFX_PREF(Once, "gfx.logging.crash.length",              GfxLoggingCrashLength, uint32_t, 16);
   DECL_GFX_PREF(Live, "gfx.logging.painted-pixel-count.enabled",GfxLoggingPaintedPixelCountEnabled, bool, false);
   // The maximums here are quite conservative, we can tighten them if problems show up.
   DECL_GFX_PREF(Once, "gfx.logging.texture-usage.enabled",     GfxLoggingTextureUsageEnabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.logging.peak-texture-usage.enabled",GfxLoggingPeakTextureUsageEnabled, bool, false);
   DECL_GFX_PREF(Once, "gfx.max-alloc-size",                    MaxAllocSize, int32_t, (int32_t)500000000);
   DECL_GFX_PREF(Once, "gfx.max-texture-size",                  MaxTextureSize, int32_t, (int32_t)32767);
   DECL_GFX_PREF(Live, "gfx.partialpresent.force",              PartialPresent, int32_t, 0);
@@ -570,61 +476,41 @@ private:
 
 public:
   // Manage the singleton:
   static gfxPrefs& GetSingleton()
   {
     MOZ_ASSERT(!sInstanceHasBeenDestroyed, "Should never recreate a gfxPrefs instance!");
     if (!sInstance) {
       sInstance = new gfxPrefs;
-      sInstance->Init();
     }
     MOZ_ASSERT(SingletonExists());
     return *sInstance;
   }
   static void DestroySingleton();
   static bool SingletonExists();
 
 private:
   static gfxPrefs* sInstance;
   static bool sInstanceHasBeenDestroyed;
-  static nsTArray<Pref*> sGfxPrefList;
 
 private:
-  // The constructor cannot access GetSingleton(), since sInstance (necessarily)
-  // has not been assigned yet. Follow-up initialization that needs GetSingleton()
-  // must be added to Init().
-  void Init();
-
-  static bool IsPrefsServiceAvailable();
-  static bool IsParentProcess();
   // Creating these to avoid having to include Preferences.h in the .h
   static void PrefAddVarCache(bool*, const char*, bool);
   static void PrefAddVarCache(int32_t*, const char*, int32_t);
   static void PrefAddVarCache(uint32_t*, const char*, uint32_t);
   static void PrefAddVarCache(float*, const char*, float);
   static bool PrefGet(const char*, bool);
   static int32_t PrefGet(const char*, int32_t);
   static uint32_t PrefGet(const char*, uint32_t);
   static float PrefGet(const char*, float);
   static void PrefSet(const char* aPref, bool aValue);
   static void PrefSet(const char* aPref, int32_t aValue);
   static void PrefSet(const char* aPref, uint32_t aValue);
   static void PrefSet(const char* aPref, float aValue);
-  static void WatchChanges(const char* aPrefname, Pref* aPref);
-  static void UnwatchChanges(const char* aPrefname, Pref* aPref);
-  // Creating these to avoid having to include PGPU.h in the .h
-  static void CopyPrefValue(const bool* aValue, GfxPrefValue* aOutValue);
-  static void CopyPrefValue(const int32_t* aValue, GfxPrefValue* aOutValue);
-  static void CopyPrefValue(const uint32_t* aValue, GfxPrefValue* aOutValue);
-  static void CopyPrefValue(const float* aValue, GfxPrefValue* aOutValue);
-  static void CopyPrefValue(const GfxPrefValue* aValue, bool* aOutValue);
-  static void CopyPrefValue(const GfxPrefValue* aValue, int32_t* aOutValue);
-  static void CopyPrefValue(const GfxPrefValue* aValue, uint32_t* aOutValue);
-  static void CopyPrefValue(const GfxPrefValue* aValue, float* aOutValue);
 
   static void AssertMainThread();
 
   gfxPrefs();
   ~gfxPrefs();
   gfxPrefs(const gfxPrefs&) = delete;
   gfxPrefs& operator=(const gfxPrefs&) = delete;
 };
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -430,23 +430,16 @@ Preferences::GetInstanceForService()
   NS_DispatchToMainThread(runnable);
 
   NS_ADDREF(sPreferences);
   return sPreferences;
 }
 
 // static
 bool
-Preferences::IsServiceAvailable()
-{
-  return !!sPreferences;
-}
-
-// static
-bool
 Preferences::InitStaticMembers()
 {
 #ifndef MOZ_B2G
   MOZ_ASSERT(NS_IsMainThread());
 #endif
 
   if (!sShutdown && !sPreferences) {
     nsCOMPtr<nsIPrefService> prefService =
--- a/modules/libpref/Preferences.h
+++ b/modules/libpref/Preferences.h
@@ -47,21 +47,16 @@ public:
   NS_FORWARD_NSIPREFBRANCH(sRootBranch->)
   NS_DECL_NSIOBSERVER
 
   Preferences();
 
   nsresult Init();
 
   /**
-   * Returns true if the Preferences service is available, false otherwise.
-   */
-  static bool IsServiceAvailable();
-
-  /**
    * Reset loaded user prefs then read them
    */
   static nsresult ResetAndReadUserPrefs();
 
   /**
    * Returns the singleton instance which is addreffed.
    */
   static Preferences* GetInstanceForService();