Skip to content

Commit

Permalink
rsx/overlays: Add simple reference counting for messages to hide them…
Browse files Browse the repository at this point in the history
… manually

Move some code in Emulator::Pause() so thread pausing is the first thing done by this function
  • Loading branch information
elad335 committed Oct 29, 2022
1 parent c7f2cd7 commit a2d3616
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 25 deletions.
12 changes: 7 additions & 5 deletions rpcs3/Emu/RSX/Overlays/overlay_message.cpp
Expand Up @@ -7,9 +7,10 @@ namespace rsx
namespace overlays
{
template <typename T>
message_item::message_item(T msg_id, u64 expiration)
message_item::message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs)
{
m_expiration_time = get_system_time() + expiration;
m_expiration_time = expiration == umax ? expiration : get_system_time() + expiration;
m_refs = std::move(refs);

m_text.set_font("Arial", 16);
m_text.set_text(msg_id);
Expand All @@ -21,12 +22,13 @@ namespace rsx
m_fade_animation.duration = 2.f;
m_fade_animation.active = true;
}
template message_item::message_item(std::string msg_id, u64);
template message_item::message_item(localized_string_id msg_id, u64);
template message_item::message_item(std::string msg_id, u64, std::shared_ptr<atomic_t<u32>>);
template message_item::message_item(localized_string_id msg_id, u64, std::shared_ptr<atomic_t<u32>>);

u64 message_item::get_expiration() const
{
return m_expiration_time;
// If reference counting is enabled and reached 0 consider it expired
return m_refs && *m_refs == 0 ? 0 : m_expiration_time;
}

compiled_resource message_item::get_compiled()
Expand Down
13 changes: 7 additions & 6 deletions rpcs3/Emu/RSX/Overlays/overlay_message.h
Expand Up @@ -11,7 +11,7 @@ namespace rsx
{
public:
template <typename T>
message_item(T msg_id, u64 expiration);
message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs);
void update(usz index, u64 time);

u64 get_expiration() const;
Expand All @@ -22,6 +22,7 @@ namespace rsx
animation_color_interpolate m_fade_animation;

u64 m_expiration_time = 0;
std::shared_ptr<atomic_t<u32>> m_refs;
bool m_processed = false;
usz m_cur_pos = umax;
};
Expand All @@ -33,20 +34,20 @@ namespace rsx
compiled_resource get_compiled() override;

template <typename T>
void queue_message(T msg_id, u64 expiration)
void queue_message(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs)
{
std::lock_guard lock(m_mutex_queue);

if constexpr (std::is_same_v<T, std::initializer_list<localized_string_id>>)
{
for (auto id : msg_id)
{
m_queue.emplace_back(id, expiration);
m_queue.emplace_back(id, expiration, refs);
}
}
else
{
m_queue.emplace_back(msg_id, expiration);
m_queue.emplace_back(msg_id, expiration, std::move(refs));
}

visible = true;
Expand All @@ -58,7 +59,7 @@ namespace rsx
};

template <typename T>
void queue_message(T msg_id, u64 expiration = 5'000'000)
void queue_message(T msg_id, u64 expiration = 5'000'000, std::shared_ptr<atomic_t<u32>> refs = {})
{
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
{
Expand All @@ -68,7 +69,7 @@ namespace rsx
msg_overlay = std::make_shared<rsx::overlays::message>();
msg_overlay = manager->add(msg_overlay);
}
msg_overlay->queue_message(msg_id, expiration);
msg_overlay->queue_message(msg_id, expiration, std::move(refs));
}
}

Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/RSX/RSXThread.cpp
Expand Up @@ -18,6 +18,7 @@
#include "Emu/Cell/lv2/sys_time.h"
#include "Emu/Cell/Modules/cellGcmSys.h"
#include "Overlays/overlay_perf_metrics.h"
#include "Overlays/overlay_message.h"
#include "Program/GLSLCommon.h"
#include "Utilities/date_time.h"
#include "Utilities/StrUtil.h"
Expand Down
75 changes: 62 additions & 13 deletions rpcs3/Emu/System.cpp
Expand Up @@ -26,6 +26,7 @@
#include "Emu/title.h"
#include "Emu/IdManager.h"
#include "Emu/RSX/Capture/rsx_replay.h"
#include "Emu/RSX/Overlays/overlay_message.h"

#include "Loader/PSF.h"
#include "Loader/TAR.h"
Expand Down Expand Up @@ -101,6 +102,11 @@ namespace atomic_wait
extern void parse_hashtable(bool(*cb)(u64 id, u32 refs, u64 ptr, u32 max_coll));
}

namespace rsx
{
void set_native_ui_flip();
}

template<>
void fmt_class_string<game_boot_result>::format(std::string& out, u64 arg)
{
Expand Down Expand Up @@ -2050,8 +2056,53 @@ bool Emulator::Pause(bool freeze_emulation)
// Signal profilers to print results (if enabled)
cpu_thread::flush_profilers();

auto on_select = [](u32, cpu_thread& cpu)
{
cpu.state += cpu_flag::dbg_global_pause;
};

idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);

if (auto rsx = g_fxo->try_get<rsx::thread>())
{
rsx->state += cpu_flag::dbg_global_pause;
}

GetCallbacks().on_pause();

BlockingCallFromMainThread([this]()
{
if (IsStopped())
{
return;
}

auto msg_ref = std::make_shared<atomic_t<u32>>(1);

// No timeout
rsx::overlays::queue_message(localized_string_id::EMULATION_PAUSED_RESUME_WITH_START, -1, msg_ref);
m_pause_msgs_refs.emplace_back(msg_ref);

auto refresh_l = [this, msg_ref]()
{
while (*msg_ref && IsPaused())
{
// Refresh Native UI
rsx::set_native_ui_flip();
thread_ctrl::wait_for(33'000);
}
};

struct thread_t
{
std::unique_ptr<named_thread<decltype(refresh_l)>> m_thread;
};

g_fxo->get<thread_t>().m_thread.reset();
g_fxo->get<thread_t>().m_thread = std::make_unique<named_thread<decltype(refresh_l)>>("Pause Message Thread"sv, std::move(refresh_l));
});

static atomic_t<u32> pause_mark = 0;

if (freeze_emulation)
Expand All @@ -2069,19 +2120,6 @@ bool Emulator::Pause(bool freeze_emulation)
sys_log.error("Emulator::Pause() error: concurrent access");
}

auto on_select = [](u32, cpu_thread& cpu)
{
cpu.state += cpu_flag::dbg_global_pause;
};

idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);

if (auto rsx = g_fxo->try_get<rsx::thread>())
{
rsx->state += cpu_flag::dbg_global_pause;
}

// Always Enable display sleep, not only if it was prevented.
enable_display_sleep();

Expand Down Expand Up @@ -2167,6 +2205,17 @@ void Emulator::Resume()

sys_log.success("Emulation has been resumed!");

BlockingCallFromMainThread([this]()
{
for (auto& ref : m_pause_msgs_refs)
{
// Delete the message queued on pause
*ref = 0;
}

m_pause_msgs_refs.clear();
});

if (g_cfg.misc.prevent_display_sleep)
{
disable_display_sleep();
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/Emu/System.h
Expand Up @@ -144,6 +144,8 @@ class Emulator final

bool m_state_inspection_savestate = false;

std::vector<std::shared_ptr<atomic_t<u32>>> m_pause_msgs_refs;

std::vector<std::function<void()>> deferred_deserialization;

void ExecDeserializationRemnants()
Expand Down
3 changes: 3 additions & 0 deletions rpcs3/Emu/localized_string_id.h
Expand Up @@ -146,4 +146,7 @@ enum class localized_string_id
RPCN_ERROR_INVALID_PROTOCOL_VERSION,
RPCN_ERROR_UNKNOWN,
RPCN_SUCCESS_LOGGED_ON,

EMULATION_PAUSED_RESUME_WITH_START,
EMULATION_RESUMING,
};
2 changes: 1 addition & 1 deletion rpcs3/Input/pad_thread.cpp
Expand Up @@ -439,7 +439,7 @@ void pad_thread::operator()()
m_track_start_press_begin_timestamp = 0;

sys_log.success("Unpausing emulation using the START button in a few seconds...");
rsx::overlays::queue_message("Unpausing...!"s, 2'500'000);
rsx::overlays::queue_message(localized_string_id::EMULATION_RESUMING, 2'500'000);

m_resume_emulation_flag = true;

Expand Down
2 changes: 2 additions & 0 deletions rpcs3/rpcs3qt/localized_emu.h
Expand Up @@ -167,6 +167,8 @@ class localized_emu : public QObject
case localized_string_id::RPCN_ERROR_INVALID_PROTOCOL_VERSION: return tr("RPCN Misc Error: Protocol Version Error (outdated RPCS3?)");
case localized_string_id::RPCN_ERROR_UNKNOWN: return tr("RPCN: Unknown Error");
case localized_string_id::RPCN_SUCCESS_LOGGED_ON: return tr("Successfully logged on RPCN!");
case localized_string_id::EMULATION_PAUSED_RESUME_WITH_START: return tr("Press and hold the START button to resume");
case localized_string_id::EMULATION_RESUMING: return tr("Resuming...!");
case localized_string_id::INVALID: return tr("Invalid");
default: return tr("Unknown");
}
Expand Down

0 comments on commit a2d3616

Please sign in to comment.