Commit df222bb4 authored by keishi@chromium.org's avatar keishi@chromium.org

Move webaudio to oilpan transitional types

We don't allow on-heap allocations in the audio thread. We change AsyncAudioDecoder::decode so we won't allocate an AudioBuffer in the audio thread.

BUG=340522

Review URL: https://codereview.chromium.org/205173002

git-svn-id: svn://svn.chromium.org/blink/trunk@173725 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d1d4228b
...@@ -35,9 +35,9 @@ class ExceptionState; ...@@ -35,9 +35,9 @@ class ExceptionState;
class AnalyserNode FINAL : public AudioBasicInspectorNode { class AnalyserNode FINAL : public AudioBasicInspectorNode {
public: public:
static PassRefPtr<AnalyserNode> create(AudioContext* context, float sampleRate) static PassRefPtrWillBeRawPtr<AnalyserNode> create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new AnalyserNode(context, sampleRate)); return adoptRefWillBeNoop(new AnalyserNode(context, sampleRate));
} }
virtual ~AnalyserNode(); virtual ~AnalyserNode();
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#include "modules/webaudio/AudioBuffer.h" #include "modules/webaudio/AudioBuffer.h"
#include "modules/webaudio/AudioBufferCallback.h" #include "modules/webaudio/AudioBufferCallback.h"
#include "platform/Task.h" #include "platform/Task.h"
#include "platform/audio/AudioBus.h"
#include "platform/audio/AudioFileReader.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "wtf/ArrayBuffer.h" #include "wtf/ArrayBuffer.h"
#include "wtf/MainThread.h" #include "wtf/MainThread.h"
...@@ -63,26 +65,26 @@ void AsyncAudioDecoder::decodeAsync(ArrayBuffer* audioData, float sampleRate, Pa ...@@ -63,26 +65,26 @@ void AsyncAudioDecoder::decodeAsync(ArrayBuffer* audioData, float sampleRate, Pa
void AsyncAudioDecoder::decode(ArrayBuffer* audioData, float sampleRate, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback) void AsyncAudioDecoder::decode(ArrayBuffer* audioData, float sampleRate, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback)
{ {
// Do the actual decoding and invoke the callback. RefPtr<AudioBus> bus = createBusFromInMemoryAudioFile(audioData->data(), audioData->byteLength(), false, sampleRate);
RefPtr<AudioBuffer> audioBuffer = AudioBuffer::createFromAudioFileData(audioData->data(), audioData->byteLength(), false, sampleRate);
// Decoding is finished, but we need to do the callbacks on the main thread. // Decoding is finished, but we need to do the callbacks on the main thread.
// The leaked reference to audioBuffer is picked up in notifyComplete. // The leaked reference to audioBuffer is picked up in notifyComplete.
callOnMainThread(WTF::bind(&AsyncAudioDecoder::notifyComplete, audioData, successCallback, errorCallback, audioBuffer.release().leakRef())); callOnMainThread(WTF::bind(&AsyncAudioDecoder::notifyComplete, audioData, successCallback, errorCallback, bus.release().leakRef()));
} }
void AsyncAudioDecoder::notifyComplete(ArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, AudioBuffer* audioBuffer) void AsyncAudioDecoder::notifyComplete(ArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, AudioBus* audioBus)
{ {
// Adopt references, so everything gets correctly dereffed. // Adopt references, so everything gets correctly dereffed.
RefPtr<ArrayBuffer> audioDataRef = adoptRef(audioData); RefPtr<ArrayBuffer> audioDataRef = adoptRef(audioData);
OwnPtr<AudioBufferCallback> successCallbackPtr = adoptPtr(successCallback); OwnPtr<AudioBufferCallback> successCallbackPtr = adoptPtr(successCallback);
OwnPtr<AudioBufferCallback> errorCallbackPtr = adoptPtr(errorCallback); OwnPtr<AudioBufferCallback> errorCallbackPtr = adoptPtr(errorCallback);
RefPtr<AudioBuffer> audioBufferRef = adoptRef(audioBuffer); RefPtr<AudioBus> audioBusRef = adoptRef(audioBus);
if (audioBuffer && successCallback) RefPtrWillBeRawPtr<AudioBuffer> audioBuffer = AudioBuffer::createFromAudioBus(audioBus);
successCallback->handleEvent(audioBuffer); if (audioBuffer.get() && successCallback)
successCallback->handleEvent(audioBuffer.get());
else if (errorCallback) else if (errorCallback)
errorCallback->handleEvent(audioBuffer); errorCallback->handleEvent(audioBuffer.get());
} }
} // namespace WebCore } // namespace WebCore
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#ifndef AsyncAudioDecoder_h #ifndef AsyncAudioDecoder_h
#define AsyncAudioDecoder_h #define AsyncAudioDecoder_h
#include "platform/heap/Handle.h"
#include "public/platform/WebThread.h" #include "public/platform/WebThread.h"
#include "wtf/Forward.h" #include "wtf/Forward.h"
#include "wtf/OwnPtr.h" #include "wtf/OwnPtr.h"
...@@ -33,6 +34,7 @@ namespace WebCore { ...@@ -33,6 +34,7 @@ namespace WebCore {
class AudioBuffer; class AudioBuffer;
class AudioBufferCallback; class AudioBufferCallback;
class AudioBus;
// AsyncAudioDecoder asynchronously decodes audio file data from an ArrayBuffer in a worker thread. // AsyncAudioDecoder asynchronously decodes audio file data from an ArrayBuffer in a worker thread.
// Upon successful decoding, a completion callback will be invoked with the decoded PCM data in an AudioBuffer. // Upon successful decoding, a completion callback will be invoked with the decoded PCM data in an AudioBuffer.
...@@ -47,8 +49,9 @@ public: ...@@ -47,8 +49,9 @@ public:
void decodeAsync(ArrayBuffer* audioData, float sampleRate, PassOwnPtr<AudioBufferCallback> successCallback, PassOwnPtr<AudioBufferCallback> errorCallback); void decodeAsync(ArrayBuffer* audioData, float sampleRate, PassOwnPtr<AudioBufferCallback> successCallback, PassOwnPtr<AudioBufferCallback> errorCallback);
private: private:
PassRefPtrWillBeRawPtr<AudioBuffer> createAudioBufferFromAudioBus(AudioBus*);
static void decode(ArrayBuffer* audioData, float sampleRate, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback); static void decode(ArrayBuffer* audioData, float sampleRate, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback);
static void notifyComplete(ArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, AudioBuffer*); static void notifyComplete(ArrayBuffer* audioData, AudioBufferCallback* successCallback, AudioBufferCallback* errorCallback, AudioBus*);
OwnPtr<blink::WebThread> m_thread; OwnPtr<blink::WebThread> m_thread;
}; };
......
...@@ -53,19 +53,19 @@ float AudioBuffer::maxAllowedSampleRate() ...@@ -53,19 +53,19 @@ float AudioBuffer::maxAllowedSampleRate()
return 192000; return 192000;
} }
PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) PassRefPtrWillBeRawPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate)
{ {
if (sampleRate < minAllowedSampleRate() || sampleRate > maxAllowedSampleRate() || numberOfChannels > AudioContext::maxNumberOfChannels() || !numberOfChannels || !numberOfFrames) if (sampleRate < minAllowedSampleRate() || sampleRate > maxAllowedSampleRate() || numberOfChannels > AudioContext::maxNumberOfChannels() || !numberOfChannels || !numberOfFrames)
return nullptr; return nullptr;
RefPtr<AudioBuffer> buffer = adoptRef(new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate)); RefPtrWillBeRawPtr<AudioBuffer> buffer = adoptRefWillBeNoop(new AudioBuffer(numberOfChannels, numberOfFrames, sampleRate));
if (!buffer->createdSuccessfully(numberOfChannels)) if (!buffer->createdSuccessfully(numberOfChannels))
return nullptr; return nullptr;
return buffer; return buffer;
} }
PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState& exceptionState) PassRefPtrWillBeRawPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState& exceptionState)
{ {
if (!numberOfChannels || numberOfChannels > AudioContext::maxNumberOfChannels()) { if (!numberOfChannels || numberOfChannels > AudioContext::maxNumberOfChannels()) {
exceptionState.throwDOMException( exceptionState.throwDOMException(
...@@ -103,7 +103,7 @@ PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t nu ...@@ -103,7 +103,7 @@ PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t nu
return nullptr; return nullptr;
} }
RefPtr<AudioBuffer> audioBuffer = create(numberOfChannels, numberOfFrames, sampleRate); RefPtrWillBeRawPtr<AudioBuffer> audioBuffer = create(numberOfChannels, numberOfFrames, sampleRate);
if (!audioBuffer.get()) { if (!audioBuffer.get()) {
exceptionState.throwDOMException( exceptionState.throwDOMException(
...@@ -118,11 +118,11 @@ PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t nu ...@@ -118,11 +118,11 @@ PassRefPtr<AudioBuffer> AudioBuffer::create(unsigned numberOfChannels, size_t nu
return audioBuffer; return audioBuffer;
} }
PassRefPtr<AudioBuffer> AudioBuffer::createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, float sampleRate) PassRefPtrWillBeRawPtr<AudioBuffer> AudioBuffer::createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, float sampleRate)
{ {
RefPtr<AudioBus> bus = createBusFromInMemoryAudioFile(data, dataSize, mixToMono, sampleRate); RefPtr<AudioBus> bus = createBusFromInMemoryAudioFile(data, dataSize, mixToMono, sampleRate);
if (bus.get()) { if (bus.get()) {
RefPtr<AudioBuffer> buffer = adoptRef(new AudioBuffer(bus.get())); RefPtrWillBeRawPtr<AudioBuffer> buffer = adoptRefWillBeNoop(new AudioBuffer(bus.get()));
if (buffer->createdSuccessfully(bus->numberOfChannels())) if (buffer->createdSuccessfully(bus->numberOfChannels()))
return buffer; return buffer;
} }
...@@ -130,6 +130,16 @@ PassRefPtr<AudioBuffer> AudioBuffer::createFromAudioFileData(const void* data, s ...@@ -130,6 +130,16 @@ PassRefPtr<AudioBuffer> AudioBuffer::createFromAudioFileData(const void* data, s
return nullptr; return nullptr;
} }
PassRefPtrWillBeRawPtr<AudioBuffer> AudioBuffer::createFromAudioBus(AudioBus* bus)
{
if (!bus)
return nullptr;
RefPtrWillBeRawPtr<AudioBuffer> buffer = adoptRefWillBeNoop(new AudioBuffer(bus));
if (buffer->createdSuccessfully(bus->numberOfChannels()))
return buffer;
return nullptr;
}
bool AudioBuffer::createdSuccessfully(unsigned desiredNumberOfChannels) const bool AudioBuffer::createdSuccessfully(unsigned desiredNumberOfChannels) const
{ {
return numberOfChannels() == desiredNumberOfChannels; return numberOfChannels() == desiredNumberOfChannels;
......
...@@ -41,13 +41,15 @@ namespace WebCore { ...@@ -41,13 +41,15 @@ namespace WebCore {
class AudioBus; class AudioBus;
class ExceptionState; class ExceptionState;
class AudioBuffer : public ScriptWrappable, public RefCounted<AudioBuffer> { class AudioBuffer : public RefCountedWillBeGarbageCollectedFinalized<AudioBuffer>, public ScriptWrappable {
public: public:
static PassRefPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate); static PassRefPtrWillBeRawPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
static PassRefPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&); static PassRefPtrWillBeRawPtr<AudioBuffer> create(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&);
// Returns 0 if data is not a valid audio file. // Returns 0 if data is not a valid audio file.
static PassRefPtr<AudioBuffer> createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, float sampleRate); static PassRefPtrWillBeRawPtr<AudioBuffer> createFromAudioFileData(const void* data, size_t dataSize, bool mixToMono, float sampleRate);
static PassRefPtrWillBeRawPtr<AudioBuffer> createFromAudioBus(AudioBus*);
// Format // Format
size_t length() const { return m_length; } size_t length() const { return m_length; }
...@@ -62,6 +64,9 @@ public: ...@@ -62,6 +64,9 @@ public:
static float minAllowedSampleRate(); static float minAllowedSampleRate();
static float maxAllowedSampleRate(); static float maxAllowedSampleRate();
void trace(Visitor*) { }
protected: protected:
AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate); AudioBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate);
explicit AudioBuffer(AudioBus*); explicit AudioBuffer(AudioBus*);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
*/ */
[ [
WillBeGarbageCollected,
Conditional=WEB_AUDIO Conditional=WEB_AUDIO
] interface AudioBuffer { ] interface AudioBuffer {
readonly attribute long length; // in sample-frames readonly attribute long length; // in sample-frames
......
...@@ -49,9 +49,9 @@ const double DefaultGrainDuration = 0.020; // 20ms ...@@ -49,9 +49,9 @@ const double DefaultGrainDuration = 0.020; // 20ms
// to minimize linear interpolation aliasing. // to minimize linear interpolation aliasing.
const double MaxRate = 1024; const double MaxRate = 1024;
PassRefPtr<AudioBufferSourceNode> AudioBufferSourceNode::create(AudioContext* context, float sampleRate) PassRefPtrWillBeRawPtr<AudioBufferSourceNode> AudioBufferSourceNode::create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new AudioBufferSourceNode(context, sampleRate)); return adoptRefWillBeNoop(new AudioBufferSourceNode(context, sampleRate));
} }
AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, float sampleRate) AudioBufferSourceNode::AudioBufferSourceNode(AudioContext* context, float sampleRate)
...@@ -475,6 +475,13 @@ void AudioBufferSourceNode::finish() ...@@ -475,6 +475,13 @@ void AudioBufferSourceNode::finish()
AudioScheduledSourceNode::finish(); AudioScheduledSourceNode::finish();
} }
void AudioBufferSourceNode::trace(Visitor* visitor)
{
visitor->trace(m_buffer);
visitor->trace(m_playbackRate);
AudioScheduledSourceNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -44,7 +44,7 @@ class AudioContext; ...@@ -44,7 +44,7 @@ class AudioContext;
class AudioBufferSourceNode FINAL : public AudioScheduledSourceNode { class AudioBufferSourceNode FINAL : public AudioScheduledSourceNode {
public: public:
static PassRefPtr<AudioBufferSourceNode> create(AudioContext*, float sampleRate); static PassRefPtrWillBeRawPtr<AudioBufferSourceNode> create(AudioContext*, float sampleRate);
virtual ~AudioBufferSourceNode(); virtual ~AudioBufferSourceNode();
...@@ -89,6 +89,8 @@ public: ...@@ -89,6 +89,8 @@ public:
// AudioScheduledSourceNode // AudioScheduledSourceNode
virtual void finish() OVERRIDE; virtual void finish() OVERRIDE;
virtual void trace(Visitor*) OVERRIDE;
private: private:
AudioBufferSourceNode(AudioContext*, float sampleRate); AudioBufferSourceNode(AudioContext*, float sampleRate);
...@@ -99,14 +101,14 @@ private: ...@@ -99,14 +101,14 @@ private:
inline bool renderSilenceAndFinishIfNotLooping(AudioBus*, unsigned index, size_t framesToProcess); inline bool renderSilenceAndFinishIfNotLooping(AudioBus*, unsigned index, size_t framesToProcess);
// m_buffer holds the sample data which this node outputs. // m_buffer holds the sample data which this node outputs.
RefPtr<AudioBuffer> m_buffer; RefPtrWillBeMember<AudioBuffer> m_buffer;
// Pointers for the buffer and destination. // Pointers for the buffer and destination.
OwnPtr<const float*[]> m_sourceChannels; OwnPtr<const float*[]> m_sourceChannels;
OwnPtr<float*[]> m_destinationChannels; OwnPtr<float*[]> m_destinationChannels;
// Used for the "playbackRate" attributes. // Used for the "playbackRate" attributes.
RefPtr<AudioParam> m_playbackRate; RefPtrWillBeMember<AudioParam> m_playbackRate;
// If m_isLooping is false, then this node will be done playing and become inactive after it reaches the end of the sample data in the buffer. // If m_isLooping is false, then this node will be done playing and become inactive after it reaches the end of the sample data in the buffer.
// If true, it will wrap around to the start of the buffer each time it reaches the end. // If true, it will wrap around to the start of the buffer each time it reaches the end.
......
...@@ -29,9 +29,10 @@ ...@@ -29,9 +29,10 @@
#include "core/dom/ActiveDOMObject.h" #include "core/dom/ActiveDOMObject.h"
#include "core/events/EventListener.h" #include "core/events/EventListener.h"
#include "core/events/EventTarget.h" #include "core/events/EventTarget.h"
#include "platform/audio/AudioBus.h"
#include "modules/webaudio/AsyncAudioDecoder.h" #include "modules/webaudio/AsyncAudioDecoder.h"
#include "modules/webaudio/AudioDestinationNode.h" #include "modules/webaudio/AudioDestinationNode.h"
#include "platform/audio/AudioBus.h"
#include "platform/heap/Handle.h"
#include "wtf/HashSet.h" #include "wtf/HashSet.h"
#include "wtf/MainThread.h" #include "wtf/MainThread.h"
#include "wtf/OwnPtr.h" #include "wtf/OwnPtr.h"
...@@ -73,14 +74,16 @@ class WaveShaperNode; ...@@ -73,14 +74,16 @@ class WaveShaperNode;
// AudioContext is the cornerstone of the web audio API and all AudioNodes are created from it. // AudioContext is the cornerstone of the web audio API and all AudioNodes are created from it.
// For thread safety between the audio thread and the main thread, it has a rendering graph locking mechanism. // For thread safety between the audio thread and the main thread, it has a rendering graph locking mechanism.
class AudioContext : public ActiveDOMObject, public ScriptWrappable, public ThreadSafeRefCounted<AudioContext>, public EventTargetWithInlineData { class AudioContext : public ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected<AudioContext>, public ActiveDOMObject, public ScriptWrappable, public EventTargetWithInlineData {
DEFINE_EVENT_TARGET_REFCOUNTING(ThreadSafeRefCounted<AudioContext>); DEFINE_EVENT_TARGET_REFCOUNTING(ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected<AudioContext>);
public: public:
// Create an AudioContext for rendering to the audio hardware. // Create an AudioContext for rendering to the audio hardware.
static PassRefPtr<AudioContext> create(Document&, ExceptionState&); static PassRefPtrWillBeRawPtr<AudioContext> create(Document&, ExceptionState&);
virtual ~AudioContext(); virtual ~AudioContext();
virtual void trace(Visitor*);
bool isInitialized() const; bool isInitialized() const;
// The constructor of an AudioNode must call this to initialize the context. // The constructor of an AudioNode must call this to initialize the context.
void lazyInitialize(); void lazyInitialize();
...@@ -96,7 +99,7 @@ public: ...@@ -96,7 +99,7 @@ public:
double currentTime() const { return m_destinationNode->currentTime(); } double currentTime() const { return m_destinationNode->currentTime(); }
float sampleRate() const { return m_destinationNode->sampleRate(); } float sampleRate() const { return m_destinationNode->sampleRate(); }
PassRefPtr<AudioBuffer> createBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&); PassRefPtrWillBeRawPtr<AudioBuffer> createBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&);
// Asynchronous audio file data decoding. // Asynchronous audio file data decoding.
void decodeAudioData(ArrayBuffer*, PassOwnPtr<AudioBufferCallback>, PassOwnPtr<AudioBufferCallback>, ExceptionState&); void decodeAudioData(ArrayBuffer*, PassOwnPtr<AudioBufferCallback>, PassOwnPtr<AudioBufferCallback>, ExceptionState&);
...@@ -104,29 +107,29 @@ public: ...@@ -104,29 +107,29 @@ public:
AudioListener* listener() { return m_listener.get(); } AudioListener* listener() { return m_listener.get(); }
// The AudioNode create methods are called on the main thread (from JavaScript). // The AudioNode create methods are called on the main thread (from JavaScript).
PassRefPtr<AudioBufferSourceNode> createBufferSource(); PassRefPtrWillBeRawPtr<AudioBufferSourceNode> createBufferSource();
PassRefPtr<MediaElementAudioSourceNode> createMediaElementSource(HTMLMediaElement*, ExceptionState&); PassRefPtrWillBeRawPtr<MediaElementAudioSourceNode> createMediaElementSource(HTMLMediaElement*, ExceptionState&);
PassRefPtr<MediaStreamAudioSourceNode> createMediaStreamSource(MediaStream*, ExceptionState&); PassRefPtrWillBeRawPtr<MediaStreamAudioSourceNode> createMediaStreamSource(MediaStream*, ExceptionState&);
PassRefPtr<MediaStreamAudioDestinationNode> createMediaStreamDestination(); PassRefPtrWillBeRawPtr<MediaStreamAudioDestinationNode> createMediaStreamDestination();
PassRefPtr<GainNode> createGain(); PassRefPtrWillBeRawPtr<GainNode> createGain();
PassRefPtr<BiquadFilterNode> createBiquadFilter(); PassRefPtrWillBeRawPtr<BiquadFilterNode> createBiquadFilter();
PassRefPtr<WaveShaperNode> createWaveShaper(); PassRefPtrWillBeRawPtr<WaveShaperNode> createWaveShaper();
PassRefPtr<DelayNode> createDelay(ExceptionState&); PassRefPtrWillBeRawPtr<DelayNode> createDelay(ExceptionState&);
PassRefPtr<DelayNode> createDelay(double maxDelayTime, ExceptionState&); PassRefPtrWillBeRawPtr<DelayNode> createDelay(double maxDelayTime, ExceptionState&);
PassRefPtr<PannerNode> createPanner(); PassRefPtrWillBeRawPtr<PannerNode> createPanner();
PassRefPtr<ConvolverNode> createConvolver(); PassRefPtrWillBeRawPtr<ConvolverNode> createConvolver();
PassRefPtr<DynamicsCompressorNode> createDynamicsCompressor(); PassRefPtrWillBeRawPtr<DynamicsCompressorNode> createDynamicsCompressor();
PassRefPtr<AnalyserNode> createAnalyser(); PassRefPtrWillBeRawPtr<AnalyserNode> createAnalyser();
PassRefPtr<ScriptProcessorNode> createScriptProcessor(ExceptionState&); PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(ExceptionState&);
PassRefPtr<ScriptProcessorNode> createScriptProcessor(size_t bufferSize, ExceptionState&); PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(size_t bufferSize, ExceptionState&);
PassRefPtr<ScriptProcessorNode> createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, ExceptionState&); PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, ExceptionState&);
PassRefPtr<ScriptProcessorNode> createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionState&); PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(size_t bufferSize, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionState&);
PassRefPtr<ChannelSplitterNode> createChannelSplitter(ExceptionState&); PassRefPtrWillBeRawPtr<ChannelSplitterNode> createChannelSplitter(ExceptionState&);
PassRefPtr<ChannelSplitterNode> createChannelSplitter(size_t numberOfOutputs, ExceptionState&); PassRefPtrWillBeRawPtr<ChannelSplitterNode> createChannelSplitter(size_t numberOfOutputs, ExceptionState&);
PassRefPtr<ChannelMergerNode> createChannelMerger(ExceptionState&); PassRefPtrWillBeRawPtr<ChannelMergerNode> createChannelMerger(ExceptionState&);
PassRefPtr<ChannelMergerNode> createChannelMerger(size_t numberOfInputs, ExceptionState&); PassRefPtrWillBeRawPtr<ChannelMergerNode> createChannelMerger(size_t numberOfInputs, ExceptionState&);
PassRefPtr<OscillatorNode> createOscillator(); PassRefPtrWillBeRawPtr<OscillatorNode> createOscillator();
PassRefPtr<PeriodicWave> createPeriodicWave(Float32Array* real, Float32Array* imag, ExceptionState&); PassRefPtrWillBeRawPtr<PeriodicWave> createPeriodicWave(Float32Array* real, Float32Array* imag, ExceptionState&);
// When a source node has no more processing to do (has finished playing), then it tells the context to dereference it. // When a source node has no more processing to do (has finished playing), then it tells the context to dereference it.
void notifyNodeFinishedProcessing(AudioNode*); void notifyNodeFinishedProcessing(AudioNode*);
...@@ -266,8 +269,8 @@ private: ...@@ -266,8 +269,8 @@ private:
// Make sure to dereference them here. // Make sure to dereference them here.
void derefUnfinishedSourceNodes(); void derefUnfinishedSourceNodes();
RefPtr<AudioDestinationNode> m_destinationNode; RefPtrWillBeMember<AudioDestinationNode> m_destinationNode;
RefPtr<AudioListener> m_listener; RefPtrWillBeMember<AudioListener> m_listener;
// Only accessed in the audio thread. // Only accessed in the audio thread.
Vector<AudioNode*> m_finishedNodes; Vector<AudioNode*> m_finishedNodes;
...@@ -288,7 +291,7 @@ private: ...@@ -288,7 +291,7 @@ private:
bool m_isDeletionScheduled; bool m_isDeletionScheduled;
// Only accessed when the graph lock is held. // Only accessed when the graph lock is held.
HashSet<AudioSummingJunction*> m_dirtySummingJunctions; HashSet<AudioSummingJunction* > m_dirtySummingJunctions;
HashSet<AudioNodeOutput*> m_dirtyAudioNodeOutputs; HashSet<AudioNodeOutput*> m_dirtyAudioNodeOutputs;
void handleDirtyAudioSummingJunctions(); void handleDirtyAudioSummingJunctions();
void handleDirtyAudioNodeOutputs(); void handleDirtyAudioNodeOutputs();
...@@ -311,7 +314,7 @@ private: ...@@ -311,7 +314,7 @@ private:
// Only accessed in the audio thread. // Only accessed in the audio thread.
Vector<AudioNode*> m_deferredFinishDerefList; Vector<AudioNode*> m_deferredFinishDerefList;
RefPtr<AudioBuffer> m_renderTarget; RefPtrWillBeMember<AudioBuffer> m_renderTarget;
bool m_isOfflineContext; bool m_isOfflineContext;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
*/ */
[ [
WillBeGarbageCollected,
ActiveDOMObject, ActiveDOMObject,
Conditional=WEB_AUDIO, Conditional=WEB_AUDIO,
Constructor, Constructor,
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "bindings/v8/ScriptWrappable.h" #include "bindings/v8/ScriptWrappable.h"
#include "platform/geometry/FloatPoint3D.h" #include "platform/geometry/FloatPoint3D.h"
#include "platform/heap/Handle.h"
#include "wtf/PassRefPtr.h" #include "wtf/PassRefPtr.h"
#include "wtf/RefCounted.h" #include "wtf/RefCounted.h"
#include "wtf/Vector.h" #include "wtf/Vector.h"
...@@ -41,11 +42,11 @@ class PannerNode; ...@@ -41,11 +42,11 @@ class PannerNode;
// AudioListener maintains the state of the listener in the audio scene as defined in the OpenAL specification. // AudioListener maintains the state of the listener in the audio scene as defined in the OpenAL specification.
class AudioListener : public ScriptWrappable, public RefCounted<AudioListener> { class AudioListener : public RefCountedWillBeGarbageCollectedFinalized<AudioListener>, public ScriptWrappable {
public: public:
static PassRefPtr<AudioListener> create() static PassRefPtrWillBeRawPtr<AudioListener> create()
{ {
return adoptRef(new AudioListener()); return adoptRefWillBeNoop(new AudioListener());
} }
virtual ~AudioListener(); virtual ~AudioListener();
...@@ -78,6 +79,8 @@ public: ...@@ -78,6 +79,8 @@ public:
void addPanner(PannerNode*); void addPanner(PannerNode*);
void removePanner(PannerNode*); void removePanner(PannerNode*);
void trace(Visitor*) { }
private: private:
AudioListener(); AudioListener();
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
*/ */
[ [
WillBeGarbageCollected,
Conditional=WEB_AUDIO Conditional=WEB_AUDIO
] interface AudioListener { ] interface AudioListener {
attribute float dopplerFactor; // same as OpenAL (default 1.0) attribute float dopplerFactor; // same as OpenAL (default 1.0)
......
...@@ -48,6 +48,9 @@ AudioNode::AudioNode(AudioContext* context, float sampleRate) ...@@ -48,6 +48,9 @@ AudioNode::AudioNode(AudioContext* context, float sampleRate)
, m_nodeType(NodeTypeUnknown) , m_nodeType(NodeTypeUnknown)
, m_context(context) , m_context(context)
, m_sampleRate(sampleRate) , m_sampleRate(sampleRate)
#if ENABLE(OILPAN)
, m_keepAlive(adoptPtr(new Persistent<AudioNode>(this)))
#endif
, m_lastProcessingTime(-1) , m_lastProcessingTime(-1)
, m_lastNonSilentTime(-1) , m_lastNonSilentTime(-1)
, m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class) , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class)
...@@ -473,6 +476,9 @@ void AudioNode::disableOutputsIfNecessary() ...@@ -473,6 +476,9 @@ void AudioNode::disableOutputsIfNecessary()
void AudioNode::ref(RefType refType) void AudioNode::ref(RefType refType)
{ {
#if ENABLE(OILPAN)
ASSERT(m_keepAlive);
#endif
switch (refType) { switch (refType) {
case RefTypeNormal: case RefTypeNormal:
atomicIncrement(&m_normalRefCount); atomicIncrement(&m_normalRefCount);
...@@ -587,6 +593,24 @@ void AudioNode::printNodeCounts() ...@@ -587,6 +593,24 @@ void AudioNode::printNodeCounts()
#endif // DEBUG_AUDIONODE_REFERENCES #endif // DEBUG_AUDIONODE_REFERENCES
void AudioNode::trace(Visitor* visitor)
{
visitor->trace(m_context);
}
#if ENABLE(OILPAN)
void AudioNode::clearKeepAlive()
{
// It is safe to drop the self-persistent when the ref count
// of a AudioNode reaches zero. At that point, the
// AudioNode node is removed from the AudioContext and
// it cannot be reattached. Therefore, the reference count
// will not go above zero again.
ASSERT(m_keepAlive);
m_keepAlive = nullptr;
}
#endif
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -50,7 +50,8 @@ class ExceptionState; ...@@ -50,7 +50,8 @@ class ExceptionState;
// An AudioDestinationNode has one input and no outputs and represents the final destination to the audio hardware. // An AudioDestinationNode has one input and no outputs and represents the final destination to the audio hardware.
// Most processing nodes such as filters will have one input and one output, although multiple inputs and outputs are possible. // Most processing nodes such as filters will have one input and one output, although multiple inputs and outputs are possible.
class AudioNode : public ScriptWrappable, public EventTargetWithInlineData { // AudioNode has its own ref-counting mechanism that use RefTypes so we cannot use RefCountedGarbageCollected.
class AudioNode : public NoBaseWillBeGarbageCollectedFinalized<AudioNode>, public ScriptWrappable, public EventTargetWithInlineData {
public: public:
enum { ProcessingSizeInFrames = 128 }; enum { ProcessingSizeInFrames = 128 };
...@@ -179,6 +180,12 @@ public: ...@@ -179,6 +180,12 @@ public:
virtual const AtomicString& interfaceName() const OVERRIDE FINAL; virtual const AtomicString& interfaceName() const OVERRIDE FINAL;
virtual ExecutionContext* executionContext() const OVERRIDE FINAL; virtual ExecutionContext* executionContext() const OVERRIDE FINAL;
virtual void trace(Visitor*);
#if ENABLE(OILPAN)
void clearKeepAlive();
#endif
protected: protected:
// Inputs and outputs must be created before the AudioNode is initialized. // Inputs and outputs must be created before the AudioNode is initialized.
void addInput(PassOwnPtr<AudioNodeInput>); void addInput(PassOwnPtr<AudioNodeInput>);
...@@ -195,11 +202,23 @@ protected: ...@@ -195,11 +202,23 @@ protected:
private: private:
volatile bool m_isInitialized; volatile bool m_isInitialized;
NodeType m_nodeType; NodeType m_nodeType;
RefPtr<AudioContext> m_context; RefPtrWillBeMember<AudioContext> m_context;
float m_sampleRate; float m_sampleRate;
Vector<OwnPtr<AudioNodeInput> > m_inputs; Vector<OwnPtr<AudioNodeInput> > m_inputs;
Vector<OwnPtr<AudioNodeOutput> > m_outputs; Vector<OwnPtr<AudioNodeOutput> > m_outputs;
#if ENABLE(OILPAN)
// AudioNodes are in the oilpan heap but they are still reference counted at
// the same time. This is because we are not allowed to stop the audio
// thread and thus the audio thread cannot allocate objects in the oilpan
// heap.
// The m_keepAlive handle is used to keep a persistent reference to this
// AudioNode while someone has a reference to this AudioNode through a
// RefPtr.
GC_PLUGIN_IGNORE("http://crbug.com/353083")
OwnPtr<Persistent<AudioNode> > m_keepAlive;
#endif
double m_lastProcessingTime; double m_lastProcessingTime;
double m_lastNonSilentTime; double m_lastNonSilentTime;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
[ [
WillBeGarbageCollected,
Conditional=WEB_AUDIO, Conditional=WEB_AUDIO,
Custom=Wrap, Custom=Wrap,
] interface AudioNode : EventTarget { ] interface AudioNode : EventTarget {
......
...@@ -140,8 +140,7 @@ private: ...@@ -140,8 +140,7 @@ private:
unsigned m_renderingFanOutCount; unsigned m_renderingFanOutCount;
unsigned m_renderingParamFanOutCount; unsigned m_renderingParamFanOutCount;
HashSet<RefPtr<AudioParam> > m_params; WillBePersistentHeapHashSet<RefPtrWillBeMember<AudioParam> > m_params;
typedef HashSet<RefPtr<AudioParam> >::iterator ParamsIterator;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -43,14 +43,14 @@ namespace WebCore { ...@@ -43,14 +43,14 @@ namespace WebCore {
class AudioNodeOutput; class AudioNodeOutput;
class AudioParam FINAL : public RefCounted<AudioParam>, public ScriptWrappable, public AudioSummingJunction { class AudioParam FINAL : public RefCountedWillBeGarbageCollectedFinalized<AudioParam>, public ScriptWrappable, public AudioSummingJunction {
public: public:
static const double DefaultSmoothingConstant; static const double DefaultSmoothingConstant;
static const double SnapThreshold; static const double SnapThreshold;
static PassRefPtr<AudioParam> create(AudioContext* context, const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0) static PassRefPtrWillBeRawPtr<AudioParam> create(AudioContext* context, const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0)
{ {
return adoptRef(new AudioParam(context, name, defaultValue, minValue, maxValue, units)); return adoptRefWillBeNoop(new AudioParam(context, name, defaultValue, minValue, maxValue, units));
} }
// AudioSummingJunction // AudioSummingJunction
...@@ -102,6 +102,8 @@ public: ...@@ -102,6 +102,8 @@ public:
void connect(AudioNodeOutput*); void connect(AudioNodeOutput*);
void disconnect(AudioNodeOutput*); void disconnect(AudioNodeOutput*);
void trace(Visitor*) { }
protected: protected:
AudioParam(AudioContext* context, const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0) AudioParam(AudioContext* context, const String& name, double defaultValue, double minValue, double maxValue, unsigned units = 0)
: AudioSummingJunction(context) : AudioSummingJunction(context)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
*/ */
[ [
WillBeGarbageCollected,
Conditional=WEB_AUDIO Conditional=WEB_AUDIO
] interface AudioParam { ] interface AudioParam {
attribute float value; attribute float value;
......
...@@ -35,7 +35,7 @@ PassRefPtrWillBeRawPtr<AudioProcessingEvent> AudioProcessingEvent::create() ...@@ -35,7 +35,7 @@ PassRefPtrWillBeRawPtr<AudioProcessingEvent> AudioProcessingEvent::create()
return adoptRefWillBeNoop(new AudioProcessingEvent); return adoptRefWillBeNoop(new AudioProcessingEvent);
} }
PassRefPtrWillBeRawPtr<AudioProcessingEvent> AudioProcessingEvent::create(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer, double playbackTime) PassRefPtrWillBeRawPtr<AudioProcessingEvent> AudioProcessingEvent::create(PassRefPtrWillBeRawPtr<AudioBuffer> inputBuffer, PassRefPtrWillBeRawPtr<AudioBuffer> outputBuffer, double playbackTime)
{ {
return adoptRefWillBeNoop(new AudioProcessingEvent(inputBuffer, outputBuffer, playbackTime)); return adoptRefWillBeNoop(new AudioProcessingEvent(inputBuffer, outputBuffer, playbackTime));
} }
...@@ -45,7 +45,7 @@ AudioProcessingEvent::AudioProcessingEvent() ...@@ -45,7 +45,7 @@ AudioProcessingEvent::AudioProcessingEvent()
ScriptWrappable::init(this); ScriptWrappable::init(this);
} }
AudioProcessingEvent::AudioProcessingEvent(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer, double playbackTime) AudioProcessingEvent::AudioProcessingEvent(PassRefPtrWillBeRawPtr<AudioBuffer> inputBuffer, PassRefPtrWillBeRawPtr<AudioBuffer> outputBuffer, double playbackTime)
: Event(EventTypeNames::audioprocess, true, false) : Event(EventTypeNames::audioprocess, true, false)
, m_inputBuffer(inputBuffer) , m_inputBuffer(inputBuffer)
, m_outputBuffer(outputBuffer) , m_outputBuffer(outputBuffer)
...@@ -65,6 +65,8 @@ const AtomicString& AudioProcessingEvent::interfaceName() const ...@@ -65,6 +65,8 @@ const AtomicString& AudioProcessingEvent::interfaceName() const
void AudioProcessingEvent::trace(Visitor* visitor) void AudioProcessingEvent::trace(Visitor* visitor)
{ {
visitor->trace(m_inputBuffer);
visitor->trace(m_outputBuffer);
Event::trace(visitor); Event::trace(visitor);
} }
......
...@@ -37,7 +37,7 @@ class AudioBuffer; ...@@ -37,7 +37,7 @@ class AudioBuffer;
class AudioProcessingEvent FINAL : public Event { class AudioProcessingEvent FINAL : public Event {
public: public:
static PassRefPtrWillBeRawPtr<AudioProcessingEvent> create(); static PassRefPtrWillBeRawPtr<AudioProcessingEvent> create();
static PassRefPtrWillBeRawPtr<AudioProcessingEvent> create(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer, double playbackTime); static PassRefPtrWillBeRawPtr<AudioProcessingEvent> create(PassRefPtrWillBeRawPtr<AudioBuffer> inputBuffer, PassRefPtrWillBeRawPtr<AudioBuffer> outputBuffer, double playbackTime);
virtual ~AudioProcessingEvent(); virtual ~AudioProcessingEvent();
...@@ -51,10 +51,10 @@ public: ...@@ -51,10 +51,10 @@ public:
private: private:
AudioProcessingEvent(); AudioProcessingEvent();
AudioProcessingEvent(PassRefPtr<AudioBuffer> inputBuffer, PassRefPtr<AudioBuffer> outputBuffer, double playbackTime); AudioProcessingEvent(PassRefPtrWillBeRawPtr<AudioBuffer> inputBuffer, PassRefPtrWillBeRawPtr<AudioBuffer> outputBuffer, double playbackTime);
RefPtr<AudioBuffer> m_inputBuffer; RefPtrWillBeMember<AudioBuffer> m_inputBuffer;
RefPtr<AudioBuffer> m_outputBuffer; RefPtrWillBeMember<AudioBuffer> m_outputBuffer;
double m_playbackTime; double m_playbackTime;
}; };
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define AudioSummingJunction_h #define AudioSummingJunction_h
#include "platform/audio/AudioBus.h" #include "platform/audio/AudioBus.h"
#include "platform/heap/Handle.h"
#include "wtf/HashSet.h" #include "wtf/HashSet.h"
#include "wtf/Vector.h" #include "wtf/Vector.h"
...@@ -60,7 +61,7 @@ public: ...@@ -60,7 +61,7 @@ public:
virtual void didUpdate() = 0; virtual void didUpdate() = 0;
protected: protected:
RefPtr<AudioContext> m_context; RefPtrWillBePersistent<AudioContext> m_context;
// m_outputs contains the AudioNodeOutputs representing current connections which are not disabled. // m_outputs contains the AudioNodeOutputs representing current connections which are not disabled.
// The rendering code should never use this directly, but instead uses m_renderingOutputs. // The rendering code should never use this directly, but instead uses m_renderingOutputs.
......
...@@ -46,9 +46,9 @@ public: ...@@ -46,9 +46,9 @@ public:
ALLPASS = 7 ALLPASS = 7
}; };
static PassRefPtr<BiquadFilterNode> create(AudioContext* context, float sampleRate) static PassRefPtrWillBeRawPtr<BiquadFilterNode> create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new BiquadFilterNode(context, sampleRate)); return adoptRefWillBeNoop(new BiquadFilterNode(context, sampleRate));
} }
String type() const; String type() const;
......
...@@ -80,10 +80,10 @@ public: ...@@ -80,10 +80,10 @@ public:
private: private:
FilterType m_type; FilterType m_type;
RefPtr<AudioParam> m_parameter1; RefPtrWillBePersistent<AudioParam> m_parameter1;
RefPtr<AudioParam> m_parameter2; RefPtrWillBePersistent<AudioParam> m_parameter2;
RefPtr<AudioParam> m_parameter3; RefPtrWillBePersistent<AudioParam> m_parameter3;
RefPtr<AudioParam> m_parameter4; RefPtrWillBePersistent<AudioParam> m_parameter4;
// so DSP kernels know when to re-compute coefficients // so DSP kernels know when to re-compute coefficients
bool m_filterCoefficientsDirty; bool m_filterCoefficientsDirty;
......
...@@ -40,12 +40,12 @@ const unsigned DefaultNumberOfOutputChannels = 1; ...@@ -40,12 +40,12 @@ const unsigned DefaultNumberOfOutputChannels = 1;
namespace WebCore { namespace WebCore {
PassRefPtr<ChannelMergerNode> ChannelMergerNode::create(AudioContext* context, float sampleRate, unsigned numberOfInputs) PassRefPtrWillBeRawPtr<ChannelMergerNode> ChannelMergerNode::create(AudioContext* context, float sampleRate, unsigned numberOfInputs)
{ {
if (!numberOfInputs || numberOfInputs > AudioContext::maxNumberOfChannels()) if (!numberOfInputs || numberOfInputs > AudioContext::maxNumberOfChannels())
return nullptr; return nullptr;
return adoptRef(new ChannelMergerNode(context, sampleRate, numberOfInputs)); return adoptRefWillBeNoop(new ChannelMergerNode(context, sampleRate, numberOfInputs));
} }
ChannelMergerNode::ChannelMergerNode(AudioContext* context, float sampleRate, unsigned numberOfInputs) ChannelMergerNode::ChannelMergerNode(AudioContext* context, float sampleRate, unsigned numberOfInputs)
......
...@@ -38,7 +38,7 @@ class AudioContext; ...@@ -38,7 +38,7 @@ class AudioContext;
class ChannelMergerNode FINAL : public AudioNode { class ChannelMergerNode FINAL : public AudioNode {
public: public:
static PassRefPtr<ChannelMergerNode> create(AudioContext*, float sampleRate, unsigned numberOfInputs); static PassRefPtrWillBeRawPtr<ChannelMergerNode> create(AudioContext*, float sampleRate, unsigned numberOfInputs);
// AudioNode // AudioNode
virtual void process(size_t framesToProcess) OVERRIDE; virtual void process(size_t framesToProcess) OVERRIDE;
......
...@@ -34,12 +34,12 @@ ...@@ -34,12 +34,12 @@
namespace WebCore { namespace WebCore {
PassRefPtr<ChannelSplitterNode> ChannelSplitterNode::create(AudioContext* context, float sampleRate, unsigned numberOfOutputs) PassRefPtrWillBeRawPtr<ChannelSplitterNode> ChannelSplitterNode::create(AudioContext* context, float sampleRate, unsigned numberOfOutputs)
{ {
if (!numberOfOutputs || numberOfOutputs > AudioContext::maxNumberOfChannels()) if (!numberOfOutputs || numberOfOutputs > AudioContext::maxNumberOfChannels())
return nullptr; return nullptr;
return adoptRef(new ChannelSplitterNode(context, sampleRate, numberOfOutputs)); return adoptRefWillBeNoop(new ChannelSplitterNode(context, sampleRate, numberOfOutputs));
} }
ChannelSplitterNode::ChannelSplitterNode(AudioContext* context, float sampleRate, unsigned numberOfOutputs) ChannelSplitterNode::ChannelSplitterNode(AudioContext* context, float sampleRate, unsigned numberOfOutputs)
......
...@@ -34,7 +34,7 @@ class AudioContext; ...@@ -34,7 +34,7 @@ class AudioContext;
class ChannelSplitterNode FINAL : public AudioNode { class ChannelSplitterNode FINAL : public AudioNode {
public: public:
static PassRefPtr<ChannelSplitterNode> create(AudioContext*, float sampleRate, unsigned numberOfOutputs); static PassRefPtrWillBeRawPtr<ChannelSplitterNode> create(AudioContext*, float sampleRate, unsigned numberOfOutputs);
// AudioNode // AudioNode
virtual void process(size_t framesToProcess) OVERRIDE; virtual void process(size_t framesToProcess) OVERRIDE;
......
...@@ -179,6 +179,12 @@ double ConvolverNode::latencyTime() const ...@@ -179,6 +179,12 @@ double ConvolverNode::latencyTime() const
return std::numeric_limits<double>::infinity(); return std::numeric_limits<double>::infinity();
} }
void ConvolverNode::trace(Visitor* visitor)
{
visitor->trace(m_buffer);
AudioNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -38,9 +38,9 @@ class Reverb; ...@@ -38,9 +38,9 @@ class Reverb;
class ConvolverNode FINAL : public AudioNode { class ConvolverNode FINAL : public AudioNode {
public: public:
static PassRefPtr<ConvolverNode> create(AudioContext* context, float sampleRate) static PassRefPtrWillBeRawPtr<ConvolverNode> create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new ConvolverNode(context, sampleRate)); return adoptRefWillBeNoop(new ConvolverNode(context, sampleRate));
} }
virtual ~ConvolverNode(); virtual ~ConvolverNode();
...@@ -57,6 +57,8 @@ public: ...@@ -57,6 +57,8 @@ public:
bool normalize() const { return m_normalize; } bool normalize() const { return m_normalize; }
void setNormalize(bool normalize) { m_normalize = normalize; } void setNormalize(bool normalize) { m_normalize = normalize; }
virtual void trace(Visitor*) OVERRIDE;
private: private:
ConvolverNode(AudioContext*, float sampleRate); ConvolverNode(AudioContext*, float sampleRate);
...@@ -64,7 +66,7 @@ private: ...@@ -64,7 +66,7 @@ private:
virtual double latencyTime() const OVERRIDE; virtual double latencyTime() const OVERRIDE;
OwnPtr<Reverb> m_reverb; OwnPtr<Reverb> m_reverb;
RefPtr<AudioBuffer> m_buffer; RefPtrWillBeMember<AudioBuffer> m_buffer;
// This synchronizes dynamic changes to the convolution impulse response with process(). // This synchronizes dynamic changes to the convolution impulse response with process().
mutable Mutex m_processLock; mutable Mutex m_processLock;
......
...@@ -36,9 +36,9 @@ class ExceptionState; ...@@ -36,9 +36,9 @@ class ExceptionState;
class DefaultAudioDestinationNode FINAL : public AudioDestinationNode { class DefaultAudioDestinationNode FINAL : public AudioDestinationNode {
public: public:
static PassRefPtr<DefaultAudioDestinationNode> create(AudioContext* context) static PassRefPtrWillBeRawPtr<DefaultAudioDestinationNode> create(AudioContext* context)
{ {
return adoptRef(new DefaultAudioDestinationNode(context)); return adoptRefWillBeNoop(new DefaultAudioDestinationNode(context));
} }
virtual ~DefaultAudioDestinationNode(); virtual ~DefaultAudioDestinationNode();
......
...@@ -36,9 +36,9 @@ class ExceptionState; ...@@ -36,9 +36,9 @@ class ExceptionState;
class DelayNode FINAL : public AudioBasicProcessorNode { class DelayNode FINAL : public AudioBasicProcessorNode {
public: public:
static PassRefPtr<DelayNode> create(AudioContext* context, float sampleRate, double maxDelayTime, ExceptionState& exceptionState) static PassRefPtrWillBeRawPtr<DelayNode> create(AudioContext* context, float sampleRate, double maxDelayTime, ExceptionState& exceptionState)
{ {
return adoptRef(new DelayNode(context, sampleRate, maxDelayTime, exceptionState)); return adoptRefWillBeNoop(new DelayNode(context, sampleRate, maxDelayTime, exceptionState));
} }
AudioParam* delayTime(); AudioParam* delayTime();
......
...@@ -46,7 +46,7 @@ public: ...@@ -46,7 +46,7 @@ public:
double maxDelayTime() { return m_maxDelayTime; } double maxDelayTime() { return m_maxDelayTime; }
private: private:
RefPtr<AudioParam> m_delayTime; RefPtrWillBePersistent<AudioParam> m_delayTime;
double m_maxDelayTime; double m_maxDelayTime;
}; };
......
...@@ -113,6 +113,17 @@ double DynamicsCompressorNode::latencyTime() const ...@@ -113,6 +113,17 @@ double DynamicsCompressorNode::latencyTime() const
return m_dynamicsCompressor->latencyTime(); return m_dynamicsCompressor->latencyTime();
} }
void DynamicsCompressorNode::trace(Visitor* visitor)
{
visitor->trace(m_threshold);
visitor->trace(m_knee);
visitor->trace(m_ratio);
visitor->trace(m_reduction);
visitor->trace(m_attack);
visitor->trace(m_release);
AudioNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -35,9 +35,9 @@ class DynamicsCompressor; ...@@ -35,9 +35,9 @@ class DynamicsCompressor;
class DynamicsCompressorNode FINAL : public AudioNode { class DynamicsCompressorNode FINAL : public AudioNode {
public: public:
static PassRefPtr<DynamicsCompressorNode> create(AudioContext* context, float sampleRate) static PassRefPtrWillBeRawPtr<DynamicsCompressorNode> create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new DynamicsCompressorNode(context, sampleRate)); return adoptRefWillBeNoop(new DynamicsCompressorNode(context, sampleRate));
} }
virtual ~DynamicsCompressorNode(); virtual ~DynamicsCompressorNode();
...@@ -57,6 +57,8 @@ public: ...@@ -57,6 +57,8 @@ public:
// Amount by which the compressor is currently compressing the signal in decibels. // Amount by which the compressor is currently compressing the signal in decibels.
AudioParam* reduction() { return m_reduction.get(); } AudioParam* reduction() { return m_reduction.get(); }
virtual void trace(Visitor*) OVERRIDE;
private: private:
virtual double tailTime() const OVERRIDE; virtual double tailTime() const OVERRIDE;
virtual double latencyTime() const OVERRIDE; virtual double latencyTime() const OVERRIDE;
...@@ -64,12 +66,12 @@ private: ...@@ -64,12 +66,12 @@ private:
DynamicsCompressorNode(AudioContext*, float sampleRate); DynamicsCompressorNode(AudioContext*, float sampleRate);
OwnPtr<DynamicsCompressor> m_dynamicsCompressor; OwnPtr<DynamicsCompressor> m_dynamicsCompressor;
RefPtr<AudioParam> m_threshold; RefPtrWillBeMember<AudioParam> m_threshold;
RefPtr<AudioParam> m_knee; RefPtrWillBeMember<AudioParam> m_knee;
RefPtr<AudioParam> m_ratio; RefPtrWillBeMember<AudioParam> m_ratio;
RefPtr<AudioParam> m_reduction; RefPtrWillBeMember<AudioParam> m_reduction;
RefPtr<AudioParam> m_attack; RefPtrWillBeMember<AudioParam> m_attack;
RefPtr<AudioParam> m_release; RefPtrWillBeMember<AudioParam> m_release;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -108,6 +108,12 @@ void GainNode::checkNumberOfChannelsForInput(AudioNodeInput* input) ...@@ -108,6 +108,12 @@ void GainNode::checkNumberOfChannelsForInput(AudioNodeInput* input)
AudioNode::checkNumberOfChannelsForInput(input); AudioNode::checkNumberOfChannelsForInput(input);
} }
void GainNode::trace(Visitor* visitor)
{
visitor->trace(m_gain);
AudioNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -39,9 +39,9 @@ class AudioContext; ...@@ -39,9 +39,9 @@ class AudioContext;
class GainNode FINAL : public AudioNode { class GainNode FINAL : public AudioNode {
public: public:
static PassRefPtr<GainNode> create(AudioContext* context, float sampleRate) static PassRefPtrWillBeRawPtr<GainNode> create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new GainNode(context, sampleRate)); return adoptRefWillBeNoop(new GainNode(context, sampleRate));
} }
// AudioNode // AudioNode
...@@ -53,6 +53,8 @@ public: ...@@ -53,6 +53,8 @@ public:
// JavaScript interface // JavaScript interface
AudioParam* gain() { return m_gain.get(); } AudioParam* gain() { return m_gain.get(); }
virtual void trace(Visitor*) OVERRIDE;
private: private:
virtual double tailTime() const OVERRIDE { return 0; } virtual double tailTime() const OVERRIDE { return 0; }
virtual double latencyTime() const OVERRIDE { return 0; } virtual double latencyTime() const OVERRIDE { return 0; }
...@@ -60,7 +62,7 @@ private: ...@@ -60,7 +62,7 @@ private:
GainNode(AudioContext*, float sampleRate); GainNode(AudioContext*, float sampleRate);
float m_lastGain; // for de-zippering float m_lastGain; // for de-zippering
RefPtr<AudioParam> m_gain; RefPtrWillBeMember<AudioParam> m_gain;
AudioFloatArray m_sampleAccurateGainValues; AudioFloatArray m_sampleAccurateGainValues;
}; };
......
...@@ -41,9 +41,9 @@ const unsigned maxSampleRate = 192000; ...@@ -41,9 +41,9 @@ const unsigned maxSampleRate = 192000;
namespace WebCore { namespace WebCore {
PassRefPtr<MediaElementAudioSourceNode> MediaElementAudioSourceNode::create(AudioContext* context, HTMLMediaElement* mediaElement) PassRefPtrWillBeRawPtr<MediaElementAudioSourceNode> MediaElementAudioSourceNode::create(AudioContext* context, HTMLMediaElement* mediaElement)
{ {
return adoptRef(new MediaElementAudioSourceNode(context, mediaElement)); return adoptRefWillBeNoop(new MediaElementAudioSourceNode(context, mediaElement));
} }
MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* context, HTMLMediaElement* mediaElement) MediaElementAudioSourceNode::MediaElementAudioSourceNode(AudioContext* context, HTMLMediaElement* mediaElement)
......
...@@ -41,7 +41,7 @@ class HTMLMediaElement; ...@@ -41,7 +41,7 @@ class HTMLMediaElement;
class MediaElementAudioSourceNode FINAL : public AudioSourceNode, public AudioSourceProviderClient { class MediaElementAudioSourceNode FINAL : public AudioSourceNode, public AudioSourceProviderClient {
public: public:
static PassRefPtr<MediaElementAudioSourceNode> create(AudioContext*, HTMLMediaElement*); static PassRefPtrWillBeRawPtr<MediaElementAudioSourceNode> create(AudioContext*, HTMLMediaElement*);
virtual ~MediaElementAudioSourceNode(); virtual ~MediaElementAudioSourceNode();
......
...@@ -37,9 +37,9 @@ ...@@ -37,9 +37,9 @@
namespace WebCore { namespace WebCore {
PassRefPtr<MediaStreamAudioDestinationNode> MediaStreamAudioDestinationNode::create(AudioContext* context, size_t numberOfChannels) PassRefPtrWillBeRawPtr<MediaStreamAudioDestinationNode> MediaStreamAudioDestinationNode::create(AudioContext* context, size_t numberOfChannels)
{ {
return adoptRef(new MediaStreamAudioDestinationNode(context, numberOfChannels)); return adoptRefWillBeNoop(new MediaStreamAudioDestinationNode(context, numberOfChannels));
} }
MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* context, size_t numberOfChannels) MediaStreamAudioDestinationNode::MediaStreamAudioDestinationNode(AudioContext* context, size_t numberOfChannels)
......
...@@ -39,7 +39,7 @@ class AudioContext; ...@@ -39,7 +39,7 @@ class AudioContext;
class MediaStreamAudioDestinationNode FINAL : public AudioBasicInspectorNode { class MediaStreamAudioDestinationNode FINAL : public AudioBasicInspectorNode {
public: public:
static PassRefPtr<MediaStreamAudioDestinationNode> create(AudioContext*, size_t numberOfChannels); static PassRefPtrWillBeRawPtr<MediaStreamAudioDestinationNode> create(AudioContext*, size_t numberOfChannels);
virtual ~MediaStreamAudioDestinationNode(); virtual ~MediaStreamAudioDestinationNode();
......
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
namespace WebCore { namespace WebCore {
PassRefPtr<MediaStreamAudioSourceNode> MediaStreamAudioSourceNode::create(AudioContext* context, MediaStream* mediaStream, MediaStreamTrack* audioTrack, PassOwnPtr<AudioSourceProvider> audioSourceProvider) PassRefPtrWillBeRawPtr<MediaStreamAudioSourceNode> MediaStreamAudioSourceNode::create(AudioContext* context, MediaStream* mediaStream, MediaStreamTrack* audioTrack, PassOwnPtr<AudioSourceProvider> audioSourceProvider)
{ {
return adoptRef(new MediaStreamAudioSourceNode(context, mediaStream, audioTrack, audioSourceProvider)); return adoptRefWillBeNoop(new MediaStreamAudioSourceNode(context, mediaStream, audioTrack, audioSourceProvider));
} }
MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* context, MediaStream* mediaStream, MediaStreamTrack* audioTrack, PassOwnPtr<AudioSourceProvider> audioSourceProvider) MediaStreamAudioSourceNode::MediaStreamAudioSourceNode(AudioContext* context, MediaStream* mediaStream, MediaStreamTrack* audioTrack, PassOwnPtr<AudioSourceProvider> audioSourceProvider)
......
...@@ -41,7 +41,7 @@ class AudioContext; ...@@ -41,7 +41,7 @@ class AudioContext;
class MediaStreamAudioSourceNode FINAL : public AudioSourceNode, public AudioSourceProviderClient { class MediaStreamAudioSourceNode FINAL : public AudioSourceNode, public AudioSourceProviderClient {
public: public:
static PassRefPtr<MediaStreamAudioSourceNode> create(AudioContext*, MediaStream*, MediaStreamTrack*, PassOwnPtr<AudioSourceProvider>); static PassRefPtrWillBeRawPtr<MediaStreamAudioSourceNode> create(AudioContext*, MediaStream*, MediaStreamTrack*, PassOwnPtr<AudioSourceProvider>);
virtual ~MediaStreamAudioSourceNode(); virtual ~MediaStreamAudioSourceNode();
......
...@@ -35,7 +35,7 @@ PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> OfflineAudioCompletionEvent: ...@@ -35,7 +35,7 @@ PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> OfflineAudioCompletionEvent:
return adoptRefWillBeNoop(new OfflineAudioCompletionEvent); return adoptRefWillBeNoop(new OfflineAudioCompletionEvent);
} }
PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> OfflineAudioCompletionEvent::create(PassRefPtr<AudioBuffer> renderedBuffer) PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> OfflineAudioCompletionEvent::create(PassRefPtrWillBeRawPtr<AudioBuffer> renderedBuffer)
{ {
return adoptRefWillBeNoop(new OfflineAudioCompletionEvent(renderedBuffer)); return adoptRefWillBeNoop(new OfflineAudioCompletionEvent(renderedBuffer));
} }
...@@ -45,7 +45,7 @@ OfflineAudioCompletionEvent::OfflineAudioCompletionEvent() ...@@ -45,7 +45,7 @@ OfflineAudioCompletionEvent::OfflineAudioCompletionEvent()
ScriptWrappable::init(this); ScriptWrappable::init(this);
} }
OfflineAudioCompletionEvent::OfflineAudioCompletionEvent(PassRefPtr<AudioBuffer> renderedBuffer) OfflineAudioCompletionEvent::OfflineAudioCompletionEvent(PassRefPtrWillBeRawPtr<AudioBuffer> renderedBuffer)
: Event(EventTypeNames::complete, true, false) : Event(EventTypeNames::complete, true, false)
, m_renderedBuffer(renderedBuffer) , m_renderedBuffer(renderedBuffer)
{ {
...@@ -63,6 +63,7 @@ const AtomicString& OfflineAudioCompletionEvent::interfaceName() const ...@@ -63,6 +63,7 @@ const AtomicString& OfflineAudioCompletionEvent::interfaceName() const
void OfflineAudioCompletionEvent::trace(Visitor* visitor) void OfflineAudioCompletionEvent::trace(Visitor* visitor)
{ {
visitor->trace(m_renderedBuffer);
Event::trace(visitor); Event::trace(visitor);
} }
......
...@@ -37,7 +37,7 @@ class AudioBuffer; ...@@ -37,7 +37,7 @@ class AudioBuffer;
class OfflineAudioCompletionEvent FINAL : public Event { class OfflineAudioCompletionEvent FINAL : public Event {
public: public:
static PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> create(); static PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> create();
static PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> create(PassRefPtr<AudioBuffer> renderedBuffer); static PassRefPtrWillBeRawPtr<OfflineAudioCompletionEvent> create(PassRefPtrWillBeRawPtr<AudioBuffer> renderedBuffer);
virtual ~OfflineAudioCompletionEvent(); virtual ~OfflineAudioCompletionEvent();
...@@ -49,9 +49,9 @@ public: ...@@ -49,9 +49,9 @@ public:
private: private:
OfflineAudioCompletionEvent(); OfflineAudioCompletionEvent();
explicit OfflineAudioCompletionEvent(PassRefPtr<AudioBuffer> renderedBuffer); explicit OfflineAudioCompletionEvent(PassRefPtrWillBeRawPtr<AudioBuffer> renderedBuffer);
RefPtr<AudioBuffer> m_renderedBuffer; RefPtrWillBeMember<AudioBuffer> m_renderedBuffer;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
namespace WebCore { namespace WebCore {
PassRefPtr<OfflineAudioContext> OfflineAudioContext::create(ExecutionContext* context, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState& exceptionState) PassRefPtrWillBeRawPtr<OfflineAudioContext> OfflineAudioContext::create(ExecutionContext* context, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState& exceptionState)
{ {
// FIXME: add support for workers. // FIXME: add support for workers.
if (!context || !context->isDocument()) { if (!context || !context->isDocument()) {
...@@ -71,7 +71,7 @@ PassRefPtr<OfflineAudioContext> OfflineAudioContext::create(ExecutionContext* co ...@@ -71,7 +71,7 @@ PassRefPtr<OfflineAudioContext> OfflineAudioContext::create(ExecutionContext* co
return nullptr; return nullptr;
} }
RefPtr<OfflineAudioContext> audioContext(adoptRef(new OfflineAudioContext(document, numberOfChannels, numberOfFrames, sampleRate))); RefPtrWillBeRawPtr<OfflineAudioContext> audioContext(adoptRefWillBeThreadSafeRefCountedGarbageCollected(new OfflineAudioContext(document, numberOfChannels, numberOfFrames, sampleRate)));
if (!audioContext->destination()) { if (!audioContext->destination()) {
exceptionState.throwDOMException( exceptionState.throwDOMException(
......
...@@ -33,7 +33,7 @@ class ExceptionState; ...@@ -33,7 +33,7 @@ class ExceptionState;
class OfflineAudioContext FINAL : public AudioContext { class OfflineAudioContext FINAL : public AudioContext {
public: public:
static PassRefPtr<OfflineAudioContext> create(ExecutionContext*, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&); static PassRefPtrWillBeRawPtr<OfflineAudioContext> create(ExecutionContext*, unsigned numberOfChannels, size_t numberOfFrames, float sampleRate, ExceptionState&);
virtual ~OfflineAudioContext(); virtual ~OfflineAudioContext();
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
*/ */
[ [
WillBeGarbageCollected,
Conditional=WEB_AUDIO, Conditional=WEB_AUDIO,
Constructor(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate), Constructor(unsigned long numberOfChannels, unsigned long numberOfFrames, float sampleRate),
ConstructorCallWith=ExecutionContext, ConstructorCallWith=ExecutionContext,
......
...@@ -153,6 +153,12 @@ void OfflineAudioDestinationNode::notifyComplete() ...@@ -153,6 +153,12 @@ void OfflineAudioDestinationNode::notifyComplete()
context()->fireCompletionEvent(); context()->fireCompletionEvent();
} }
void OfflineAudioDestinationNode::trace(Visitor* visitor)
{
visitor->trace(m_renderTarget);
AudioDestinationNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -38,9 +38,9 @@ class AudioContext; ...@@ -38,9 +38,9 @@ class AudioContext;
class OfflineAudioDestinationNode FINAL : public AudioDestinationNode { class OfflineAudioDestinationNode FINAL : public AudioDestinationNode {
public: public:
static PassRefPtr<OfflineAudioDestinationNode> create(AudioContext* context, AudioBuffer* renderTarget) static PassRefPtrWillBeRawPtr<OfflineAudioDestinationNode> create(AudioContext* context, AudioBuffer* renderTarget)
{ {
return adoptRef(new OfflineAudioDestinationNode(context, renderTarget)); return adoptRefWillBeNoop(new OfflineAudioDestinationNode(context, renderTarget));
} }
virtual ~OfflineAudioDestinationNode(); virtual ~OfflineAudioDestinationNode();
...@@ -54,6 +54,8 @@ public: ...@@ -54,6 +54,8 @@ public:
virtual float sampleRate() const OVERRIDE { return m_renderTarget->sampleRate(); } virtual float sampleRate() const OVERRIDE { return m_renderTarget->sampleRate(); }
virtual void trace(Visitor*) OVERRIDE;
private: private:
class OfflineRenderingTask; class OfflineRenderingTask;
friend class OfflineRenderingTask; friend class OfflineRenderingTask;
...@@ -61,7 +63,7 @@ private: ...@@ -61,7 +63,7 @@ private:
OfflineAudioDestinationNode(AudioContext*, AudioBuffer* renderTarget); OfflineAudioDestinationNode(AudioContext*, AudioBuffer* renderTarget);
// This AudioNode renders into this AudioBuffer. // This AudioNode renders into this AudioBuffer.
RefPtr<AudioBuffer> m_renderTarget; RefPtrWillBeMember<AudioBuffer> m_renderTarget;
// Temporary AudioBus for each render quantum. // Temporary AudioBus for each render quantum.
RefPtr<AudioBus> m_renderBus; RefPtr<AudioBus> m_renderBus;
......
...@@ -43,9 +43,9 @@ namespace WebCore { ...@@ -43,9 +43,9 @@ namespace WebCore {
using namespace VectorMath; using namespace VectorMath;
PassRefPtr<OscillatorNode> OscillatorNode::create(AudioContext* context, float sampleRate) PassRefPtrWillBeRawPtr<OscillatorNode> OscillatorNode::create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new OscillatorNode(context, sampleRate)); return adoptRefWillBeNoop(new OscillatorNode(context, sampleRate));
} }
OscillatorNode::OscillatorNode(AudioContext* context, float sampleRate) OscillatorNode::OscillatorNode(AudioContext* context, float sampleRate)
...@@ -116,22 +116,22 @@ bool OscillatorNode::setType(unsigned type) ...@@ -116,22 +116,22 @@ bool OscillatorNode::setType(unsigned type)
switch (type) { switch (type) {
case SINE: { case SINE: {
DEFINE_STATIC_REF(PeriodicWave, periodicWaveSine, (PeriodicWave::createSine(sampleRate))); DEFINE_STATIC_REF_WILL_BE_PERSISTENT(PeriodicWave, periodicWaveSine, (PeriodicWave::createSine(sampleRate)));
periodicWave = periodicWaveSine; periodicWave = periodicWaveSine;
break; break;
} }
case SQUARE: { case SQUARE: {
DEFINE_STATIC_REF(PeriodicWave, periodicWaveSquare, (PeriodicWave::createSquare(sampleRate))); DEFINE_STATIC_REF_WILL_BE_PERSISTENT(PeriodicWave, periodicWaveSquare, (PeriodicWave::createSquare(sampleRate)));
periodicWave = periodicWaveSquare; periodicWave = periodicWaveSquare;
break; break;
} }
case SAWTOOTH: { case SAWTOOTH: {
DEFINE_STATIC_REF(PeriodicWave, periodicWaveSawtooth, (PeriodicWave::createSawtooth(sampleRate))); DEFINE_STATIC_REF_WILL_BE_PERSISTENT(PeriodicWave, periodicWaveSawtooth, (PeriodicWave::createSawtooth(sampleRate)));
periodicWave = periodicWaveSawtooth; periodicWave = periodicWaveSawtooth;
break; break;
} }
case TRIANGLE: { case TRIANGLE: {
DEFINE_STATIC_REF(PeriodicWave, periodicWaveTriangle, (PeriodicWave::createTriangle(sampleRate))); DEFINE_STATIC_REF_WILL_BE_PERSISTENT(PeriodicWave, periodicWaveTriangle, (PeriodicWave::createTriangle(sampleRate)));
periodicWave = periodicWaveTriangle; periodicWave = periodicWaveTriangle;
break; break;
} }
...@@ -341,6 +341,14 @@ bool OscillatorNode::propagatesSilence() const ...@@ -341,6 +341,14 @@ bool OscillatorNode::propagatesSilence() const
return !isPlayingOrScheduled() || hasFinished() || !m_periodicWave.get(); return !isPlayingOrScheduled() || hasFinished() || !m_periodicWave.get();
} }
void OscillatorNode::trace(Visitor* visitor)
{
visitor->trace(m_frequency);
visitor->trace(m_detune);
visitor->trace(m_periodicWave);
AudioScheduledSourceNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -52,7 +52,7 @@ public: ...@@ -52,7 +52,7 @@ public:
CUSTOM = 4 CUSTOM = 4
}; };
static PassRefPtr<OscillatorNode> create(AudioContext*, float sampleRate); static PassRefPtrWillBeRawPtr<OscillatorNode> create(AudioContext*, float sampleRate);
virtual ~OscillatorNode(); virtual ~OscillatorNode();
...@@ -68,6 +68,8 @@ public: ...@@ -68,6 +68,8 @@ public:
void setPeriodicWave(PeriodicWave*); void setPeriodicWave(PeriodicWave*);
virtual void trace(Visitor*) OVERRIDE;
private: private:
OscillatorNode(AudioContext*, float sampleRate); OscillatorNode(AudioContext*, float sampleRate);
...@@ -82,10 +84,10 @@ private: ...@@ -82,10 +84,10 @@ private:
unsigned short m_type; unsigned short m_type;
// Frequency value in Hertz. // Frequency value in Hertz.
RefPtr<AudioParam> m_frequency; RefPtrWillBeMember<AudioParam> m_frequency;
// Detune value (deviating from the frequency) in Cents. // Detune value (deviating from the frequency) in Cents.
RefPtr<AudioParam> m_detune; RefPtrWillBeMember<AudioParam> m_detune;
bool m_firstRender; bool m_firstRender;
...@@ -100,7 +102,7 @@ private: ...@@ -100,7 +102,7 @@ private:
AudioFloatArray m_phaseIncrements; AudioFloatArray m_phaseIncrements;
AudioFloatArray m_detuneValues; AudioFloatArray m_detuneValues;
RefPtr<PeriodicWave> m_periodicWave; RefPtrWillBeMember<PeriodicWave> m_periodicWave;
}; };
} // namespace WebCore } // namespace WebCore
......
...@@ -54,9 +54,9 @@ public: ...@@ -54,9 +54,9 @@ public:
DopplerRateDirty = 0x4, DopplerRateDirty = 0x4,
}; };
static PassRefPtr<PannerNode> create(AudioContext* context, float sampleRate) static PassRefPtrWillBeRawPtr<PannerNode> create(AudioContext* context, float sampleRate)
{ {
return adoptRef(new PannerNode(context, sampleRate)); return adoptRefWillBeNoop(new PannerNode(context, sampleRate));
} }
virtual ~PannerNode(); virtual ~PannerNode();
......
...@@ -45,12 +45,12 @@ namespace WebCore { ...@@ -45,12 +45,12 @@ namespace WebCore {
using namespace VectorMath; using namespace VectorMath;
PassRefPtr<PeriodicWave> PeriodicWave::create(float sampleRate, Float32Array* real, Float32Array* imag) PassRefPtrWillBeRawPtr<PeriodicWave> PeriodicWave::create(float sampleRate, Float32Array* real, Float32Array* imag)
{ {
bool isGood = real && imag && real->length() == imag->length(); bool isGood = real && imag && real->length() == imag->length();
ASSERT(isGood); ASSERT(isGood);
if (isGood) { if (isGood) {
RefPtr<PeriodicWave> periodicWave = adoptRef(new PeriodicWave(sampleRate)); RefPtrWillBeRawPtr<PeriodicWave> periodicWave = adoptRefWillBeNoop(new PeriodicWave(sampleRate));
size_t numberOfComponents = real->length(); size_t numberOfComponents = real->length();
periodicWave->createBandLimitedTables(real->data(), imag->data(), numberOfComponents); periodicWave->createBandLimitedTables(real->data(), imag->data(), numberOfComponents);
return periodicWave; return periodicWave;
...@@ -58,30 +58,30 @@ PassRefPtr<PeriodicWave> PeriodicWave::create(float sampleRate, Float32Array* re ...@@ -58,30 +58,30 @@ PassRefPtr<PeriodicWave> PeriodicWave::create(float sampleRate, Float32Array* re
return nullptr; return nullptr;
} }
PassRefPtr<PeriodicWave> PeriodicWave::createSine(float sampleRate) PassRefPtrWillBeRawPtr<PeriodicWave> PeriodicWave::createSine(float sampleRate)
{ {
RefPtr<PeriodicWave> periodicWave = adoptRef(new PeriodicWave(sampleRate)); RefPtrWillBeRawPtr<PeriodicWave> periodicWave = adoptRefWillBeNoop(new PeriodicWave(sampleRate));
periodicWave->generateBasicWaveform(OscillatorNode::SINE); periodicWave->generateBasicWaveform(OscillatorNode::SINE);
return periodicWave; return periodicWave;
} }
PassRefPtr<PeriodicWave> PeriodicWave::createSquare(float sampleRate) PassRefPtrWillBeRawPtr<PeriodicWave> PeriodicWave::createSquare(float sampleRate)
{ {
RefPtr<PeriodicWave> periodicWave = adoptRef(new PeriodicWave(sampleRate)); RefPtrWillBeRawPtr<PeriodicWave> periodicWave = adoptRefWillBeNoop(new PeriodicWave(sampleRate));
periodicWave->generateBasicWaveform(OscillatorNode::SQUARE); periodicWave->generateBasicWaveform(OscillatorNode::SQUARE);
return periodicWave; return periodicWave;
} }
PassRefPtr<PeriodicWave> PeriodicWave::createSawtooth(float sampleRate) PassRefPtrWillBeRawPtr<PeriodicWave> PeriodicWave::createSawtooth(float sampleRate)
{ {
RefPtr<PeriodicWave> periodicWave = adoptRef(new PeriodicWave(sampleRate)); RefPtrWillBeRawPtr<PeriodicWave> periodicWave = adoptRefWillBeNoop(new PeriodicWave(sampleRate));
periodicWave->generateBasicWaveform(OscillatorNode::SAWTOOTH); periodicWave->generateBasicWaveform(OscillatorNode::SAWTOOTH);
return periodicWave; return periodicWave;
} }
PassRefPtr<PeriodicWave> PeriodicWave::createTriangle(float sampleRate) PassRefPtrWillBeRawPtr<PeriodicWave> PeriodicWave::createTriangle(float sampleRate)
{ {
RefPtr<PeriodicWave> periodicWave = adoptRef(new PeriodicWave(sampleRate)); RefPtrWillBeRawPtr<PeriodicWave> periodicWave = adoptRefWillBeNoop(new PeriodicWave(sampleRate));
periodicWave->generateBasicWaveform(OscillatorNode::TRIANGLE); periodicWave->generateBasicWaveform(OscillatorNode::TRIANGLE);
return periodicWave; return periodicWave;
} }
......
...@@ -40,15 +40,15 @@ ...@@ -40,15 +40,15 @@
namespace WebCore { namespace WebCore {
class PeriodicWave : public ScriptWrappable, public RefCounted<PeriodicWave> { class PeriodicWave : public RefCountedWillBeGarbageCollectedFinalized<PeriodicWave>, public ScriptWrappable {
public: public:
static PassRefPtr<PeriodicWave> createSine(float sampleRate); static PassRefPtrWillBeRawPtr<PeriodicWave> createSine(float sampleRate);
static PassRefPtr<PeriodicWave> createSquare(float sampleRate); static PassRefPtrWillBeRawPtr<PeriodicWave> createSquare(float sampleRate);
static PassRefPtr<PeriodicWave> createSawtooth(float sampleRate); static PassRefPtrWillBeRawPtr<PeriodicWave> createSawtooth(float sampleRate);
static PassRefPtr<PeriodicWave> createTriangle(float sampleRate); static PassRefPtrWillBeRawPtr<PeriodicWave> createTriangle(float sampleRate);
// Creates an arbitrary periodic wave given the frequency components (Fourier coefficients). // Creates an arbitrary periodic wave given the frequency components (Fourier coefficients).
static PassRefPtr<PeriodicWave> create(float sampleRate, Float32Array* real, Float32Array* imag); static PassRefPtrWillBeRawPtr<PeriodicWave> create(float sampleRate, Float32Array* real, Float32Array* imag);
// Returns pointers to the lower and higher wave data for the pitch range containing // Returns pointers to the lower and higher wave data for the pitch range containing
// the given fundamental frequency. These two tables are in adjacent "pitch" ranges // the given fundamental frequency. These two tables are in adjacent "pitch" ranges
...@@ -63,6 +63,8 @@ public: ...@@ -63,6 +63,8 @@ public:
unsigned periodicWaveSize() const { return m_periodicWaveSize; } unsigned periodicWaveSize() const { return m_periodicWaveSize; }
void trace(Visitor*) { }
private: private:
explicit PeriodicWave(float sampleRate); explicit PeriodicWave(float sampleRate);
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
// PeriodicWave represents a periodic audio waveform given by its Fourier coefficients. // PeriodicWave represents a periodic audio waveform given by its Fourier coefficients.
[ [
WillBeGarbageCollected,
Conditional=WEB_AUDIO Conditional=WEB_AUDIO
] interface PeriodicWave { ] interface PeriodicWave {
......
...@@ -56,7 +56,7 @@ static size_t chooseBufferSize() ...@@ -56,7 +56,7 @@ static size_t chooseBufferSize()
return bufferSize; return bufferSize;
} }
PassRefPtr<ScriptProcessorNode> ScriptProcessorNode::create(AudioContext* context, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels) PassRefPtrWillBeRawPtr<ScriptProcessorNode> ScriptProcessorNode::create(AudioContext* context, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels)
{ {
// Check for valid buffer size. // Check for valid buffer size.
switch (bufferSize) { switch (bufferSize) {
...@@ -84,7 +84,7 @@ PassRefPtr<ScriptProcessorNode> ScriptProcessorNode::create(AudioContext* contex ...@@ -84,7 +84,7 @@ PassRefPtr<ScriptProcessorNode> ScriptProcessorNode::create(AudioContext* contex
if (numberOfOutputChannels > AudioContext::maxNumberOfChannels()) if (numberOfOutputChannels > AudioContext::maxNumberOfChannels())
return nullptr; return nullptr;
return adoptRef(new ScriptProcessorNode(context, sampleRate, bufferSize, numberOfInputChannels, numberOfOutputChannels)); return adoptRefWillBeNoop(new ScriptProcessorNode(context, sampleRate, bufferSize, numberOfInputChannels, numberOfOutputChannels));
} }
ScriptProcessorNode::ScriptProcessorNode(AudioContext* context, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels) ScriptProcessorNode::ScriptProcessorNode(AudioContext* context, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels)
...@@ -127,8 +127,8 @@ void ScriptProcessorNode::initialize() ...@@ -127,8 +127,8 @@ void ScriptProcessorNode::initialize()
// Create double buffers on both the input and output sides. // Create double buffers on both the input and output sides.
// These AudioBuffers will be directly accessed in the main thread by JavaScript. // These AudioBuffers will be directly accessed in the main thread by JavaScript.
for (unsigned i = 0; i < 2; ++i) { for (unsigned i = 0; i < 2; ++i) {
RefPtr<AudioBuffer> inputBuffer = m_numberOfInputChannels ? AudioBuffer::create(m_numberOfInputChannels, bufferSize(), sampleRate) : nullptr; RefPtrWillBeRawPtr<AudioBuffer> inputBuffer = m_numberOfInputChannels ? AudioBuffer::create(m_numberOfInputChannels, bufferSize(), sampleRate) : nullptr;
RefPtr<AudioBuffer> outputBuffer = m_numberOfOutputChannels ? AudioBuffer::create(m_numberOfOutputChannels, bufferSize(), sampleRate) : nullptr; RefPtrWillBeRawPtr<AudioBuffer> outputBuffer = m_numberOfOutputChannels ? AudioBuffer::create(m_numberOfOutputChannels, bufferSize(), sampleRate) : nullptr;
m_inputBuffers.append(inputBuffer); m_inputBuffers.append(inputBuffer);
m_outputBuffers.append(outputBuffer); m_outputBuffers.append(outputBuffer);
...@@ -284,6 +284,13 @@ double ScriptProcessorNode::latencyTime() const ...@@ -284,6 +284,13 @@ double ScriptProcessorNode::latencyTime() const
return std::numeric_limits<double>::infinity(); return std::numeric_limits<double>::infinity();
} }
void ScriptProcessorNode::trace(Visitor* visitor)
{
visitor->trace(m_inputBuffers);
visitor->trace(m_outputBuffers);
AudioNode::trace(visitor);
}
} // namespace WebCore } // namespace WebCore
#endif // ENABLE(WEB_AUDIO) #endif // ENABLE(WEB_AUDIO)
...@@ -50,7 +50,7 @@ public: ...@@ -50,7 +50,7 @@ public:
// This value controls how frequently the onaudioprocess event handler is called and how many sample-frames need to be processed each call. // This value controls how frequently the onaudioprocess event handler is called and how many sample-frames need to be processed each call.
// Lower numbers for bufferSize will result in a lower (better) latency. Higher numbers will be necessary to avoid audio breakup and glitches. // Lower numbers for bufferSize will result in a lower (better) latency. Higher numbers will be necessary to avoid audio breakup and glitches.
// The value chosen must carefully balance between latency and audio quality. // The value chosen must carefully balance between latency and audio quality.
static PassRefPtr<ScriptProcessorNode> create(AudioContext*, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels); static PassRefPtrWillBeRawPtr<ScriptProcessorNode> create(AudioContext*, float sampleRate, size_t bufferSize, unsigned numberOfInputChannels, unsigned numberOfOutputChannels);
virtual ~ScriptProcessorNode(); virtual ~ScriptProcessorNode();
...@@ -63,6 +63,7 @@ public: ...@@ -63,6 +63,7 @@ public:
DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess); DEFINE_ATTRIBUTE_EVENT_LISTENER(audioprocess);
void trace(Visitor*);
private: private:
virtual double tailTime() const OVERRIDE; virtual double tailTime() const OVERRIDE;
...@@ -78,8 +79,8 @@ private: ...@@ -78,8 +79,8 @@ private:
void swapBuffers() { m_doubleBufferIndex = 1 - m_doubleBufferIndex; } void swapBuffers() { m_doubleBufferIndex = 1 - m_doubleBufferIndex; }
unsigned m_doubleBufferIndex; unsigned m_doubleBufferIndex;
unsigned m_doubleBufferIndexForEvent; unsigned m_doubleBufferIndexForEvent;
Vector<RefPtr<AudioBuffer> > m_inputBuffers; WillBeHeapVector<RefPtrWillBeMember<AudioBuffer> > m_inputBuffers;
Vector<RefPtr<AudioBuffer> > m_outputBuffers; WillBeHeapVector<RefPtrWillBeMember<AudioBuffer> > m_outputBuffers;
size_t m_bufferSize; size_t m_bufferSize;
unsigned m_bufferReadWriteIndex; unsigned m_bufferReadWriteIndex;
......
...@@ -36,9 +36,9 @@ class ExceptionState; ...@@ -36,9 +36,9 @@ class ExceptionState;
class WaveShaperNode FINAL : public AudioBasicProcessorNode { class WaveShaperNode FINAL : public AudioBasicProcessorNode {
public: public:
static PassRefPtr<WaveShaperNode> create(AudioContext* context) static PassRefPtrWillBeRawPtr<WaveShaperNode> create(AudioContext* context)
{ {
return adoptRef(new WaveShaperNode(context)); return adoptRefWillBeNoop(new WaveShaperNode(context));
} }
// setCurve() is called on the main thread. // setCurve() is called on the main thread.
......
...@@ -777,6 +777,7 @@ template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, ...@@ -777,6 +777,7 @@ template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a,
#define RefCountedWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected #define RefCountedWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected
#define ThreadSafeRefCountedWillBeGarbageCollected WebCore::GarbageCollected #define ThreadSafeRefCountedWillBeGarbageCollected WebCore::GarbageCollected
#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WebCore::GarbageCollectedFinalized
#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WebCore::ThreadSafeRefCountedGarbageCollected
#define TreeSharedWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected #define TreeSharedWillBeRefCountedGarbageCollected WebCore::RefCountedGarbageCollected
#define PersistentWillBeMember WebCore::Member #define PersistentWillBeMember WebCore::Member
#define RefPtrWillBePersistent WebCore::Persistent #define RefPtrWillBePersistent WebCore::Persistent
...@@ -830,6 +831,13 @@ template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCo ...@@ -830,6 +831,13 @@ template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCo
return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr)); return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
} }
template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr)
{
static const bool isThreadSafeRefCountedGarbageCollected = WTF::IsSubclassOfTemplate<T, ThreadSafeRefCountedGarbageCollected>::value;
COMPILE_ASSERT(isThreadSafeRefCountedGarbageCollected, useAdoptRefWillBeNoop);
return PassRefPtrWillBeRawPtr<T>(adoptRefCountedGarbageCollected(ptr));
}
template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr)
{ {
static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<T, RefCountedGarbageCollected>::value; static const bool notRefCountedGarbageCollected = !WTF::IsSubclassOfTemplate<T, RefCountedGarbageCollected>::value;
...@@ -862,6 +870,7 @@ public: ...@@ -862,6 +870,7 @@ public:
#define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted #define RefCountedWillBeRefCountedGarbageCollected WTF::RefCounted
#define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted #define ThreadSafeRefCountedWillBeGarbageCollected WTF::ThreadSafeRefCounted
#define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted #define ThreadSafeRefCountedWillBeGarbageCollectedFinalized WTF::ThreadSafeRefCounted
#define ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbageCollected WTF::ThreadSafeRefCounted
#define TreeSharedWillBeRefCountedGarbageCollected WebCore::TreeShared #define TreeSharedWillBeRefCountedGarbageCollected WebCore::TreeShared
#define PersistentWillBeMember WebCore::Persistent #define PersistentWillBeMember WebCore::Persistent
#define RefPtrWillBePersistent WTF::RefPtr #define RefPtrWillBePersistent WTF::RefPtr
...@@ -901,6 +910,7 @@ public: ...@@ -901,6 +910,7 @@ public:
template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); } template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeNoop(T* ptr) { return adoptRef(ptr); }
template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); } template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
template<typename T> PassRefPtrWillBeRawPtr<T> adoptRefWillBeThreadSafeRefCountedGarbageCollected(T* ptr) { return adoptRef(ptr); }
template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); } template<typename T> PassOwnPtrWillBeRawPtr<T> adoptPtrWillBeNoop(T* ptr) { return adoptPtr(ptr); }
#define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED #define WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED WTF_MAKE_FAST_ALLOCATED
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "wtf/ListHashSet.h" #include "wtf/ListHashSet.h"
#include "wtf/OwnPtr.h" #include "wtf/OwnPtr.h"
#include "wtf/PassRefPtr.h" #include "wtf/PassRefPtr.h"
#include "wtf/ThreadSafeRefCounted.h"
#include <stdint.h> #include <stdint.h>
...@@ -70,6 +71,7 @@ class HeapStats; ...@@ -70,6 +71,7 @@ class HeapStats;
class PageMemory; class PageMemory;
template<ThreadAffinity affinity> class ThreadLocalPersistents; template<ThreadAffinity affinity> class ThreadLocalPersistents;
template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > > class Persistent; template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > > class Persistent;
template<typename T> class CrossThreadPersistent;
PLATFORM_EXPORT size_t osPageSize(); PLATFORM_EXPORT size_t osPageSize();
...@@ -559,6 +561,56 @@ private: ...@@ -559,6 +561,56 @@ private:
friend class ThreadState; friend class ThreadState;
}; };
// FIXME: This is currently used by the WebAudio code.
// We should attempt to restructure the WebAudio code so that the main thread
// alone determines life-time and receives messages about life-time from the
// audio thread.
template<typename T>
class ThreadSafeRefCountedGarbageCollected : public GarbageCollectedFinalized<T>, public WTF::ThreadSafeRefCountedBase {
WTF_MAKE_NONCOPYABLE(ThreadSafeRefCountedGarbageCollected);
public:
ThreadSafeRefCountedGarbageCollected()
{
m_keepAlive = adoptPtr(new CrossThreadPersistent<T>(static_cast<T*>(this)));
}
// Override ref to deal with a case where a reference count goes up
// from 0 to 1. This can happen in the following scenario:
// (1) The reference count becomes 0, but on-stack pointers keep references to the object.
// (2) The on-stack pointer is assigned to a RefPtr. The reference count becomes 1.
// In this case, we have to resurrect m_keepAlive.
void ref()
{
MutexLocker lock(m_mutex);
if (UNLIKELY(!refCount())) {
ASSERT(!m_keepAlive);
m_keepAlive = adoptPtr(new CrossThreadPersistent<T>(static_cast<T*>(this)));
}
WTF::ThreadSafeRefCountedBase::ref();
}
// Override deref to deal with our own deallocation based on ref counting.
void deref()
{
MutexLocker lock(m_mutex);
if (derefBase()) {
ASSERT(m_keepAlive);
m_keepAlive.clear();
}
}
using GarbageCollectedFinalized<T>::operator new;
using GarbageCollectedFinalized<T>::operator delete;
protected:
~ThreadSafeRefCountedGarbageCollected() { }
private:
OwnPtr<CrossThreadPersistent<T> > m_keepAlive;
mutable Mutex m_mutex;
};
// The CallbackStack contains all the visitor callbacks used to trace and mark // The CallbackStack contains all the visitor callbacks used to trace and mark
// objects. A specific CallbackStack instance contains at most bufferSize elements. // objects. A specific CallbackStack instance contains at most bufferSize elements.
// If more space is needed a new CallbackStack instance is created and chained // If more space is needed a new CallbackStack instance is created and chained
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment