Changeset 265052 in webkit


Ignore:
Timestamp:
Jul 29, 2020 1:24:46 PM (4 years ago)
Author:
Chris Dumez
Message:

Calling AudioNode constructors should have identical behavior to using create*() function on BaseAudioContext
https://bugs.webkit.org/show_bug.cgi?id=214931

Reviewed by Eric Carlson.

Calling AudioNode constructors should have identical behavior to using create*() function on BaseAudioContext.
Otherwise, this leads to assertion hits on the bots like we saw for Bug 214851.

We need to make sure that the AudioContext gets initialized when an AudioNode constructor gets called. We also
need to make sure refNode() gets called if necessary.

  • Modules/webaudio/BaseAudioContext.cpp:

(WebCore::BaseAudioContext::createPanner):
(WebCore::BaseAudioContext::createOscillator):
(WebCore::BaseAudioContext::createPeriodicWave):

  • Modules/webaudio/BaseAudioContext.h:
  • Modules/webaudio/OscillatorNode.cpp:

(WebCore::OscillatorNode::create):

  • Modules/webaudio/PannerNode.cpp:

(WebCore::PannerNode::create):

  • Modules/webaudio/PeriodicWave.cpp:

(WebCore::PeriodicWave::create):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r265051 r265052  
     12020-07-29  Chris Dumez  <cdumez@apple.com>
     2
     3        Calling AudioNode constructors should have identical behavior to using create*() function on BaseAudioContext
     4        https://bugs.webkit.org/show_bug.cgi?id=214931
     5
     6        Reviewed by Eric Carlson.
     7
     8        Calling AudioNode constructors should have identical behavior to using create*() function on BaseAudioContext.
     9        Otherwise, this leads to assertion hits on the bots like we saw for Bug 214851.
     10
     11        We need to make sure that the AudioContext gets initialized when an AudioNode constructor gets called. We also
     12        need to make sure refNode() gets called if necessary.
     13
     14        * Modules/webaudio/BaseAudioContext.cpp:
     15        (WebCore::BaseAudioContext::createPanner):
     16        (WebCore::BaseAudioContext::createOscillator):
     17        (WebCore::BaseAudioContext::createPeriodicWave):
     18        * Modules/webaudio/BaseAudioContext.h:
     19        * Modules/webaudio/OscillatorNode.cpp:
     20        (WebCore::OscillatorNode::create):
     21        * Modules/webaudio/PannerNode.cpp:
     22        (WebCore::PannerNode::create):
     23        * Modules/webaudio/PeriodicWave.cpp:
     24        (WebCore::PeriodicWave::create):
     25
    1262020-07-29  Simon Fraser  <simon.fraser@apple.com>
    227
  • trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.cpp

    r265038 r265052  
    519519   
    520520    ASSERT(isMainThread());
    521     if (m_isStopScheduled)
    522         return Exception { InvalidStateError };
    523 
    524     lazyInitialize();
    525521    return PannerNode::create(*this);
    526522}
     
    621617   
    622618    ASSERT(isMainThread());
    623     if (m_isStopScheduled)
    624         return Exception { InvalidStateError };
    625 
    626     lazyInitialize();
    627 
    628     auto node = OscillatorNode::create(*this);
    629     if (node.hasException())
    630         return node.releaseException();
    631 
    632     // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
    633     // When this happens, AudioScheduledSourceNode::finish() calls BaseAudioContext::notifyNodeFinishedProcessing().
    634     auto nodeValue = node.releaseReturnValue();
    635     refNode(nodeValue);
    636     return nodeValue;
     619    return OscillatorNode::create(*this);
    637620}
    638621
     
    642625   
    643626    ASSERT(isMainThread());
    644     if (m_isStopScheduled)
    645         return Exception { InvalidStateError };
    646    
    647     if (real.size() != imaginary.size())
    648         return Exception { IndexSizeError, "real and imaginary must have the same length"_s };
    649627   
    650628    PeriodicWaveOptions options;
     
    652630    options.imag = WTFMove(imaginary);
    653631    options.disableNormalization = constraints.disableNormalization;
    654     lazyInitialize();
    655632    return PeriodicWave::create(*this, WTFMove(options));
    656633}
  • trunk/Source/WebCore/Modules/webaudio/BaseAudioContext.h

    r264782 r265052  
    286286    };
    287287
     288    // The context itself keeps a reference to all source nodes. The source nodes, then reference all nodes they're connected to.
     289    // In turn, these nodes reference all nodes they're connected to. All nodes are ultimately connected to the AudioDestinationNode.
     290    // When the context dereferences a source node, it will be deactivated from the rendering graph along with all other nodes it is
     291    // uniquely connected to. See the AudioNode::ref() and AudioNode::deref() methods for more details.
     292    void refNode(AudioNode&);
     293    void derefNode(AudioNode&);
     294
     295    void lazyInitialize();
     296
    288297protected:
    289298    explicit BaseAudioContext(Document&, const AudioContextOptions& = { });
     
    296305    AudioDestinationNode* destinationNode() const { return m_destinationNode.get(); }
    297306
    298     void lazyInitialize();
    299307    void uninitialize();
    300308
     
    302310    const char* logClassName() const final { return "BaseAudioContext"; }
    303311#endif
    304 
    305     // The context itself keeps a reference to all source nodes.  The source nodes, then reference all nodes they're connected to.
    306     // In turn, these nodes reference all nodes they're connected to.  All nodes are ultimately connected to the AudioDestinationNode.
    307     // When the context dereferences a source node, it will be deactivated from the rendering graph along with all other nodes it is
    308     // uniquely connected to.  See the AudioNode::ref() and AudioNode::deref() methods for more details.
    309     void refNode(AudioNode&);
    310     void derefNode(AudioNode&);
    311312
    312313    void addReaction(State, DOMPromiseDeferred<void>&&);
  • trunk/Source/WebCore/Modules/webaudio/OscillatorNode.cpp

    r265028 r265052  
    4848ExceptionOr<Ref<OscillatorNode>> OscillatorNode::create(BaseAudioContext& context, const OscillatorOptions& options)
    4949{
     50    if (context.isStopped())
     51        return Exception { InvalidStateError };
     52
     53    context.lazyInitialize();
     54
    5055    if (options.type == OscillatorType::Custom && !options.periodicWave)
    5156        return Exception { InvalidStateError, "Must provide periodicWave when using custom type."_s };
     
    7277            return result.releaseException();
    7378    }
    74    
     79
     80    // Because this is an AudioScheduledSourceNode, the context keeps a reference until it has finished playing.
     81    // When this happens, AudioScheduledSourceNode::finish() calls BaseAudioContext::notifyNodeFinishedProcessing().
     82    context.refNode(oscillator);
     83
    7584    return oscillator;
    7685}
  • trunk/Source/WebCore/Modules/webaudio/PannerNode.cpp

    r264620 r265052  
    6363ExceptionOr<Ref<PannerNode>> PannerNode::create(BaseAudioContext& context, const PannerOptions& options)
    6464{
     65    if (context.isStopped())
     66        return Exception { InvalidStateError };
     67
     68    context.lazyInitialize();
     69
    6570    auto panner = adoptRef(*new PannerNode(context, options));
    6671
  • trunk/Source/WebCore/Modules/webaudio/PeriodicWave.cpp

    r264941 r265052  
    5757ExceptionOr<Ref<PeriodicWave>> PeriodicWave::create(BaseAudioContext& context, PeriodicWaveOptions&& options)
    5858{
     59    if (context.isStopped())
     60        return Exception { InvalidStateError };
     61
     62    context.lazyInitialize();
     63
    5964    Vector<float> real;
    6065    Vector<float> imag;
Note: See TracChangeset for help on using the changeset viewer.