зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1860954 don't store the graph lookup key in the graphs hashtable r=padenot,pehrsons
The necessary values for the lookup are now all in the graph itself. I suspect this would also be possible with nsTHashtable but HashSet is designed for a lookup class that differs from the stored class and requires less boilerplate. Depends on D191831 Differential Revision: https://phabricator.services.mozilla.com/D191832
This commit is contained in:
Родитель
9956d39635
Коммит
89c28e8c37
|
@ -120,29 +120,34 @@ namespace {
|
||||||
* A hash table containing the graph instances, one per Window ID,
|
* A hash table containing the graph instances, one per Window ID,
|
||||||
* sample rate, and device ID combination.
|
* sample rate, and device ID combination.
|
||||||
*/
|
*/
|
||||||
class GraphKey final {
|
struct GraphLookup final {
|
||||||
public:
|
HashNumber Hash() const {
|
||||||
GraphKey(uint64_t aWindowID, TrackRate aSampleRate,
|
|
||||||
CubebUtils::AudioDeviceID aOutputDeviceID)
|
|
||||||
: mWindowID(aWindowID),
|
|
||||||
mSampleRate(aSampleRate),
|
|
||||||
mOutputDeviceID(aOutputDeviceID) {}
|
|
||||||
GraphKey(const GraphKey&) = default;
|
|
||||||
~GraphKey() = default;
|
|
||||||
bool operator==(const GraphKey& b) const {
|
|
||||||
return mWindowID == b.mWindowID && mSampleRate == b.mSampleRate &&
|
|
||||||
mOutputDeviceID == b.mOutputDeviceID;
|
|
||||||
}
|
|
||||||
PLDHashNumber Hash() const {
|
|
||||||
return HashGeneric(mWindowID, mSampleRate, mOutputDeviceID);
|
return HashGeneric(mWindowID, mSampleRate, mOutputDeviceID);
|
||||||
}
|
}
|
||||||
|
const uint64_t mWindowID;
|
||||||
private:
|
const TrackRate mSampleRate;
|
||||||
uint64_t mWindowID;
|
const CubebUtils::AudioDeviceID mOutputDeviceID;
|
||||||
TrackRate mSampleRate;
|
|
||||||
CubebUtils::AudioDeviceID mOutputDeviceID;
|
|
||||||
};
|
};
|
||||||
nsTHashMap<nsGenericHashKey<GraphKey>, MediaTrackGraphImpl*> gGraphs;
|
|
||||||
|
struct GraphHasher { // for HashSet
|
||||||
|
using Lookup = const GraphLookup;
|
||||||
|
|
||||||
|
static HashNumber hash(const Lookup& aLookup) { return aLookup.Hash(); }
|
||||||
|
|
||||||
|
static bool match(const MediaTrackGraphImpl* aGraph, const Lookup& aLookup) {
|
||||||
|
return aGraph->mWindowID == aLookup.mWindowID &&
|
||||||
|
aGraph->GraphRate() == aLookup.mSampleRate &&
|
||||||
|
aGraph->mOutputDeviceID == aLookup.mOutputDeviceID;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// The weak reference to the graph is removed when its last track is removed.
|
||||||
|
using GraphHashSet =
|
||||||
|
HashSet<MediaTrackGraphImpl*, GraphHasher, InfallibleAllocPolicy>;
|
||||||
|
GraphHashSet* Graphs() {
|
||||||
|
static GraphHashSet sGraphs(4); // 4 is minimum HashSet capacity
|
||||||
|
return &sGraphs;
|
||||||
|
}
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
static void ApplyTrackDisabling(DisabledTrackMode aDisabledMode,
|
static void ApplyTrackDisabling(DisabledTrackMode aDisabledMode,
|
||||||
|
@ -3284,8 +3289,9 @@ MediaTrackGraphImpl* MediaTrackGraphImpl::GetInstanceIfExists(
|
||||||
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
|
||||||
MOZ_ASSERT(aSampleRate > 0);
|
MOZ_ASSERT(aSampleRate > 0);
|
||||||
|
|
||||||
GraphKey key(aWindowID, aSampleRate, aOutputDeviceID);
|
GraphHashSet::Ptr p =
|
||||||
return gGraphs.Get(key);
|
Graphs()->lookup({aWindowID, aSampleRate, aOutputDeviceID});
|
||||||
|
return p ? *p : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public method has an nsPIDOMWindowInner* parameter to ensure that the
|
// Public method has an nsPIDOMWindowInner* parameter to ensure that the
|
||||||
|
@ -3313,31 +3319,31 @@ MediaTrackGraphImpl* MediaTrackGraphImpl::GetInstance(
|
||||||
MOZ_ASSERT(aGraphDriverRequested != OFFLINE_THREAD_DRIVER,
|
MOZ_ASSERT(aGraphDriverRequested != OFFLINE_THREAD_DRIVER,
|
||||||
"Use CreateNonRealtimeInstance() for offline graphs");
|
"Use CreateNonRealtimeInstance() for offline graphs");
|
||||||
|
|
||||||
MediaTrackGraphImpl* graph =
|
GraphHashSet* graphs = Graphs();
|
||||||
GetInstanceIfExists(aWindowID, aSampleRate, aOutputDeviceID);
|
GraphHashSet::AddPtr addPtr =
|
||||||
|
graphs->lookupForAdd({aWindowID, aSampleRate, aOutputDeviceID});
|
||||||
if (!graph) {
|
if (addPtr) { // graph already exists
|
||||||
GraphRunType runType = DIRECT_DRIVER;
|
return *addPtr;
|
||||||
if (Preferences::GetBool("media.audiograph.single_thread.enabled", true)) {
|
|
||||||
runType = SINGLE_THREAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
// In a real time graph, the number of output channels is determined by
|
|
||||||
// the underlying number of channel of the default audio output device, and
|
|
||||||
// capped to 8.
|
|
||||||
uint32_t channelCount =
|
|
||||||
std::min<uint32_t>(8, CubebUtils::MaxNumberOfChannels());
|
|
||||||
graph = new MediaTrackGraphImpl(aGraphDriverRequested, runType, aWindowID,
|
|
||||||
aSampleRate, channelCount, aOutputDeviceID,
|
|
||||||
aMainThread);
|
|
||||||
GraphKey key(aWindowID, aSampleRate, aOutputDeviceID);
|
|
||||||
gGraphs.InsertOrUpdate(key, graph);
|
|
||||||
|
|
||||||
LOG(LogLevel::Debug,
|
|
||||||
("Starting up MediaTrackGraph %p for window 0x%" PRIx64, graph,
|
|
||||||
aWindowID));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GraphRunType runType = DIRECT_DRIVER;
|
||||||
|
if (Preferences::GetBool("media.audiograph.single_thread.enabled", true)) {
|
||||||
|
runType = SINGLE_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a real time graph, the number of output channels is determined by
|
||||||
|
// the underlying number of channel of the default audio output device, and
|
||||||
|
// capped to 8.
|
||||||
|
uint32_t channelCount =
|
||||||
|
std::min<uint32_t>(8, CubebUtils::MaxNumberOfChannels());
|
||||||
|
MediaTrackGraphImpl* graph = new MediaTrackGraphImpl(
|
||||||
|
aGraphDriverRequested, runType, aWindowID, aSampleRate, channelCount,
|
||||||
|
aOutputDeviceID, aMainThread);
|
||||||
|
MOZ_ALWAYS_TRUE(graphs->add(addPtr, graph));
|
||||||
|
|
||||||
|
LOG(LogLevel::Debug, ("Starting up MediaTrackGraph %p for window 0x%" PRIx64,
|
||||||
|
graph, aWindowID));
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3549,14 +3555,9 @@ void MediaTrackGraph::AddTrack(MediaTrack* aTrack) {
|
||||||
MediaTrackGraphImpl* graph = static_cast<MediaTrackGraphImpl*>(this);
|
MediaTrackGraphImpl* graph = static_cast<MediaTrackGraphImpl*>(this);
|
||||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||||
if (graph->mRealtime) {
|
if (graph->mRealtime) {
|
||||||
bool found = false;
|
GraphHashSet::Ptr p = Graphs()->lookup(
|
||||||
for (const auto& currentGraph : gGraphs.Values()) {
|
{graph->mWindowID, GraphRate(), graph->mOutputDeviceID});
|
||||||
if (currentGraph == graph) {
|
MOZ_DIAGNOSTIC_ASSERT(p, "Graph must not be shutting down");
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(found, "Graph must not be shutting down");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
NS_ADDREF(aTrack);
|
NS_ADDREF(aTrack);
|
||||||
|
@ -3574,12 +3575,11 @@ void MediaTrackGraphImpl::RemoveTrack(MediaTrack* aTrack) {
|
||||||
this, aTrack));
|
this, aTrack));
|
||||||
if (mRealtime) {
|
if (mRealtime) {
|
||||||
// Find the graph in the hash table and remove it.
|
// Find the graph in the hash table and remove it.
|
||||||
for (auto iter = gGraphs.Iter(); !iter.Done(); iter.Next()) {
|
GraphHashSet* graphs = Graphs();
|
||||||
if (iter.UserData() == this) {
|
GraphHashSet::Ptr p =
|
||||||
iter.Remove();
|
graphs->lookup({mWindowID, mSampleRate, mOutputDeviceID});
|
||||||
break;
|
MOZ_ASSERT(*p == this);
|
||||||
}
|
graphs->remove(p);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// The graph thread will shut itself down soon, but won't be able to do
|
// The graph thread will shut itself down soon, but won't be able to do
|
||||||
// that if JS continues to run.
|
// that if JS continues to run.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче