Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(409)

Side by Side Diff: Source/modules/webaudio/AudioNode.cpp

Issue 349213007: WebAudio: Remove AudioNode::RefType. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 , m_nodeType(NodeTypeUnknown) 48 , m_nodeType(NodeTypeUnknown)
49 , m_context(context) 49 , m_context(context)
50 , m_sampleRate(sampleRate) 50 , m_sampleRate(sampleRate)
51 #if ENABLE(OILPAN) 51 #if ENABLE(OILPAN)
52 , m_keepAlive(adoptPtr(new Persistent<AudioNode>(this))) 52 , m_keepAlive(adoptPtr(new Persistent<AudioNode>(this)))
53 #endif 53 #endif
54 , m_lastProcessingTime(-1) 54 , m_lastProcessingTime(-1)
55 , m_lastNonSilentTime(-1) 55 , m_lastNonSilentTime(-1)
56 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefC ounted class) 56 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefC ounted class)
57 , m_connectionRefCount(0) 57 , m_connectionRefCount(0)
58 , m_wasDisconnected(false)
58 , m_isMarkedForDeletion(false) 59 , m_isMarkedForDeletion(false)
59 , m_isDisabled(false) 60 , m_isDisabled(false)
60 , m_channelCount(2) 61 , m_channelCount(2)
61 , m_channelCountMode(Max) 62 , m_channelCountMode(Max)
62 , m_channelInterpretation(AudioBus::Speakers) 63 , m_channelInterpretation(AudioBus::Speakers)
63 { 64 {
64 ScriptWrappable::init(this); 65 ScriptWrappable::init(this);
65 #if DEBUG_AUDIONODE_REFERENCES 66 #if DEBUG_AUDIONODE_REFERENCES
66 if (!s_isNodeCountInitialized) { 67 if (!s_isNodeCountInitialized) {
67 s_isNodeCountInitialized = true; 68 s_isNodeCountInitialized = true;
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 // a tailTime attribute. Then the AudioNode only needs to remain "active " for tailTime seconds after there are no 463 // a tailTime attribute. Then the AudioNode only needs to remain "active " for tailTime seconds after there are no
463 // longer any active connections. 464 // longer any active connections.
464 if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) { 465 if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) {
465 m_isDisabled = true; 466 m_isDisabled = true;
466 for (unsigned i = 0; i < m_outputs.size(); ++i) 467 for (unsigned i = 0; i < m_outputs.size(); ++i)
467 output(i)->disable(); 468 output(i)->disable();
468 } 469 }
469 } 470 }
470 } 471 }
471 472
472 void AudioNode::ref(RefType refType) 473 void AudioNode::ref()
473 { 474 {
474 #if ENABLE(OILPAN) 475 #if ENABLE(OILPAN)
475 ASSERT(m_keepAlive); 476 ASSERT(m_keepAlive);
476 #endif 477 #endif
477 switch (refType) { 478 atomicIncrement(&m_normalRefCount);
478 case RefTypeNormal:
479 atomicIncrement(&m_normalRefCount);
480 break;
481 case RefTypeConnection:
482 atomicIncrement(&m_connectionRefCount);
483 break;
484 default:
485 ASSERT_NOT_REACHED();
486 }
487 479
488 #if DEBUG_AUDIONODE_REFERENCES 480 #if DEBUG_AUDIONODE_REFERENCES
489 fprintf(stderr, "%p: %d: AudioNode::ref(%d) %d %d\n", this, nodeType(), refT ype, m_normalRefCount, m_connectionRefCount); 481 fprintf(stderr, "%p: %d: AudioNode::ref(%d) %d %d\n", this, nodeType(), refT ype, m_normalRefCount, m_connectionRefCount);
Raymond Toy 2014/07/09 22:10:34 Please fix this fprintf since refType is gone.
tkent 2014/07/10 08:07:42 will do
490 #endif 482 #endif
491
492 // See the disabling code in finishDeref() below. This handles the case wher e a node
493 // is being re-connected after being used at least once and disconnected.
494 // In this case, we need to re-enable.
495 if (refType == RefTypeConnection)
496 enableOutputsIfNecessary();
497 } 483 }
498 484
499 void AudioNode::deref(RefType refType) 485 void AudioNode::wasConnected()
486 {
487 atomicIncrement(&m_connectionRefCount);
488 // See the disabling code in finishDeref() below. This handles the case
489 // where a node is being re-connected after being used at least once and
490 // disconnected. In this case, we need to re-enable.
491 enableOutputsIfNecessary();
492 }
493
494 void AudioNode::deref()
500 { 495 {
501 // The actually work for deref happens completely within the audio context's graph lock. 496 // The actually work for deref happens completely within the audio context's graph lock.
502 // In the case of the audio thread, we must use a tryLock to avoid glitches. 497 // In the case of the audio thread, we must use a tryLock to avoid glitches.
503 bool hasLock = false; 498 bool hasLock = false;
504 bool mustReleaseLock = false; 499 bool mustReleaseLock = false;
505 500
506 if (context()->isAudioThread()) { 501 if (context()->isAudioThread()) {
507 // Real-time audio thread must not contend lock (to avoid glitches). 502 // Real-time audio thread must not contend lock (to avoid glitches).
508 hasLock = context()->tryLock(mustReleaseLock); 503 hasLock = context()->tryLock(mustReleaseLock);
509 } else { 504 } else {
510 context()->lock(mustReleaseLock); 505 context()->lock(mustReleaseLock);
511 hasLock = true; 506 hasLock = true;
512 } 507 }
513 508
514 if (hasLock) { 509 if (hasLock) {
515 // This is where the real deref work happens. 510 // This is where the real deref work happens.
516 finishDeref(refType); 511 finishDeref();
517 512
518 if (mustReleaseLock) 513 if (mustReleaseLock)
519 context()->unlock(); 514 context()->unlock();
520 } else { 515 } else {
521 // We were unable to get the lock, so put this in a list to finish up la ter. 516 // We were unable to get the lock, so put this in a list to finish up la ter.
522 ASSERT(context()->isAudioThread()); 517 ASSERT(context()->isAudioThread());
523 ASSERT(refType == RefTypeConnection);
524 context()->addDeferredFinishDeref(this); 518 context()->addDeferredFinishDeref(this);
525 } 519 }
526 520
527 // Once AudioContext::uninitialize() is called there's no more chances for d eleteMarkedNodes() to get called, so we call here. 521 // Once AudioContext::uninitialize() is called there's no more chances for d eleteMarkedNodes() to get called, so we call here.
528 // We can't call in AudioContext::~AudioContext() since it will never be cal led as long as any AudioNode is alive 522 // We can't call in AudioContext::~AudioContext() since it will never be cal led as long as any AudioNode is alive
529 // because AudioNodes keep a reference to the context. 523 // because AudioNodes keep a reference to the context.
530 if (!context()->isInitialized()) 524 if (!context()->isInitialized())
531 context()->deleteMarkedNodes(); 525 context()->deleteMarkedNodes();
532 } 526 }
533 527
534 void AudioNode::finishDeref(RefType refType) 528 void AudioNode::willBeDisconnected()
529 {
530 // This function should be called before deref().
Raymond Toy 2014/07/09 22:10:33 Should or must be called before deref()?
tkent 2014/07/10 08:07:42 Must. I'll remove this comment. The comment in A
531 ASSERT(m_normalRefCount > 0);
532 atomicDecrement(&m_connectionRefCount);
533 m_wasDisconnected = true;
534 }
535
536 void AudioNode::finishDeref()
535 { 537 {
536 ASSERT(context()->isGraphOwner()); 538 ASSERT(context()->isGraphOwner());
537 539
538 switch (refType) { 540 ASSERT(m_normalRefCount > 0);
539 case RefTypeNormal: 541 atomicDecrement(&m_normalRefCount);
540 ASSERT(m_normalRefCount > 0);
541 atomicDecrement(&m_normalRefCount);
542 break;
543 case RefTypeConnection:
544 ASSERT(m_connectionRefCount > 0);
545 atomicDecrement(&m_connectionRefCount);
546 break;
547 default:
548 ASSERT_NOT_REACHED();
549 }
550 542
551 #if DEBUG_AUDIONODE_REFERENCES 543 #if DEBUG_AUDIONODE_REFERENCES
552 fprintf(stderr, "%p: %d: AudioNode::deref(%d) %d %d\n", this, nodeType(), re fType, m_normalRefCount, m_connectionRefCount); 544 fprintf(stderr, "%p: %d: AudioNode::deref(%d) %d %d\n", this, nodeType(), re fType, m_normalRefCount, m_connectionRefCount);
Raymond Toy 2014/07/09 22:10:34 Fix fprintf since refType is gone now.
tkent 2014/07/10 08:07:42 will do.
553 #endif 545 #endif
554 546
555 if (!m_connectionRefCount) { 547 if (m_wasDisconnected) {
556 if (!m_normalRefCount) { 548 if (m_connectionRefCount == 0 && m_normalRefCount > 0)
557 if (!m_isMarkedForDeletion) { 549 disableOutputsIfNecessary();
558 // All references are gone - we need to go away. 550 m_wasDisconnected = false;
559 for (unsigned i = 0; i < m_outputs.size(); ++i) 551 }
560 output(i)->disconnectAll(); // This will deref() nodes we're connected to.
561 552
562 // Mark for deletion at end of each render quantum or when conte xt shuts down. 553 if (!m_normalRefCount && !m_isMarkedForDeletion) {
563 context()->markForDeletion(this); 554 // All references are gone - we need to go away.
564 m_isMarkedForDeletion = true; 555 for (unsigned i = 0; i < m_outputs.size(); ++i)
565 } 556 output(i)->disconnectAll(); // This will deref() nodes we're connect ed to.
566 } else if (refType == RefTypeConnection) 557
567 disableOutputsIfNecessary(); 558 // Mark for deletion at end of each render quantum or when context shuts
559 // down.
560 context()->markForDeletion(this);
561 m_isMarkedForDeletion = true;
568 } 562 }
569 } 563 }
570 564
571 #if DEBUG_AUDIONODE_REFERENCES 565 #if DEBUG_AUDIONODE_REFERENCES
572 566
573 bool AudioNode::s_isNodeCountInitialized = false; 567 bool AudioNode::s_isNodeCountInitialized = false;
574 int AudioNode::s_nodeCount[NodeTypeEnd]; 568 int AudioNode::s_nodeCount[NodeTypeEnd];
575 569
576 void AudioNode::printNodeCounts() 570 void AudioNode::printNodeCounts()
577 { 571 {
(...skipping 25 matching lines...) Expand all
603 // it cannot be reattached. Therefore, the reference count 597 // it cannot be reattached. Therefore, the reference count
604 // will not go above zero again. 598 // will not go above zero again.
605 ASSERT(m_keepAlive); 599 ASSERT(m_keepAlive);
606 m_keepAlive = nullptr; 600 m_keepAlive = nullptr;
607 } 601 }
608 #endif 602 #endif
609 603
610 } // namespace WebCore 604 } // namespace WebCore
611 605
612 #endif // ENABLE(WEB_AUDIO) 606 #endif // ENABLE(WEB_AUDIO)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698