| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 unsigned AudioNode::s_instanceCount = 0; | 46 unsigned AudioNode::s_instanceCount = 0; |
| 47 | 47 |
| 48 AudioNode::AudioNode(AudioContext* context, float sampleRate) | 48 AudioNode::AudioNode(AudioContext* context, float sampleRate) |
| 49 : m_isInitialized(false) | 49 : m_isInitialized(false) |
| 50 , m_nodeType(NodeTypeUnknown) | 50 , m_nodeType(NodeTypeUnknown) |
| 51 , m_context(context) | 51 , m_context(context) |
| 52 , m_sampleRate(sampleRate) | 52 , m_sampleRate(sampleRate) |
| 53 , m_lastProcessingTime(-1) | 53 , m_lastProcessingTime(-1) |
| 54 , m_lastNonSilentTime(-1) | 54 , m_lastNonSilentTime(-1) |
| 55 #if !ENABLE(OILPAN) | 55 #if !ENABLE(OILPAN) |
| 56 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefC
ounted class) | 56 // Start with 0, because we use m_normalRefCount only for ref() and deref() |
| 57 // that are explicitly called. Other references are managed by Oilpan. |
| 58 , m_normalRefCount(0) |
| 57 #endif | 59 #endif |
| 58 , m_connectionRefCount(0) | 60 , m_connectionRefCount(0) |
| 59 , m_isDisabled(false) | 61 , m_isDisabled(false) |
| 60 , m_isDisposeCalled(false) | 62 , m_isDisposeCalled(false) |
| 61 , m_channelCount(2) | 63 , m_channelCount(2) |
| 62 , m_channelCountMode(Max) | 64 , m_channelCountMode(Max) |
| 63 , m_channelInterpretation(AudioBus::Speakers) | 65 , m_channelInterpretation(AudioBus::Speakers) |
| 64 { | 66 { |
| 65 ScriptWrappable::init(this); | 67 ScriptWrappable::init(this); |
| 66 #if ENABLE(OILPAN) | |
| 67 m_context->registerLiveNode(*this); | 68 m_context->registerLiveNode(*this); |
| 68 #endif | |
| 69 #if DEBUG_AUDIONODE_REFERENCES | 69 #if DEBUG_AUDIONODE_REFERENCES |
| 70 if (!s_isNodeCountInitialized) { | 70 if (!s_isNodeCountInitialized) { |
| 71 s_isNodeCountInitialized = true; | 71 s_isNodeCountInitialized = true; |
| 72 atexit(AudioNode::printNodeCounts); | 72 atexit(AudioNode::printNodeCounts); |
| 73 } | 73 } |
| 74 #endif | 74 #endif |
| 75 ++s_instanceCount; | 75 ++s_instanceCount; |
| 76 } | 76 } |
| 77 | 77 |
| 78 AudioNode::~AudioNode() | 78 AudioNode::~AudioNode() |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 #if DEBUG_AUDIONODE_REFERENCES | 169 #if DEBUG_AUDIONODE_REFERENCES |
| 170 ++s_nodeCount[type]; | 170 ++s_nodeCount[type]; |
| 171 #endif | 171 #endif |
| 172 } | 172 } |
| 173 | 173 |
| 174 void AudioNode::addInput() | 174 void AudioNode::addInput() |
| 175 { | 175 { |
| 176 m_inputs.append(AudioNodeInput::create(*this)); | 176 m_inputs.append(AudioNodeInput::create(*this)); |
| 177 } | 177 } |
| 178 | 178 |
| 179 void AudioNode::addOutput(PassOwnPtrWillBeRawPtr<AudioNodeOutput> output) | 179 void AudioNode::addOutput(AudioNodeOutput* output) |
| 180 { | 180 { |
| 181 m_outputs.append(output); | 181 m_outputs.append(output); |
| 182 } | 182 } |
| 183 | 183 |
| 184 AudioNodeInput* AudioNode::input(unsigned i) | 184 AudioNodeInput* AudioNode::input(unsigned i) |
| 185 { | 185 { |
| 186 if (i < m_inputs.size()) | 186 if (i < m_inputs.size()) |
| 187 return m_inputs[i].get(); | 187 return m_inputs[i].get(); |
| 188 return 0; | 188 return 0; |
| 189 } | 189 } |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 m_isDisabled = true; | 492 m_isDisabled = true; |
| 493 for (unsigned i = 0; i < m_outputs.size(); ++i) | 493 for (unsigned i = 0; i < m_outputs.size(); ++i) |
| 494 output(i)->disable(); | 494 output(i)->disable(); |
| 495 } | 495 } |
| 496 } | 496 } |
| 497 } | 497 } |
| 498 | 498 |
| 499 #if !ENABLE(OILPAN) | 499 #if !ENABLE(OILPAN) |
| 500 void AudioNode::ref() | 500 void AudioNode::ref() |
| 501 { | 501 { |
| 502 atomicIncrement(&m_normalRefCount); | 502 // We create a self-keep-alive persistent handle when the first ref() |
| 503 // is called. |
| 504 if (atomicIncrement(&m_normalRefCount) == 1) { |
| 505 ASSERT(!m_keepAlive); |
| 506 m_keepAlive = this; |
| 507 } |
| 508 ASSERT(m_keepAlive); |
| 503 | 509 |
| 504 #if DEBUG_AUDIONODE_REFERENCES | 510 #if DEBUG_AUDIONODE_REFERENCES |
| 505 fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_norm
alRefCount, m_connectionRefCount); | 511 fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_norm
alRefCount, m_connectionRefCount); |
| 506 #endif | 512 #endif |
| 507 } | 513 } |
| 508 #endif | 514 #endif |
| 509 | 515 |
| 510 void AudioNode::makeConnection() | 516 void AudioNode::makeConnection() |
| 511 { | 517 { |
| 512 atomicIncrement(&m_connectionRefCount); | 518 atomicIncrement(&m_connectionRefCount); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 537 // This is where the real deref work happens. | 543 // This is where the real deref work happens. |
| 538 finishDeref(); | 544 finishDeref(); |
| 539 | 545 |
| 540 if (mustReleaseLock) | 546 if (mustReleaseLock) |
| 541 context()->unlock(); | 547 context()->unlock(); |
| 542 } else { | 548 } else { |
| 543 // We were unable to get the lock, so put this in a list to finish up la
ter. | 549 // We were unable to get the lock, so put this in a list to finish up la
ter. |
| 544 ASSERT(context()->isAudioThread()); | 550 ASSERT(context()->isAudioThread()); |
| 545 context()->addDeferredFinishDeref(this); | 551 context()->addDeferredFinishDeref(this); |
| 546 } | 552 } |
| 547 | |
| 548 // Once AudioContext::uninitialize() is called there's no more chances for d
eleteMarkedNodes() to get called, so we call here. | |
| 549 // We can't call in AudioContext::~AudioContext() since it will never be cal
led as long as any AudioNode is alive | |
| 550 // because AudioNodes keep a reference to the context. | |
| 551 if (!context()->isInitialized()) | |
| 552 context()->deleteMarkedNodes(); | |
| 553 } | 553 } |
| 554 #endif | 554 #endif |
| 555 | 555 |
| 556 void AudioNode::breakConnection() | 556 void AudioNode::breakConnection() |
| 557 { | 557 { |
| 558 // The actual work for deref happens completely within the audio context's | 558 // The actual work for deref happens completely within the audio context's |
| 559 // graph lock. In the case of the audio thread, we must use a tryLock to | 559 // graph lock. In the case of the audio thread, we must use a tryLock to |
| 560 // avoid glitches. | 560 // avoid glitches. |
| 561 bool hasLock = false; | 561 bool hasLock = false; |
| 562 bool mustReleaseLock = false; | 562 bool mustReleaseLock = false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 578 // We were unable to get the lock, so put this in a list to finish up | 578 // We were unable to get the lock, so put this in a list to finish up |
| 579 // later. | 579 // later. |
| 580 ASSERT(context()->isAudioThread()); | 580 ASSERT(context()->isAudioThread()); |
| 581 context()->addDeferredBreakConnection(*this); | 581 context()->addDeferredBreakConnection(*this); |
| 582 } | 582 } |
| 583 } | 583 } |
| 584 | 584 |
| 585 void AudioNode::breakConnectionWithLock() | 585 void AudioNode::breakConnectionWithLock() |
| 586 { | 586 { |
| 587 atomicDecrement(&m_connectionRefCount); | 587 atomicDecrement(&m_connectionRefCount); |
| 588 #if !ENABLE(OILPAN) | |
| 589 ASSERT(m_normalRefCount > 0); | |
| 590 #endif | |
| 591 if (!m_connectionRefCount) | 588 if (!m_connectionRefCount) |
| 592 disableOutputsIfNecessary(); | 589 disableOutputsIfNecessary(); |
| 593 } | 590 } |
| 594 | 591 |
| 595 #if !ENABLE(OILPAN) | 592 #if !ENABLE(OILPAN) |
| 596 void AudioNode::finishDeref() | 593 void AudioNode::finishDeref() |
| 597 { | 594 { |
| 598 ASSERT(context()->isGraphOwner()); | 595 ASSERT(context()->isGraphOwner()); |
| 599 | 596 |
| 600 ASSERT(m_normalRefCount > 0); | 597 ASSERT(m_normalRefCount > 0); |
| 601 atomicDecrement(&m_normalRefCount); | 598 atomicDecrement(&m_normalRefCount); |
| 602 | 599 |
| 603 #if DEBUG_AUDIONODE_REFERENCES | 600 #if DEBUG_AUDIONODE_REFERENCES |
| 604 fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_no
rmalRefCount, m_connectionRefCount); | 601 fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_no
rmalRefCount, m_connectionRefCount); |
| 605 #endif | 602 #endif |
| 606 | 603 |
| 607 if (!m_normalRefCount) { | 604 if (!m_normalRefCount) { |
| 608 // Mark for deletion at end of each render quantum or when context shuts | 605 // This self-keep-alive handle can be resurrected when the ref() is |
| 609 // down. | 606 // called again. |
| 610 context()->markForDeletion(this); | 607 m_keepAlive = nullptr; |
| 611 } | 608 } |
| 612 } | 609 } |
| 613 #endif | 610 #endif |
| 614 | 611 |
| 615 #if DEBUG_AUDIONODE_REFERENCES | 612 #if DEBUG_AUDIONODE_REFERENCES |
| 616 | 613 |
| 617 bool AudioNode::s_isNodeCountInitialized = false; | 614 bool AudioNode::s_isNodeCountInitialized = false; |
| 618 int AudioNode::s_nodeCount[NodeTypeEnd]; | 615 int AudioNode::s_nodeCount[NodeTypeEnd]; |
| 619 | 616 |
| 620 void AudioNode::printNodeCounts() | 617 void AudioNode::printNodeCounts() |
| (...skipping 15 matching lines...) Expand all Loading... |
| 636 { | 633 { |
| 637 visitor->trace(m_context); | 634 visitor->trace(m_context); |
| 638 visitor->trace(m_inputs); | 635 visitor->trace(m_inputs); |
| 639 visitor->trace(m_outputs); | 636 visitor->trace(m_outputs); |
| 640 EventTargetWithInlineData::trace(visitor); | 637 EventTargetWithInlineData::trace(visitor); |
| 641 } | 638 } |
| 642 | 639 |
| 643 } // namespace blink | 640 } // namespace blink |
| 644 | 641 |
| 645 #endif // ENABLE(WEB_AUDIO) | 642 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |