mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
RSX/Qt: Reuse gs_frame if possible
This commit is contained in:
parent
99f1f4c22a
commit
1ab3a0bd73
18 changed files with 101 additions and 16 deletions
|
@ -498,6 +498,9 @@ void lv2_exitspawn(ppu_thread& ppu, std::vector<std::string>& argv, std::vector<
|
|||
};
|
||||
|
||||
signal_system_cache_can_stay();
|
||||
|
||||
// Make sure we keep the game window opened
|
||||
Emu.SetContinuousMode(true);
|
||||
Emu.Kill(false);
|
||||
});
|
||||
|
||||
|
|
|
@ -52,6 +52,14 @@ GLGSRender::GLGSRender(utils::serial* ar) noexcept : GSRender(ar)
|
|||
backend_config.supports_normalized_barycentrics = true;
|
||||
}
|
||||
|
||||
GLGSRender::~GLGSRender()
|
||||
{
|
||||
if (m_frame)
|
||||
{
|
||||
m_frame->reset();
|
||||
}
|
||||
}
|
||||
|
||||
extern CellGcmContextData current_context;
|
||||
|
||||
void GLGSRender::set_viewport()
|
||||
|
|
|
@ -159,6 +159,7 @@ public:
|
|||
|
||||
GLGSRender(utils::serial* ar) noexcept;
|
||||
GLGSRender() noexcept : GLGSRender(nullptr) {}
|
||||
virtual ~GLGSRender();
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ public:
|
|||
virtual ~GSFrameBase() = default;
|
||||
|
||||
virtual void close() = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual bool shown() = 0;
|
||||
virtual void hide() = 0;
|
||||
virtual void show() = 0;
|
||||
|
|
|
@ -18,7 +18,7 @@ GSRender::~GSRender()
|
|||
{
|
||||
m_context = nullptr;
|
||||
|
||||
if (m_frame)
|
||||
if (m_frame && !m_continuous_mode)
|
||||
{
|
||||
m_frame->close();
|
||||
}
|
||||
|
@ -39,7 +39,10 @@ void GSRender::on_exit()
|
|||
|
||||
if (m_frame)
|
||||
{
|
||||
m_frame->hide();
|
||||
if (!m_continuous_mode)
|
||||
{
|
||||
m_frame->hide();
|
||||
}
|
||||
m_frame->delete_context(m_context);
|
||||
m_context = nullptr;
|
||||
}
|
||||
|
|
|
@ -21,12 +21,15 @@ class GSRender : public rsx::thread
|
|||
protected:
|
||||
GSFrameBase* m_frame;
|
||||
draw_context_t m_context = nullptr;
|
||||
bool m_continuous_mode = false;
|
||||
|
||||
public:
|
||||
~GSRender() override;
|
||||
|
||||
GSRender(utils::serial* ar) noexcept;
|
||||
|
||||
void set_continuous_mode(bool continuous_mode) { m_continuous_mode = continuous_mode; }
|
||||
|
||||
void on_init_thread() override;
|
||||
void on_exit() override;
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ namespace rsx
|
|||
|
||||
Emu.CallFromMainThread([]()
|
||||
{
|
||||
Emu.SetContinuousMode(true);
|
||||
Emu.Restart(false);
|
||||
});
|
||||
return page_navigation::exit;
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace rsx
|
|||
if (!suspend_mode)
|
||||
{
|
||||
Emu.after_kill_callback = []() { Emu.Restart(); };
|
||||
Emu.SetContinuousMode(true);
|
||||
}
|
||||
Emu.Kill(false, true);
|
||||
});
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
#include "Emu/RSX/VK/VulkanAPI.h"
|
||||
#endif
|
||||
|
||||
#include "Emu/RSX/GSRender.h"
|
||||
|
||||
LOG_CHANNEL(sys_log, "SYS");
|
||||
|
||||
// Preallocate 32 MiB
|
||||
|
@ -1005,6 +1007,16 @@ void Emulator::SetForceBoot(bool force_boot)
|
|||
m_force_boot = force_boot;
|
||||
}
|
||||
|
||||
void Emulator::SetContinuousMode(bool continuous_mode)
|
||||
{
|
||||
m_continuous_mode = continuous_mode;
|
||||
|
||||
if (GSRender* render = static_cast<GSRender*>(g_fxo->try_get<rsx::thread>()))
|
||||
{
|
||||
render->set_continuous_mode(continuous_mode);
|
||||
}
|
||||
}
|
||||
|
||||
game_boot_result Emulator::Load(const std::string& title_id, bool is_disc_patch, usz recursion_count)
|
||||
{
|
||||
if (recursion_count == 0 && m_restrict_emu_state_change)
|
||||
|
@ -2897,6 +2909,9 @@ void qt_events_aware_op(int repeat_duration_ms, std::function<bool()> wrapped_op
|
|||
|
||||
void Emulator::GracefulShutdown(bool allow_autoexit, bool async_op, bool savestate)
|
||||
{
|
||||
// Make sure we close the game window
|
||||
Emu.SetContinuousMode(false);
|
||||
|
||||
// Ensure no game has booted inbetween
|
||||
const auto guard = Emu.MakeEmulationStateGuard();
|
||||
|
||||
|
@ -3278,7 +3293,6 @@ void Emulator::Kill(bool allow_autoexit, bool savestate, savestate_stage* save_s
|
|||
thread_ctrl::wait_for(5'000);
|
||||
}
|
||||
|
||||
|
||||
*closed_sucessfully = true;
|
||||
}));
|
||||
|
||||
|
|
|
@ -154,6 +154,7 @@ class Emulator final
|
|||
// 2. It signifies that we don't want to exit on Kill(), for example if we want to transition to another application.
|
||||
bool m_force_boot = false;
|
||||
|
||||
bool m_continuous_mode = false;
|
||||
bool m_has_gui = true;
|
||||
|
||||
bool m_state_inspection_savestate = false;
|
||||
|
@ -346,6 +347,15 @@ public:
|
|||
return m_config_mode == cfg_mode::continuous;
|
||||
}
|
||||
|
||||
bool ContinuousModeEnabled(bool reset)
|
||||
{
|
||||
if (reset)
|
||||
{
|
||||
return std::exchange(m_continuous_mode, false);
|
||||
}
|
||||
return m_continuous_mode;
|
||||
}
|
||||
|
||||
class emulation_state_guard_t
|
||||
{
|
||||
class Emulator* _this = nullptr;
|
||||
|
@ -385,6 +395,7 @@ public:
|
|||
bool BootRsxCapture(const std::string& path);
|
||||
|
||||
void SetForceBoot(bool force_boot);
|
||||
void SetContinuousMode(bool continuous_mode);
|
||||
|
||||
game_boot_result Load(const std::string& title_id = "", bool is_disc_patch = false, usz recursion_count = 0);
|
||||
void Run(bool start_playtime);
|
||||
|
|
|
@ -133,7 +133,7 @@ EmuCallbacks main_application::CreateCallbacks()
|
|||
basic_keyboard_handler* ret = g_fxo->init<KeyboardHandlerBase, basic_keyboard_handler>(Emu.DeserialManager());
|
||||
ensure(ret);
|
||||
ret->moveToThread(get_thread());
|
||||
ret->SetTargetWindow(m_game_window);
|
||||
ret->SetTargetWindow(reinterpret_cast<QWindow*>(m_game_window));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ EmuCallbacks main_application::CreateCallbacks()
|
|||
basic_mouse_handler* ret = g_fxo->init<MouseHandlerBase, basic_mouse_handler>(Emu.DeserialManager());
|
||||
ensure(ret);
|
||||
ret->moveToThread(get_thread());
|
||||
ret->SetTargetWindow(m_game_window);
|
||||
ret->SetTargetWindow(reinterpret_cast<QWindow*>(m_game_window));
|
||||
break;
|
||||
}
|
||||
case mouse_handler::raw:
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <QWindow>
|
||||
#include <QThread>
|
||||
|
||||
struct EmuCallbacks;
|
||||
class gs_frame;
|
||||
|
||||
class main_application
|
||||
{
|
||||
|
@ -25,5 +26,5 @@ protected:
|
|||
EmuCallbacks CreateCallbacks();
|
||||
|
||||
std::string m_active_user;
|
||||
QWindow* m_game_window = nullptr; // (Currently) only needed so that pad handlers have a valid target for event filtering.
|
||||
gs_frame* m_game_window = nullptr;
|
||||
};
|
||||
|
|
|
@ -28,6 +28,11 @@ gl_gs_frame::gl_gs_frame(QScreen* screen, const QRect& geometry, const QIcon& ap
|
|||
show();
|
||||
}
|
||||
|
||||
void gl_gs_frame::reset()
|
||||
{
|
||||
m_primary_context = nullptr;
|
||||
}
|
||||
|
||||
draw_context_t gl_gs_frame::make_context()
|
||||
{
|
||||
auto context = new GLContext();
|
||||
|
|
|
@ -20,6 +20,7 @@ private:
|
|||
public:
|
||||
explicit gl_gs_frame(QScreen* screen, const QRect& geometry, const QIcon& appIcon, std::shared_ptr<gui_settings> gui_settings, bool force_fullscreen);
|
||||
|
||||
void reset() override;
|
||||
draw_context_t make_context() override;
|
||||
void set_current(draw_context_t ctx) override;
|
||||
void delete_context(draw_context_t ctx) override;
|
||||
|
|
|
@ -328,6 +328,7 @@ void gs_frame::handle_shortcut(gui::shortcuts::shortcut shortcut_key, const QKey
|
|||
{
|
||||
Emu.Restart();
|
||||
};
|
||||
Emu.SetContinuousMode(true);
|
||||
}
|
||||
|
||||
Emu.Kill(false, true);
|
||||
|
@ -623,6 +624,10 @@ void gs_frame::close()
|
|||
});
|
||||
}
|
||||
|
||||
void gs_frame::reset()
|
||||
{
|
||||
}
|
||||
|
||||
bool gs_frame::shown()
|
||||
{
|
||||
return QWindow::isVisible();
|
||||
|
|
|
@ -80,6 +80,7 @@ protected:
|
|||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
void close() override;
|
||||
void reset() override;
|
||||
|
||||
bool shown() override;
|
||||
void hide() override;
|
||||
|
|
|
@ -348,6 +348,28 @@ void gui_application::InitializeConnects()
|
|||
|
||||
std::unique_ptr<gs_frame> gui_application::get_gs_frame()
|
||||
{
|
||||
// Load AppIcon
|
||||
const QIcon app_icon = m_main_window ? m_main_window->GetAppIcon() : gui::utils::get_app_icon_from_path(Emu.GetBoot(), Emu.GetTitleID());
|
||||
|
||||
if (m_game_window)
|
||||
{
|
||||
// Check if the continuous mode is enabled. We reset the mode after each use in order to ensure that it is only used when explicitly needed.
|
||||
const bool continuous_mode_enabled = Emu.ContinuousModeEnabled(true);
|
||||
|
||||
if (Emu.IsChildProcess() || continuous_mode_enabled)
|
||||
{
|
||||
gui_log.notice("gui_application: Re-using old game window (IsChildProcess=%d, ContinuousModeEnabled=%d)", Emu.IsChildProcess(), continuous_mode_enabled);
|
||||
|
||||
if (!app_icon.isNull())
|
||||
{
|
||||
m_game_window->setIcon(app_icon);
|
||||
}
|
||||
return std::unique_ptr<gs_frame>(m_game_window);
|
||||
}
|
||||
}
|
||||
|
||||
gui_log.notice("gui_application: Creating new game window");
|
||||
|
||||
extern const std::unordered_map<video_resolution, std::pair<int, int>, value_hash<video_resolution>> g_video_out_resolution_map;
|
||||
|
||||
auto [w, h] = ::at32(g_video_out_resolution_map, g_cfg.video.resolution);
|
||||
|
@ -424,9 +446,6 @@ std::unique_ptr<gs_frame> gui_application::get_gs_frame()
|
|||
frame_geometry.setSize(QSize(w, h));
|
||||
}
|
||||
|
||||
// Load AppIcon
|
||||
const QIcon app_icon = m_main_window ? m_main_window->GetAppIcon() : gui::utils::get_app_icon_from_path(Emu.GetBoot(), Emu.GetTitleID());
|
||||
|
||||
gs_frame* frame = nullptr;
|
||||
|
||||
switch (g_cfg.video.renderer.get())
|
||||
|
@ -446,6 +465,12 @@ std::unique_ptr<gs_frame> gui_application::get_gs_frame()
|
|||
|
||||
m_game_window = frame;
|
||||
|
||||
connect(m_game_window, &gs_frame::destroyed, this, [this]()
|
||||
{
|
||||
gui_log.notice("gui_application: Deleting old game window");
|
||||
m_game_window = nullptr;
|
||||
});
|
||||
|
||||
return std::unique_ptr<gs_frame>(frame);
|
||||
}
|
||||
|
||||
|
@ -582,10 +607,10 @@ void gui_application::InitializeCallbacks()
|
|||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0: static_cast<gs_frame*>(m_game_window)->progress_reset(value); break;
|
||||
case 1: static_cast<gs_frame*>(m_game_window)->progress_increment(value); break;
|
||||
case 2: static_cast<gs_frame*>(m_game_window)->progress_set_limit(value); break;
|
||||
case 3: static_cast<gs_frame*>(m_game_window)->progress_set_value(value); break;
|
||||
case 0: m_game_window->progress_reset(value); break;
|
||||
case 1: m_game_window->progress_increment(value); break;
|
||||
case 2: m_game_window->progress_set_limit(value); break;
|
||||
case 3: m_game_window->progress_set_value(value); break;
|
||||
default: gui_log.fatal("Unknown type in handle_taskbar_progress(type=%d, value=%d)", type, value); break;
|
||||
}
|
||||
}
|
||||
|
@ -1045,7 +1070,7 @@ void gui_application::OnShortcutChange()
|
|||
{
|
||||
if (m_game_window)
|
||||
{
|
||||
static_cast<gs_frame*>(m_game_window)->update_shortcuts();
|
||||
m_game_window->update_shortcuts();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1074,7 +1099,7 @@ void gui_application::OnAppStateChanged(Qt::ApplicationState state)
|
|||
}
|
||||
|
||||
const auto emu_state = Emu.GetStatus();
|
||||
const bool is_active = state == Qt::ApplicationActive;
|
||||
const bool is_active = state & Qt::ApplicationActive;
|
||||
|
||||
if (emu_state != system_state::paused && emu_state != system_state::running)
|
||||
{
|
||||
|
|
|
@ -2590,6 +2590,7 @@ void main_window::CreateConnects()
|
|||
{
|
||||
Emu.Restart();
|
||||
};
|
||||
Emu.SetContinuousMode(true);
|
||||
}
|
||||
|
||||
Emu.Kill(false, true);
|
||||
|
|
Loading…
Add table
Reference in a new issue