Bug 1291702 - Refactor the input node iteration loop on destination node when disconnecting nodes. r=karlt

MozReview-Commit-ID: FE19hEVhA7R
This commit is contained in:
Paul Adenot 2016-09-09 13:41:01 +02:00
Родитель fd13f2e7a3
Коммит 5424c454d0
2 изменённых файлов: 71 добавлений и 65 удалений

Просмотреть файл

@ -292,12 +292,12 @@ AudioNode::SendChannelMixingParametersToStream()
} }
bool bool
AudioNode::DisconnectFromOutputIfConnected(AudioNode& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex) AudioNode::DisconnectFromOutputIfConnected(AudioNode& aDestination, uint32_t aOutputNodeIndex, uint32_t aInputIndex)
{ {
WEB_AUDIO_API_LOG("%f: %s %u Disconnect()", Context()->CurrentTime(), WEB_AUDIO_API_LOG("%f: %s %u Disconnect()", Context()->CurrentTime(),
NodeType(), Id()); NodeType(), Id());
MOZ_ASSERT(aOutputIndex < mOutputNodes.Length()); MOZ_ASSERT(aOutputNodeIndex < mOutputNodes.Length());
MOZ_ASSERT(aInputIndex < aDestination.InputNodes().Length()); MOZ_ASSERT(aInputIndex < aDestination.InputNodes().Length());
// An upstream node may be starting to play on the graph thread, and the // An upstream node may be starting to play on the graph thread, and the
@ -332,8 +332,8 @@ AudioNode::DisconnectFromOutputIfConnected(AudioNode& aDestination, uint32_t aOu
// Remove one instance of 'dest' from mOutputNodes. There could be // Remove one instance of 'dest' from mOutputNodes. There could be
// others, and it's not correct to remove them all since some of them // others, and it's not correct to remove them all since some of them
// could be for different output ports. // could be for different output ports.
RefPtr<AudioNode> output = mOutputNodes[aOutputIndex].forget(); RefPtr<AudioNode> output = mOutputNodes[aOutputNodeIndex].forget();
mOutputNodes.RemoveElementAt(aOutputIndex); mOutputNodes.RemoveElementAt(aOutputNodeIndex);
output->NotifyInputsChanged(); output->NotifyInputsChanged();
if (mStream) { if (mStream) {
nsCOMPtr<nsIRunnable> runnable = new RunnableRelease(output.forget()); nsCOMPtr<nsIRunnable> runnable = new RunnableRelease(output.forget());
@ -343,9 +343,9 @@ AudioNode::DisconnectFromOutputIfConnected(AudioNode& aDestination, uint32_t aOu
} }
bool bool
AudioNode::DisconnectFromParamIfConnected(AudioParam& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex) AudioNode::DisconnectFromOutputIfConnected(AudioParam& aDestination, uint32_t aOutputParamIndex, uint32_t aInputIndex)
{ {
MOZ_ASSERT(aOutputIndex < mOutputParams.Length()); MOZ_ASSERT(aOutputParamIndex < mOutputParams.Length());
MOZ_ASSERT(aInputIndex < aDestination.InputNodes().Length()); MOZ_ASSERT(aInputIndex < aDestination.InputNodes().Length());
const InputNode& input = aDestination.InputNodes()[aInputIndex]; const InputNode& input = aDestination.InputNodes()[aInputIndex];
@ -356,29 +356,42 @@ AudioNode::DisconnectFromParamIfConnected(AudioParam& aDestination, uint32_t aOu
// Remove one instance of 'dest' from mOutputParams. There could be // Remove one instance of 'dest' from mOutputParams. There could be
// others, and it's not correct to remove them all since some of them // others, and it's not correct to remove them all since some of them
// could be for different output ports. // could be for different output ports.
mOutputParams.RemoveElementAt(aOutputIndex); mOutputParams.RemoveElementAt(aOutputParamIndex);
return true; return true;
} }
template<typename DestinationType, typename Predicate>
bool
AudioNode::DisconnectMatchingDestinationInputs(DestinationType& aDestination,
uint32_t aDestinationIndex,
Predicate aPredicate)
{
bool wasConnected = false;
for (int32_t inputIndex = aDestination.InputNodes().Length() - 1; inputIndex >= 0; --inputIndex) {
const InputNode& input = aDestination.InputNodes()[inputIndex];
if (aPredicate(input)) {
if (DisconnectFromOutputIfConnected(aDestination, aDestinationIndex, inputIndex)) {
wasConnected = true;
break;
}
}
}
return wasConnected;
}
void void
AudioNode::Disconnect(ErrorResult& aRv) AudioNode::Disconnect(ErrorResult& aRv)
{ {
for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) {
AudioNode* dest = mOutputNodes[outputIndex]; AudioNode* dest = mOutputNodes[outputIndex];
for (int32_t inputIndex = dest->mInputNodes.Length() - 1; inputIndex >= 0; --inputIndex) { DisconnectMatchingDestinationInputs(*dest, outputIndex,
if (DisconnectFromOutputIfConnected(*dest, outputIndex, inputIndex)) { [](const InputNode&) { return true; });
break;
}
}
} }
for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) {
AudioParam* dest = mOutputParams[outputIndex]; AudioParam* dest = mOutputParams[outputIndex];
for (int32_t inputIndex = dest->InputNodes().Length() - 1; inputIndex >= 0; --inputIndex) { DisconnectMatchingDestinationInputs(*dest, outputIndex,
if (DisconnectFromParamIfConnected(*dest, outputIndex, inputIndex)) { [](const InputNode&) { return true; });
break;
}
}
} }
// This disconnection may have disconnected a panner and a source. // This disconnection may have disconnected a panner and a source.
@ -395,26 +408,18 @@ AudioNode::Disconnect(uint32_t aOutput, ErrorResult& aRv)
for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) {
AudioNode* dest = mOutputNodes[outputIndex]; AudioNode* dest = mOutputNodes[outputIndex];
for (int32_t inputIndex = dest->mInputNodes.Length() - 1; inputIndex >= 0; --inputIndex) { DisconnectMatchingDestinationInputs(*dest, outputIndex,
InputNode& input = dest->mInputNodes[inputIndex]; [aOutput](const InputNode& aInput) {
if (input.mOutputPort == aOutput) { return aInput.mOutputPort == aOutput;
if (DisconnectFromOutputIfConnected(*dest, outputIndex, inputIndex)) { });
break;
}
}
}
} }
for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) {
AudioParam* dest = mOutputParams[outputIndex]; AudioParam* dest = mOutputParams[outputIndex];
for (int32_t inputIndex = dest->InputNodes().Length() - 1; inputIndex >= 0; --inputIndex) { DisconnectMatchingDestinationInputs(*dest, outputIndex,
const InputNode& input = dest->InputNodes()[inputIndex]; [aOutput](const InputNode& aInput) {
if (input.mOutputPort == aOutput) { return aInput.mOutputPort == aOutput;
if (DisconnectFromParamIfConnected(*dest, outputIndex, inputIndex)) { });
break;
}
}
}
} }
// This disconnection may have disconnected a panner and a source. // This disconnection may have disconnected a panner and a source.
@ -455,15 +460,11 @@ AudioNode::Disconnect(AudioNode& aDestination, uint32_t aOutput, ErrorResult& aR
bool wasConnected = false; bool wasConnected = false;
for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) {
for (int32_t inputIndex = aDestination.mInputNodes.Length() - 1; inputIndex >= 0; --inputIndex) { wasConnected |=
InputNode& input = aDestination.mInputNodes[inputIndex]; DisconnectMatchingDestinationInputs(aDestination, outputIndex,
if (input.mOutputPort == aOutput) { [aOutput](const InputNode& aInput) {
if (DisconnectFromOutputIfConnected(aDestination, outputIndex, inputIndex)) { return aInput.mOutputPort == aOutput;
wasConnected = true; });
break;
}
}
}
} }
if (!wasConnected) { if (!wasConnected) {
@ -491,13 +492,12 @@ AudioNode::Disconnect(AudioNode& aDestination, uint32_t aOutput, uint32_t aInput
bool wasConnected = false; bool wasConnected = false;
for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputNodes.Length() - 1; outputIndex >= 0; --outputIndex) {
for (int32_t inputIndex = aDestination.mInputNodes.Length() - 1; inputIndex >= 0; --inputIndex) { wasConnected |=
InputNode& input = aDestination.mInputNodes[inputIndex]; DisconnectMatchingDestinationInputs(aDestination, outputIndex,
if (input.mOutputPort == aOutput && input.mInputPort == aInput) { [aOutput, aInput](const InputNode& aInputNode) {
wasConnected |= DisconnectFromOutputIfConnected(aDestination, outputIndex, inputIndex); return aInputNode.mOutputPort == aOutput &&
break; aInputNode.mInputPort == aInput;
} });
}
} }
if (!wasConnected) { if (!wasConnected) {
@ -515,12 +515,9 @@ AudioNode::Disconnect(AudioParam& aDestination, ErrorResult& aRv)
bool wasConnected = false; bool wasConnected = false;
for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) {
for (int32_t inputIndex = aDestination.InputNodes().Length() - 1; inputIndex >= 0; --inputIndex) { wasConnected |=
if (DisconnectFromParamIfConnected(aDestination, outputIndex, inputIndex)) { DisconnectMatchingDestinationInputs(aDestination, outputIndex,
wasConnected = true; [](const InputNode&) { return true; });
break;
}
}
} }
if (!wasConnected) { if (!wasConnected) {
@ -540,15 +537,11 @@ AudioNode::Disconnect(AudioParam& aDestination, uint32_t aOutput, ErrorResult& a
bool wasConnected = false; bool wasConnected = false;
for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) { for (int32_t outputIndex = mOutputParams.Length() - 1; outputIndex >= 0; --outputIndex) {
for (int32_t inputIndex = aDestination.InputNodes().Length() - 1; inputIndex >= 0; --inputIndex) { wasConnected |=
const InputNode& input = aDestination.InputNodes()[inputIndex]; DisconnectMatchingDestinationInputs(aDestination, outputIndex,
if (input.mOutputPort == aOutput) { [aOutput](const InputNode& aNode) {
if (DisconnectFromParamIfConnected(aDestination, outputIndex, inputIndex)) { return aNode.mOutputPort == aOutput;
wasConnected = true; });
break;
}
}
}
} }
if (!wasConnected) { if (!wasConnected) {

Просмотреть файл

@ -222,6 +222,19 @@ public:
virtual const char* NodeType() const = 0; virtual const char* NodeType() const = 0;
private: private:
// Given:
//
// - a DestinationType, that can be an AudioNode or an AudioParam ;
// - a Predicate, a function that takes an InputNode& and returns a bool ;
//
// This method iterates on the InputNodes() of aDestination, and calls
// `DisconnectFromOutputIfConnected` with this input node, if aPredicate
// returns true.
template<typename DestinationType, typename Predicate>
bool DisconnectMatchingDestinationInputs(DestinationType& aDestination,
uint32_t aDestinationIndex,
Predicate aPredicate);
virtual void LastRelease() override virtual void LastRelease() override
{ {
// We are about to be deleted, disconnect the object from the graph before // We are about to be deleted, disconnect the object from the graph before
@ -231,7 +244,7 @@ private:
// Callers must hold a reference to 'this'. // Callers must hold a reference to 'this'.
void DisconnectFromGraph(); void DisconnectFromGraph();
bool DisconnectFromOutputIfConnected(AudioNode& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex); bool DisconnectFromOutputIfConnected(AudioNode& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex);
bool DisconnectFromParamIfConnected(AudioParam& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex); bool DisconnectFromOutputIfConnected(AudioParam& aDestination, uint32_t aOutputIndex, uint32_t aInputIndex);
protected: protected:
// Helpers for sending different value types to streams // Helpers for sending different value types to streams