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
This commit is contained in:
luc-git 2023-04-28 21:47:49 +02:00
parent 9bd8c9290b
commit 2d14dc49f7
7 changed files with 30 additions and 7 deletions

View file

@ -60,10 +60,17 @@ static GMainWindow* GetMainWindow() {
void EmuThread::run() { void EmuThread::run() {
MicroProfileOnThreadCreate("EmuThread"); MicroProfileOnThreadCreate("EmuThread");
const auto scope = core_context.Acquire(); 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); emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
Core::System& system = Core::System::GetInstance();
system.Renderer().Rasterizer()->LoadDiskResources( system.Renderer().Rasterizer()->LoadDiskResources(
stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) { stop_run, [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
emit LoadProgress(stage, value, total); emit LoadProgress(stage, value, total);

View file

@ -12,6 +12,7 @@
#include <QWidget> #include <QWidget>
#include "core/core.h" #include "core/core.h"
#include "core/frontend/emu_window.h" #include "core/frontend/emu_window.h"
#include "video_core/custom_textures/custom_tex_manager.h"
class QKeyEvent; class QKeyEvent;
class QTouchEvent; class QTouchEvent;
@ -79,6 +80,7 @@ private:
std::atomic<bool> stop_run{false}; std::atomic<bool> stop_run{false};
std::mutex running_mutex; std::mutex running_mutex;
std::condition_variable running_cv; std::condition_variable running_cv;
std::size_t number_textures;
Frontend::GraphicsContext& core_context; Frontend::GraphicsContext& core_context;

View file

@ -62,6 +62,8 @@ QProgressBar::chunk {
// Definitions for the differences in text and styling for each stage // Definitions for the differences in text and styling for each stage
const static std::unordered_map<VideoCore::LoadCallbackStage, const char*> stage_translations{ const static std::unordered_map<VideoCore::LoadCallbackStage, const char*> stage_translations{
{VideoCore::LoadCallbackStage::Prepare, QT_TRANSLATE_NOOP("LoadingScreen", "Loading...")}, {VideoCore::LoadCallbackStage::Prepare, QT_TRANSLATE_NOOP("LoadingScreen", "Loading...")},
{VideoCore::LoadCallbackStage::Preload,
QT_TRANSLATE_NOOP("LoadingScreen", "Preloading Textures %1 / %2")},
{VideoCore::LoadCallbackStage::Decompile, {VideoCore::LoadCallbackStage::Decompile,
QT_TRANSLATE_NOOP("LoadingScreen", "Preparing Shaders %1 / %2")}, QT_TRANSLATE_NOOP("LoadingScreen", "Preparing Shaders %1 / %2")},
{VideoCore::LoadCallbackStage::Build, {VideoCore::LoadCallbackStage::Build,
@ -70,6 +72,7 @@ const static std::unordered_map<VideoCore::LoadCallbackStage, const char*> stage
}; };
const static std::unordered_map<VideoCore::LoadCallbackStage, const char*> progressbar_style{ const static std::unordered_map<VideoCore::LoadCallbackStage, const char*> progressbar_style{
{VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE}, {VideoCore::LoadCallbackStage::Prepare, PROGRESSBAR_STYLE_PREPARE},
{VideoCore::LoadCallbackStage::Preload, PROGRESSBAR_STYLE_BUILD},
{VideoCore::LoadCallbackStage::Decompile, PROGRESSBAR_STYLE_DECOMPILE}, {VideoCore::LoadCallbackStage::Decompile, PROGRESSBAR_STYLE_DECOMPILE},
{VideoCore::LoadCallbackStage::Build, PROGRESSBAR_STYLE_BUILD}, {VideoCore::LoadCallbackStage::Build, PROGRESSBAR_STYLE_BUILD},
{VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE}, {VideoCore::LoadCallbackStage::Complete, PROGRESSBAR_STYLE_COMPLETE},
@ -186,7 +189,8 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size
// update labels and progress bar // update labels and progress bar
const auto& stg = tr(stage_translations.at(stage)); const auto& stg = tr(stage_translations.at(stage));
if (stage == VideoCore::LoadCallbackStage::Decompile || 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)); ui->stage->setText(stg.arg(value).arg(total));
} else { } else {
ui->stage->setText(stg); ui->stage->setText(stg);

View file

@ -323,9 +323,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
if (Settings::values.custom_textures) { if (Settings::values.custom_textures) {
custom_tex_manager->FindCustomTextures(); custom_tex_manager->FindCustomTextures();
} }
if (Settings::values.preload_textures) {
custom_tex_manager->PreloadTextures();
}
if (Settings::values.dump_textures) { if (Settings::values.dump_textures) {
custom_tex_manager->WriteConfig(); custom_tex_manager->WriteConfig();
} }
@ -554,6 +551,7 @@ void System::Shutdown(bool is_deserializing) {
cheat_engine.reset(); cheat_engine.reset();
app_loader.reset(); app_loader.reset();
} }
custom_tex_manager.reset();
telemetry_session.reset(); telemetry_session.reset();
rpc_server.reset(); rpc_server.reset();
archive_manager.reset(); archive_manager.reset();

View file

@ -190,8 +190,10 @@ void CustomTexManager::WriteConfig() {
file.WriteString(output); file.WriteString(output);
} }
void CustomTexManager::PreloadTextures() { void CustomTexManager::PreloadTextures(const std::atomic_bool& stop_run,
const VideoCore::DiskResourceLoadCallback& callback) {
u64 size_sum = 0; u64 size_sum = 0;
size_t preloaded = 0;
const u64 sys_mem = Common::GetMemInfo().total_physical_memory; const u64 sys_mem = Common::GetMemInfo().total_physical_memory;
const u64 recommended_min_mem = 2 * size_t(1024 * 1024 * 1024); 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"); LOG_WARNING(Render, "Aborting texture preload due to insufficient memory");
return; return;
} }
if (stop_run) {
return;
}
material->LoadFromDisk(flip_png_files); material->LoadFromDisk(flip_png_files);
size_sum += material->size; size_sum += material->size;
if (callback) {
callback(VideoCore::LoadCallbackStage::Preload, preloaded, custom_textures.size());
}
preloaded++;
} }
}); });
workers->WaitForRequests(); workers->WaitForRequests();

View file

@ -10,6 +10,7 @@
#include <unordered_set> #include <unordered_set>
#include "common/thread_worker.h" #include "common/thread_worker.h"
#include "video_core/custom_textures/material.h" #include "video_core/custom_textures/material.h"
#include "video_core/rasterizer_interface.h"
namespace Core { namespace Core {
class System; class System;
@ -43,7 +44,8 @@ public:
void WriteConfig(); void WriteConfig();
/// Preloads all registered custom textures /// 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 /// Saves the provided pixel data described by params to disk as png
void DumpTexture(const SurfaceParams& params, u32 level, std::span<u8> data, u64 data_hash); void DumpTexture(const SurfaceParams& params, u32 level, std::span<u8> data, u64 data_hash);

View file

@ -21,6 +21,7 @@ namespace VideoCore {
enum class LoadCallbackStage { enum class LoadCallbackStage {
Prepare, Prepare,
Preload,
Decompile, Decompile,
Build, Build,
Complete, Complete,