| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 #include "core/events/EventListener.h" | 29 #include "core/events/EventListener.h" |
| 30 #include "modules/EventTargetModules.h" | 30 #include "modules/EventTargetModules.h" |
| 31 #include "modules/webaudio/AsyncAudioDecoder.h" | 31 #include "modules/webaudio/AsyncAudioDecoder.h" |
| 32 #include "modules/webaudio/AudioDestinationNode.h" | 32 #include "modules/webaudio/AudioDestinationNode.h" |
| 33 #include "platform/audio/AudioBus.h" | 33 #include "platform/audio/AudioBus.h" |
| 34 #include "platform/heap/Handle.h" | 34 #include "platform/heap/Handle.h" |
| 35 #include "wtf/HashSet.h" | 35 #include "wtf/HashSet.h" |
| 36 #include "wtf/MainThread.h" | 36 #include "wtf/MainThread.h" |
| 37 #include "wtf/OwnPtr.h" | 37 #include "wtf/OwnPtr.h" |
| 38 #include "wtf/PassRefPtr.h" | 38 #include "wtf/PassRefPtr.h" |
| 39 #include "wtf/RefCounted.h" | |
| 40 #include "wtf/RefPtr.h" | 39 #include "wtf/RefPtr.h" |
| 41 #include "wtf/ThreadSafeRefCounted.h" | 40 #include "wtf/ThreadSafeRefCounted.h" |
| 42 #include "wtf/Threading.h" | 41 #include "wtf/Threading.h" |
| 43 #include "wtf/Vector.h" | 42 #include "wtf/Vector.h" |
| 44 #include "wtf/text/AtomicStringHash.h" | 43 #include "wtf/text/AtomicStringHash.h" |
| 45 | 44 |
| 46 namespace blink { | 45 namespace blink { |
| 47 | 46 |
| 48 class AnalyserNode; | 47 class AnalyserNode; |
| 49 class AudioBuffer; | 48 class AudioBuffer; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 66 class MediaStreamAudioSourceNode; | 65 class MediaStreamAudioSourceNode; |
| 67 class OscillatorNode; | 66 class OscillatorNode; |
| 68 class PannerNode; | 67 class PannerNode; |
| 69 class PeriodicWave; | 68 class PeriodicWave; |
| 70 class ScriptProcessorNode; | 69 class ScriptProcessorNode; |
| 71 class WaveShaperNode; | 70 class WaveShaperNode; |
| 72 | 71 |
| 73 // AudioContext is the cornerstone of the web audio API and all AudioNodes are c
reated from it. | 72 // AudioContext is the cornerstone of the web audio API and all AudioNodes are c
reated from it. |
| 74 // For thread safety between the audio thread and the main thread, it has a rend
ering graph locking mechanism. | 73 // For thread safety between the audio thread and the main thread, it has a rend
ering graph locking mechanism. |
| 75 | 74 |
| 76 class AudioContext : public ThreadSafeRefCountedWillBeThreadSafeRefCountedGarbag
eCollected<AudioContext>, public ActiveDOMObject, public EventTargetWithInlineDa
ta { | 75 // FIXME: Oilpan: This should be ThreadSafeRefCountedGarbageCollectedWillBeGarba
geCollectedFinalized. |
| 77 DEFINE_EVENT_TARGET_REFCOUNTING(ThreadSafeRefCountedWillBeThreadSafeRefCount
edGarbageCollected<AudioContext>); | 76 class AudioContext : public ThreadSafeRefCountedGarbageCollected<AudioContext>,
public ActiveDOMObject, public EventTargetWithInlineData { |
| 77 DEFINE_EVENT_TARGET_REFCOUNTING(ThreadSafeRefCountedGarbageCollected<AudioCo
ntext>); |
| 78 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AudioContext); | 78 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(AudioContext); |
| 79 public: | 79 public: |
| 80 // Create an AudioContext for rendering to the audio hardware. | 80 // Create an AudioContext for rendering to the audio hardware. |
| 81 static PassRefPtrWillBeRawPtr<AudioContext> create(Document&, ExceptionState
&); | 81 static AudioContext* create(Document&, ExceptionState&); |
| 82 | 82 |
| 83 virtual ~AudioContext(); | 83 virtual ~AudioContext(); |
| 84 | 84 |
| 85 virtual void trace(Visitor*) OVERRIDE; | 85 virtual void trace(Visitor*) OVERRIDE; |
| 86 | 86 |
| 87 bool isInitialized() const { return m_isInitialized; } | 87 bool isInitialized() const { return m_isInitialized; } |
| 88 bool isOfflineContext() { return m_isOfflineContext; } | 88 bool isOfflineContext() { return m_isOfflineContext; } |
| 89 | 89 |
| 90 // Document notification | 90 // Document notification |
| 91 virtual void stop() OVERRIDE FINAL; | 91 virtual void stop() OVERRIDE FINAL; |
| 92 virtual bool hasPendingActivity() const OVERRIDE; | 92 virtual bool hasPendingActivity() const OVERRIDE; |
| 93 | 93 |
| 94 AudioDestinationNode* destination() { return m_destinationNode.get(); } | 94 AudioDestinationNode* destination() { return m_destinationNode.get(); } |
| 95 size_t currentSampleFrame() const { return m_destinationNode->currentSampleF
rame(); } | 95 size_t currentSampleFrame() const { return m_destinationNode->currentSampleF
rame(); } |
| 96 double currentTime() const { return m_destinationNode->currentTime(); } | 96 double currentTime() const { return m_destinationNode->currentTime(); } |
| 97 float sampleRate() const { return m_destinationNode->sampleRate(); } | 97 float sampleRate() const { return m_destinationNode->sampleRate(); } |
| 98 | 98 |
| 99 PassRefPtrWillBeRawPtr<AudioBuffer> createBuffer(unsigned numberOfChannels,
size_t numberOfFrames, float sampleRate, ExceptionState&); | 99 AudioBuffer* createBuffer(unsigned numberOfChannels, size_t numberOfFrames,
float sampleRate, ExceptionState&); |
| 100 | 100 |
| 101 // Asynchronous audio file data decoding. | 101 // Asynchronous audio file data decoding. |
| 102 void decodeAudioData(ArrayBuffer*, PassOwnPtr<AudioBufferCallback>, PassOwnP
tr<AudioBufferCallback>, ExceptionState&); | 102 void decodeAudioData(ArrayBuffer*, PassOwnPtr<AudioBufferCallback>, PassOwnP
tr<AudioBufferCallback>, ExceptionState&); |
| 103 | 103 |
| 104 AudioListener* listener() { return m_listener.get(); } | 104 AudioListener* listener() { return m_listener.get(); } |
| 105 | 105 |
| 106 // The AudioNode create methods are called on the main thread (from JavaScri
pt). | 106 // The AudioNode create methods are called on the main thread (from JavaScri
pt). |
| 107 PassRefPtrWillBeRawPtr<AudioBufferSourceNode> createBufferSource(); | 107 AudioBufferSourceNode* createBufferSource(); |
| 108 PassRefPtrWillBeRawPtr<MediaElementAudioSourceNode> createMediaElementSource
(HTMLMediaElement*, ExceptionState&); | 108 MediaElementAudioSourceNode* createMediaElementSource(HTMLMediaElement*, Exc
eptionState&); |
| 109 PassRefPtrWillBeRawPtr<MediaStreamAudioSourceNode> createMediaStreamSource(M
ediaStream*, ExceptionState&); | 109 MediaStreamAudioSourceNode* createMediaStreamSource(MediaStream*, ExceptionS
tate&); |
| 110 PassRefPtrWillBeRawPtr<MediaStreamAudioDestinationNode> createMediaStreamDes
tination(); | 110 MediaStreamAudioDestinationNode* createMediaStreamDestination(); |
| 111 PassRefPtrWillBeRawPtr<GainNode> createGain(); | 111 GainNode* createGain(); |
| 112 PassRefPtrWillBeRawPtr<BiquadFilterNode> createBiquadFilter(); | 112 BiquadFilterNode* createBiquadFilter(); |
| 113 PassRefPtrWillBeRawPtr<WaveShaperNode> createWaveShaper(); | 113 WaveShaperNode* createWaveShaper(); |
| 114 PassRefPtrWillBeRawPtr<DelayNode> createDelay(ExceptionState&); | 114 DelayNode* createDelay(ExceptionState&); |
| 115 PassRefPtrWillBeRawPtr<DelayNode> createDelay(double maxDelayTime, Exception
State&); | 115 DelayNode* createDelay(double maxDelayTime, ExceptionState&); |
| 116 PassRefPtrWillBeRawPtr<PannerNode> createPanner(); | 116 PannerNode* createPanner(); |
| 117 PassRefPtrWillBeRawPtr<ConvolverNode> createConvolver(); | 117 ConvolverNode* createConvolver(); |
| 118 PassRefPtrWillBeRawPtr<DynamicsCompressorNode> createDynamicsCompressor(); | 118 DynamicsCompressorNode* createDynamicsCompressor(); |
| 119 PassRefPtrWillBeRawPtr<AnalyserNode> createAnalyser(); | 119 AnalyserNode* createAnalyser(); |
| 120 PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(ExceptionS
tate&); | 120 ScriptProcessorNode* createScriptProcessor(ExceptionState&); |
| 121 PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(size_t buf
ferSize, ExceptionState&); | 121 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, ExceptionState
&); |
| 122 PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(size_t buf
ferSize, size_t numberOfInputChannels, ExceptionState&); | 122 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, size_t numberO
fInputChannels, ExceptionState&); |
| 123 PassRefPtrWillBeRawPtr<ScriptProcessorNode> createScriptProcessor(size_t buf
ferSize, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionS
tate&); | 123 ScriptProcessorNode* createScriptProcessor(size_t bufferSize, size_t numberO
fInputChannels, size_t numberOfOutputChannels, ExceptionState&); |
| 124 PassRefPtrWillBeRawPtr<ChannelSplitterNode> createChannelSplitter(ExceptionS
tate&); | 124 ChannelSplitterNode* createChannelSplitter(ExceptionState&); |
| 125 PassRefPtrWillBeRawPtr<ChannelSplitterNode> createChannelSplitter(size_t num
berOfOutputs, ExceptionState&); | 125 ChannelSplitterNode* createChannelSplitter(size_t numberOfOutputs, Exception
State&); |
| 126 PassRefPtrWillBeRawPtr<ChannelMergerNode> createChannelMerger(ExceptionState
&); | 126 ChannelMergerNode* createChannelMerger(ExceptionState&); |
| 127 PassRefPtrWillBeRawPtr<ChannelMergerNode> createChannelMerger(size_t numberO
fInputs, ExceptionState&); | 127 ChannelMergerNode* createChannelMerger(size_t numberOfInputs, ExceptionState
&); |
| 128 PassRefPtrWillBeRawPtr<OscillatorNode> createOscillator(); | 128 OscillatorNode* createOscillator(); |
| 129 PassRefPtrWillBeRawPtr<PeriodicWave> createPeriodicWave(Float32Array* real,
Float32Array* imag, ExceptionState&); | 129 PeriodicWave* createPeriodicWave(Float32Array* real, Float32Array* imag, Exc
eptionState&); |
| 130 | 130 |
| 131 // When a source node has no more processing to do (has finished playing), t
hen it tells the context to dereference it. | 131 // When a source node has no more processing to do (has finished playing), t
hen it tells the context to dereference it. |
| 132 void notifyNodeFinishedProcessing(AudioNode*); | 132 void notifyNodeFinishedProcessing(AudioNode*); |
| 133 | 133 |
| 134 // Called at the start of each render quantum. | 134 // Called at the start of each render quantum. |
| 135 void handlePreRenderTasks(); | 135 void handlePreRenderTasks(); |
| 136 | 136 |
| 137 // Called at the end of each render quantum. | 137 // Called at the end of each render quantum. |
| 138 void handlePostRenderTasks(); | 138 void handlePostRenderTasks(); |
| 139 | 139 |
| 140 // Called periodically at the end of each render quantum to dereference fini
shed source nodes. | 140 // Called periodically at the end of each render quantum to dereference fini
shed source nodes. |
| 141 void derefFinishedSourceNodes(); | 141 void derefFinishedSourceNodes(); |
| 142 | 142 |
| 143 #if ENABLE(OILPAN) | |
| 144 void registerLiveAudioSummingJunction(AudioSummingJunction&); | 143 void registerLiveAudioSummingJunction(AudioSummingJunction&); |
| 145 void registerLiveNode(AudioNode&); | 144 void registerLiveNode(AudioNode&); |
| 146 #else | |
| 147 // We schedule deletion of all marked nodes at the end of each realtime rend
er quantum. | |
| 148 void markForDeletion(AudioNode*); | |
| 149 void deleteMarkedNodes(); | |
| 150 #endif | |
| 151 | 145 |
| 152 // AudioContext can pull node(s) at the end of each render quantum even when
they are not connected to any downstream nodes. | 146 // AudioContext can pull node(s) at the end of each render quantum even when
they are not connected to any downstream nodes. |
| 153 // These two methods are called by the nodes who want to add/remove themselv
es into/from the automatic pull lists. | 147 // These two methods are called by the nodes who want to add/remove themselv
es into/from the automatic pull lists. |
| 154 void addAutomaticPullNode(AudioNode*); | 148 void addAutomaticPullNode(AudioNode*); |
| 155 void removeAutomaticPullNode(AudioNode*); | 149 void removeAutomaticPullNode(AudioNode*); |
| 156 | 150 |
| 157 // Called right before handlePostRenderTasks() to handle nodes which need to
be pulled even when they are not connected to anything. | 151 // Called right before handlePostRenderTasks() to handle nodes which need to
be pulled even when they are not connected to anything. |
| 158 void processAutomaticPullNodes(size_t framesToProcess); | 152 void processAutomaticPullNodes(size_t framesToProcess); |
| 159 | 153 |
| 160 // Keeps track of the number of connections made. | 154 // Keeps track of the number of connections made. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 ASSERT(context); | 192 ASSERT(context); |
| 199 context->lock(m_mustReleaseLock); | 193 context->lock(m_mustReleaseLock); |
| 200 } | 194 } |
| 201 | 195 |
| 202 ~AutoLocker() | 196 ~AutoLocker() |
| 203 { | 197 { |
| 204 if (m_mustReleaseLock) | 198 if (m_mustReleaseLock) |
| 205 m_context->unlock(); | 199 m_context->unlock(); |
| 206 } | 200 } |
| 207 private: | 201 private: |
| 208 RawPtrWillBeMember<AudioContext> m_context; | 202 Member<AudioContext> m_context; |
| 209 bool m_mustReleaseLock; | 203 bool m_mustReleaseLock; |
| 210 }; | 204 }; |
| 211 | 205 |
| 212 // In AudioNode::breakConnection() and deref(), a tryLock() is used for | 206 // In AudioNode::breakConnection() and deref(), a tryLock() is used for |
| 213 // calling actual processing, but if it fails keep track here. | 207 // calling actual processing, but if it fails keep track here. |
| 214 void addDeferredBreakConnection(AudioNode&); | 208 void addDeferredBreakConnection(AudioNode&); |
| 215 #if !ENABLE(OILPAN) | |
| 216 void addDeferredFinishDeref(AudioNode*); | |
| 217 #endif | |
| 218 | 209 |
| 219 // In the audio thread at the start of each render cycle, we'll call this. | 210 // In the audio thread at the start of each render cycle, we'll call this. |
| 220 void handleDeferredAudioNodeTasks(); | 211 void handleDeferredAudioNodeTasks(); |
| 221 | 212 |
| 222 // Only accessed when the graph lock is held. | 213 // Only accessed when the graph lock is held. |
| 223 void markSummingJunctionDirty(AudioSummingJunction*); | 214 void markSummingJunctionDirty(AudioSummingJunction*); |
| 224 void markAudioNodeOutputDirty(AudioNodeOutput*); | 215 void markAudioNodeOutputDirty(AudioNodeOutput*); |
| 225 void unmarkDirtyNode(AudioNode&); | 216 void unmarkDirtyNode(AudioNode&); |
| 226 | 217 |
| 227 // Must be called on main thread. | 218 // Must be called on main thread. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 247 private: | 238 private: |
| 248 void initialize(); | 239 void initialize(); |
| 249 void uninitialize(); | 240 void uninitialize(); |
| 250 | 241 |
| 251 // ExecutionContext calls stop twice. | 242 // ExecutionContext calls stop twice. |
| 252 // We'd like to schedule only one stop action for them. | 243 // We'd like to schedule only one stop action for them. |
| 253 bool m_isStopScheduled; | 244 bool m_isStopScheduled; |
| 254 bool m_isCleared; | 245 bool m_isCleared; |
| 255 void clear(); | 246 void clear(); |
| 256 | 247 |
| 257 #if !ENABLE(OILPAN) | |
| 258 void scheduleNodeDeletion(); | |
| 259 static void deleteMarkedNodesDispatch(void* userData); | |
| 260 #endif | |
| 261 | |
| 262 // Set to true when the destination node has been initialized and is ready t
o process data. | 248 // Set to true when the destination node has been initialized and is ready t
o process data. |
| 263 bool m_isInitialized; | 249 bool m_isInitialized; |
| 264 | 250 |
| 265 // The context itself keeps a reference to all source nodes. The source nod
es, then reference all nodes they're connected to. | 251 // The context itself keeps a reference to all source nodes. The source nod
es, then reference all nodes they're connected to. |
| 266 // In turn, these nodes reference all nodes they're connected to. All nodes
are ultimately connected to the AudioDestinationNode. | 252 // In turn, these nodes reference all nodes they're connected to. All nodes
are ultimately connected to the AudioDestinationNode. |
| 267 // When the context dereferences a source node, it will be deactivated from
the rendering graph along with all other nodes it is | 253 // When the context dereferences a source node, it will be deactivated from
the rendering graph along with all other nodes it is |
| 268 // uniquely connected to. See the AudioNode::ref() and AudioNode::deref() m
ethods for more details. | 254 // uniquely connected to. See the AudioNode::ref() and AudioNode::deref() m
ethods for more details. |
| 269 void refNode(AudioNode*); | 255 void refNode(AudioNode*); |
| 270 void derefNode(AudioNode*); | 256 void derefNode(AudioNode*); |
| 271 | 257 |
| 272 // When the context goes away, there might still be some sources which haven
't finished playing. | 258 // When the context goes away, there might still be some sources which haven
't finished playing. |
| 273 // Make sure to dereference them here. | 259 // Make sure to dereference them here. |
| 274 void derefUnfinishedSourceNodes(); | 260 void derefUnfinishedSourceNodes(); |
| 275 | 261 |
| 276 RefPtrWillBeMember<AudioDestinationNode> m_destinationNode; | 262 Member<AudioDestinationNode> m_destinationNode; |
| 277 RefPtrWillBeMember<AudioListener> m_listener; | 263 Member<AudioListener> m_listener; |
| 278 | 264 |
| 279 // Only accessed in the audio thread. | 265 // Only accessed in the audio thread. |
| 280 // Oilpan: Since items are added to the vector by the audio thread (not regi
stered to Oilpan), | 266 // Oilpan: Since items are added to the vector by the audio thread (not regi
stered to Oilpan), |
| 281 // we cannot use a HeapVector. | 267 // we cannot use a HeapVector. |
| 268 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
| 282 Vector<AudioNode*> m_finishedNodes; | 269 Vector<AudioNode*> m_finishedNodes; |
| 283 | 270 |
| 284 // List of source nodes. This is either accessed when the graph lock is | 271 // List of source nodes. This is either accessed when the graph lock is |
| 285 // held, or on the main thread when the audio thread has finished. | 272 // held, or on the main thread when the audio thread has finished. |
| 286 // This RefPtr is connection reference. We must call AudioNode:: | |
| 287 // makeConnection() after ref(), and call AudioNode::breakConnection() | |
| 288 // before deref(). | |
| 289 // Oilpan: This Vector holds connection references. We must call | 273 // Oilpan: This Vector holds connection references. We must call |
| 290 // AudioNode::makeConnection when we add an AudioNode to this, and must call | 274 // AudioNode::makeConnection when we add an AudioNode to this, and must call |
| 291 // AudioNode::breakConnection() when we remove an AudioNode from this. | 275 // AudioNode::breakConnection() when we remove an AudioNode from this. |
| 292 WillBeHeapVector<RefPtrWillBeMember<AudioNode> > m_referencedNodes; | 276 HeapVector<Member<AudioNode> > m_referencedNodes; |
| 293 | 277 |
| 294 #if ENABLE(OILPAN) | |
| 295 class AudioNodeDisposer { | 278 class AudioNodeDisposer { |
| 296 public: | 279 public: |
| 297 explicit AudioNodeDisposer(AudioNode& node) : m_node(node) { } | 280 explicit AudioNodeDisposer(AudioNode& node) : m_node(node) { } |
| 298 ~AudioNodeDisposer(); | 281 ~AudioNodeDisposer(); |
| 299 | 282 |
| 300 private: | 283 private: |
| 301 AudioNode& m_node; | 284 AudioNode& m_node; |
| 302 }; | 285 }; |
| 303 HeapHashMap<WeakMember<AudioNode>, OwnPtr<AudioNodeDisposer> > m_liveNodes; | 286 HeapHashMap<WeakMember<AudioNode>, OwnPtr<AudioNodeDisposer> > m_liveNodes; |
| 304 | 287 |
| 305 class AudioSummingJunctionDisposer { | 288 class AudioSummingJunctionDisposer { |
| 306 public: | 289 public: |
| 307 explicit AudioSummingJunctionDisposer(AudioSummingJunction& junction) :
m_junction(junction) { } | 290 explicit AudioSummingJunctionDisposer(AudioSummingJunction& junction) :
m_junction(junction) { } |
| 308 ~AudioSummingJunctionDisposer(); | 291 ~AudioSummingJunctionDisposer(); |
| 309 | 292 |
| 310 private: | 293 private: |
| 311 AudioSummingJunction& m_junction; | 294 AudioSummingJunction& m_junction; |
| 312 }; | 295 }; |
| 313 // The purpose of m_liveAudioSummingJunctions is to remove a dying | 296 // The purpose of m_liveAudioSummingJunctions is to remove a dying |
| 314 // AudioSummingJunction from m_dirtySummingJunctions. However we put all of | 297 // AudioSummingJunction from m_dirtySummingJunctions. However we put all of |
| 315 // AudioSummingJunction objects to m_liveAudioSummingJunctions to avoid | 298 // AudioSummingJunction objects to m_liveAudioSummingJunctions to avoid |
| 316 // concurrent access to m_liveAudioSummingJunctions. | 299 // concurrent access to m_liveAudioSummingJunctions. |
| 317 HeapHashMap<WeakMember<AudioSummingJunction>, OwnPtr<AudioSummingJunctionDis
poser> > m_liveAudioSummingJunctions; | 300 HeapHashMap<WeakMember<AudioSummingJunction>, OwnPtr<AudioSummingJunctionDis
poser> > m_liveAudioSummingJunctions; |
| 318 #else | |
| 319 // Accumulate nodes which need to be deleted here. | |
| 320 // This is copied to m_nodesToDelete at the end of a render cycle in handleP
ostRenderTasks(), where we're assured of a stable graph | |
| 321 // state which will have no references to any of the nodes in m_nodesToDelet
e once the context lock is released | |
| 322 // (when handlePostRenderTasks() has completed). | |
| 323 // Oilpan: Since items are added to the vector by the audio thread (not regi
stered to Oilpan), | |
| 324 // we cannot use a HeapVector. | |
| 325 Vector<AudioNode*> m_nodesMarkedForDeletion; | |
| 326 | |
| 327 // They will be scheduled for deletion (on the main thread) at the end of a
render cycle (in realtime thread). | |
| 328 // Oilpan: Since items are added to the vector by the audio thread (not regi
stered to Oilpan), | |
| 329 // we cannot use a HeapVector. | |
| 330 Vector<AudioNode*> m_nodesToDelete; | |
| 331 bool m_isDeletionScheduled; | |
| 332 #endif | |
| 333 | 301 |
| 334 // These two HashSet must be accessed only when the graph lock is held. | 302 // These two HashSet must be accessed only when the graph lock is held. |
| 335 // Oilpan: These HashSet should be HeapHashSet<WeakMember<AudioNodeOutput>> | 303 // Oilpan: These HashSet should be HeapHashSet<WeakMember<AudioNodeOutput>> |
| 336 // ideally. But it's difficult to lock them correctly during GC. | 304 // ideally. But it's difficult to lock them correctly during GC. |
| 337 // Oilpan: Since items are added to these hash sets by the audio thread (not
registered to Oilpan), | 305 // Oilpan: Since items are added to these hash sets by the audio thread (not
registered to Oilpan), |
| 338 // we cannot use HeapHashSets. | 306 // we cannot use HeapHashSets. |
| 307 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
| 339 HashSet<AudioSummingJunction*> m_dirtySummingJunctions; | 308 HashSet<AudioSummingJunction*> m_dirtySummingJunctions; |
| 309 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
| 340 HashSet<AudioNodeOutput*> m_dirtyAudioNodeOutputs; | 310 HashSet<AudioNodeOutput*> m_dirtyAudioNodeOutputs; |
| 341 void handleDirtyAudioSummingJunctions(); | 311 void handleDirtyAudioSummingJunctions(); |
| 342 void handleDirtyAudioNodeOutputs(); | 312 void handleDirtyAudioNodeOutputs(); |
| 343 | 313 |
| 344 // For the sake of thread safety, we maintain a seperate Vector of automatic
pull nodes for rendering in m_renderingAutomaticPullNodes. | 314 // For the sake of thread safety, we maintain a seperate Vector of automatic
pull nodes for rendering in m_renderingAutomaticPullNodes. |
| 345 // It will be copied from m_automaticPullNodes by updateAutomaticPullNodes()
at the very start or end of the rendering quantum. | 315 // It will be copied from m_automaticPullNodes by updateAutomaticPullNodes()
at the very start or end of the rendering quantum. |
| 346 // Oilpan: Since items are added to the vector/hash set by the audio thread
(not registered to Oilpan), | 316 // Oilpan: Since items are added to the vector/hash set by the audio thread
(not registered to Oilpan), |
| 347 // we cannot use a HeapVector/HeapHashSet. | 317 // we cannot use a HeapVector/HeapHashSet. |
| 318 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
| 348 HashSet<AudioNode*> m_automaticPullNodes; | 319 HashSet<AudioNode*> m_automaticPullNodes; |
| 320 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
| 349 Vector<AudioNode*> m_renderingAutomaticPullNodes; | 321 Vector<AudioNode*> m_renderingAutomaticPullNodes; |
| 350 // m_automaticPullNodesNeedUpdating keeps track if m_automaticPullNodes is m
odified. | 322 // m_automaticPullNodesNeedUpdating keeps track if m_automaticPullNodes is m
odified. |
| 351 bool m_automaticPullNodesNeedUpdating; | 323 bool m_automaticPullNodesNeedUpdating; |
| 352 void updateAutomaticPullNodes(); | 324 void updateAutomaticPullNodes(); |
| 353 | 325 |
| 354 unsigned m_connectionCount; | 326 unsigned m_connectionCount; |
| 355 | 327 |
| 356 // Graph locking. | 328 // Graph locking. |
| 357 Mutex m_contextGraphMutex; | 329 Mutex m_contextGraphMutex; |
| 358 volatile ThreadIdentifier m_audioThread; | 330 volatile ThreadIdentifier m_audioThread; |
| 359 volatile ThreadIdentifier m_graphOwnerThread; // if the lock is held then th
is is the thread which owns it, otherwise == UndefinedThreadIdentifier | 331 volatile ThreadIdentifier m_graphOwnerThread; // if the lock is held then th
is is the thread which owns it, otherwise == UndefinedThreadIdentifier |
| 360 | 332 |
| 361 // Only accessed in the audio thread. | 333 // Only accessed in the audio thread. |
| 362 // Oilpan: Since items are added to these vectors by the audio thread (not r
egistered to Oilpan), | 334 // Oilpan: Since items are added to these vectors by the audio thread (not r
egistered to Oilpan), |
| 363 // we cannot use HeapVectors. | 335 // we cannot use HeapVectors. |
| 336 GC_PLUGIN_IGNORE("http://crbug.com/404527") |
| 364 Vector<AudioNode*> m_deferredBreakConnectionList; | 337 Vector<AudioNode*> m_deferredBreakConnectionList; |
| 365 Vector<AudioNode*> m_deferredFinishDerefList; | |
| 366 | 338 |
| 367 RefPtrWillBeMember<AudioBuffer> m_renderTarget; | 339 Member<AudioBuffer> m_renderTarget; |
| 368 | 340 |
| 369 bool m_isOfflineContext; | 341 bool m_isOfflineContext; |
| 370 | 342 |
| 371 AsyncAudioDecoder m_audioDecoder; | 343 AsyncAudioDecoder m_audioDecoder; |
| 372 | 344 |
| 373 // This is considering 32 is large enough for multiple channels audio. | 345 // This is considering 32 is large enough for multiple channels audio. |
| 374 // It is somewhat arbitrary and could be increased if necessary. | 346 // It is somewhat arbitrary and could be increased if necessary. |
| 375 enum { MaxNumberOfChannels = 32 }; | 347 enum { MaxNumberOfChannels = 32 }; |
| 376 }; | 348 }; |
| 377 | 349 |
| 378 } // namespace blink | 350 } // namespace blink |
| 379 | 351 |
| 380 #endif // AudioContext_h | 352 #endif // AudioContext_h |
| OLD | NEW |