-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
CustomAssetLoader.cpp
105 lines (91 loc) · 3.21 KB
/
CustomAssetLoader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2023 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoCommon/GraphicsModSystem/Runtime/CustomAssetLoader.h"
#include "Common/Logging/Log.h"
#include "Common/MemoryUtil.h"
#include "Common/StringUtil.h"
#include "VideoCommon/GraphicsModSystem/Runtime/CustomAssetLibrary.h"
namespace VideoCommon
{
void CustomAssetLoader::Init()
{
m_file_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_file_monitor_thread = std::thread([this]() {
Common::SetCurrentThreadName("File monitor");
while (true)
{
if (m_file_monitor_thread_shutdown.IsSet())
{
break;
}
std::this_thread::sleep_for(TIME_BETWEEN_FILE_MONITOR_CHECKS);
std::lock_guard lk(m_files_lock);
for (auto& [path, file_to_monitor] : m_files_to_monitor)
{
if (auto ptr = file_to_monitor.m_asset.lock())
{
auto write_time = std::filesystem::last_write_time(path);
if (write_time > file_to_monitor.m_cached_write_time)
{
file_to_monitor.m_cached_write_time = write_time;
ptr->Unload(&m_stats);
(void)ptr->Load(&m_stats);
}
}
}
}
});
m_asset_load_thread.Reset("Custom Asset Loader", [this](std::weak_ptr<CustomAsset> asset) {
if (auto ptr = asset.lock())
{
if (ptr->Load(&m_stats))
{
if (m_max_memory_available >= m_total_bytes_loaded + ptr->GetBytesLoaded())
{
m_total_bytes_loaded += ptr->GetBytesLoaded();
auto monitor_id = ptr->GetOwningLibrary()->GetMonitorId(ptr->GetAssetId());
std::lock_guard lk(m_files_lock);
m_files_to_monitor.try_emplace(
monitor_id, FileMonitorInfo{std::filesystem::last_write_time(monitor_id), ptr});
}
else
{
ERROR_LOG_FMT(VIDEO, "Failed to load asset {} because there was not enough memory.",
PathToString(ptr->GetAssetId()));
ptr->Unload(&m_stats);
}
}
}
});
}
void CustomAssetLoader ::Shutdown()
{
m_asset_load_thread.Shutdown(true);
m_file_monitor_thread_shutdown.Set();
m_file_monitor_thread.join();
m_files_to_monitor.clear();
m_total_bytes_loaded = 0;
m_stats.Reset();
}
std::shared_ptr<CustomTextureAsset>
CustomAssetLoader::LoadTexture(const std::filesystem::path& texture_path,
std::shared_ptr<CustomAssetLibrary> library)
{
return Load<CustomTextureAsset>(texture_path, m_textures, std::move(library));
}
std::shared_ptr<CustomGameTextureAsset>
CustomAssetLoader::LoadGameTexture(const std::filesystem::path& texture_path,
std::shared_ptr<CustomAssetLibrary> library)
{
return Load<CustomGameTextureAsset>(texture_path, m_game_textures, std::move(library));
}
const CustomAssetLoaderStats* CustomAssetLoader::GetStats() const
{
return &m_stats;
}
} // namespace VideoCommon