From 725d4195df78fa9efef29d4e162cdad1d69904a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 16 Mar 2023 11:53:39 +0100 Subject: [PATCH] Small cleanup of purging code --- GPU/Common/ReplacedTexture.cpp | 40 ++++++++++++++++++++++++---------- GPU/Common/ReplacedTexture.h | 6 ++--- GPU/Common/TextureReplacer.cpp | 2 +- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/GPU/Common/ReplacedTexture.cpp b/GPU/Common/ReplacedTexture.cpp index fc5c1cde43..ed4915e1cd 100644 --- a/GPU/Common/ReplacedTexture.cpp +++ b/GPU/Common/ReplacedTexture.cpp @@ -95,9 +95,6 @@ private: ReplacedTexture::ReplacedTexture(VFSBackend *vfs, const ReplacementDesc &desc) : vfs_(vfs), desc_(desc) { logId_ = desc.logId; - SetState(ReplacementState::POPULATED); - - // TODO: What used to be here is now done on the thread task. } ReplacedTexture::~ReplacedTexture() { @@ -115,19 +112,38 @@ ReplacedTexture::~ReplacedTexture() { } } -void ReplacedTexture::PurgeIfOlder(double t) { - if (threadWaitable_ && !threadWaitable_->WaitFor(0.0)) +void ReplacedTexture::PurgeIfNotUsedSinceTime(double t) { + if (State() != ReplacementState::ACTIVE) { return; - if (lastUsed_ >= t) + } + + // If there's some leftover threadWaitable, get rid of it. + if (threadWaitable_) { + if (threadWaitable_->WaitFor(0.0)) { + delete threadWaitable_; + threadWaitable_ = nullptr; + // Continue with purging. + } else { + // Try next time. + return; + } + } + + // "atomic-enough" to not lock? + if (lastUsed_ >= t) { return; + } std::lock_guard guard(lock_); - if (data_.size() && lastUsed < t) { - // We have to lock since multiple textures might reference this same data. - data_.clear(); - // This means we have to reload. If we never purge any, there's no need. - SetState(ReplacementState::POPULATED); - } + + // We have to lock since multiple textures might reference this same data. + data_.clear(); + levels_.clear(); + fmt = Draw::DataFormat::UNDEFINED; + alphaStatus_ = ReplacedTextureAlpha::UNKNOWN; + + // This means we have to reload. If we never purge any, there's no need. + SetState(ReplacementState::POPULATED); } // This can only return true if ACTIVE or NOT_FOUND. diff --git a/GPU/Common/ReplacedTexture.h b/GPU/Common/ReplacedTexture.h index 138494594c..4b6657fee2 100644 --- a/GPU/Common/ReplacedTexture.h +++ b/GPU/Common/ReplacedTexture.h @@ -170,19 +170,19 @@ private: void Prepare(VFSBackend *vfs); LoadLevelResult LoadLevelData(VFSFileReference *fileRef, const std::string &filename, int level, Draw::DataFormat *pixelFormat); - void PurgeIfOlder(double t); + void PurgeIfNotUsedSinceTime(double t); std::vector> data_; std::vector levels_; - ReplacedTextureAlpha alphaStatus_ = ReplacedTextureAlpha::UNKNOWN; double lastUsed_ = 0.0; LimitedWaitable *threadWaitable_ = nullptr; std::mutex lock_; Draw::DataFormat fmt = Draw::DataFormat::UNDEFINED; // NOTE: Right now, the only supported format is Draw::DataFormat::R8G8B8A8_UNORM. + ReplacedTextureAlpha alphaStatus_ = ReplacedTextureAlpha::UNKNOWN; double lastUsed = 0.0; - std::atomic state_ = ReplacementState::UNINITIALIZED; + std::atomic state_ = ReplacementState::POPULATED; VFSBackend *vfs_ = nullptr; ReplacementDesc desc_; diff --git a/GPU/Common/TextureReplacer.cpp b/GPU/Common/TextureReplacer.cpp index c2a7394709..432cf51c07 100644 --- a/GPU/Common/TextureReplacer.cpp +++ b/GPU/Common/TextureReplacer.cpp @@ -746,7 +746,7 @@ void TextureReplacer::Decimate(ReplacerDecimateMode mode) { size_t totalSize = 0; for (auto &item : levelCache_) { std::lock_guard guard(item.second->lock_); - item.second->PurgeIfOlder(threshold); + item.second->PurgeIfNotUsedSinceTime(threshold); totalSize += item.second->GetTotalDataSize(); // TODO: Make something better. // don't actually delete the items here, just clean out the data. }