diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 3cf4eb0b92..3ec247d558 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -70,6 +70,7 @@ #include #include #include +#include #include "util/asm.hpp" #include "util/vm.hpp" #include "util/v128.hpp" @@ -80,12 +81,7 @@ const bool s_use_ssse3 = utils::has_ssse3(); extern atomic_t g_watchdog_hold_ctr; -extern atomic_t g_progr; -extern atomic_t g_progr_show; -extern atomic_t g_progr_ftotal; -extern atomic_t g_progr_fdone; -extern atomic_t g_progr_ptotal; -extern atomic_t g_progr_pdone; +#include "Emu/system_progress.hpp" // Should be of the same type using spu_rdata_t = decltype(ppu_thread::rdata); @@ -2402,9 +2398,8 @@ extern void ppu_precompile(std::vector& dir_queue, std::vector fnext = 0; @@ -2521,8 +2516,6 @@ extern void ppu_precompile(std::vector& dir_queue, std::vector progr; + if (!check_only) { // Initialize progress dialog - g_progr = "Loading PPU modules..."; - g_progr_show = true; + progr.emplace("Loading PPU modules..."); } struct jit_core_allocator @@ -3057,7 +3042,6 @@ bool ppu_initialize(const ppu_module& info, bool check_only) if (Emu.IsStopped() || !get_current_cpu_thread()) { - g_progr_show = false; return compiled_new; } @@ -3084,8 +3068,6 @@ bool ppu_initialize(const ppu_module& info, bool check_only) } } - g_progr_show = false; - if (Emu.IsStopped() || !get_current_cpu_thread()) { return compiled_new; diff --git a/rpcs3/Emu/Cell/SPURecompiler.cpp b/rpcs3/Emu/Cell/SPURecompiler.cpp index 21d0b3be97..8212e35119 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.cpp +++ b/rpcs3/Emu/Cell/SPURecompiler.cpp @@ -17,15 +17,13 @@ #include #include #include +#include #include "util/v128.hpp" #include "util/v128sse.hpp" #include "util/sysinfo.hpp" -extern atomic_t g_progr; -extern atomic_t g_progr_show; -extern atomic_t g_progr_ptotal; -extern atomic_t g_progr_pdone; +#include "Emu/system_progress.hpp" const spu_decoder s_spu_itype; const spu_decoder s_spu_iname; @@ -417,6 +415,8 @@ void spu_cache::initialize() u32 worker_count = 0; + std::optional progr; + if (g_cfg.core.spu_decoder == spu_decoder_type::asmjit || g_cfg.core.spu_decoder == spu_decoder_type::llvm) { // Initialize progress dialog (wait for previous progress done) @@ -425,9 +425,8 @@ void spu_cache::initialize() std::this_thread::sleep_for(5ms); } - g_progr = "Building SPU cache..."; g_progr_ptotal += ::size32(func_list); - g_progr_show = true; + progr.emplace("Building SPU cache..."); worker_count = Emu.GetMaxThreads(); } @@ -527,11 +526,6 @@ void spu_cache::initialize() spu_log.notice("SPU Runtime: Worker %u built %u programs.", i + 1, workers[i]); } - if (g_cfg.core.spu_decoder == spu_decoder_type::asmjit || g_cfg.core.spu_decoder == spu_decoder_type::llvm) - { - g_progr_show = false; - } - if (Emu.IsStopped()) { spu_log.error("SPU Runtime: Cache building aborted."); diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 80161bc525..e73ac63a51 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -82,8 +82,7 @@ std::array, 16> g_tty_input; std::mutex g_tty_mutex; // Progress display server synchronization variables -atomic_t g_progr{""}; -atomic_t g_progr_show{false}; +atomic_t g_progr{nullptr}; atomic_t g_progr_ftotal{0}; atomic_t g_progr_fdone{0}; atomic_t g_progr_ptotal{0}; @@ -343,7 +342,9 @@ namespace while (thread_ctrl::state() != thread_state::aborting) { // Wait for the start condition - while (!g_progr_show) + auto text0 = +g_progr; + + while (!text0) { if (thread_ctrl::state() == thread_state::aborting) { @@ -351,6 +352,7 @@ namespace } std::this_thread::sleep_for(5ms); + text0 = +g_progr; } if (thread_ctrl::state() == thread_state::aborting) @@ -374,7 +376,7 @@ namespace type.progress_bar_count = 1; native_dlg = manager->create(!!g_cfg.video.shader_preloading_dialog.use_custom_background); - native_dlg->show(false, +g_progr, type, nullptr); + native_dlg->show(false, text0, type, nullptr); native_dlg->progress_bar_set_message(0, "Please wait"); } } @@ -394,9 +396,9 @@ namespace }); }; - Emu.CallAfter([dlg]() + Emu.CallAfter([dlg, text0]() { - dlg->Create(+g_progr, +g_progr); + dlg->Create(text0, text0); }); } @@ -404,6 +406,7 @@ namespace u32 fdone = 0; u32 ptotal = 0; u32 pdone = 0; + auto text1 = text0; // Update progress while (thread_ctrl::state() != thread_state::aborting) @@ -412,13 +415,15 @@ namespace const u32 fdone_new = g_progr_fdone; const u32 ptotal_new = g_progr_ptotal; const u32 pdone_new = g_progr_pdone; + const auto text_new = g_progr.load(); - if (ftotal != ftotal_new || fdone != fdone_new || ptotal != ptotal_new || pdone != pdone_new) + if (ftotal != ftotal_new || fdone != fdone_new || ptotal != ptotal_new || pdone != pdone_new || text_new != text1) { ftotal = ftotal_new; fdone = fdone_new; ptotal = ptotal_new; pdone = pdone_new; + text1 = text_new; // Compute new progress in percents // Assume not all programs were found if files were not compiled (as it may contain more) @@ -438,20 +443,20 @@ namespace if (native_dlg) { - native_dlg->set_text(+g_progr); + native_dlg->set_text(text_new ? text_new : ""); native_dlg->progress_bar_set_message(0, progr); native_dlg->progress_bar_set_value(0, std::floor(value)); } else if (dlg) { - dlg->SetMsg(+g_progr); + dlg->SetMsg(text_new ? text_new : ""); dlg->ProgressBarSetMsg(0, progr); dlg->ProgressBarSetValue(0, std::floor(value)); } }); } - if (!g_progr_show) + if (!text_new) { // Close dialog break; @@ -470,7 +475,6 @@ namespace g_progr_fdone -= fdone; g_progr_ptotal -= ptotal; g_progr_pdone -= pdone; - g_progr_show = false; Emu.CallAfter([=]() { @@ -492,7 +496,7 @@ namespace g_progr_fdone.release(0); g_progr_ptotal.release(0); g_progr_pdone.release(0); - g_progr_show.release(false); + g_progr.release(nullptr); } static auto constexpr thread_name = "Progress Dialog Server"sv; diff --git a/rpcs3/Emu/system_progress.hpp b/rpcs3/Emu/system_progress.hpp new file mode 100644 index 0000000000..8963e57d1c --- /dev/null +++ b/rpcs3/Emu/system_progress.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "util/types.hpp" +#include "util/atomic.hpp" + +extern atomic_t g_progr; +extern atomic_t g_progr_ftotal; +extern atomic_t g_progr_fdone; +extern atomic_t g_progr_ptotal; +extern atomic_t g_progr_pdone; + +// Initialize progress dialog (can be recursive) +class scoped_progress_dialog final +{ + // Saved previous value + const char* const m_prev; + +public: + scoped_progress_dialog(const char* text) + : m_prev(g_progr.exchange(text ? text : "")) + { + } + + scoped_progress_dialog(const scoped_progress_dialog&) = delete; + + scoped_progress_dialog& operator=(const scoped_progress_dialog&) = delete; + + ~scoped_progress_dialog() + { + g_progr.release(m_prev); + } +};