Skip to content

Commit

Permalink
Synchronize AudioWorkletProcessor information upon script evaluation
Browse files Browse the repository at this point in the history
Spec: https://webaudio.github.io/web-audio-api/#dfn-node-name-to-parameter-descriptor-map

Upon the evaluation of script in AudioWorkletGlobalScope, the
associated AudioWokrletMessagingProxy (which is associated
with a BaseAudioContext) needs to be updated with the data
from the script.

Bug: 755566
Change-Id: I9013adf67710b9d8cf932efc94be27116727dd95
Reviewed-on: https://chromium-review.googlesource.com/622067
Reviewed-by: Raymond Toy <rtoy@chromium.org>
Reviewed-by: Hiroki Nakagawa <nhiroki@chromium.org>
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#498664}
  • Loading branch information
hoch authored and Commit Bot committed Aug 30, 2017
1 parent fb6e6ca commit fc048ad
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "bindings/core/v8/WorkerOrWorkletScriptController.h"
#include "bindings/modules/v8/V8AudioParamDescriptor.h"
#include "core/dom/ExceptionCode.h"
#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h"
#include "modules/webaudio/AudioBuffer.h"
#include "modules/webaudio/AudioParamDescriptor.h"
#include "modules/webaudio/AudioWorkletProcessor.h"
Expand Down Expand Up @@ -208,6 +209,23 @@ AudioWorkletProcessorDefinition* AudioWorkletGlobalScope::FindDefinition(
return processor_definition_map_.at(name);
}

unsigned AudioWorkletGlobalScope::NumberOfRegisteredDefinitions() {
return processor_definition_map_.size();
}

std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>>
AudioWorkletGlobalScope::WorkletProcessorInfoListForSynchronization() {
auto processor_info_list =
WTF::MakeUnique<Vector<CrossThreadAudioWorkletProcessorInfo>>();
for (auto definition_entry : processor_definition_map_) {
if (!definition_entry.value->IsSynchronized()) {
definition_entry.value->MarkAsSynchronized();
processor_info_list->emplace_back(*definition_entry.value);
}
}
return processor_info_list;
}

DEFINE_TRACE(AudioWorkletGlobalScope) {
visitor->Trace(processor_definition_map_);
visitor->Trace(processor_instances_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
#include "core/dom/ExecutionContext.h"
#include "core/workers/ThreadedWorkletGlobalScope.h"
#include "modules/ModulesExport.h"
#include "modules/webaudio/AudioParamDescriptor.h"
#include "platform/bindings/ScriptWrappable.h"

namespace blink {

class AudioBuffer;
class AudioWorkletProcessor;
class AudioWorkletProcessorDefinition;
class CrossThreadAudioWorkletProcessorInfo;
class ExceptionState;

// This is constructed and destroyed on a worker thread, and all methods also
Expand Down Expand Up @@ -50,6 +52,11 @@ class MODULES_EXPORT AudioWorkletGlobalScope final

AudioWorkletProcessorDefinition* FindDefinition(const String& name);

unsigned NumberOfRegisteredDefinitions();

std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>>
WorkletProcessorInfoListForSynchronization();

DECLARE_TRACE();
DECLARE_TRACE_WRAPPERS();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "modules/webaudio/AudioWorkletMessagingProxy.h"

#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h"
#include "modules/webaudio/AudioWorkletObjectProxy.h"
#include "modules/webaudio/AudioWorkletThread.h"

Expand All @@ -16,18 +17,32 @@ AudioWorkletMessagingProxy::AudioWorkletMessagingProxy(

AudioWorkletMessagingProxy::~AudioWorkletMessagingProxy() {}

void AudioWorkletMessagingProxy::SynchronizeWorkletData() {
void AudioWorkletMessagingProxy::SynchronizeWorkletProcessorInfoList(
std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>> info_list) {
DCHECK(IsMainThread());

// TODO(crbug.com/755566): the argument will be a set of a node name and
// parameter descriptors. Use the information to update the copy in
// AudioWorkletMessagingProxy.
for (auto& processor_info : *info_list) {
processor_info_map_.insert(processor_info.Name(),
processor_info.ParamInfoList());
}
}

bool AudioWorkletMessagingProxy::IsProcessorRegistered(
const String& name) const {
return processor_info_map_.Contains(name);
}

const Vector<CrossThreadAudioParamInfo>
AudioWorkletMessagingProxy::GetParamInfoListForProcessor(
const String& name) const {
DCHECK(IsProcessorRegistered(name));
return processor_info_map_.at(name);
}

std::unique_ptr<ThreadedWorkletObjectProxy>
AudioWorkletMessagingProxy::CreateObjectProxy(
ThreadedWorkletMessagingProxy* messaging_proxy,
ParentFrameTaskRunners* parent_frame_task_runners) {
AudioWorkletMessagingProxy::CreateObjectProxy(
ThreadedWorkletMessagingProxy* messaging_proxy,
ParentFrameTaskRunners* parent_frame_task_runners) {
return WTF::MakeUnique<AudioWorkletObjectProxy>(
static_cast<AudioWorkletMessagingProxy*>(messaging_proxy),
parent_frame_task_runners);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

namespace blink {

class CrossThreadAudioParamInfo;
class CrossThreadAudioWorkletProcessorInfo;
class ExecutionContext;
class WorkerThread;

Expand All @@ -20,9 +22,20 @@ class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy {
public:
AudioWorkletMessagingProxy(ExecutionContext*, WorkerClients*);

// Invoked by AudioWorkletObjectProxy to synchronize the information from
// AudioWorkletGlobalScope after the script code evaluation.
void SynchronizeWorkletData();
// Invoked by AudioWorkletObjectProxy on AudioWorkletThread to fetch the
// information from AudioWorkletGlobalScope to AudioWorkletMessagingProxy
// after the script code evaluation. It copies the information about newly
// added AudioWorkletProcessor since the previous synchronization. (e.g.
// processor name and AudioParam list)
void SynchronizeWorkletProcessorInfoList(
std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>>);

// Returns true if the processor with given name is registered in
// AudioWorkletGlobalScope.
bool IsProcessorRegistered(const String& name) const;

const Vector<CrossThreadAudioParamInfo> GetParamInfoListForProcessor(
const String& name) const;

private:
~AudioWorkletMessagingProxy() override;
Expand All @@ -33,6 +46,9 @@ class AudioWorkletMessagingProxy final : public ThreadedWorkletMessagingProxy {
ParentFrameTaskRunners*) override;

std::unique_ptr<WorkerThread> CreateWorkerThread() override;

// Each entry consists of processor name and associated AudioParam list.
HashMap<String, Vector<CrossThreadAudioParamInfo>> processor_info_map_;
};

} // namespace blink
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "core/workers/ThreadedWorkletMessagingProxy.h"
#include "core/workers/WorkerThread.h"
#include "modules/webaudio/CrossThreadAudioWorkletProcessorInfo.h"
#include "modules/webaudio/AudioWorkletGlobalScope.h"
#include "modules/webaudio/AudioWorkletMessagingProxy.h"
#include "platform/CrossThreadFunctional.h"
Expand All @@ -26,15 +27,23 @@ void AudioWorkletObjectProxy::DidCreateWorkerGlobalScope(

void AudioWorkletObjectProxy::DidEvaluateModuleScript(bool success) {
DCHECK(global_scope_);
// TODO(crbug.com/755566): Extract/build the information for synchronization
// and send it to the associated AudioWorkletMessagingProxy. Currently this
// is an empty cross-thread call for the future implementation.
GetParentFrameTaskRunners()->Get(TaskType::kUnthrottled)
->PostTask(
BLINK_FROM_HERE,
CrossThreadBind(
&AudioWorkletMessagingProxy::SynchronizeWorkletData,
GetAudioWorkletMessagingProxyWeakPtr()));

if (!success || global_scope_->NumberOfRegisteredDefinitions() == 0)
return;

std::unique_ptr<Vector<CrossThreadAudioWorkletProcessorInfo>>
processor_info_list =
global_scope_->WorkletProcessorInfoListForSynchronization();

if (processor_info_list->size() == 0)
return;

GetParentFrameTaskRunners()->Get(TaskType::kUnthrottled)->PostTask(
BLINK_FROM_HERE,
CrossThreadBind(
&AudioWorkletMessagingProxy::SynchronizeWorkletProcessorInfoList,
GetAudioWorkletMessagingProxyWeakPtr(),
WTF::Passed(std::move(processor_info_list))));
}

void AudioWorkletObjectProxy::WillDestroyWorkerGlobalScope() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class MODULES_EXPORT AudioWorkletProcessorDefinition final
const Vector<String> GetAudioParamDescriptorNames() const;
const AudioParamDescriptor* GetAudioParamDescriptor(const String& key) const;

// Flag for data synchronization of definition between
// AudioWorkletMessagingProxy and AudioWorkletGlobalScope.
bool IsSynchronized() const { return is_synchronized_; }
void MarkAsSynchronized() { is_synchronized_ = true; }

DEFINE_INLINE_TRACE() { visitor->Trace(audio_param_descriptors_); };
DECLARE_TRACE_WRAPPERS();

Expand All @@ -52,6 +57,7 @@ class MODULES_EXPORT AudioWorkletProcessorDefinition final
v8::Local<v8::Function> process);

const String name_;
bool is_synchronized_ = false;

// The definition is per global scope. The active instance of
// |AudioProcessorWorklet| should be passed into these to perform JS function.
Expand Down
1 change: 1 addition & 0 deletions third_party/WebKit/Source/modules/webaudio/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ blink_modules_sources("webaudio") {
"ConstantSourceNode.h",
"ConvolverNode.cpp",
"ConvolverNode.h",
"CrossThreadAudioWorkletProcessorInfo.h",
"DefaultAudioDestinationNode.cpp",
"DefaultAudioDestinationNode.h",
"DeferredTaskHandler.cpp",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CrossThreadAudioWorkletProcessorInfo_h
#define CrossThreadAudioWorkletProcessorInfo_h

#include "modules/webaudio/AudioParamDescriptor.h"
#include "modules/webaudio/AudioWorkletProcessorDefinition.h"

namespace blink {

// A class for shallow repackage of |AudioParamDescriptor|. This is created only
// when requested when the synchronization between AudioWorkletMessagingProxy
// and AudioWorkletGlobalScope.
class CrossThreadAudioParamInfo {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

public:
explicit CrossThreadAudioParamInfo(const AudioParamDescriptor* descriptor)
: name_(descriptor->name().IsolatedCopy()),
default_value_(descriptor->defaultValue()),
max_value_(descriptor->maxValue()),
min_value_(descriptor->minValue()) {}

const String& Name() const { return name_; }
float DefaultValue() const { return default_value_; }
float MaxValue() const { return max_value_; }
float MinValue() const { return min_value_; }

private:
const String name_;
const float default_value_;
const float max_value_;
const float min_value_;
};

// A class for shallow repackage of |AudioWorkletProcessorDefinition|. This is
// created only when requested when the synchronization between
// AudioWorkletMessagingProxy and AudioWorkletGlobalScope.
class CrossThreadAudioWorkletProcessorInfo {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();

public:
explicit CrossThreadAudioWorkletProcessorInfo(
const AudioWorkletProcessorDefinition& definition)
: name_(definition.GetName().IsolatedCopy()) {
// To avoid unnecessary reallocations of the vector.
param_info_list_.ReserveInitialCapacity(
definition.GetAudioParamDescriptorNames().size());

for (const String& name : definition.GetAudioParamDescriptorNames()) {
param_info_list_.emplace_back(
definition.GetAudioParamDescriptor(name));
}
}

const String& Name() const { return name_; }
Vector<CrossThreadAudioParamInfo> ParamInfoList() { return param_info_list_; }

private:
const String name_;
Vector<CrossThreadAudioParamInfo> param_info_list_;
};

} // namespace blink

#endif // CrossThreadAudioWorkletProcessorInfo_h

0 comments on commit fc048ad

Please sign in to comment.