HostInterface: Move setting update logic to base class

This commit is contained in:
Connor McLaughlin 2020-01-24 14:51:52 +10:00
parent 82563d94f4
commit f2231d6669
4 changed files with 90 additions and 79 deletions

View file

@ -442,6 +442,8 @@ void HostInterface::UpdateSpeedLimiterState()
m_last_throttle_time = 0; m_last_throttle_time = 0;
} }
void HostInterface::SwitchGPURenderer() {}
void HostInterface::OnPerformanceCountersUpdated() {} void HostInterface::OnPerformanceCountersUpdated() {}
void HostInterface::OnRunningGameChanged() {} void HostInterface::OnRunningGameChanged() {}
@ -511,6 +513,42 @@ std::string HostInterface::GetGameListDatabaseFileName() const
return GetUserDirectoryRelativePath("cache/redump.dat"); return GetUserDirectoryRelativePath("cache/redump.dat");
} }
void HostInterface::UpdateSettings(const std::function<void()>& apply_callback)
{
// TODO: Should we move this to the base class?
const GPURenderer old_gpu_renderer = m_settings.gpu_renderer;
const u32 old_gpu_resolution_scale = m_settings.gpu_resolution_scale;
const bool old_gpu_true_color = m_settings.gpu_true_color;
const bool old_gpu_texture_filtering = m_settings.gpu_texture_filtering;
const bool old_gpu_force_progressive_scan = m_settings.gpu_force_progressive_scan;
const bool old_vsync_enabled = m_settings.video_sync_enabled;
const bool old_audio_sync_enabled = m_settings.audio_sync_enabled;
const bool old_speed_limiter_enabled = m_settings.speed_limiter_enabled;
const bool old_display_linear_filtering = m_settings.display_linear_filtering;
apply_callback();
// TODO: Fast path for hardware->software switches
if (m_settings.gpu_renderer != old_gpu_renderer)
SwitchGPURenderer();
if (m_settings.video_sync_enabled != old_vsync_enabled || m_settings.audio_sync_enabled != old_audio_sync_enabled ||
m_settings.speed_limiter_enabled != old_speed_limiter_enabled)
{
UpdateSpeedLimiterState();
}
if (m_settings.gpu_resolution_scale != old_gpu_resolution_scale || m_settings.gpu_true_color != old_gpu_true_color ||
m_settings.gpu_texture_filtering != old_gpu_texture_filtering ||
m_settings.gpu_force_progressive_scan != old_gpu_force_progressive_scan)
{
m_system->UpdateGPUSettings();
}
if (m_settings.display_linear_filtering != old_display_linear_filtering)
m_display->SetDisplayLinearFiltering(m_settings.display_linear_filtering);
}
void HostInterface::RunFrame() void HostInterface::RunFrame()
{ {
m_frame_timer.Reset(); m_frame_timer.Reset();

View file

@ -4,6 +4,7 @@
#include "types.h" #include "types.h"
#include <chrono> #include <chrono>
#include <deque> #include <deque>
#include <functional>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
@ -85,6 +86,7 @@ protected:
float duration; float duration;
}; };
virtual void SwitchGPURenderer();
virtual void OnPerformanceCountersUpdated(); virtual void OnPerformanceCountersUpdated();
virtual void OnRunningGameChanged(); virtual void OnRunningGameChanged();
@ -102,6 +104,8 @@ protected:
/// Returns the path of the game database cache file. /// Returns the path of the game database cache file.
std::string GetGameListDatabaseFileName() const; std::string GetGameListDatabaseFileName() const;
void UpdateSettings(const std::function<void()>& apply_callback);
void RunFrame(); void RunFrame();
/// Throttles the system, i.e. sleeps until it's time to execute the next frame. /// Throttles the system, i.e. sleeps until it's time to execute the next frame.

View file

@ -108,42 +108,11 @@ void QtHostInterface::applySettings()
return; return;
} }
// TODO: Should we move this to the base class? UpdateSettings([this]() {
const GPURenderer old_gpu_renderer = m_settings.gpu_renderer;
const u32 old_gpu_resolution_scale = m_settings.gpu_resolution_scale;
const bool old_gpu_true_color = m_settings.gpu_true_color;
const bool old_gpu_texture_filtering = m_settings.gpu_texture_filtering;
const bool old_gpu_force_progressive_scan = m_settings.gpu_force_progressive_scan;
const bool old_vsync_enabled = m_settings.video_sync_enabled;
const bool old_audio_sync_enabled = m_settings.audio_sync_enabled;
const bool old_speed_limiter_enabled = m_settings.speed_limiter_enabled;
const bool old_display_linear_filtering = m_settings.display_linear_filtering;
{
std::lock_guard<std::mutex> guard(m_qsettings_mutex); std::lock_guard<std::mutex> guard(m_qsettings_mutex);
QtSettingsInterface si(m_qsettings); QtSettingsInterface si(m_qsettings);
m_settings.Load(si); m_settings.Load(si);
} });
// TODO: Fast path for hardware->software switches
if (m_settings.gpu_renderer != old_gpu_renderer)
switchGPURenderer();
if (m_settings.video_sync_enabled != old_vsync_enabled || m_settings.audio_sync_enabled != old_audio_sync_enabled ||
m_settings.speed_limiter_enabled != old_speed_limiter_enabled)
{
UpdateSpeedLimiterState();
}
if (m_settings.gpu_resolution_scale != old_gpu_resolution_scale || m_settings.gpu_true_color != old_gpu_true_color ||
m_settings.gpu_texture_filtering != old_gpu_texture_filtering ||
m_settings.gpu_force_progressive_scan != old_gpu_force_progressive_scan)
{
m_system->UpdateGPUSettings();
}
if (m_settings.display_linear_filtering != old_display_linear_filtering)
m_display_window->getHostDisplayInterface()->SetDisplayLinearFiltering(m_settings.display_linear_filtering);
} }
void QtHostInterface::checkSettings() void QtHostInterface::checkSettings()
@ -254,6 +223,51 @@ void QtHostInterface::onDisplayWindowResized(int width, int height)
m_display_window->onWindowResized(width, height); m_display_window->onWindowResized(width, height);
} }
void QtHostInterface::SwitchGPURenderer()
{
// Due to the GPU class owning textures, we have to shut the system down.
std::unique_ptr<ByteStream> stream;
if (m_system)
{
stream = ByteStream_CreateGrowableMemoryStream(nullptr, 8 * 1024);
if (!m_system->SaveState(stream.get()) || !stream->SeekAbsolute(0))
ReportError("Failed to save state before GPU renderer switch");
DestroySystem();
m_audio_stream->PauseOutput(true);
m_display_window->destroyDeviceContext();
}
const bool restore_state = static_cast<bool>(stream);
emit recreateDisplayWidgetRequested(restore_state);
Assert(m_display_window != nullptr);
if (restore_state)
{
if (!m_display_window->initializeDeviceContext(m_settings.gpu_use_debug_device))
{
emit runningGameChanged(QString(), QString(), QString());
emit emulationStopped();
return;
}
CreateSystem();
if (!BootSystem(nullptr, nullptr) || !m_system->LoadState(stream.get()))
{
ReportError("Failed to load state after GPU renderer switch, resetting");
m_system->Reset();
}
if (!m_paused)
{
m_audio_stream->PauseOutput(false);
UpdateSpeedLimiterState();
}
}
ResetPerformanceCounters();
}
void QtHostInterface::OnPerformanceCountersUpdated() void QtHostInterface::OnPerformanceCountersUpdated()
{ {
HostInterface::OnPerformanceCountersUpdated(); HostInterface::OnPerformanceCountersUpdated();
@ -517,51 +531,6 @@ void QtHostInterface::createAudioStream()
} }
} }
void QtHostInterface::switchGPURenderer()
{
// Due to the GPU class owning textures, we have to shut the system down.
std::unique_ptr<ByteStream> stream;
if (m_system)
{
stream = ByteStream_CreateGrowableMemoryStream(nullptr, 8 * 1024);
if (!m_system->SaveState(stream.get()) || !stream->SeekAbsolute(0))
ReportError("Failed to save state before GPU renderer switch");
DestroySystem();
m_audio_stream->PauseOutput(true);
m_display_window->destroyDeviceContext();
}
const bool restore_state = static_cast<bool>(stream);
emit recreateDisplayWidgetRequested(restore_state);
Assert(m_display_window != nullptr);
if (restore_state)
{
if (!m_display_window->initializeDeviceContext(m_settings.gpu_use_debug_device))
{
emit runningGameChanged(QString(), QString(), QString());
emit emulationStopped();
return;
}
CreateSystem();
if (!BootSystem(nullptr, nullptr) || !m_system->LoadState(stream.get()))
{
ReportError("Failed to load state after GPU renderer switch, resetting");
m_system->Reset();
}
if (!m_paused)
{
m_audio_stream->PauseOutput(false);
UpdateSpeedLimiterState();
}
}
ResetPerformanceCounters();
}
void QtHostInterface::createThread() void QtHostInterface::createThread()
{ {
m_original_thread = QThread::currentThread(); m_original_thread = QThread::currentThread();

View file

@ -89,6 +89,7 @@ private Q_SLOTS:
void onDisplayWindowResized(int width, int height); void onDisplayWindowResized(int width, int height);
protected: protected:
void SwitchGPURenderer() override;
void OnPerformanceCountersUpdated() override; void OnPerformanceCountersUpdated() override;
void OnRunningGameChanged() override; void OnRunningGameChanged() override;
@ -120,7 +121,6 @@ private:
void updateHotkeyInputMap(); void updateHotkeyInputMap();
void addButtonToInputMap(const QString& binding, InputButtonHandler handler); void addButtonToInputMap(const QString& binding, InputButtonHandler handler);
void createAudioStream(); void createAudioStream();
void switchGPURenderer();
void createThread(); void createThread();
void stopThread(); void stopThread();
void threadEntryPoint(); void threadEntryPoint();