Chromium Code Reviews| Index: Source/modules/webaudio/AudioContext.cpp |
| diff --git a/Source/modules/webaudio/AudioContext.cpp b/Source/modules/webaudio/AudioContext.cpp |
| index 69e4e8aea09bbec1185dc7349224f6e568ebe2c7..5ec8923f3a4c7a1b4e3334898dbddc78eda55f0d 100644 |
| --- a/Source/modules/webaudio/AudioContext.cpp |
| +++ b/Source/modules/webaudio/AudioContext.cpp |
| @@ -30,6 +30,7 @@ |
| #include "bindings/core/v8/ExceptionMessages.h" |
| #include "bindings/core/v8/ExceptionState.h" |
| +#include "bindings/core/v8/ScriptState.h" |
| #include "core/dom/Document.h" |
| #include "core/dom/ExceptionCode.h" |
| #include "core/html/HTMLMediaElement.h" |
| @@ -101,6 +102,7 @@ AudioContext::AudioContext(Document* document) |
| , m_isCleared(false) |
| , m_isInitialized(false) |
| , m_destinationNode(nullptr) |
| + , m_isResolvingResumePromises(false) |
| , m_automaticPullNodesNeedUpdating(false) |
| , m_connectionCount(0) |
| , m_audioThread(0) |
| @@ -121,6 +123,7 @@ AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t |
| , m_isCleared(false) |
| , m_isInitialized(false) |
| , m_destinationNode(nullptr) |
| + , m_isResolvingResumePromises(false) |
| , m_automaticPullNodesNeedUpdating(false) |
| , m_connectionCount(0) |
| , m_audioThread(0) |
| @@ -531,6 +534,40 @@ PeriodicWave* AudioContext::createPeriodicWave(Float32Array* real, Float32Array* |
| return PeriodicWave::create(sampleRate(), real, imag); |
| } |
| +void AudioContext::suspendContext() |
| +{ |
| + ASSERT(isMainThread()); |
| + AutoLocker locker(this); |
| + |
| + if (m_destinationNode && !isOfflineContext()) |
| + m_destinationNode->stop(); |
| +} |
| + |
| +ScriptPromise AudioContext::resumeContext(ScriptState* scriptState) |
| +{ |
| + ASSERT(isMainThread()); |
| + AutoLocker locker(this); |
| + |
| + RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); |
| + |
| + ScriptPromise promise = resolver->promise(); |
| + |
| + if (isOfflineContext()) { |
| + // For offline context, just resolve the promise now. |
| + resolver->resolve(); |
| + } else { |
| + // Restart the destination node to pull on the audio graph. |
| + if (m_destinationNode) |
| + m_destinationNode->startRendering(); |
| + |
| + // Save the promise which will get resolved when the destination node starts pulling on the |
| + // graph again. |
| + m_resumePromises.append(resolver); |
| + } |
| + |
| + return promise; |
| +} |
| + |
| void AudioContext::notifyNodeFinishedProcessing(AudioNode* node) |
| { |
| ASSERT(isAudioThread()); |
| @@ -637,6 +674,8 @@ void AudioContext::handlePreRenderTasks() |
| handleDirtyAudioNodeOutputs(); |
| updateAutomaticPullNodes(); |
| + resolvePromisesForResume(); |
| + |
| unlock(); |
| } |
| } |
| @@ -802,6 +841,30 @@ void AudioContext::processAutomaticPullNodes(size_t framesToProcess) |
| m_renderingAutomaticPullNodes[i]->processIfNecessary(framesToProcess); |
| } |
| +void AudioContext::resolvePromisesForResumeOnMainThread() |
| +{ |
| + ASSERT(isMainThread); |
|
yhirano
2014/10/08 01:12:14
Please acquire the lock.
yhirano
2014/10/08 01:15:54
Oh, I found AudioContext::lock is not callable fro
Raymond Toy
2014/10/14 17:16:59
Done.
|
| + |
| + for (unsigned k = 0; k < m_resumePromises.size(); ++k) |
| + m_resumePromises[k]->resolve(); |
| + |
| + m_resumePromises.clear(); |
| + m_isResolvingResumePromises = false; |
| +} |
| + |
| +void AudioContext::resolvePromisesForResume() |
| +{ |
| + ASSERT(isAudioThread()); |
| + |
|
yhirano
2014/10/08 01:12:14
Please add a comment that the lock is already acqu
Raymond Toy
2014/10/14 17:16:59
Done.
|
| + // Resolve any pending promises created by resume(). Only do this we if haven't already started |
| + // resolving these promises. This gets called very often and it takes some time use to resolve |
| + // the promises in the main thread. |
| + if (!m_isResolvingResumePromises && m_resumePromises.size() > 0) { |
| + m_isResolvingResumePromises = true; |
| + callOnMainThread(bind(&AudioContext::resolvePromisesForResumeOnMainThread, this)); |
| + } |
| +} |
| + |
| const AtomicString& AudioContext::interfaceName() const |
| { |
| return EventTargetNames::AudioContext; |