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

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

Issue 438293003: Enable Oilpan by default for webaudio/ (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 4 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
« no previous file with comments | « Source/modules/webaudio/AudioNode.h ('k') | Source/modules/webaudio/AudioNode.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 45
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)
56 , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefC ounted class)
57 #endif
58 , m_connectionRefCount(0) 55 , m_connectionRefCount(0)
59 , m_isDisabled(false) 56 , m_isDisabled(false)
60 , m_isDisposeCalled(false) 57 , m_isDisposeCalled(false)
61 , m_channelCount(2) 58 , m_channelCount(2)
62 , m_channelCountMode(Max) 59 , m_channelCountMode(Max)
63 , m_channelInterpretation(AudioBus::Speakers) 60 , m_channelInterpretation(AudioBus::Speakers)
64 { 61 {
65 ScriptWrappable::init(this); 62 ScriptWrappable::init(this);
66 #if ENABLE(OILPAN)
67 m_context->registerLiveNode(*this); 63 m_context->registerLiveNode(*this);
68 #endif
69 #if DEBUG_AUDIONODE_REFERENCES 64 #if DEBUG_AUDIONODE_REFERENCES
70 if (!s_isNodeCountInitialized) { 65 if (!s_isNodeCountInitialized) {
71 s_isNodeCountInitialized = true; 66 s_isNodeCountInitialized = true;
72 atexit(AudioNode::printNodeCounts); 67 atexit(AudioNode::printNodeCounts);
73 } 68 }
74 #endif 69 #endif
75 ++s_instanceCount; 70 ++s_instanceCount;
76 } 71 }
77 72
78 AudioNode::~AudioNode() 73 AudioNode::~AudioNode()
79 { 74 {
80 ASSERT(m_isDisposeCalled); 75 ASSERT(m_isDisposeCalled);
81 --s_instanceCount; 76 --s_instanceCount;
82 #if DEBUG_AUDIONODE_REFERENCES 77 #if DEBUG_AUDIONODE_REFERENCES
83 --s_nodeCount[nodeType()]; 78 --s_nodeCount[nodeType()];
84 #if ENABLE(OILPAN)
85 fprintf(stderr, "%p: %d: AudioNode::~AudioNode() %d\n", this, nodeType(), m_ connectionRefCount); 79 fprintf(stderr, "%p: %d: AudioNode::~AudioNode() %d\n", this, nodeType(), m_ connectionRefCount);
86 #else
87 fprintf(stderr, "%p: %d: AudioNode::~AudioNode() %d %d\n", this, nodeType(), m_normalRefCount, m_connectionRefCount);
88 #endif
89 #endif 80 #endif
90 } 81 }
91 82
92 void AudioNode::initialize() 83 void AudioNode::initialize()
93 { 84 {
94 m_isInitialized = true; 85 m_isInitialized = true;
95 } 86 }
96 87
97 void AudioNode::uninitialize() 88 void AudioNode::uninitialize()
98 { 89 {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 #if DEBUG_AUDIONODE_REFERENCES 160 #if DEBUG_AUDIONODE_REFERENCES
170 ++s_nodeCount[type]; 161 ++s_nodeCount[type];
171 #endif 162 #endif
172 } 163 }
173 164
174 void AudioNode::addInput() 165 void AudioNode::addInput()
175 { 166 {
176 m_inputs.append(AudioNodeInput::create(*this)); 167 m_inputs.append(AudioNodeInput::create(*this));
177 } 168 }
178 169
179 void AudioNode::addOutput(PassOwnPtrWillBeRawPtr<AudioNodeOutput> output) 170 void AudioNode::addOutput(AudioNodeOutput* output)
180 { 171 {
181 m_outputs.append(output); 172 m_outputs.append(output);
182 } 173 }
183 174
184 AudioNodeInput* AudioNode::input(unsigned i) 175 AudioNodeInput* AudioNode::input(unsigned i)
185 { 176 {
186 if (i < m_inputs.size()) 177 if (i < m_inputs.size())
187 return m_inputs[i].get(); 178 return m_inputs[i].get();
188 return 0; 179 return 0;
189 } 180 }
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 457
467 m_isDisabled = false; 458 m_isDisabled = false;
468 for (unsigned i = 0; i < m_outputs.size(); ++i) 459 for (unsigned i = 0; i < m_outputs.size(); ++i)
469 output(i)->enable(); 460 output(i)->enable();
470 } 461 }
471 } 462 }
472 463
473 void AudioNode::disableOutputsIfNecessary() 464 void AudioNode::disableOutputsIfNecessary()
474 { 465 {
475 // Disable outputs if appropriate. We do this if the number of connections i s 0 or 1. The case 466 // Disable outputs if appropriate. We do this if the number of connections i s 0 or 1. The case
476 // of 0 is from finishDeref() where there are no connections left. The case of 1 is from 467 // of 0 is from deref() where there are no connections left. The case of 1 i s from
477 // AudioNodeInput::disable() where we want to disable outputs when there's o nly one connection 468 // AudioNodeInput::disable() where we want to disable outputs when there's o nly one connection
478 // left because we're ready to go away, but can't quite yet. 469 // left because we're ready to go away, but can't quite yet.
479 if (m_connectionRefCount <= 1 && !m_isDisabled) { 470 if (m_connectionRefCount <= 1 && !m_isDisabled) {
480 // Still may have JavaScript references, but no more "active" connection references, so put all of our outputs in a "dormant" disabled state. 471 // Still may have JavaScript references, but no more "active" connection references, so put all of our outputs in a "dormant" disabled state.
481 // Garbage collection may take a very long time after this time, so the "dormant" disabled nodes should not bog down the rendering... 472 // Garbage collection may take a very long time after this time, so the "dormant" disabled nodes should not bog down the rendering...
482 473
483 // As far as JavaScript is concerned, our outputs must still appear to b e connected. 474 // As far as JavaScript is concerned, our outputs must still appear to b e connected.
484 // But internally our outputs should be disabled from the inputs they're connected to. 475 // But internally our outputs should be disabled from the inputs they're connected to.
485 // disable() can recursively deref connections (and call disable()) down a whole chain of connected nodes. 476 // disable() can recursively deref connections (and call disable()) down a whole chain of connected nodes.
486 477
487 // FIXME: we special case the convolver and delay since they have a sign ificant tail-time and shouldn't be disconnected simply 478 // FIXME: we special case the convolver and delay since they have a sign ificant tail-time and shouldn't be disconnected simply
488 // because they no longer have any input connections. This needs to be h andled more generally where AudioNodes have 479 // because they no longer have any input connections. This needs to be h andled more generally where AudioNodes have
489 // a tailTime attribute. Then the AudioNode only needs to remain "active " for tailTime seconds after there are no 480 // a tailTime attribute. Then the AudioNode only needs to remain "active " for tailTime seconds after there are no
490 // longer any active connections. 481 // longer any active connections.
491 if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) { 482 if (nodeType() != NodeTypeConvolver && nodeType() != NodeTypeDelay) {
492 m_isDisabled = true; 483 m_isDisabled = true;
493 for (unsigned i = 0; i < m_outputs.size(); ++i) 484 for (unsigned i = 0; i < m_outputs.size(); ++i)
494 output(i)->disable(); 485 output(i)->disable();
495 } 486 }
496 } 487 }
497 } 488 }
498 489
499 #if !ENABLE(OILPAN)
500 void AudioNode::ref()
501 {
502 atomicIncrement(&m_normalRefCount);
503
504 #if DEBUG_AUDIONODE_REFERENCES
505 fprintf(stderr, "%p: %d: AudioNode::ref() %d %d\n", this, nodeType(), m_norm alRefCount, m_connectionRefCount);
506 #endif
507 }
508 #endif
509
510 void AudioNode::makeConnection() 490 void AudioNode::makeConnection()
511 { 491 {
512 atomicIncrement(&m_connectionRefCount); 492 atomicIncrement(&m_connectionRefCount);
513 // See the disabling code in finishDeref() below. This handles the case 493 // See the disabling code in disableOutputsIfNecessary(). This handles
514 // where a node is being re-connected after being used at least once and 494 // the case where a node is being re-connected after being used at least
515 // disconnected. In this case, we need to re-enable. 495 // once and disconnected. In this case, we need to re-enable.
516 enableOutputsIfNecessary(); 496 enableOutputsIfNecessary();
517 } 497 }
518 498
519 #if !ENABLE(OILPAN)
520 void AudioNode::deref()
521 {
522 // The actual work for deref happens completely within the audio context's
523 // graph lock. In the case of the audio thread, we must use a tryLock to
524 // avoid glitches.
525 bool hasLock = false;
526 bool mustReleaseLock = false;
527
528 if (context()->isAudioThread()) {
529 // Real-time audio thread must not contend lock (to avoid glitches).
530 hasLock = context()->tryLock(mustReleaseLock);
531 } else {
532 context()->lock(mustReleaseLock);
533 hasLock = true;
534 }
535
536 if (hasLock) {
537 // This is where the real deref work happens.
538 finishDeref();
539
540 if (mustReleaseLock)
541 context()->unlock();
542 } else {
543 // We were unable to get the lock, so put this in a list to finish up la ter.
544 ASSERT(context()->isAudioThread());
545 context()->addDeferredFinishDeref(this);
546 }
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 }
554 #endif
555
556 void AudioNode::breakConnection() 499 void AudioNode::breakConnection()
557 { 500 {
558 // The actual work for deref happens completely within the audio context's 501 // 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 502 // graph lock. In the case of the audio thread, we must use a tryLock to
560 // avoid glitches. 503 // avoid glitches.
561 bool hasLock = false; 504 bool hasLock = false;
562 bool mustReleaseLock = false; 505 bool mustReleaseLock = false;
563 506
564 if (context()->isAudioThread()) { 507 if (context()->isAudioThread()) {
565 // Real-time audio thread must not contend lock (to avoid glitches). 508 // Real-time audio thread must not contend lock (to avoid glitches).
(...skipping 12 matching lines...) Expand all
578 // We were unable to get the lock, so put this in a list to finish up 521 // We were unable to get the lock, so put this in a list to finish up
579 // later. 522 // later.
580 ASSERT(context()->isAudioThread()); 523 ASSERT(context()->isAudioThread());
581 context()->addDeferredBreakConnection(*this); 524 context()->addDeferredBreakConnection(*this);
582 } 525 }
583 } 526 }
584 527
585 void AudioNode::breakConnectionWithLock() 528 void AudioNode::breakConnectionWithLock()
586 { 529 {
587 atomicDecrement(&m_connectionRefCount); 530 atomicDecrement(&m_connectionRefCount);
588 #if !ENABLE(OILPAN)
589 ASSERT(m_normalRefCount > 0);
590 #endif
591 if (!m_connectionRefCount) 531 if (!m_connectionRefCount)
592 disableOutputsIfNecessary(); 532 disableOutputsIfNecessary();
593 } 533 }
594 534
595 #if !ENABLE(OILPAN)
596 void AudioNode::finishDeref()
597 {
598 ASSERT(context()->isGraphOwner());
599
600 ASSERT(m_normalRefCount > 0);
601 atomicDecrement(&m_normalRefCount);
602
603 #if DEBUG_AUDIONODE_REFERENCES
604 fprintf(stderr, "%p: %d: AudioNode::deref() %d %d\n", this, nodeType(), m_no rmalRefCount, m_connectionRefCount);
605 #endif
606
607 if (!m_normalRefCount) {
608 // Mark for deletion at end of each render quantum or when context shuts
609 // down.
610 context()->markForDeletion(this);
611 }
612 }
613 #endif
614
615 #if DEBUG_AUDIONODE_REFERENCES 535 #if DEBUG_AUDIONODE_REFERENCES
616 536
617 bool AudioNode::s_isNodeCountInitialized = false; 537 bool AudioNode::s_isNodeCountInitialized = false;
618 int AudioNode::s_nodeCount[NodeTypeEnd]; 538 int AudioNode::s_nodeCount[NodeTypeEnd];
619 539
620 void AudioNode::printNodeCounts() 540 void AudioNode::printNodeCounts()
621 { 541 {
622 fprintf(stderr, "\n\n"); 542 fprintf(stderr, "\n\n");
623 fprintf(stderr, "===========================\n"); 543 fprintf(stderr, "===========================\n");
624 fprintf(stderr, "AudioNode: reference counts\n"); 544 fprintf(stderr, "AudioNode: reference counts\n");
(...skipping 11 matching lines...) Expand all
636 { 556 {
637 visitor->trace(m_context); 557 visitor->trace(m_context);
638 visitor->trace(m_inputs); 558 visitor->trace(m_inputs);
639 visitor->trace(m_outputs); 559 visitor->trace(m_outputs);
640 EventTargetWithInlineData::trace(visitor); 560 EventTargetWithInlineData::trace(visitor);
641 } 561 }
642 562
643 } // namespace blink 563 } // namespace blink
644 564
645 #endif // ENABLE(WEB_AUDIO) 565 #endif // ENABLE(WEB_AUDIO)
OLDNEW
« no previous file with comments | « Source/modules/webaudio/AudioNode.h ('k') | Source/modules/webaudio/AudioNode.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698