Index: Source/modules/webaudio/AudioContext.cpp |
diff --git a/Source/modules/webaudio/AudioContext.cpp b/Source/modules/webaudio/AudioContext.cpp |
index a6e0aebbeeab2c4dc1278d17ec43f392fd25f5df..9b903cf6ea81526aeaaf0299b50e1c84f63e24f1 100644 |
--- a/Source/modules/webaudio/AudioContext.cpp |
+++ b/Source/modules/webaudio/AudioContext.cpp |
@@ -730,15 +730,9 @@ void AudioContext::notifyStateChange() |
ScriptPromise AudioContext::suspendContext(ScriptState* scriptState) |
{ |
ASSERT(isMainThread()); |
- AutoLocker locker(this); |
+ ASSERT(!isOfflineContext()); |
- if (isOfflineContext()) { |
- return ScriptPromise::rejectWithDOMException( |
- scriptState, |
- DOMException::create( |
- InvalidAccessError, |
- "cannot suspend an OfflineAudioContext")); |
- } |
+ AutoLocker locker(this); |
RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); |
ScriptPromise promise = resolver->promise(); |
@@ -852,6 +846,18 @@ void AudioContext::handlePreRenderTasks() |
{ |
ASSERT(isAudioThread()); |
+ // If this is Offline Audio Context, simply lock the graph and do the tasks. |
Raymond Toy
2015/06/15 20:42:13
You should probably mention why it's ok to wait fo
|
+ // For the precise offline audio rendering, we need these tasks to be |
+ // performed every render quantum without deferring them. The trylock() |
+ // below is not suitable for this purpose. |
+ if (isOfflineContext()) { |
+ deferredTaskHandler().forceLock(); |
+ deferredTaskHandler().handleDeferredTasks(); |
+ handleStoppableSourceNodes(); |
+ unlock(); |
+ return; |
+ } |
Raymond Toy
2015/06/15 20:42:13
Previous version had this as part of the trylock b
|
+ |
// At the beginning of every render quantum, try to update the internal rendering graph state (from main thread changes). |
// It's OK if the tryLock() fails, we'll just take slightly longer to pick up the changes. |
if (tryLock()) { |
@@ -870,6 +876,18 @@ void AudioContext::handlePostRenderTasks() |
{ |
ASSERT(isAudioThread()); |
+ // Same as |handlePreRenderTasks()|. We perform these for Offline Audio |
+ // Context. |
+ if (isOfflineContext()) { |
+ deferredTaskHandler().forceLock(); |
+ deferredTaskHandler().breakConnections(); |
+ releaseFinishedSourceNodes(); |
+ deferredTaskHandler().handleDeferredTasks(); |
+ deferredTaskHandler().requestToDeleteHandlersOnMainThread(); |
+ unlock(); |
+ return; |
+ } |
+ |
// Must use a tryLock() here too. Don't worry, the lock will very rarely be contended and this method is called frequently. |
// The worst that can happen is that there will be some nodes which will take slightly longer than usual to be deleted or removed |
// from the render graph (in which case they'll render silence). |
@@ -945,9 +963,10 @@ ExecutionContext* AudioContext::executionContext() const |
void AudioContext::startRendering() |
{ |
- // This is called for both online and offline contexts. |
+ // This is only for the real-time context. |
ASSERT(isMainThread()); |
ASSERT(m_destinationNode); |
+ ASSERT(!isOfflineContext()); |
if (m_contextState == Suspended) { |
destination()->audioDestinationHandler().startRendering(); |
@@ -970,32 +989,23 @@ void AudioContext::stopRendering() |
void AudioContext::fireCompletionEvent() |
{ |
- ASSERT(isMainThread()); |
- if (!isMainThread()) |
- return; |
- |
- AudioBuffer* renderedBuffer = m_renderTarget.get(); |
- |
- // For an offline context, we set the state to closed here so that the oncomplete handler sees |
- // that the context has been closed. |
- setContextState(Closed); |
+ ASSERT_WITH_MESSAGE(1, "fireCompletionEvent() only valid for offline audio context"); |
+} |
- ASSERT(renderedBuffer); |
- if (!renderedBuffer) |
- return; |
+bool AudioContext::shouldSuspendNow() |
+{ |
+ ASSERT_WITH_MESSAGE(1, "shouldSuspendNow() only valid for offline audio context"); |
+ return false; |
+} |
- // Avoid firing the event if the document has already gone away. |
- if (executionContext()) { |
- // Call the offline rendering completion event listener and resolve the promise too. |
- dispatchEvent(OfflineAudioCompletionEvent::create(renderedBuffer)); |
- m_offlineResolver->resolve(renderedBuffer); |
- } |
+void AudioContext::resolvePendingSuspendPromises() |
+{ |
+ ASSERT_WITH_MESSAGE(1, "clearResolvedSuspend() only valid for offline audio context"); |
} |
DEFINE_TRACE(AudioContext) |
{ |
visitor->trace(m_closeResolver); |
- visitor->trace(m_offlineResolver); |
visitor->trace(m_renderTarget); |
visitor->trace(m_destinationNode); |
visitor->trace(m_listener); |