summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
diff options
context:
space:
mode:
authoriwubcode <iwubcode@users.noreply.github.com>2023-06-02 14:43:28 -0500
committeriwubcode <iwubcode@users.noreply.github.com>2023-06-02 17:31:31 -0500
commitc93940c6ee8194fa48663b9bcd0f153c9d72a3ea (patch)
treececac7e393819059a0e1ffbc4ce723b6969bac72 /Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
parent4ee27404eeeb30e8f6a8a20be92d21cb6c96e8e4 (diff)
VideoCommon: add multithreaded asset loader and define a texture asset
Diffstat (limited to 'Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp')
-rw-r--r--Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp93
1 files changed, 93 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
new file mode 100644
index 0000000000..d2189e655b
--- /dev/null
+++ b/Source/Core/VideoCommon/Assets/CustomAssetLoader.cpp
@@ -0,0 +1,93 @@
+// Copyright 2023 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "VideoCommon/Assets/CustomAssetLoader.h"
+
+#include "Common/Logging/Log.h"
+#include "Common/MemoryUtil.h"
+#include "VideoCommon/Assets/CustomAssetLibrary.h"
+
+namespace VideoCommon
+{
+void CustomAssetLoader::Init()
+{
+ m_asset_monitor_thread_shutdown.Clear();
+
+ const size_t sys_mem = Common::MemPhysical();
+ const size_t recommended_min_mem = 2 * size_t(1024 * 1024 * 1024);
+ // keep 2GB memory for system stability if system RAM is 4GB+ - use half of memory in other cases
+ m_max_memory_available =
+ (sys_mem / 2 < recommended_min_mem) ? (sys_mem / 2) : (sys_mem - recommended_min_mem);
+
+ m_asset_monitor_thread = std::thread([this]() {
+ Common::SetCurrentThreadName("Asset monitor");
+ while (true)
+ {
+ if (m_asset_monitor_thread_shutdown.IsSet())
+ {
+ break;
+ }
+
+ std::this_thread::sleep_for(TIME_BETWEEN_ASSET_MONITOR_CHECKS);
+
+ std::lock_guard lk(m_assets_lock);
+ for (auto& [asset_id, asset_to_monitor] : m_assets_to_monitor)
+ {
+ if (auto ptr = asset_to_monitor.lock())
+ {
+ const auto write_time = ptr->GetLastWriteTime();
+ if (write_time > ptr->GetLastLoadedTime())
+ {
+ (void)ptr->Load();
+ }
+ }
+ }
+ }
+ });
+
+ m_asset_load_thread.Reset("Custom Asset Loader", [this](std::weak_ptr<CustomAsset> asset) {
+ if (auto ptr = asset.lock())
+ {
+ if (ptr->Load())
+ {
+ if (m_max_memory_available >= m_total_bytes_loaded + ptr->GetByteSizeInMemory())
+ {
+ m_total_bytes_loaded += ptr->GetByteSizeInMemory();
+
+ std::lock_guard lk(m_assets_lock);
+ m_assets_to_monitor.try_emplace(ptr->GetAssetId(), ptr);
+ }
+ else
+ {
+ ERROR_LOG_FMT(VIDEO, "Failed to load asset {} because there was not enough memory.",
+ ptr->GetAssetId());
+ }
+ }
+ }
+ });
+}
+
+void CustomAssetLoader ::Shutdown()
+{
+ m_asset_load_thread.Shutdown(true);
+
+ m_asset_monitor_thread_shutdown.Set();
+ m_asset_monitor_thread.join();
+ m_assets_to_monitor.clear();
+ m_total_bytes_loaded = 0;
+}
+
+std::shared_ptr<RawTextureAsset>
+CustomAssetLoader::LoadTexture(const CustomAssetLibrary::AssetID& asset_id,
+ std::shared_ptr<CustomAssetLibrary> library)
+{
+ return LoadOrCreateAsset<RawTextureAsset>(asset_id, m_textures, std::move(library));
+}
+
+std::shared_ptr<GameTextureAsset>
+CustomAssetLoader::LoadGameTexture(const CustomAssetLibrary::AssetID& asset_id,
+ std::shared_ptr<CustomAssetLibrary> library)
+{
+ return LoadOrCreateAsset<GameTextureAsset>(asset_id, m_game_textures, std::move(library));
+}
+} // namespace VideoCommon