bug 1519562 send AudioParamDescriptors from registerProcessor() to AudioContext r=padenot
authorKarl Tomlinson <karlt+@karlt.net>
Thu, 21 Feb 2019 03:12:59 +0000
changeset 460211 8de3a62c5f7616292ae2432cbd46a2b4497bcb5f
parent 460210 601af10b11006fea91df5d39bef3e363b9f74f3d
child 460212 e65b65bf6a76a2d33be297917d171d8c6ebefb9a
push id35588
push usernbeleuzu@mozilla.com
push dateThu, 21 Feb 2019 15:59:59 +0000
treeherdermozilla-central@7fba2ab9df84 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1519562
milestone67.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 1519562 send AudioParamDescriptors from registerProcessor() to AudioContext r=padenot Differential Revision: https://phabricator.services.mozilla.com/D20274
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
dom/media/webaudio/AudioWorkletGlobalScope.cpp
dom/media/webaudio/AudioWorkletImpl.h
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -1193,16 +1193,23 @@ void AudioContext::Mute() const {
 
 void AudioContext::Unmute() const {
   MOZ_ASSERT(!mIsOffline);
   if (mDestination) {
     mDestination->Unmute();
   }
 }
 
+void AudioContext::SetParamMapForWorkletName(
+    const nsAString& aName, AudioParamDescriptorMap* aParamMap) {
+  MOZ_ASSERT(!mWorkletParamDescriptors.GetValue(aName));
+  Unused << mWorkletParamDescriptors.Put(aName, std::move(*aParamMap),
+                                         fallible);
+}
+
 size_t AudioContext::SizeOfIncludingThis(
     mozilla::MallocSizeOf aMallocSizeOf) const {
   // AudioNodes are tracked separately because we do not want the AudioContext
   // to track all of the AudioNodes it creates, so we wouldn't be able to
   // traverse them from here.
 
   size_t amount = aMallocSizeOf(this);
   if (mListener) {
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -2,16 +2,17 @@
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 AudioContext_h_
 #define AudioContext_h_
 
+#include "AudioParamDescriptorMap.h"
 #include "mozilla/dom/OfflineAudioContextBinding.h"
 #include "MediaBufferDecoder.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/TypedArray.h"
 #include "mozilla/RelativeTimeline.h"
 #include "mozilla/UniquePtr.h"
@@ -306,16 +307,20 @@ class AudioContext final : public DOMEve
   void UnregisterNode(AudioNode* aNode);
 
   void OnStateChanged(void* aPromise, AudioContextState aNewState);
 
   BasicWaveFormCache* GetBasicWaveFormCache();
 
   bool CheckClosed(ErrorResult& aRv);
 
+  // Steals from |aParamMap|
+  void SetParamMapForWorkletName(const nsAString& aName,
+                                 AudioParamDescriptorMap* aParamMap);
+
   void Dispatch(already_AddRefed<nsIRunnable>&& aRunnable);
 
  private:
   void DisconnectFromWindow();
   void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob);
   void ShutdownDecoder();
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
@@ -366,16 +371,18 @@ class AudioContext final : public DOMEve
   // is not allowed to play, the promise would be pending in this array and be
   // resolved until audio context has been allowed and user call resume() again.
   nsTArray<RefPtr<Promise>> mPendingResumePromises;
   // See RegisterActiveNode.  These will keep the AudioContext alive while it
   // is rendering and the window remains alive.
   nsTHashtable<nsRefPtrHashKey<AudioNode>> mActiveNodes;
   // Raw (non-owning) references to all AudioNodes for this AudioContext.
   nsTHashtable<nsPtrHashKey<AudioNode>> mAllNodes;
+  nsDataHashtable<nsStringHashKey, AudioParamDescriptorMap>
+      mWorkletParamDescriptors;
   // Cache to avoid recomputing basic waveforms all the time.
   RefPtr<BasicWaveFormCache> mBasicWaveFormCache;
   // Number of channels passed in the OfflineAudioContext ctor.
   uint32_t mNumberOfChannels;
   bool mIsOffline;
   bool mIsStarted;
   bool mIsShutDown;
   // Close has been called, reject suspend and resume call.
--- a/dom/media/webaudio/AudioWorkletGlobalScope.cpp
+++ b/dom/media/webaudio/AudioWorkletGlobalScope.cpp
@@ -1,16 +1,18 @@
 /* -*- 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 "AudioWorkletGlobalScope.h"
 
+#include "AudioNodeEngine.h"
+#include "AudioNodeStream.h"
 #include "AudioWorkletImpl.h"
 #include "jsapi.h"
 #include "mozilla/dom/AudioWorkletGlobalScopeBinding.h"
 #include "mozilla/dom/WorkletPrincipal.h"
 #include "mozilla/dom/AudioParamDescriptorBinding.h"
 #include "nsPrintfCString.h"
 #include "nsTHashtable.h"
 
@@ -181,20 +183,27 @@ void AudioWorkletGlobalScope::RegisterPr
    * 11. Queue a task to the control thread to add the key-value pair
    *     (name - descriptors) to the node name to parameter descriptor
    *     map of the associated BaseAudioContext.
    */
   AudioParamDescriptorMap map = DescriptorsFromJS(aCx, descriptors, aRv);
   if (aRv.Failed()) {
     return;
   }
-  // TODO: we don't have a proper mechanism to communicate with the
-  // control thread currently. See
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=1473467#c3
-  // and https://bugzilla.mozilla.org/show_bug.cgi?id=1492014
+
+  NS_DispatchToMainThread(NS_NewRunnableFunction(
+      "AudioWorkletGlobalScope: parameter descriptors",
+      [impl = mImpl, name = nsString(aName), map = std::move(map)]() mutable {
+        AudioNode* destinationNode =
+            impl->DestinationStream()->Engine()->NodeMainThread();
+        if (!destinationNode) {
+          return;
+        }
+        destinationNode->Context()->SetParamMapForWorkletName(name, &map);
+      }));
 }
 
 WorkletImpl* AudioWorkletGlobalScope::Impl() const { return mImpl; }
 
 uint64_t AudioWorkletGlobalScope::CurrentFrame() const { return mCurrentFrame; }
 
 double AudioWorkletGlobalScope::CurrentTime() const { return mCurrentTime; }
 
--- a/dom/media/webaudio/AudioWorkletImpl.h
+++ b/dom/media/webaudio/AudioWorkletImpl.h
@@ -24,16 +24,19 @@ class AudioWorkletImpl final : public Wo
   static already_AddRefed<dom::Worklet> CreateWorklet(
       dom::AudioContext* aContext, ErrorResult& aRv);
 
   JSObject* WrapWorklet(JSContext* aCx, dom::Worklet* aWorklet,
                         JS::Handle<JSObject*> aGivenProto) override;
 
   nsresult SendControlMessage(already_AddRefed<nsIRunnable> aRunnable) override;
 
+  // Any thread:
+  AudioNodeStream* DestinationStream() { return mDestinationStream; }
+
  protected:
   // Execution thread only.
   already_AddRefed<dom::WorkletGlobalScope> ConstructGlobalScope() override;
 
  private:
   AudioWorkletImpl(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
                    AudioNodeStream* aDestinationStream);
   ~AudioWorkletImpl();