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 |