Bug 1206637: P1. Add MediaPrefs convenience class. r=cpearce
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 09 May 2016 14:59:02 +1000
changeset 297112 ac4e5703ea9a44c7f28b5ef6b639481be2c5b6f7
parent 297111 63073a4784cf19fb3b8006134635e2ff2dcb50ce
child 297113 04331c8f60b61d41d887c492f3769f1ab594d7bb
push id76607
push userjyavenard@mozilla.com
push dateThu, 12 May 2016 09:31:21 +0000
treeherdermozilla-inbound@04331c8f60b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1206637
milestone49.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 1206637: P1. Add MediaPrefs convenience class. r=cpearce Almost identical to gfxPrefs, with the exception that preferences can't be set (as it doesn't work with e10s anyway). The generated code size is tiny enough that we don't have to bother about having duplicates. MozReview-Commit-ID: 5SZyscvIzzS
dom/media/MediaPrefs.cpp
dom/media/MediaPrefs.h
dom/media/mediasink/DecodedAudioDataSink.cpp
dom/media/moz.build
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPrefs.h
layout/build/nsLayoutStatics.cpp
widget/GfxInfoBase.cpp
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaPrefs.cpp
@@ -0,0 +1,72 @@
+/* -*- 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 "MediaPrefs.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/StaticPtr.h"
+#include "MainThreadUtils.h"
+
+namespace mozilla {
+
+StaticAutoPtr<MediaPrefs> MediaPrefs::sInstance;
+
+MediaPrefs&
+MediaPrefs::GetSingleton()
+{
+  if (!sInstance) {
+    sInstance = new MediaPrefs;
+    ClearOnShutdown(&sInstance);
+  }
+  MOZ_ASSERT(SingletonExists());
+  return *sInstance;
+}
+
+bool
+MediaPrefs::SingletonExists()
+{
+  return sInstance != nullptr;
+}
+
+MediaPrefs::MediaPrefs()
+{
+  MediaPrefs::AssertMainThread();
+}
+
+void MediaPrefs::AssertMainThread()
+{
+  MOZ_ASSERT(NS_IsMainThread(), "this code must be run on the main thread");
+}
+
+void MediaPrefs::PrefAddVarCache(bool* aVariable,
+                                 const char* aPref,
+                                 bool aDefault)
+{
+  Preferences::AddBoolVarCache(aVariable, aPref, aDefault);
+}
+
+void MediaPrefs::PrefAddVarCache(int32_t* aVariable,
+                                 const char* aPref,
+                                 int32_t aDefault)
+{
+  Preferences::AddIntVarCache(aVariable, aPref, aDefault);
+}
+
+void MediaPrefs::PrefAddVarCache(uint32_t* aVariable,
+                                 const char* aPref,
+                                 uint32_t aDefault)
+{
+  Preferences::AddUintVarCache(aVariable, aPref, aDefault);
+}
+
+void MediaPrefs::PrefAddVarCache(float* aVariable,
+                                 const char* aPref,
+                                 float aDefault)
+{
+  Preferences::AddFloatVarCache(aVariable, aPref, aDefault);
+}
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/media/MediaPrefs.h
@@ -0,0 +1,100 @@
+/* -*- 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 MEDIA_PREFS_H
+#define MEDIA_PREFS_H
+
+// First time MediaPrefs::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.
+
+// To register a preference, you need to add a line in this file using
+// the DECL_MEDIA_PREF macro.
+//
+// For example this line in the .h:
+//   DECL_MEDIA_PREF("media.resampling.enabled",AudioSinkResampling,bool,false);
+// means that you can call
+//   const bool& var = MediaPrefs::AudioSinkResampling();
+// from any thread, you will get the most up to date preference value of
+// "media.resampling.enabled".  If the value is not set, the default would be
+// false.
+
+#define DECL_MEDIA_PREF(Pref, Name, Type, Default)                            \
+public:                                                                       \
+static const Type& Name() { MOZ_ASSERT(SingletonExists()); return GetSingleton().mPref##Name.mValue; } \
+private:                                                                      \
+static const char* Get##Name##PrefName() { return Pref; }                     \
+static Type Get##Name##PrefDefault() { return Default; }                      \
+PrefTemplate<Type, Get##Name##PrefDefault, Get##Name##PrefName> mPref##Name
+
+namespace mozilla {
+
+template<class T> class StaticAutoPtr;
+
+class MediaPrefs final
+{
+
+private:
+  // Since we cannot use const char*, use a function that returns it.
+  template <class T, T Default(), const char* Pref()>
+  class PrefTemplate
+  {
+  public:
+    PrefTemplate()
+    : mValue(Default())
+    {
+      Register(Pref());
+    }
+    T mValue;
+  private:
+    void Register(const char* aPreference)
+    {
+      AssertMainThread();
+      PrefAddVarCache(&mValue, aPreference, mValue);
+    }
+  };
+
+  // This is where DECL_MEDIA_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.
+  DECL_MEDIA_PREF("accessibility.monoaudio.enable", MonoAudio, bool, false);
+  DECL_MEDIA_PREF("media.resampling.enabled",       AudioSinkResampling, bool, false);
+  DECL_MEDIA_PREF("media.resampling.rate",          AudioSinkResampleRate, uint32_t, 48000);
+  DECL_MEDIA_PREF("media.forcestereo.enabled",      AudioSinkForceStereo, bool, true);
+
+  // WARNING:
+  // Please make sure that you've added your new preference to the list above in alphabetical order.
+  // Please do not just append it to the end of the list.
+
+public:
+  // Manage the singleton:
+  static MediaPrefs& GetSingleton();
+  static bool SingletonExists();
+
+private:
+  template<class T> friend class StaticAutoPtr;
+  static StaticAutoPtr<MediaPrefs> sInstance;
+
+  // 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 void AssertMainThread();
+
+  MediaPrefs();
+  MediaPrefs(const MediaPrefs&) = delete;
+  MediaPrefs& operator=(const MediaPrefs&) = delete;
+};
+
+#undef DECL_MEDIA_PREF /* Don't need it outside of this file */
+
+} // namespace mozilla
+
+#endif /* MEDIA_PREFS_H */
--- a/dom/media/mediasink/DecodedAudioDataSink.cpp
+++ b/dom/media/mediasink/DecodedAudioDataSink.cpp
@@ -7,17 +7,17 @@
 #include "nsPrintfCString.h"
 #include "MediaQueue.h"
 #include "DecodedAudioDataSink.h"
 #include "VideoUtils.h"
 #include "AudioConverter.h"
 
 #include "mozilla/CheckedInt.h"
 #include "mozilla/DebugOnly.h"
-#include "gfxPrefs.h"
+#include "MediaPrefs.h"
 
 namespace mozilla {
 
 extern LazyLogModule gMediaDecoderLog;
 #define SINK_LOG(msg, ...) \
   MOZ_LOG(gMediaDecoderLog, LogLevel::Debug, \
     ("DecodedAudioDataSink=%p " msg, this, ##__VA_ARGS__))
 #define SINK_LOG_V(msg, ...) \
@@ -48,36 +48,36 @@ DecodedAudioDataSink::DecodedAudioDataSi
   , mErrored(false)
   , mPlaybackComplete(false)
   , mOwnerThread(aThread)
   , mProcessedQueueLength(0)
   , mFramesParsed(0)
   , mLastEndTime(0)
   , mIsAudioDataAudible(false)
 {
-  bool resampling = gfxPrefs::AudioSinkResampling();
+  bool resampling = MediaPrefs::AudioSinkResampling();
 
   if (resampling) {
-    mOutputRate = gfxPrefs::AudioSinkResampleRate();
+    mOutputRate = MediaPrefs::AudioSinkResampleRate();
   } else if (mInfo.mRate == 44100 || mInfo.mRate == 48000) {
     // The original rate is of good quality and we want to minimize unecessary
     // resampling. The common scenario being that the sampling rate is one or
     // the other, this allows to minimize audio quality regression and hoping
     // content provider want change from those rates mid-stream.
     mOutputRate = mInfo.mRate;
   } else {
     // We will resample all data to match cubeb's preferred sampling rate.
     mOutputRate = AudioStream::GetPreferredRate();
   }
   MOZ_DIAGNOSTIC_ASSERT(mOutputRate, "output rate can't be 0.");
 
-  bool monoAudioEnabled = gfxPrefs::MonoAudio();
+  bool monoAudioEnabled = MediaPrefs::MonoAudio();
 
   mOutputChannels = monoAudioEnabled
-    ? 1 : (gfxPrefs::AudioSinkForceStereo() ? 2 : mInfo.mChannels);
+    ? 1 : (MediaPrefs::AudioSinkForceStereo() ? 2 : mInfo.mChannels);
 }
 
 DecodedAudioDataSink::~DecodedAudioDataSink()
 {
 }
 
 RefPtr<GenericPromise>
 DecodedAudioDataSink::Init(const PlaybackParams& aParams)
--- a/dom/media/moz.build
+++ b/dom/media/moz.build
@@ -114,16 +114,17 @@ EXPORTS += [
     'MediaDecoder.h',
     'MediaDecoderOwner.h',
     'MediaDecoderReader.h',
     'MediaDecoderStateMachine.h',
     'MediaEventSource.h',
     'MediaFormatReader.h',
     'MediaInfo.h',
     'MediaMetadataManager.h',
+    'MediaPrefs.h',
     'MediaQueue.h',
     'MediaRecorder.h',
     'MediaResource.h',
     'MediaResourceCallback.h',
     'MediaSegment.h',
     'MediaStatistics.h',
     'MediaStreamGraph.h',
     'MediaTimer.h',
@@ -225,16 +226,17 @@ UNIFIED_SOURCES += [
     'MediaDecoderReader.cpp',
     'MediaDecoderReaderWrapper.cpp',
     'MediaDecoderStateMachine.cpp',
     'MediaDeviceInfo.cpp',
     'MediaDevices.cpp',
     'MediaFormatReader.cpp',
     'MediaInfo.cpp',
     'MediaManager.cpp',
+    'MediaPrefs.cpp',
     'MediaRecorder.cpp',
     'MediaResource.cpp',
     'MediaShutdownManager.cpp',
     'MediaStreamError.cpp',
     'MediaStreamGraph.cpp',
     'MediaStreamTrack.cpp',
     'MediaTimer.cpp',
     'MediaTrack.cpp',
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -18,16 +18,17 @@
 #include "prprf.h"
 
 #include "gfxCrashReporterUtils.h"
 #include "gfxPlatform.h"
 #include "gfxPrefs.h"
 #include "gfxEnv.h"
 #include "gfxTextRun.h"
 #include "gfxConfig.h"
+#include "MediaPrefs.h"
 
 #ifdef XP_WIN
 #include <process.h>
 #define getpid _getpid
 #else
 #include <unistd.h>
 #endif
 
@@ -582,16 +583,17 @@ gfxPlatform::Init()
     MOZ_RELEASE_ASSERT(NS_IsMainThread());
     if (gEverInitialized) {
         NS_RUNTIMEABORT("Already started???");
     }
     gEverInitialized = true;
 
     // Initialize the preferences by creating the singleton.
     gfxPrefs::GetSingleton();
+    MediaPrefs::GetSingleton();
 
     auto fwd = new CrashStatsLogForwarder("GraphicsCriticalError");
     fwd->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength());
 
     // Drop a note in the crash report if we end up forcing an option that could
     // destabilize things.  New items should be appended at the end (of an existing
     // or in a new section), so that we don't have to know the version to interpret
     // these cryptic strings.
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -130,22 +130,16 @@ private:
     }
     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.
 
-  // It's a short time fix, and will be removed after landing bug 1206637.
-  DECL_GFX_PREF(Live, "accessibility.monoaudio.enable",        MonoAudio, bool, false);
-  DECL_GFX_PREF(Live, "media.resampling.enabled",              AudioSinkResampling, bool, false);
-  DECL_GFX_PREF(Live, "media.resampling.rate",                 AudioSinkResampleRate, uint32_t, 48000);
-  DECL_GFX_PREF(Live, "media.forcestereo.enabled",             AudioSinkForceStereo, bool, true);
-
   // The apz prefs are explained in AsyncPanZoomController.cpp
   DECL_GFX_PREF(Live, "apz.allow_checkerboarding",             APZAllowCheckerboarding, bool, true);
   DECL_GFX_PREF(Live, "apz.allow_immediate_handoff",           APZAllowImmediateHandoff, bool, true);
   DECL_GFX_PREF(Live, "apz.allow_zooming",                     APZAllowZooming, bool, false);
   DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle",          APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
   DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold",      APZAxisBreakoutThreshold, float, 1.0f / 32.0f);
   DECL_GFX_PREF(Live, "apz.axis_lock.direct_pan_angle",        APZAllowedDirectPanAngle, float, float(M_PI / 3.0) /* 60 degrees */);
   DECL_GFX_PREF(Live, "apz.axis_lock.lock_angle",              APZAxisLockAngle, float, float(M_PI / 6.0) /* 30 degrees */);
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -122,16 +122,17 @@ using namespace mozilla::system;
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/IMEStateManager.h"
 #include "nsDocument.h"
 #include "mozilla/dom/HTMLVideoElement.h"
 #include "CameraPreferences.h"
 #include "TouchManager.h"
 #include "MediaDecoder.h"
+#include "MediaPrefs.h"
 #include "mozilla/layers/CompositorLRU.h"
 #include "mozilla/dom/devicestorage/DeviceStorageStatics.h"
 #include "mozilla/ServoBindings.h"
 #include "mozilla/StaticPresData.h"
 #include "mozilla/dom/WebIDLGlobalNameHash.h"
 
 #ifdef MOZ_B2G_BT
 #include "mozilla/dom/BluetoothUUID.h"
@@ -305,16 +306,17 @@ nsLayoutStatics::Initialize()
   ServiceWorkerRegistrar::Initialize();
 
 #ifdef DEBUG
   nsStyleContext::Initialize();
   mozilla::LayerAnimationInfo::Initialize();
 #endif
 
   MediaDecoder::InitStatics();
+  MediaPrefs::GetSingleton();
 
   PromiseDebugging::Init();
 
   layers::CompositorLRU::Init();
 
   mozilla::dom::devicestorage::DeviceStorageStatics::Initialize();
 
   mozilla::dom::WebCryptoThreadPool::Initialize();
--- a/widget/GfxInfoBase.cpp
+++ b/widget/GfxInfoBase.cpp
@@ -26,16 +26,17 @@
 #include "nsIDOMNodeList.h"
 #include "nsTArray.h"
 #include "nsXULAppAPI.h"
 #include "nsIXULAppInfo.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Logging.h"
+#include "MediaPrefs.h"
 #include "gfxPrefs.h"
 #include "gfxPlatform.h"
 #include "gfxConfig.h"
 #include "DriverCrashGuard.h"
 
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
 #endif
@@ -560,16 +561,17 @@ GfxInfoBase::~GfxInfoBase()
 {
 }
 
 nsresult
 GfxInfoBase::Init()
 {
   InitGfxDriverInfoShutdownObserver();
   gfxPrefs::GetSingleton();
+  MediaPrefs::GetSingleton();
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
     os->AddObserver(this, "blocklist-data-gfxItems", true);
   }
 
   return NS_OK;
 }