Bug 1206637: P1. Add MediaPrefs convenience class. r?cpearce draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Mon, 09 May 2016 14:59:02 +1000
changeset 366201 30b2332a0723a42477b219c1f894c2a25ca06f5a
parent 365730 3461f3cae78495f100a0f7d3d2e0b89292d3ec02
child 366202 97fac3f805965bf530df6744be1ab1d3328c84e0
child 366228 9b3b27524046c48d17ee43a9ab471620f6847f5b
push id17922
push userbmo:jyavenard@mozilla.com
push dateThu, 12 May 2016 05:38:51 +0000
reviewerscpearce
bugs1206637
milestone49.0a1
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, ...) \
@@ -47,36 +47,36 @@ DecodedAudioDataSink::DecodedAudioDataSi
   , mWritten(0)
   , mErrored(false)
   , mPlaybackComplete(false)
   , mOwnerThread(aThread)
   , mProcessedQueueLength(0)
   , mFramesParsed(0)
   , mLastEndTime(0)
 {
-  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"
 
 #if defined(MOZ_CRASHREPORTER)
 #include "nsExceptionHandler.h"
 #endif
 
@@ -559,16 +560,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;
 }