From 30bd0e60c7c3a60433ef16f09dbfc5d649907673 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 15 Feb 2021 18:04:11 -0800 Subject: [PATCH] UI: Avoid audio locks where possible. In case of thread contention, avoid locking if not necessary. See #13469. --- UI/BackgroundAudio.cpp | 43 +++++++++++++++++++++--------------------- UI/BackgroundAudio.h | 7 +++++-- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/UI/BackgroundAudio.cpp b/UI/BackgroundAudio.cpp index 7d6ff7732e..809993d5b4 100644 --- a/UI/BackgroundAudio.cpp +++ b/UI/BackgroundAudio.cpp @@ -248,6 +248,7 @@ BackgroundAudio g_BackgroundAudio; BackgroundAudio::BackgroundAudio() { buffer = new int[BUFSIZE](); + sndLoadPending_.store(false); } BackgroundAudio::~BackgroundAudio() { @@ -308,21 +309,24 @@ void BackgroundAudio::Clear(bool hard) { at3Reader_ = nullptr; } playbackOffset_ = 0; + sndLoadPending_ = false; } void BackgroundAudio::SetGame(const std::string &path) { - std::lock_guard lock(mutex_); if (path == bgGamePath_) { // Do nothing return; } - if (path.size() == 0) { + std::lock_guard lock(mutex_); + if (path.empty()) { Clear(false); + sndLoadPending_ = false; fadingOut_ = true; } else { Clear(true); gameLastChanged_ = time_now_d(); + sndLoadPending_ = true; fadingOut_ = false; } volume_ = 1.0f; @@ -397,27 +401,24 @@ int BackgroundAudio::Play() { void BackgroundAudio::Update() { // If there's a game, and some time has passed since the selected game // last changed... (to prevent crazy amount of reads when skipping through a list) - if (bgGamePath_.size() && (time_now_d() - gameLastChanged_ > 0.5)) { + if (sndLoadPending_ && (time_now_d() - gameLastChanged_ > 0.5)) { std::lock_guard lock(mutex_); - if (!at3Reader_) { - // Grab some audio from the current game and play it. - if (!g_gameInfoCache) - return; + // Already loaded somehow? Or no game info cache? + if (at3Reader_ || !g_gameInfoCache) + return; - std::shared_ptr gameInfo = g_gameInfoCache->GetInfo(NULL, bgGamePath_, GAMEINFO_WANTSND); - if (!gameInfo) - return; - - if (gameInfo->pending) { - // Should try again shortly.. - return; - } - - if (gameInfo->sndFileData.size()) { - const std::string &data = gameInfo->sndFileData; - at3Reader_ = new AT3PlusReader(data); - lastPlaybackTime_ = 0.0; - } + // Grab some audio from the current game and play it. + std::shared_ptr gameInfo = g_gameInfoCache->GetInfo(nullptr, bgGamePath_, GAMEINFO_WANTSND); + if (!gameInfo || gameInfo->pending) { + // Should try again shortly.. + return; } + + const std::string &data = gameInfo->sndFileData; + if (!data.empty()) { + at3Reader_ = new AT3PlusReader(data); + lastPlaybackTime_ = 0.0; + } + sndLoadPending_ = false; } } diff --git a/UI/BackgroundAudio.h b/UI/BackgroundAudio.h index fb572f52a7..d8c1ba18e6 100644 --- a/UI/BackgroundAudio.h +++ b/UI/BackgroundAudio.h @@ -1,7 +1,8 @@ #pragma once -#include +#include #include +#include #include #include "Common/UI/Root.h" @@ -13,7 +14,6 @@ public: BackgroundAudio(); ~BackgroundAudio(); - void Clear(bool hard); void SetGame(const std::string &path); void Update(); int Play(); @@ -22,12 +22,15 @@ public: void PlaySFX(UI::UISound sfx); private: + void Clear(bool hard); + enum { BUFSIZE = 44100, }; std::mutex mutex_; std::string bgGamePath_; + std::atomic sndLoadPending_; int playbackOffset_ = 0; AT3PlusReader *at3Reader_; double gameLastChanged_ = 0.0;