mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
b=910171 add a general means to keep active nodes alive from the AudioContext r=ehsan
AudioNodes that keep playing or tail-time references need to have these references cleared when an AudioContext has completed or is shut down by the window. Storing references on the AudioContext instead of on the AudioNodes will allow the AudioContext to report playing references to the cycle collector until offline rendering starts for bug 914033. This is not necessary for tail-time references, but it is tidier to use the same code for playing and tail-time references. --HG-- extra : transplant_source : %E0%F1%06%BFV%B6XI%9BX%8E%8D7%3FsU%8F%F9%14r
This commit is contained in:
parent
92875436fc
commit
cf1704526c
@ -440,6 +440,18 @@ AudioContext::RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob)
|
||||
mDecodeJobs.RemoveElement(aDecodeJob);
|
||||
}
|
||||
|
||||
void
|
||||
AudioContext::RegisterActiveNode(AudioNode* aNode)
|
||||
{
|
||||
mActiveNodes.PutEntry(aNode);
|
||||
}
|
||||
|
||||
void
|
||||
AudioContext::UnregisterActiveNode(AudioNode* aNode)
|
||||
{
|
||||
mActiveNodes.RemoveEntry(aNode);
|
||||
}
|
||||
|
||||
void
|
||||
AudioContext::UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode)
|
||||
{
|
||||
@ -526,6 +538,11 @@ AudioContext::Shutdown()
|
||||
{
|
||||
Suspend();
|
||||
|
||||
// Release references to active nodes.
|
||||
// Active AudioNodes don't unregister in destructors, at which point the
|
||||
// Node is already unregistered.
|
||||
mActiveNodes.Clear();
|
||||
|
||||
// Stop all audio buffer source nodes, to make sure that they release
|
||||
// their self-references.
|
||||
// We first gather an array of the nodes and then call Stop on each one,
|
||||
|
@ -41,6 +41,7 @@ class AudioBuffer;
|
||||
class AudioBufferSourceNode;
|
||||
class AudioDestinationNode;
|
||||
class AudioListener;
|
||||
class AudioNode;
|
||||
class BiquadFilterNode;
|
||||
class ChannelMergerNode;
|
||||
class ChannelSplitterNode;
|
||||
@ -212,6 +213,20 @@ public:
|
||||
|
||||
MediaStreamGraph* Graph() const;
|
||||
MediaStream* DestinationStream() const;
|
||||
|
||||
// Nodes register here if they will produce sound even if they have silent
|
||||
// or no input connections. The AudioContext will keep registered nodes
|
||||
// alive until the context is collected. This takes care of "playing"
|
||||
// references and "tail-time" references.
|
||||
void RegisterActiveNode(AudioNode* aNode);
|
||||
// Nodes unregister when they have finished producing sound for the
|
||||
// foreseeable future.
|
||||
// Do NOT call UnregisterActiveNode from an AudioNode destructor.
|
||||
// If the destructor is called, then the Node has already been unregistered.
|
||||
// The destructor may be called during hashtable enumeration, during which
|
||||
// unregistering would not be safe.
|
||||
void UnregisterActiveNode(AudioNode* aNode);
|
||||
|
||||
void UnregisterAudioBufferSourceNode(AudioBufferSourceNode* aNode);
|
||||
void UnregisterPannerNode(PannerNode* aNode);
|
||||
void UnregisterOscillatorNode(OscillatorNode* aNode);
|
||||
@ -239,6 +254,9 @@ private:
|
||||
nsRefPtr<AudioListener> mListener;
|
||||
MediaBufferDecoder mDecoder;
|
||||
nsTArray<nsRefPtr<WebAudioDecodeJob> > mDecodeJobs;
|
||||
// See RegisterActiveNode. These will keep the AudioContext alive while it
|
||||
// is rendering and the window remains alive.
|
||||
nsTHashtable<nsRefPtrHashKey<AudioNode> > mActiveNodes;
|
||||
// Two hashsets containing all the PannerNodes and AudioBufferSourceNodes,
|
||||
// to compute the doppler shift, and also to stop AudioBufferSourceNodes.
|
||||
// These are all weak pointers.
|
||||
|
@ -102,9 +102,9 @@ private:
|
||||
* real-time processing and output of this AudioNode.
|
||||
*
|
||||
* We track the incoming and outgoing connections to other AudioNodes.
|
||||
* Outgoing connections have strong ownership. Also, AudioNodes add self
|
||||
* references if they produce sound on their output even when they have silent
|
||||
* or no input.
|
||||
* Outgoing connections have strong ownership. Also, AudioNodes that will
|
||||
* produce sound on their output even when they have silent or no input ask
|
||||
* the AudioContext to keep them alive until the context is finished.
|
||||
*/
|
||||
class AudioNode : public nsDOMEventTargetHelper,
|
||||
public EnableWebAudioCheck
|
||||
@ -213,6 +213,17 @@ public:
|
||||
|
||||
virtual void NotifyInputConnected() {}
|
||||
|
||||
// MarkActive() asks the context to keep the AudioNode alive until the
|
||||
// context is finished. This takes care of "playing" references and
|
||||
// "tail-time" references.
|
||||
void MarkActive() { Context()->RegisterActiveNode(this); }
|
||||
// Active nodes call MarkInactive() when they have finished producing sound
|
||||
// for the foreseeable future.
|
||||
// Do not call MarkInactive from a node destructor. If the destructor is
|
||||
// called, then the node is already inactive.
|
||||
// MarkInactive() may delete |this|.
|
||||
void MarkInactive() { Context()->UnregisterActiveNode(this); }
|
||||
|
||||
private:
|
||||
friend class AudioBufferSourceNode;
|
||||
// This could possibly delete 'this'.
|
||||
|
Loading…
Reference in New Issue
Block a user