From 2d14dc49f7d95b11242dad9074e9558d8e6c372e Mon Sep 17 00:00:00 2001 From: luc-git <102831178+luc-git@users.noreply.github.com> Date: Fri, 28 Apr 2023 21:47:49 +0200 Subject: [PATCH] Add a loading screen for the preloading textures *The PreloadTextures() function is called from the EmuThread to prevent citra to freezing *Add a the preloading textures loadingscreen in loading_screen.cpp *Add custom_tex_manager.reset() in core.cpp to release ram memory after exiting a game --- src/citra_qt/bootmanager.cpp | 9 ++++++++- src/citra_qt/bootmanager.h | 2 ++ src/citra_qt/loading_screen.cpp | 6 +++++- src/core/core.cpp | 4 +--- src/video_core/custom_textures/custom_tex_manager.cpp | 11 ++++++++++- src/video_core/custom_textures/custom_tex_manager.h | 4 +++- src/video_core/rasterizer_interface.h | 1 + 7 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index b13169bcd..d63ae36b9 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -60,10 +60,17 @@ static GMainWindow* GetMainWindow() { void EmuThread::run() { MicroProfileOnThreadCreate("EmuThread"); const auto scope = core_context.Acquire(); + Core::System& system = Core::System::GetInstance(); + + if (Settings::values.preload_textures) { + emit LoadProgress(VideoCore::LoadCallbackStage::Preload, 0, 0); + system.CustomTexManager().PreloadTextures( + stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, + std::size_t total) { emit LoadProgress(stage, value, total); }); + } emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0); - Core::System& system = Core::System::GetInstance(); system.Renderer().Rasterizer()->LoadDiskResources( stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { emit LoadProgress(stage, value, total); diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index f0019886d..838c4e2a1 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h @@ -12,6 +12,7 @@ #include #include "core/core.h" #include "core/frontend/emu_window.h" +#include "video_core/custom_textures/custom_tex_manager.h" class QKeyEvent; class QTouchEvent; @@ -79,6 +80,7 @@ private: std::atomic stop_run{false}; std::mutex running_mutex; std::condition_variable running_cv; + std::size_t number_textures; Frontend::GraphicsContext& core_context; diff --git a/src/citra_qt/loading_screen.cpp b/src/citra_qt/loading_screen.cpp index 7b9537ac9..41f25f450 100644 --- a/src/citra_qt/loading_screen.cpp +++ b/src/citra_qt/loading_screen.cpp @@ -62,6 +62,8 @@ QProgressBar::chunk { // Definitions for the differences in text and styling for each stage const static std::unordered_map stage_translations{ {VideoCore::LoadCallbackStage::Prepare, QT_TRANSLATE_NOOP("LoadingScreen", "Loading...")}, + {VideoCore::LoadCallbackStage::Preload, + QT_TRANSLATE_NOOP("LoadingScreen", "Preloading Textures %1 / %2")}, {VideoCore::LoadCallbackStage::Decompile, QT_TRANSLATE_NOOP("LoadingScreen", "Preparing Shaders %1 / %2")}, {VideoCore::LoadCallbackStage::Build, @@ -70,6 +72,7 @@ const static std::unordered_map stage }; const static std::unordered_map progressbar_style{ {VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE}, + {VideoCore::LoadCallbackStage::Preload, PROGRESSBAR_STYLE_BUILD}, {VideoCore::LoadCallbackStage::Decompile, PROGRESSBAR_STYLE_DECOMPILE}, {VideoCore::LoadCallbackStage::Build, PROGRESSBAR_STYLE_BUILD}, {VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE}, @@ -186,7 +189,8 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size // update labels and progress bar const auto& stg = tr(stage_translations.at(stage)); if (stage == VideoCore::LoadCallbackStage::Decompile || - stage == VideoCore::LoadCallbackStage::Build) { + stage == VideoCore::LoadCallbackStage::Build || + stage == VideoCore::LoadCallbackStage::Preload) { ui->stage->setText(stg.arg(value).arg(total)); } else { ui->stage->setText(stg); diff --git a/src/core/core.cpp b/src/core/core.cpp index b1dc1622f..c1c5a0ebe 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -323,9 +323,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st if (Settings::values.custom_textures) { custom_tex_manager->FindCustomTextures(); } - if (Settings::values.preload_textures) { - custom_tex_manager->PreloadTextures(); - } if (Settings::values.dump_textures) { custom_tex_manager->WriteConfig(); } @@ -554,6 +551,7 @@ void System::Shutdown(bool is_deserializing) { cheat_engine.reset(); app_loader.reset(); } + custom_tex_manager.reset(); telemetry_session.reset(); rpc_server.reset(); archive_manager.reset(); diff --git a/src/video_core/custom_textures/custom_tex_manager.cpp b/src/video_core/custom_textures/custom_tex_manager.cpp index 62962892d..6afd54ac4 100644 --- a/src/video_core/custom_textures/custom_tex_manager.cpp +++ b/src/video_core/custom_textures/custom_tex_manager.cpp @@ -190,8 +190,10 @@ void CustomTexManager::WriteConfig() { file.WriteString(output); } -void CustomTexManager::PreloadTextures() { +void CustomTexManager::PreloadTextures(const std::atomic_bool& stop_run, + const VideoCore::DiskResourceLoadCallback& callback) { u64 size_sum = 0; + size_t preloaded = 0; const u64 sys_mem = Common::GetMemInfo().total_physical_memory; const u64 recommended_min_mem = 2 * size_t(1024 * 1024 * 1024); @@ -206,8 +208,15 @@ void CustomTexManager::PreloadTextures() { LOG_WARNING(Render, "Aborting texture preload due to insufficient memory"); return; } + if (stop_run) { + return; + } material->LoadFromDisk(flip_png_files); size_sum += material->size; + if (callback) { + callback(VideoCore::LoadCallbackStage::Preload, preloaded, custom_textures.size()); + } + preloaded++; } }); workers->WaitForRequests(); diff --git a/src/video_core/custom_textures/custom_tex_manager.h b/src/video_core/custom_textures/custom_tex_manager.h index caee66a1f..007218857 100644 --- a/src/video_core/custom_textures/custom_tex_manager.h +++ b/src/video_core/custom_textures/custom_tex_manager.h @@ -10,6 +10,7 @@ #include #include "common/thread_worker.h" #include "video_core/custom_textures/material.h" +#include "video_core/rasterizer_interface.h" namespace Core { class System; @@ -43,7 +44,8 @@ public: void WriteConfig(); /// Preloads all registered custom textures - void PreloadTextures(); + void PreloadTextures(const std::atomic_bool& stop_run, + const VideoCore::DiskResourceLoadCallback& callback); /// Saves the provided pixel data described by params to disk as png void DumpTexture(const SurfaceParams& params, u32 level, std::span data, u64 data_hash); diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h index 873e4273e..b3a0e97f2 100644 --- a/src/video_core/rasterizer_interface.h +++ b/src/video_core/rasterizer_interface.h @@ -21,6 +21,7 @@ namespace VideoCore { enum class LoadCallbackStage { Prepare, + Preload, Decompile, Build, Complete,