From 322d7a82878c877bea446b9796bca2ad29a5b8e8 Mon Sep 17 00:00:00 2001 From: luc-git <102831178+luc-git@users.noreply.github.com> Date: Sun, 7 May 2023 01:34:14 +0200 Subject: [PATCH] Textures loading screen (#6478) * 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 * Add custom textures loading in EmuThread * Remove useless variable * Revert "Add custom textures loading in EmuThread" This reverts commit 45ed46fa09159f782c5d20a4330b4eb7cfcdc253. * Moved include from bootmanager.h to bootmanager.cpp --- src/citra_qt/bootmanager.cpp | 10 +++++++++- 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 + 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 4ae41f2eb..baabf8641 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp @@ -23,6 +23,7 @@ #include "input_common/keyboard.h" #include "input_common/main.h" #include "input_common/motion_emu.h" +#include "video_core/custom_textures/custom_tex_manager.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" @@ -60,10 +61,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/loading_screen.cpp b/src/citra_qt/loading_screen.cpp index 56e4b4d64..0cf6c23b7 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 60cd7a61c..31de0537e 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -322,9 +322,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 a3086c4df..305ef782f 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 42a6b4f9a..3109567ac 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,