Bug 1087944 - Implement the promise version of OfflineAudioContext. r=ehsan,smaug

--HG--
extra : rebase_source : 1ede286a68f592038320ed5b82051bb9dd3cc0db
This commit is contained in:
Paul Adenot 2014-11-19 11:38:39 +01:00
Родитель b29e662209
Коммит 1215625738
5 изменённых файлов: 52 добавлений и 12 удалений

Просмотреть файл

@ -632,17 +632,21 @@ AudioContext::GetGlobalJSObject() const
return parentObject->GetGlobalJSObject();
}
void
already_AddRefed<Promise>
AudioContext::StartRendering(ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
MOZ_ASSERT(mIsOffline, "This should only be called on OfflineAudioContext");
if (mIsStarted) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
return nullptr;
}
mIsStarted = true;
mDestination->StartRendering();
nsRefPtr<Promise> promise = Promise::Create(parentObject, aRv);
mDestination->StartRendering(promise);
return promise.forget();
}
void

Просмотреть файл

@ -191,7 +191,7 @@ public:
const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback);
// OfflineAudioContext methods
void StartRendering(ErrorResult& aRv);
already_AddRefed<Promise> StartRendering(ErrorResult& aRv);
IMPL_EVENT_HANDLER(complete)
bool IsOffline() const { return mIsOffline; }

Просмотреть файл

@ -22,6 +22,7 @@
#include "nsServiceManagerUtils.h"
#include "nsIAppShell.h"
#include "nsWidgetsCID.h"
#include "mozilla/dom/Promise.h"
namespace mozilla {
namespace dom {
@ -126,6 +127,28 @@ public:
}
}
class OnCompleteTask MOZ_FINAL : public nsRunnable
{
public:
OnCompleteTask(AudioContext* aAudioContext, AudioBuffer* aRenderedBuffer)
: mAudioContext(aAudioContext)
, mRenderedBuffer(aRenderedBuffer)
{}
NS_IMETHOD Run()
{
nsRefPtr<OfflineAudioCompletionEvent> event =
new OfflineAudioCompletionEvent(mAudioContext, nullptr, nullptr);
event->InitEvent(mRenderedBuffer);
mAudioContext->DispatchTrustedEvent(event);
return NS_OK;
}
private:
nsRefPtr<AudioContext> mAudioContext;
nsRefPtr<AudioBuffer> mRenderedBuffer;
};
void FireOfflineCompletionEvent(AudioDestinationNode* aNode)
{
AudioContext* context = aNode->Context();
@ -152,10 +175,11 @@ public:
renderedBuffer->SetRawChannelContents(i, mInputChannels[i]);
}
nsRefPtr<OfflineAudioCompletionEvent> event =
new OfflineAudioCompletionEvent(context, nullptr, nullptr);
event->InitEvent(renderedBuffer);
context->DispatchTrustedEvent(event);
aNode->ResolvePromise(renderedBuffer);
nsRefPtr<OnCompleteTask> task =
new OnCompleteTask(context, renderedBuffer);
NS_DispatchToMainThread(task);
}
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE
@ -301,7 +325,8 @@ private:
NS_IMPL_ISUPPORTS(EventProxyHandler, nsIDOMEventListener)
NS_IMPL_CYCLE_COLLECTION_INHERITED(AudioDestinationNode, AudioNode,
mAudioChannelAgent, mEventProxyHelper)
mAudioChannelAgent, mEventProxyHelper,
mOfflineRenderingPromise)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AudioDestinationNode)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
@ -415,6 +440,14 @@ AudioDestinationNode::FireOfflineCompletionEvent()
engine->FireOfflineCompletionEvent(this);
}
void
AudioDestinationNode::ResolvePromise(AudioBuffer* aRenderedBuffer)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mIsOffline);
mOfflineRenderingPromise->MaybeResolve(aRenderedBuffer);
}
uint32_t
AudioDestinationNode::MaxChannelCount() const
{
@ -463,8 +496,9 @@ AudioDestinationNode::WrapObject(JSContext* aCx)
}
void
AudioDestinationNode::StartRendering()
AudioDestinationNode::StartRendering(Promise* aPromise)
{
mOfflineRenderingPromise = aPromise;
mOfflineRenderingRef.Take(this);
mStream->Graph()->StartNonRealtimeProcessing(mFramesToProduce);
}

Просмотреть файл

@ -54,7 +54,7 @@ public:
void Mute();
void Unmute();
void StartRendering();
void StartRendering(Promise* aPromise);
void OfflineShutdown();
@ -85,6 +85,7 @@ public:
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
void InputMuted(bool aInputMuted);
void ResolvePromise(AudioBuffer* aRenderedBuffer);
protected:
virtual ~AudioDestinationNode();
@ -103,6 +104,7 @@ private:
nsCOMPtr<nsIAudioChannelAgent> mAudioChannelAgent;
nsRefPtr<EventProxyHandler> mEventProxyHelper;
nsRefPtr<Promise> mOfflineRenderingPromise;
// Audio Channel Type.
AudioChannel mAudioChannel;

Просмотреть файл

@ -16,7 +16,7 @@ callback OfflineRenderSuccessCallback = void (AudioBuffer renderedData);
interface OfflineAudioContext : AudioContext {
[Throws]
void startRendering();
Promise<AudioBuffer> startRendering();
attribute EventHandler oncomplete;