| Index: Source/modules/webaudio/AudioContext.cpp
|
| diff --git a/Source/modules/webaudio/AudioContext.cpp b/Source/modules/webaudio/AudioContext.cpp
|
| index a6e0aebbeeab2c4dc1278d17ec43f392fd25f5df..7f42f5b6b8a09a2d9f659d7c442f2824ab84c974 100644
|
| --- a/Source/modules/webaudio/AudioContext.cpp
|
| +++ b/Source/modules/webaudio/AudioContext.cpp
|
| @@ -57,6 +57,7 @@
|
| #include "modules/webaudio/OfflineAudioCompletionEvent.h"
|
| #include "modules/webaudio/OfflineAudioContext.h"
|
| #include "modules/webaudio/OfflineAudioDestinationNode.h"
|
| +#include "modules/webaudio/OnlineAudioContext.h"
|
| #include "modules/webaudio/OscillatorNode.h"
|
| #include "modules/webaudio/PannerNode.h"
|
| #include "modules/webaudio/PeriodicWave.h"
|
| @@ -67,35 +68,16 @@
|
| #include "public/platform/Platform.h"
|
| #include "wtf/text/WTFString.h"
|
|
|
| -#if DEBUG_AUDIONODE_REFERENCES
|
| -#include <stdio.h>
|
| -#endif
|
| -
|
| namespace blink {
|
|
|
| -// Don't allow more than this number of simultaneous AudioContexts talking to hardware.
|
| -const unsigned MaxHardwareContexts = 6;
|
| -unsigned AudioContext::s_hardwareContextCount = 0;
|
| -unsigned AudioContext::s_contextId = 0;
|
| -
|
| AudioContext* AudioContext::create(Document& document, ExceptionState& exceptionState)
|
| {
|
| - ASSERT(isMainThread());
|
| - if (s_hardwareContextCount >= MaxHardwareContexts) {
|
| - exceptionState.throwDOMException(
|
| - NotSupportedError,
|
| - ExceptionMessages::indexExceedsMaximumBound(
|
| - "number of hardware contexts",
|
| - s_hardwareContextCount,
|
| - MaxHardwareContexts));
|
| - return nullptr;
|
| - }
|
| -
|
| - AudioContext* audioContext = new AudioContext(&document);
|
| - audioContext->suspendIfNeeded();
|
| - return audioContext;
|
| + return OnlineAudioContext::create(document, exceptionState);
|
| }
|
|
|
| +// FIXME(dominicc): Devolve these constructors to OnlineAudioContext
|
| +// and OfflineAudioContext respectively.
|
| +
|
| // Constructor for rendering to the audio hardware.
|
| AudioContext::AudioContext(Document* document)
|
| : ActiveDOMObject(document)
|
| @@ -107,7 +89,6 @@ AudioContext::AudioContext(Document* document)
|
| , m_connectionCount(0)
|
| , m_didInitializeContextGraphMutex(false)
|
| , m_deferredTaskHandler(DeferredTaskHandler::create())
|
| - , m_isOfflineContext(false)
|
| , m_contextState(Suspended)
|
| {
|
| m_didInitializeContextGraphMutex = true;
|
| @@ -127,7 +108,6 @@ AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
|
| , m_connectionCount(0)
|
| , m_didInitializeContextGraphMutex(false)
|
| , m_deferredTaskHandler(DeferredTaskHandler::create())
|
| - , m_isOfflineContext(true)
|
| , m_contextState(Suspended)
|
| {
|
| m_didInitializeContextGraphMutex = true;
|
| @@ -141,9 +121,6 @@ AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
|
|
|
| AudioContext::~AudioContext()
|
| {
|
| -#if DEBUG_AUDIONODE_REFERENCES
|
| - fprintf(stderr, "%p: AudioContext::~AudioContext(): %u\n", this, m_contextId);
|
| -#endif
|
| deferredTaskHandler().contextWillBeDestroyed();
|
| // AudioNodes keep a reference to their context, so there should be no way to be in the destructor if there are still AudioNodes around.
|
| ASSERT(!m_isInitialized);
|
| @@ -163,22 +140,7 @@ void AudioContext::initialize()
|
|
|
| if (m_destinationNode.get()) {
|
| m_destinationNode->handler().initialize();
|
| -
|
| - if (!isOfflineContext()) {
|
| - // This starts the audio thread. The destination node's provideInput() method will now be called repeatedly to render audio.
|
| - // Each time provideInput() is called, a portion of the audio stream is rendered. Let's call this time period a "render quantum".
|
| - // NOTE: for now default AudioContext does not need an explicit startRendering() call from JavaScript.
|
| - // We may want to consider requiring it for symmetry with OfflineAudioContext.
|
| - startRendering();
|
| - ++s_hardwareContextCount;
|
| - }
|
| -
|
| - m_contextId = s_contextId++;
|
| m_isInitialized = true;
|
| -#if DEBUG_AUDIONODE_REFERENCES
|
| - fprintf(stderr, "%p: AudioContext::AudioContext(): %u #%u\n",
|
| - this, m_contextId, AudioContext::s_hardwareContextCount);
|
| -#endif
|
| }
|
| }
|
|
|
| @@ -204,25 +166,12 @@ void AudioContext::uninitialize()
|
| if (m_destinationNode)
|
| m_destinationNode->handler().uninitialize();
|
|
|
| - if (!isOfflineContext()) {
|
| - ASSERT(s_hardwareContextCount);
|
| - --s_hardwareContextCount;
|
| - }
|
| -
|
| // Get rid of the sources which may still be playing.
|
| releaseActiveSourceNodes();
|
|
|
| // Reject any pending resolvers before we go away.
|
| rejectPendingResolvers();
|
| -
|
| - // For an offline audio context, the completion event will set the state to closed. For an
|
| - // online context, we need to do it here. We only want to set the closed state once.
|
| - if (!isOfflineContext())
|
| - setContextState(Closed);
|
| -
|
| - // Resolve the promise now, if any
|
| - if (m_closeResolver)
|
| - m_closeResolver->resolve();
|
| + didClose();
|
|
|
| ASSERT(m_listener);
|
| m_listener->waitForHRTFDatabaseLoaderThreadCompletion();
|
| @@ -727,73 +676,6 @@ void AudioContext::notifyStateChange()
|
| dispatchEvent(Event::create(EventTypeNames::statechange));
|
| }
|
|
|
| -ScriptPromise AudioContext::suspendContext(ScriptState* scriptState)
|
| -{
|
| - ASSERT(isMainThread());
|
| - AutoLocker locker(this);
|
| -
|
| - if (isOfflineContext()) {
|
| - return ScriptPromise::rejectWithDOMException(
|
| - scriptState,
|
| - DOMException::create(
|
| - InvalidAccessError,
|
| - "cannot suspend an OfflineAudioContext"));
|
| - }
|
| -
|
| - RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| - ScriptPromise promise = resolver->promise();
|
| -
|
| - if (m_contextState == Closed) {
|
| - resolver->reject(
|
| - DOMException::create(InvalidStateError, "Cannot suspend a context that has been closed"));
|
| - } else {
|
| - // Stop rendering now.
|
| - if (m_destinationNode)
|
| - stopRendering();
|
| -
|
| - // Since we don't have any way of knowing when the hardware actually stops, we'll just
|
| - // resolve the promise now.
|
| - resolver->resolve();
|
| - }
|
| -
|
| - return promise;
|
| -}
|
| -
|
| -ScriptPromise AudioContext::resumeContext(ScriptState* scriptState)
|
| -{
|
| - ASSERT(isMainThread());
|
| - AutoLocker locker(this);
|
| -
|
| - if (isOfflineContext()) {
|
| - return ScriptPromise::rejectWithDOMException(
|
| - scriptState,
|
| - DOMException::create(
|
| - InvalidAccessError,
|
| - "cannot resume an OfflineAudioContext"));
|
| - }
|
| -
|
| - if (isContextClosed()) {
|
| - return ScriptPromise::rejectWithDOMException(
|
| - scriptState,
|
| - DOMException::create(
|
| - InvalidAccessError,
|
| - "cannot resume a closed AudioContext"));
|
| - }
|
| -
|
| - RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| - ScriptPromise promise = resolver->promise();
|
| -
|
| - // Restart the destination node to pull on the audio graph.
|
| - if (m_destinationNode)
|
| - startRendering();
|
| -
|
| - // Save the resolver which will get resolved when the destination node starts pulling on the
|
| - // graph again.
|
| - m_resumeResolvers.append(resolver);
|
| -
|
| - return promise;
|
| -}
|
| -
|
| void AudioContext::notifySourceNodeFinishedProcessing(AudioHandler* handler)
|
| {
|
| ASSERT(isAudioThread());
|
| @@ -955,19 +837,6 @@ void AudioContext::startRendering()
|
| }
|
| }
|
|
|
| -void AudioContext::stopRendering()
|
| -{
|
| - ASSERT(isMainThread());
|
| - ASSERT(m_destinationNode);
|
| - ASSERT(!isOfflineContext());
|
| -
|
| - if (m_contextState == Running) {
|
| - destination()->audioDestinationHandler().stopRendering();
|
| - setContextState(Suspended);
|
| - deferredTaskHandler().clearHandlersToBeDeleted();
|
| - }
|
| -}
|
| -
|
| void AudioContext::fireCompletionEvent()
|
| {
|
| ASSERT(isMainThread());
|
| @@ -994,7 +863,6 @@ void AudioContext::fireCompletionEvent()
|
|
|
| DEFINE_TRACE(AudioContext)
|
| {
|
| - visitor->trace(m_closeResolver);
|
| visitor->trace(m_offlineResolver);
|
| visitor->trace(m_renderTarget);
|
| visitor->trace(m_destinationNode);
|
| @@ -1020,35 +888,6 @@ SecurityOrigin* AudioContext::securityOrigin() const
|
| return nullptr;
|
| }
|
|
|
| -ScriptPromise AudioContext::closeContext(ScriptState* scriptState)
|
| -{
|
| - if (isOfflineContext()) {
|
| - return ScriptPromise::rejectWithDOMException(
|
| - scriptState,
|
| - DOMException::create(InvalidAccessError, "cannot close an OfflineAudioContext."));
|
| - }
|
| -
|
| - if (isContextClosed()) {
|
| - // We've already closed the context previously, but it hasn't yet been resolved, so just
|
| - // create a new promise and reject it.
|
| - return ScriptPromise::rejectWithDOMException(
|
| - scriptState,
|
| - DOMException::create(InvalidStateError,
|
| - "Cannot close a context that is being closed or has already been closed."));
|
| - }
|
| -
|
| - m_closeResolver = ScriptPromiseResolver::create(scriptState);
|
| - ScriptPromise promise = m_closeResolver->promise();
|
| -
|
| - // Stop the audio context. This will stop the destination node from pulling audio anymore. And
|
| - // since we have disconnected the destination from the audio graph, and thus has no references,
|
| - // the destination node can GCed if JS has no references. stop() will also resolve the Promise
|
| - // created here.
|
| - stop();
|
| -
|
| - return promise;
|
| -}
|
| -
|
| } // namespace blink
|
|
|
| #endif // ENABLE(WEB_AUDIO)
|
|
|