Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Unified Diff: Source/modules/webaudio/OfflineAudioContext.cpp

Issue 1140723003: Implement suspend() and resume() for OfflineAudioContext (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Promise Resolution Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: Source/modules/webaudio/OfflineAudioContext.cpp
diff --git a/Source/modules/webaudio/OfflineAudioContext.cpp b/Source/modules/webaudio/OfflineAudioContext.cpp
index d3488419e947e373d50f13cb105be0fb0604d178..d5165ce6facf6cbb27fc60ce04c0c0a1df0b5fe1 100644
--- a/Source/modules/webaudio/OfflineAudioContext.cpp
+++ b/Source/modules/webaudio/OfflineAudioContext.cpp
@@ -31,7 +31,10 @@
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
+#include "modules/webaudio/OfflineAudioDestinationNode.h"
+#include "platform/ThreadSafeFunctional.h"
#include "platform/audio/AudioUtilities.h"
+#include "public/platform/Platform.h"
namespace blink {
@@ -99,8 +102,64 @@ OfflineAudioContext::~OfflineAudioContext()
{
}
+OfflineAudioContext::ScheduledSuspendContainer::ScheduledSuspendContainer(
+ double when, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
+ : m_when(when)
Raymond Toy 2015/05/19 22:04:45 Shouldn't this quantize the time to the rendering
+ , m_resolver(resolver)
+{
+}
+
+OfflineAudioContext::ScheduledSuspendContainer::~ScheduledSuspendContainer()
+{
+}
+
+DEFINE_TRACE(OfflineAudioContext::ScheduledSuspendContainer)
+{
+ visitor->trace(m_resolver);
+}
+
+PassOwnPtr<OfflineAudioContext::ScheduledSuspendContainer>
+OfflineAudioContext::ScheduledSuspendContainer::create(
+ double when, PassRefPtrWillBeRawPtr<ScriptPromiseResolver> resolver)
+{
+ return adoptPtr(new ScheduledSuspendContainer(when, resolver));
+}
+
+bool OfflineAudioContext::ScheduledSuspendContainer::shouldBeSuspendedNow(double currentTime) const
+{
+ return m_when <= currentTime;
+}
+
+bool OfflineAudioContext::suspendIfNecessary()
+{
+ ASSERT(!isMainThread());
+
+ // Suspend if necessary and resolve the associated promise.
+ for (unsigned index = 0; index < m_scheduledSuspends.size(); ++index) {
+ if (m_scheduledSuspends.at(index)->shouldBeSuspendedNow(currentTime())) {
+ // Resolve scheduled suspend on the main thread.
+ Platform::current()->mainThread()->postTask(FROM_HERE,
+ threadSafeBind(
+ &OfflineAudioContext::suspendAndResolveOnMainThread,
+ this,
+ index));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OfflineAudioContext::isSuspendScheduled() const
+{
+ return m_scheduledSuspends.size() > 0;
+}
+
ScriptPromise OfflineAudioContext::startOfflineRendering(ScriptState* scriptState)
{
+ ASSERT(isMainThread());
+ AutoLocker locker(this);
+
// Calling close() on an OfflineAudioContext is not supported/allowed,
// but it might well have been stopped by its execution context.
if (isContextClosed()) {
@@ -121,10 +180,73 @@ ScriptPromise OfflineAudioContext::startOfflineRendering(ScriptState* scriptStat
}
m_offlineResolver = ScriptPromiseResolver::create(scriptState);
- startRendering();
+
+ // This calls AudioContext.startRendering(). It seems to be odd to go up the
+ // chain and call the parent's method, but the current OAC is basically a
+ // thin wrapper on AudioContext. (a container-like object.)
+ //
+ // If we decide to fix this structural issue completely, we have to touch
+ // AudioContext and AudioNode.
+ // startRendering();
+
+ destination()->audioDestinationHandler().startRendering();
+ setContextState(Running);
+
return m_offlineResolver->promise();
}
+ScriptPromise OfflineAudioContext::suspendOfflineRendering(ScriptState* scriptState, double when)
+{
+ ASSERT(isMainThread());
+ AutoLocker locker(this);
+
+ // suspendTime should be greater than currentTime. Note that this is called
+ // from the main thread, so the currentTime will be one rendering quantum
+ // behind the actual current time.
+ if (currentTime() < when) {
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ m_scheduledSuspends.append(ScheduledSuspendContainer::create(when, resolver));
+ return promise;
+ }
+
+ // If suspendTime is already passed, throw an exception.
+ return ScriptPromise::rejectWithDOMException(
+ scriptState,
+ DOMException::create(
+ InvalidStateError,
+ "cannot schedule a suspend in the past"));
+}
+
+ScriptPromise OfflineAudioContext::resumeOfflineRendering(ScriptState* scriptState)
+{
+ ASSERT(isMainThread());
+ AutoLocker locker(this);
+
+ RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
+ ScriptPromise promise = resolver->promise();
+ m_resumeResolvers.append(resolver);
Raymond Toy 2015/05/19 22:04:45 Not sure, but I think you can resolve the promise
hongchan 2015/05/20 22:09:40 I agree. This was just to make the structure symme
+
+ // Calling startRendering() in OfflineAudioDestinationHandler.
+ destination()->audioDestinationHandler().startRendering();
+ setContextState(Running);
+
+ return promise;
+}
+
+void OfflineAudioContext::suspendAndResolveOnMainThread(unsigned index)
+{
+ ASSERT(isMainThread());
+ AutoLocker locker(this);
+
+ setContextState(Suspended);
+
+ m_scheduledSuspends.at(index)->resolver()->resolve();
+
+ // TO FIX: does this automatically re-arrange the rest of vector?
+ m_scheduledSuspends.remove(index);
+}
+
} // namespace blink
#endif // ENABLE(WEB_AUDIO)

Powered by Google App Engine
This is Rietveld 408576698