diff options
| author | Admiral H. Curtiss <pikachu025@gmail.com> | 2023-06-03 12:24:02 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-03 12:24:02 +0200 |
| commit | 3245786af7ca5d1ea7c4ef4f71aea07f5d7bf7da (patch) | |
| tree | 73c44ea37bcc5becd5fbc7545659b6266a0b48de /Source/Core/VideoCommon | |
| parent | d03e09c8fd911d1b4e66184ceedbeca989b75a0c (diff) | |
| parent | 58d383b30b65e0e23f85e6a3a1bc5670966575eb (diff) | |
Merge pull request #11880 from iwubcode/race_condition_asset
VideoCommon: prevent potential data issue when reloading Asset data
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/Assets/CustomAsset.h | 8 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Assets/TextureAsset.cpp | 12 |
2 files changed, 14 insertions, 6 deletions
diff --git a/Source/Core/VideoCommon/Assets/CustomAsset.h b/Source/Core/VideoCommon/Assets/CustomAsset.h index d3ba5226da..1f4d5061c1 100644 --- a/Source/Core/VideoCommon/Assets/CustomAsset.h +++ b/Source/Core/VideoCommon/Assets/CustomAsset.h @@ -64,7 +64,11 @@ class CustomLoadableAsset : public CustomAsset public: using CustomAsset::CustomAsset; - const UnderlyingType* GetData() const + // Callees should understand that the type returned is + // a local copy and 'GetData()' needs to be called + // to ensure the latest copy is available if + // they want to handle reloads + [[nodiscard]] std::shared_ptr<UnderlyingType> GetData() const { std::lock_guard lk(m_lock); if (m_loaded) @@ -75,7 +79,7 @@ public: protected: bool m_loaded = false; mutable std::mutex m_lock; - UnderlyingType m_data; + std::shared_ptr<UnderlyingType> m_data; }; } // namespace VideoCommon diff --git a/Source/Core/VideoCommon/Assets/TextureAsset.cpp b/Source/Core/VideoCommon/Assets/TextureAsset.cpp index fd27ee80b6..21f897fc19 100644 --- a/Source/Core/VideoCommon/Assets/TextureAsset.cpp +++ b/Source/Core/VideoCommon/Assets/TextureAsset.cpp @@ -10,20 +10,24 @@ namespace VideoCommon CustomAssetLibrary::LoadInfo RawTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) { std::lock_guard lk(m_lock); - const auto loaded_info = m_owning_library->LoadTexture(asset_id, &m_data); + auto potential_data = std::make_shared<CustomTextureData>(); + const auto loaded_info = m_owning_library->LoadTexture(asset_id, potential_data.get()); if (loaded_info.m_bytes_loaded == 0) return {}; m_loaded = true; + m_data = std::move(potential_data); return loaded_info; } CustomAssetLibrary::LoadInfo GameTextureAsset::LoadImpl(const CustomAssetLibrary::AssetID& asset_id) { std::lock_guard lk(m_lock); - const auto loaded_info = m_owning_library->LoadGameTexture(asset_id, &m_data); + auto potential_data = std::make_shared<CustomTextureData>(); + const auto loaded_info = m_owning_library->LoadGameTexture(asset_id, potential_data.get()); if (loaded_info.m_bytes_loaded == 0) return {}; m_loaded = true; + m_data = std::move(potential_data); return loaded_info; } @@ -39,7 +43,7 @@ bool GameTextureAsset::Validate(u32 native_width, u32 native_height) const return false; } - if (m_data.m_levels.empty()) + if (m_data->m_levels.empty()) { ERROR_LOG_FMT(VIDEO, "Game texture can't be validated for asset '{}' because no data was available.", @@ -49,7 +53,7 @@ bool GameTextureAsset::Validate(u32 native_width, u32 native_height) const // Verify that the aspect ratio of the texture hasn't changed, as this could have // side-effects. - const VideoCommon::CustomTextureData::Level& first_mip = m_data.m_levels[0]; + const VideoCommon::CustomTextureData::Level& first_mip = m_data->m_levels[0]; if (first_mip.width * native_height != first_mip.height * native_width) { ERROR_LOG_FMT( |
