diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index c4199b5d37..a5df130c04 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -59,15 +59,33 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() { return NULL; } -bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, unsigned int frame) { - // this is symmetric over self / node; they cache their computations to reduce work by 2x +void AudioMixerClientData::IgnoreNodeData::cache(bool shouldIgnore) { + // do not reset the cache until it has been used, to avoid a data race + if (!_flag) { + _ignore = shouldIgnore; + _flag = true; + } +} - auto& localCache = _nodeSourcesIgnoreMap[node->getUUID()]; - if (localCache.isCached) { - assert(localCache.isCached.is_lock_free()); - bool shouldIgnore = localCache.shouldIgnore; - localCache.isCached = false; - return shouldIgnore; +bool AudioMixerClientData::IgnoreNodeData::isCached() { + assert(_flag.is_lock_free()); + return _flag; +} + +bool AudioMixerClientData::IgnoreNodeData::shouldIgnore() { + // do not reset the cache until it has been used, to avoid a data race + bool ignore = _ignore; + _flag = false; + return ignore; +} + +bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, unsigned int frame) { + // this is symmetric over self / node; if computed, it is cached in the other + + // check the cache to avoid computation + auto& cache = _nodeSourcesIgnoreMap[node->getUUID()]; + if (cache.isCached()) { + return cache.shouldIgnore(); } AudioMixerClientData* nodeData = static_cast(node->getLinkedData()); @@ -93,12 +111,8 @@ bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const Shar } } - auto& remoteCache = nodeData->_nodeSourcesIgnoreMap[self->getUUID()]; - // do not reset the cache until it has been used to avoid a data race - if (!remoteCache.isCached) { - remoteCache.shouldIgnore = shouldIgnore; - remoteCache.isCached = true; - } + // cache in node + nodeData->_nodeSourcesIgnoreMap[self->getUUID()].cache(shouldIgnore); return shouldIgnore; } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 75cfa7ff18..1cfc476b43 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -124,9 +124,14 @@ private: }; IgnoreZoneMemo _ignoreZoneMemo; - struct IgnoreNodeData { - std::atomic isCached { false }; - bool shouldIgnore { false }; + class IgnoreNodeData { + public: + void cache(bool shouldIgnore); + bool isCached(); + bool shouldIgnore(); + private: + std::atomic _flag { false }; + bool _ignore { false }; }; using NodeSourcesIgnoreMap = std::unordered_map; NodeSourcesIgnoreMap _nodeSourcesIgnoreMap;