Changeset 117354 in webkit


Ignore:
Timestamp:
May 16, 2012 3:27:08 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

Simplify AudioNode ref-counting by removing RefTypeDisabled
https://bugs.webkit.org/show_bug.cgi?id=85681

Patch by Raymond Toy <Raymond Toy> on 2012-05-16
Reviewed by Chris Rogers.

Existing tests should cover these changes.

  • Modules/webaudio/AudioNode.cpp: Remove RefTypeDiabled and m_disabledRefCount.

(WebCore::AudioNode::AudioNode):
(WebCore::AudioNode::~AudioNode):
(WebCore::AudioNode::enableOutputsIfNecessary): New
(WebCore::AudioNode::ref):
(WebCore::AudioNode::disableOutputsIfNecessary): New
(WebCore::AudioNode::finishDeref):

  • Modules/webaudio/AudioNode.h: Remove RefTypeDisabled and m_disabledRefCount.
  • Modules/webaudio/AudioNodeInput.cpp: Removed uses of RefTypeDisbled.

(WebCore::AudioNodeInput::disconnect):
(WebCore::AudioNodeInput::disable):
(WebCore::AudioNodeInput::enable):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r117353 r117354  
     12012-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
    1232012-05-16  Ojan Vafai  <ojan@chromium.org>
    224
  • trunk/Source/WebCore/Modules/webaudio/AudioNode.cpp

    r113769 r117354  
    4848    , m_normalRefCount(1) // start out with normal refCount == 1 (like WTF::RefCounted class)
    4949    , m_connectionRefCount(0)
    50     , m_disabledRefCount(0)
    5150    , m_isMarkedForDeletion(false)
    5251    , m_isDisabled(false)
     
    6463#if DEBUG_AUDIONODE_REFERENCES
    6564    --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);
    6766#endif
    6867}
     
    266265}
    267266
     267void 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
     279void 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
    268305void AudioNode::ref(RefType refType)
    269306{
     
    275312        atomicIncrement(&m_connectionRefCount);
    276313        break;
    277     case RefTypeDisabled:
    278         atomicIncrement(&m_disabledRefCount);
    279         break;
    280314    default:
    281315        ASSERT_NOT_REACHED();
     
    283317
    284318#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);
    286320#endif
    287321
     
    289323    // is being re-connected after being used at least once and disconnected.
    290324    // 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();
    299327}
    300328
     
    346374        atomicDecrement(&m_connectionRefCount);
    347375        break;
    348     case RefTypeDisabled:
    349         ASSERT(m_disabledRefCount > 0);
    350         atomicDecrement(&m_disabledRefCount);
    351         break;
    352376    default:
    353377        ASSERT_NOT_REACHED();
     
    355379   
    356380#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);
    358382#endif
    359383
    360384    if (!m_connectionRefCount) {
    361         if (!m_normalRefCount && !m_disabledRefCount) {
     385        if (!m_normalRefCount) {
    362386            if (!m_isMarkedForDeletion) {
    363387                // All references are gone - we need to go away.
     
    369393                m_isMarkedForDeletion = true;
    370394            }
    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();
    391397    }
    392398}
  • trunk/Source/WebCore/Modules/webaudio/AudioNode.h

    r115787 r117354  
    8484    // how AudioNodes can continue processing (playing one-shot sound) after there are no more
    8585    // JavaScript references to the object.
    86     enum RefType { RefTypeNormal, RefTypeConnection, RefTypeDisabled };
     86    enum RefType { RefTypeNormal, RefTypeConnection };
    8787
    8888    // Can be called from main thread or context's audio thread.
     
    154154    void unsilenceOutputs();
    155155
     156    void enableOutputsIfNecessary();
     157    void disableOutputsIfNecessary();
    156158protected:
    157159    // Inputs and outputs must be created before the AudioNode is initialized.
     
    178180    volatile int m_normalRefCount;
    179181    volatile int m_connectionRefCount;
    180     volatile int m_disabledRefCount;
    181182   
    182183    bool m_isMarkedForDeletion;
  • trunk/Source/WebCore/Modules/webaudio/AudioNodeInput.cpp

    r117126 r117354  
    8787        m_disabledOutputs.remove(output);
    8888        output->removeInput(this);
    89         node()->deref(AudioNode::RefTypeDisabled); // 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.
    9090        return;
    9191    }
     
    108108    changedOutputs();
    109109
    110     node()->ref(AudioNode::RefTypeDisabled);
    111     node()->deref(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();
    112112}
    113113
     
    127127    changedOutputs();
    128128
    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();
    131131}
    132132
Note: See TracChangeset for help on using the changeset viewer.