| 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 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 : ActiveDOMObject(document) | 104 : ActiveDOMObject(document) |
| 105 , m_isStopScheduled(false) | 105 , m_isStopScheduled(false) |
| 106 , m_isCleared(false) | 106 , m_isCleared(false) |
| 107 , m_isInitialized(false) | 107 , m_isInitialized(false) |
| 108 , m_destinationNode(nullptr) | 108 , m_destinationNode(nullptr) |
| 109 , m_isResolvingResumePromises(false) | 109 , m_isResolvingResumePromises(false) |
| 110 , m_automaticPullNodesNeedUpdating(false) | 110 , m_automaticPullNodesNeedUpdating(false) |
| 111 , m_connectionCount(0) | 111 , m_connectionCount(0) |
| 112 , m_didInitializeContextGraphMutex(false) | 112 , m_didInitializeContextGraphMutex(false) |
| 113 , m_audioThread(0) | 113 , m_audioThread(0) |
| 114 , m_lastZombie(nullptr) |
| 115 , m_lastRemovableZombie(nullptr) |
| 114 , m_isOfflineContext(false) | 116 , m_isOfflineContext(false) |
| 115 , m_contextState(Suspended) | 117 , m_contextState(Suspended) |
| 116 , m_cachedSampleFrame(0) | 118 , m_cachedSampleFrame(0) |
| 117 { | 119 { |
| 118 m_didInitializeContextGraphMutex = true; | 120 m_didInitializeContextGraphMutex = true; |
| 119 m_destinationNode = DefaultAudioDestinationNode::create(this); | 121 m_destinationNode = DefaultAudioDestinationNode::create(this); |
| 120 | 122 |
| 121 initialize(); | 123 initialize(); |
| 122 } | 124 } |
| 123 | 125 |
| 124 // Constructor for offline (non-realtime) rendering. | 126 // Constructor for offline (non-realtime) rendering. |
| 125 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, float sampleRate) | 127 AudioContext::AudioContext(Document* document, unsigned numberOfChannels, size_t
numberOfFrames, float sampleRate) |
| 126 : ActiveDOMObject(document) | 128 : ActiveDOMObject(document) |
| 127 , m_isStopScheduled(false) | 129 , m_isStopScheduled(false) |
| 128 , m_isCleared(false) | 130 , m_isCleared(false) |
| 129 , m_isInitialized(false) | 131 , m_isInitialized(false) |
| 130 , m_destinationNode(nullptr) | 132 , m_destinationNode(nullptr) |
| 131 , m_isResolvingResumePromises(false) | 133 , m_isResolvingResumePromises(false) |
| 132 , m_automaticPullNodesNeedUpdating(false) | 134 , m_automaticPullNodesNeedUpdating(false) |
| 133 , m_connectionCount(0) | 135 , m_connectionCount(0) |
| 134 , m_didInitializeContextGraphMutex(false) | 136 , m_didInitializeContextGraphMutex(false) |
| 135 , m_audioThread(0) | 137 , m_audioThread(0) |
| 138 , m_lastZombie(nullptr) |
| 139 , m_lastRemovableZombie(nullptr) |
| 136 , m_isOfflineContext(true) | 140 , m_isOfflineContext(true) |
| 137 , m_contextState(Suspended) | 141 , m_contextState(Suspended) |
| 138 , m_cachedSampleFrame(0) | 142 , m_cachedSampleFrame(0) |
| 139 { | 143 { |
| 140 m_didInitializeContextGraphMutex = true; | 144 m_didInitializeContextGraphMutex = true; |
| 141 // Create a new destination for offline rendering. | 145 // Create a new destination for offline rendering. |
| 142 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl
eRate); | 146 m_renderTarget = AudioBuffer::create(numberOfChannels, numberOfFrames, sampl
eRate); |
| 143 if (m_renderTarget.get()) | 147 if (m_renderTarget.get()) |
| 144 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa
rget.get()); | 148 m_destinationNode = OfflineAudioDestinationNode::create(this, m_renderTa
rget.get()); |
| 145 | 149 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 162 ASSERT(!m_suspendResolvers.size()); | 166 ASSERT(!m_suspendResolvers.size()); |
| 163 ASSERT(!m_isResolvingResumePromises); | 167 ASSERT(!m_isResolvingResumePromises); |
| 164 ASSERT(!m_resumeResolvers.size()); | 168 ASSERT(!m_resumeResolvers.size()); |
| 165 } | 169 } |
| 166 | 170 |
| 167 void AudioContext::initialize() | 171 void AudioContext::initialize() |
| 168 { | 172 { |
| 169 if (isInitialized()) | 173 if (isInitialized()) |
| 170 return; | 174 return; |
| 171 | 175 |
| 176 ThreadState::current()->addMarkingTask(this); |
| 172 FFTFrame::initialize(); | 177 FFTFrame::initialize(); |
| 173 m_listener = AudioListener::create(); | 178 m_listener = AudioListener::create(); |
| 174 | 179 |
| 175 if (m_destinationNode.get()) { | 180 if (m_destinationNode.get()) { |
| 176 m_destinationNode->initialize(); | 181 m_destinationNode->initialize(); |
| 177 | 182 |
| 178 if (!isOfflineContext()) { | 183 if (!isOfflineContext()) { |
| 179 // This starts the audio thread. The destination node's provideInput
() method will now be called repeatedly to render audio. | 184 // This starts the audio thread. The destination node's provideInput
() method will now be called repeatedly to render audio. |
| 180 // Each time provideInput() is called, a portion of the audio stream
is rendered. Let's call this time period a "render quantum". | 185 // Each time provideInput() is called, a portion of the audio stream
is rendered. Let's call this time period a "render quantum". |
| 181 // NOTE: for now default AudioContext does not need an explicit star
tRendering() call from JavaScript. | 186 // NOTE: for now default AudioContext does not need an explicit star
tRendering() call from JavaScript. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 setContextState(Closed); | 237 setContextState(Closed); |
| 233 | 238 |
| 234 // Resolve the promise now, if any | 239 // Resolve the promise now, if any |
| 235 if (m_closeResolver) | 240 if (m_closeResolver) |
| 236 m_closeResolver->resolve(); | 241 m_closeResolver->resolve(); |
| 237 | 242 |
| 238 ASSERT(m_listener); | 243 ASSERT(m_listener); |
| 239 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); | 244 m_listener->waitForHRTFDatabaseLoaderThreadCompletion(); |
| 240 | 245 |
| 241 clear(); | 246 clear(); |
| 247 |
| 248 ThreadState::current()->removeMarkingTask(this); |
| 249 if (m_lastZombie) |
| 250 ThreadState::current()->purifyZombies(); |
| 251 m_lastZombie = nullptr; |
| 252 m_lastRemovableZombie = nullptr; |
| 242 } | 253 } |
| 243 | 254 |
| 244 void AudioContext::stop() | 255 void AudioContext::stop() |
| 245 { | 256 { |
| 246 // Usually ExecutionContext calls stop twice. | 257 // Usually ExecutionContext calls stop twice. |
| 247 if (m_isStopScheduled) | 258 if (m_isStopScheduled) |
| 248 return; | 259 return; |
| 249 m_isStopScheduled = true; | 260 m_isStopScheduled = true; |
| 250 | 261 |
| 251 // Don't call uninitialize() immediately here because the ExecutionContext i
s in the middle | 262 // Don't call uninitialize() immediately here because the ExecutionContext i
s in the middle |
| (...skipping 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 if (tryLock()) { | 989 if (tryLock()) { |
| 979 // Update the channel count mode. | 990 // Update the channel count mode. |
| 980 updateChangedChannelCountMode(); | 991 updateChangedChannelCountMode(); |
| 981 | 992 |
| 982 // Take care of AudioNode tasks where the tryLock() failed previously. | 993 // Take care of AudioNode tasks where the tryLock() failed previously. |
| 983 handleDeferredAudioNodeTasks(); | 994 handleDeferredAudioNodeTasks(); |
| 984 | 995 |
| 985 // Dynamically clean up nodes which are no longer needed. | 996 // Dynamically clean up nodes which are no longer needed. |
| 986 derefFinishedSourceNodes(); | 997 derefFinishedSourceNodes(); |
| 987 | 998 |
| 999 m_lastRemovableZombie = m_lastZombie; |
| 1000 |
| 988 // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutpu
ts. | 1001 // Fixup the state of any dirty AudioSummingJunctions and AudioNodeOutpu
ts. |
| 989 handleDirtyAudioSummingJunctions(); | 1002 handleDirtyAudioSummingJunctions(); |
| 990 handleDirtyAudioNodeOutputs(); | 1003 handleDirtyAudioNodeOutputs(); |
| 991 | 1004 |
| 992 updateAutomaticPullNodes(); | 1005 updateAutomaticPullNodes(); |
| 993 resolvePromisesForSuspend(); | 1006 resolvePromisesForSuspend(); |
| 994 | 1007 |
| 995 unlock(); | 1008 unlock(); |
| 996 } | 1009 } |
| 997 } | 1010 } |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1274 } | 1287 } |
| 1275 } | 1288 } |
| 1276 | 1289 |
| 1277 DEFINE_TRACE(AudioContext) | 1290 DEFINE_TRACE(AudioContext) |
| 1278 { | 1291 { |
| 1279 visitor->trace(m_closeResolver); | 1292 visitor->trace(m_closeResolver); |
| 1280 visitor->trace(m_offlineResolver); | 1293 visitor->trace(m_offlineResolver); |
| 1281 visitor->trace(m_renderTarget); | 1294 visitor->trace(m_renderTarget); |
| 1282 visitor->trace(m_destinationNode); | 1295 visitor->trace(m_destinationNode); |
| 1283 visitor->trace(m_listener); | 1296 visitor->trace(m_listener); |
| 1284 // trace() can be called in AudioContext constructor, and | 1297 visitor->trace(m_referencedNodes); |
| 1285 // m_contextGraphMutex might be unavailable. | |
| 1286 if (m_didInitializeContextGraphMutex) { | |
| 1287 AutoLocker lock(this); | |
| 1288 visitor->trace(m_referencedNodes); | |
| 1289 } else { | |
| 1290 visitor->trace(m_referencedNodes); | |
| 1291 } | |
| 1292 visitor->trace(m_resumeResolvers); | 1298 visitor->trace(m_resumeResolvers); |
| 1293 visitor->trace(m_suspendResolvers); | 1299 visitor->trace(m_suspendResolvers); |
| 1294 visitor->trace(m_liveNodes); | 1300 visitor->trace(m_liveNodes); |
| 1295 visitor->trace(m_liveAudioSummingJunctions); | 1301 visitor->trace(m_liveAudioSummingJunctions); |
| 1296 RefCountedGarbageCollectedEventTargetWithInlineData<AudioContext>::trace(vis
itor); | 1302 RefCountedGarbageCollectedEventTargetWithInlineData<AudioContext>::trace(vis
itor); |
| 1297 ActiveDOMObject::trace(visitor); | 1303 ActiveDOMObject::trace(visitor); |
| 1298 } | 1304 } |
| 1299 | 1305 |
| 1300 void AudioContext::addChangedChannelCountMode(AudioNode* node) | 1306 void AudioContext::addChangedChannelCountMode(AudioNode* node) |
| 1301 { | 1307 { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1358 | 1364 |
| 1359 // Stop the audio context. This will stop the destination node from pulling
audio anymore. And | 1365 // Stop the audio context. This will stop the destination node from pulling
audio anymore. And |
| 1360 // since we have disconnected the destination from the audio graph, and thus
has no references, | 1366 // since we have disconnected the destination from the audio graph, and thus
has no references, |
| 1361 // the destination node can GCed if JS has no references. stop() will also r
esolve the Promise | 1367 // the destination node can GCed if JS has no references. stop() will also r
esolve the Promise |
| 1362 // created here. | 1368 // created here. |
| 1363 stop(); | 1369 stop(); |
| 1364 | 1370 |
| 1365 return promise; | 1371 return promise; |
| 1366 } | 1372 } |
| 1367 | 1373 |
| 1374 void AudioContext::setLastZombie(void* object) |
| 1375 { |
| 1376 ASSERT(isGraphOwner()); |
| 1377 m_lastZombie = object; |
| 1378 } |
| 1379 |
| 1380 void AudioContext::willStartMarking(ThreadState& threadState) |
| 1381 { |
| 1382 lock(); |
| 1383 if (!m_lastRemovableZombie) |
| 1384 return; |
| 1385 if (m_lastZombie != m_lastRemovableZombie) |
| 1386 return; |
| 1387 threadState.purifyZombies(); |
| 1388 m_lastZombie = nullptr; |
| 1389 m_lastRemovableZombie = nullptr; |
| 1390 } |
| 1391 |
| 1392 void AudioContext::didFinishMarking(ThreadState&) |
| 1393 { |
| 1394 unlock(); |
| 1395 } |
| 1396 |
| 1368 } // namespace blink | 1397 } // namespace blink |
| 1369 | 1398 |
| 1370 #endif // ENABLE(WEB_AUDIO) | 1399 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |