overlays: Show feedback while stopping ppu compilation

This commit is contained in:
Megamouse 2021-09-05 13:12:08 +02:00
parent e5876b3a1b
commit da4f4dafbd
4 changed files with 37 additions and 7 deletions

View File

@ -1602,6 +1602,18 @@ void Emulator::Stop(bool restart)
sys_log.notice("Stopping emulator..."); sys_log.notice("Stopping emulator...");
if (!restart)
{
// Show visual feedback to the user in case that stopping takes a while.
// This needs to be done before actually stopping, because otherwise the necessary threads will be terminated before we can show an image.
if (auto progress_dialog = g_fxo->try_get<named_thread<progress_dialog_server>>(); progress_dialog && +g_progr)
{
// We are currently showing a progress dialog. Notify it that we are going to stop emulation.
g_system_progress_stopping = true;
std::this_thread::sleep_for(20ms); // Enough for one frame to be rendered
}
}
named_thread stop_watchdog("Stop Watchdog", [&]() named_thread stop_watchdog("Stop Watchdog", [&]()
{ {
for (uint i = 0; thread_ctrl::state() != thread_state::aborting;) for (uint i = 0; thread_ctrl::state() != thread_state::aborting;)

View File

@ -15,6 +15,9 @@ atomic_t<u32> g_progr_pdone{0};
// For Batch PPU Compilation // For Batch PPU Compilation
atomic_t<bool> g_system_progress_canceled{false}; atomic_t<bool> g_system_progress_canceled{false};
// For showing feedback while stopping emulation
atomic_t<bool> g_system_progress_stopping{false};
namespace rsx::overlays namespace rsx::overlays
{ {
class progress_dialog : public message_dialog class progress_dialog : public message_dialog
@ -26,14 +29,17 @@ namespace rsx::overlays
void progress_dialog_server::operator()() void progress_dialog_server::operator()()
{ {
while (thread_ctrl::state() != thread_state::aborting) std::shared_ptr<rsx::overlays::progress_dialog> native_dlg;
g_system_progress_stopping = false;
while (!g_system_progress_stopping && thread_ctrl::state() != thread_state::aborting)
{ {
// Wait for the start condition // Wait for the start condition
auto text0 = +g_progr; auto text0 = +g_progr;
while (!text0) while (!text0)
{ {
if (thread_ctrl::state() == thread_state::aborting) if (g_system_progress_stopping || thread_ctrl::state() == thread_state::aborting)
{ {
break; break;
} }
@ -42,7 +48,7 @@ void progress_dialog_server::operator()()
text0 = +g_progr; text0 = +g_progr;
} }
if (thread_ctrl::state() == thread_state::aborting) if (g_system_progress_stopping || thread_ctrl::state() == thread_state::aborting)
{ {
break; break;
} }
@ -52,7 +58,6 @@ void progress_dialog_server::operator()()
// Initialize message dialog // Initialize message dialog
bool skip_this_one = false; // Workaround: do not open a progress dialog if there is already a cell message dialog open. bool skip_this_one = false; // Workaround: do not open a progress dialog if there is already a cell message dialog open.
std::shared_ptr<MsgDialogBase> dlg; std::shared_ptr<MsgDialogBase> dlg;
std::shared_ptr<rsx::overlays::progress_dialog> native_dlg;
if (const auto renderer = rsx::get_current_renderer(); if (const auto renderer = rsx::get_current_renderer();
renderer && renderer->is_inited) renderer && renderer->is_inited)
@ -104,7 +109,7 @@ void progress_dialog_server::operator()()
auto text1 = text0; auto text1 = text0;
// Update progress // Update progress
while (thread_ctrl::state() != thread_state::aborting) while (!g_system_progress_stopping && thread_ctrl::state() != thread_state::aborting)
{ {
const auto text_new = g_progr.load(); const auto text_new = g_progr.load();
@ -168,7 +173,7 @@ void progress_dialog_server::operator()()
std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(10ms);
} }
if (thread_ctrl::state() == thread_state::aborting) if (g_system_progress_stopping || thread_ctrl::state() == thread_state::aborting)
{ {
break; break;
} }
@ -196,6 +201,12 @@ void progress_dialog_server::operator()()
g_progr_ptotal -= ptotal; g_progr_ptotal -= ptotal;
g_progr_ptotal.notify_all(); g_progr_ptotal.notify_all();
} }
if (native_dlg && g_system_progress_stopping)
{
native_dlg->set_text("Stopping. Please wait...");
native_dlg->refresh();
}
} }
progress_dialog_server::~progress_dialog_server() progress_dialog_server::~progress_dialog_server()

View File

@ -9,6 +9,7 @@ extern atomic_t<u32> g_progr_fdone;
extern atomic_t<u32> g_progr_ptotal; extern atomic_t<u32> g_progr_ptotal;
extern atomic_t<u32> g_progr_pdone; extern atomic_t<u32> g_progr_pdone;
extern atomic_t<bool> g_system_progress_canceled; extern atomic_t<bool> g_system_progress_canceled;
extern atomic_t<bool> g_system_progress_stopping;
// Initialize progress dialog (can be recursive) // Initialize progress dialog (can be recursive)
class scoped_progress_dialog final class scoped_progress_dialog final

View File

@ -7,6 +7,7 @@
#include "Utilities/File.h" #include "Utilities/File.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/system_config.h" #include "Emu/system_config.h"
#include "Emu/system_progress.hpp"
#include "Emu/IdManager.h" #include "Emu/IdManager.h"
#include "Emu/Cell/Modules/cellScreenshot.h" #include "Emu/Cell/Modules/cellScreenshot.h"
#include "Emu/RSX/rsx_utils.h" #include "Emu/RSX/rsx_utils.h"
@ -348,7 +349,12 @@ void gs_frame::close()
{ {
Emu.CallAfter([this]() Emu.CallAfter([this]()
{ {
QWindow::hide(); // Workaround if (!(+g_progr))
{
// Hide the dialog before stopping if no progress bar is being shown.
// Otherwise users might think that the game softlocked if stopping takes too long.
QWindow::hide();
}
if (!Emu.IsStopped()) if (!Emu.IsStopped())
{ {