Changeset 117354 in webkit
- Timestamp:
- May 16, 2012 3:27:08 PM (12 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r117353 r117354 1 2012-05-16 Raymond Toy <rtoy@google.com> 2 3 Simplify AudioNode ref-counting by removing RefTypeDisabled 4 https://bugs.webkit.org/show_bug.cgi?id=85681 5 6 Reviewed by Chris Rogers. 7 8 Existing tests should cover these changes. 9 10 * Modules/webaudio/AudioNode.cpp: Remove RefTypeDiabled and m_disabledRefCount. 11 (WebCore::AudioNode::AudioNode): 12 (WebCore::AudioNode::~AudioNode): 13 (WebCore::AudioNode::enableOutputsIfNecessary): New 14 (WebCore::AudioNode::ref): 15 (WebCore::AudioNode::disableOutputsIfNecessary): New 16 (WebCore::AudioNode::finishDeref): 17 * Modules/webaudio/AudioNode.h: Remove RefTypeDisabled and m_disabledRefCount. 18 * Modules/webaudio/AudioNodeInput.cpp: Removed uses of RefTypeDisbled. 19 (WebCore::AudioNodeInput::disconnect): 20 (WebCore::AudioNodeInput::disable): 21 (WebCore::AudioNodeInput::enable): 22 1 23 2012-05-16 Ojan Vafai <ojan@chromium.org> 2 24 -
trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp
r113769 r117354 48 48 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class) 49 49 , m_connectionRefCount(0) 50 , m_disabledRefCount(0)51 50 , m_isMarkedForDeletion(false) 52 51 , m_isDisabled(false) … … 64 63 #if DEBUG_AUDIONODE_REFERENCES 65 64 --s_nodeCount[nodeType()]; 66 printf("%p: %d: AudioNode::~AudioNode() %d %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount, m_disabledRefCount);65 printf("%p: %d: AudioNode::~AudioNode() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount); 67 66 #endif 68 67 } … … 266 265 } 267 266 267 void AudioNode::enableOutputsIfNecessary() 268 { 269 if (m_isDisabled && m_connectionRefCount > 0) { 270 ASSERT(isMainThread()); 271 AudioContext::AutoLocker locker(context()); 272 273 m_isDisabled = false; 274 for (unsigned i = 0; i < m_outputs.size(); ++i) 275 output(i)->enable(); 276 } 277 } 278 279 void AudioNode::disableOutputsIfNecessary() 280 { 281 // Disable outputs if appropriate. We do this if the number of connections is 0 or 1. The case 282 // of 0 is from finishDeref() where there are no connections left. The case of 1 is from 283 // AudioNodeInput::disable() where we want to disable outputs when there's only one connection 284 // left because we're ready to go away, but can't quite yet. 285 if (m_connectionRefCount <= 1 && !m_isDisabled) { 286 // Still may have JavaScript references, but no more "active" connection references, so put all of our outputs in a "dormant" disabled state. 287 // Garbage collection may take a very long time after this time, so the "dormant" disabled nodes should not bog down the rendering... 288 289 // As far as JavaScript is concerned, our outputs must still appear to be connected. 290 // But internally our outputs should be disabled from the inputs they're connected to. 291 // disable() can recursively deref connections (and call disable()) down a whole chain of connected nodes. 292 293 // FIXME: we special case the convolver and delay since they have a significant tail-time and shouldn't be disconnected simply 294 // because they no longer have any input connections. This needs to be handled more generally where AudioNodes have 295 // a tailTime attribute. Then the AudioNode only needs to remain "active" for tailTime seconds after there are no 296 // longer any active connections. 297 if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) { 298 m_isDisabled = true; 299 for (unsigned i = 0; i < m_outputs.size(); ++i) 300 output(i)->disable(); 301 } 302 } 303 } 304 268 305 void AudioNode::ref(RefType refType) 269 306 { … … 275 312 atomicIncrement(&m_connectionRefCount); 276 313 break; 277 case RefTypeDisabled:278 atomicIncrement(&m_disabledRefCount);279 break;280 314 default: 281 315 ASSERT_NOT_REACHED(); … … 283 317 284 318 #if DEBUG_AUDIONODE_REFERENCES 285 printf("%p: %d: AudioNode::ref(%d) %d %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount, m_disabledRefCount);319 printf("%p: %d: AudioNode::ref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount); 286 320 #endif 287 321 … … 289 323 // is being re-connected after being used at least once and disconnected. 290 324 // In this case, we need to re-enable. 291 if (m_isDisabled && m_connectionRefCount > 0 && refType == RefTypeConnection) { 292 ASSERT(isMainThread()); 293 AudioContext::AutoLocker locker(context()); 294 295 m_isDisabled = false; 296 for (unsigned i = 0; i < m_outputs.size(); ++i) 297 output(i)->enable(); 298 } 325 if (refType == RefTypeConnection) 326 enableOutputsIfNecessary(); 299 327 } 300 328 … … 346 374 atomicDecrement(&m_connectionRefCount); 347 375 break; 348 case RefTypeDisabled:349 ASSERT(m_disabledRefCount > 0);350 atomicDecrement(&m_disabledRefCount);351 break;352 376 default: 353 377 ASSERT_NOT_REACHED(); … … 355 379 356 380 #if DEBUG_AUDIONODE_REFERENCES 357 printf("%p: %d: AudioNode::deref(%d) %d %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount, m_disabledRefCount);381 printf("%p: %d: AudioNode::deref(%d) %d %d\n", this, nodeType(), refType, m_normalRefCount, m_connectionRefCount); 358 382 #endif 359 383 360 384 if (!m_connectionRefCount) { 361 if (!m_normalRefCount && !m_disabledRefCount) {385 if (!m_normalRefCount) { 362 386 if (!m_isMarkedForDeletion) { 363 387 // All references are gone - we need to go away. … … 369 393 m_isMarkedForDeletion = true; 370 394 } 371 } else if (refType == RefTypeConnection) { 372 if (!m_isDisabled) { 373 // Still may have JavaScript references, but no more "active" connection references, so put all of our outputs in a "dormant" disabled state. 374 // Garbage collection may take a very long time after this time, so the "dormant" disabled nodes should not bog down the rendering... 375 376 // As far as JavaScript is concerned, our outputs must still appear to be connected. 377 // But internally our outputs should be disabled from the inputs they're connected to. 378 // disable() can recursively deref connections (and call disable()) down a whole chain of connected nodes. 379 380 // FIXME: we special case the convolver and delay since they have a significant tail-time and shouldn't be disconnected simply 381 // because they no longer have any input connections. This needs to be handled more generally where AudioNodes have 382 // a tailTime attribute. Then the AudioNode only needs to remain "active" for tailTime seconds after there are no 383 // longer any active connections. 384 if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) { 385 m_isDisabled = true; 386 for (unsigned i = 0; i < m_outputs.size(); ++i) 387 output(i)->disable(); 388 } 389 } 390 } 395 } else if (refType == RefTypeConnection) 396 disableOutputsIfNecessary(); 391 397 } 392 398 } -
trunk/Source/WebCore/Modules/webaudio/AudioNode.h
r115787 r117354 84 84 // how AudioNodes can continue processing (playing one-shot sound) after there are no more 85 85 // JavaScript references to the object. 86 enum RefType { RefTypeNormal, RefTypeConnection , RefTypeDisabled};86 enum RefType { RefTypeNormal, RefTypeConnection }; 87 87 88 88 // Can be called from main thread or context's audio thread. … … 154 154 void unsilenceOutputs(); 155 155 156 void enableOutputsIfNecessary(); 157 void disableOutputsIfNecessary(); 156 158 protected: 157 159 // Inputs and outputs must be created before the AudioNode is initialized. … … 178 180 volatile int m_normalRefCount; 179 181 volatile int m_connectionRefCount; 180 volatile int m_disabledRefCount;181 182 182 183 bool m_isMarkedForDeletion; -
trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp
r117126 r117354 87 87 m_disabledOutputs.remove(output); 88 88 output->removeInput(this); 89 node()->deref(AudioNode::RefType Disabled); // Note: it's important to return immediately after all deref() calls since the node may be deleted.89 node()->deref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted. 90 90 return; 91 91 } … … 108 108 changedOutputs(); 109 109 110 node()->ref(AudioNode::RefTypeDisabled);111 node()->d eref(AudioNode::RefTypeConnection); // Note: it's important to return immediately after all deref() calls since the node may be deleted.110 // Propagate disabled state to outputs. 111 node()->disableOutputsIfNecessary(); 112 112 } 113 113 … … 127 127 changedOutputs(); 128 128 129 node()->ref(AudioNode::RefTypeConnection);130 node()-> deref(AudioNode::RefTypeDisabled); // Note: it's important to return immediately after all deref() calls since the node may be deleted.129 // Propagate enabled state to outputs. 130 node()->enableOutputsIfNecessary(); 131 131 } 132 132
Note: See TracChangeset
for help on using the changeset viewer.