CoreTiming: Add a setting to use Common::PrecisionTimer.

This commit is contained in:
Jordan Woyak 2025-03-14 18:16:24 -05:00
parent e5c8935acc
commit 7dc27753e2
6 changed files with 46 additions and 46 deletions

View file

@ -211,6 +211,15 @@ const Info<bool> MAIN_FPRF{{System::Main, "Core", "FPRF"}, false};
const Info<bool> MAIN_ACCURATE_NANS{{System::Main, "Core", "AccurateNaNs"}, false}; const Info<bool> MAIN_ACCURATE_NANS{{System::Main, "Core", "AccurateNaNs"}, false};
const Info<bool> MAIN_DISABLE_ICACHE{{System::Main, "Core", "DisableICache"}, false}; const Info<bool> MAIN_DISABLE_ICACHE{{System::Main, "Core", "DisableICache"}, false};
const Info<float> MAIN_EMULATION_SPEED{{System::Main, "Core", "EmulationSpeed"}, 1.0f}; const Info<float> MAIN_EMULATION_SPEED{{System::Main, "Core", "EmulationSpeed"}, 1.0f};
#if defined(ANDROID)
// Currently disabled by default on Android for concern of increased power usage while on battery.
// It is also not yet exposed in the UI on Android.
constexpr bool DEFAULT_PRECISION_FRAME_TIMING = false;
#else
constexpr bool DEFAULT_PRECISION_FRAME_TIMING = true;
#endif
const Info<bool> MAIN_PRECISION_FRAME_TIMING{{System::Main, "Core", "PrecisionFrameTiming"},
DEFAULT_PRECISION_FRAME_TIMING};
const Info<float> MAIN_OVERCLOCK{{System::Main, "Core", "Overclock"}, 1.0f}; const Info<float> MAIN_OVERCLOCK{{System::Main, "Core", "Overclock"}, 1.0f};
const Info<bool> MAIN_OVERCLOCK_ENABLE{{System::Main, "Core", "OverclockEnable"}, false}; const Info<bool> MAIN_OVERCLOCK_ENABLE{{System::Main, "Core", "OverclockEnable"}, false};
const Info<bool> MAIN_RAM_OVERRIDE_ENABLE{{System::Main, "Core", "RAMOverrideEnable"}, false}; const Info<bool> MAIN_RAM_OVERRIDE_ENABLE{{System::Main, "Core", "RAMOverrideEnable"}, false};

View file

@ -125,6 +125,7 @@ extern const Info<bool> MAIN_FPRF;
extern const Info<bool> MAIN_ACCURATE_NANS; extern const Info<bool> MAIN_ACCURATE_NANS;
extern const Info<bool> MAIN_DISABLE_ICACHE; extern const Info<bool> MAIN_DISABLE_ICACHE;
extern const Info<float> MAIN_EMULATION_SPEED; extern const Info<float> MAIN_EMULATION_SPEED;
extern const Info<bool> MAIN_PRECISION_FRAME_TIMING;
extern const Info<float> MAIN_OVERCLOCK; extern const Info<float> MAIN_OVERCLOCK;
extern const Info<bool> MAIN_OVERCLOCK_ENABLE; extern const Info<bool> MAIN_OVERCLOCK_ENABLE;
extern const Info<bool> MAIN_RAM_OVERRIDE_ENABLE; extern const Info<bool> MAIN_RAM_OVERRIDE_ENABLE;

View file

@ -137,6 +137,8 @@ void CoreTimingManager::RefreshConfig()
} }
m_emulation_speed = Config::Get(Config::MAIN_EMULATION_SPEED); m_emulation_speed = Config::Get(Config::MAIN_EMULATION_SPEED);
m_use_precision_timer = Config::Get(Config::MAIN_PRECISION_FRAME_TIMING);
} }
void CoreTimingManager::DoState(PointerWrap& p) void CoreTimingManager::DoState(PointerWrap& p)
@ -373,6 +375,12 @@ void CoreTimingManager::SleepUntil(TimePoint time_point)
{ {
const TimePoint time = Clock::now(); const TimePoint time = Clock::now();
if (time >= time_point)
return;
if (m_use_precision_timer)
m_precision_timer.SleepUntil(time_point);
else
std::this_thread::sleep_until(time_point); std::this_thread::sleep_until(time_point);
if (Core::IsCPUThread()) if (Core::IsCPUThread())
@ -416,15 +424,7 @@ void CoreTimingManager::Throttle(const s64 target_cycle)
// It doesn't matter what amount of lag we skip VI at, as long as it's constant. // It doesn't matter what amount of lag we skip VI at, as long as it's constant.
m_throttle_disable_vi_int = 0.0 < speed && m_throttle_deadline < vi_deadline; m_throttle_disable_vi_int = 0.0 < speed && m_throttle_deadline < vi_deadline;
// Only sleep if we are behind the deadline SleepUntil(m_throttle_deadline);
if (time < m_throttle_deadline)
{
std::this_thread::sleep_until(m_throttle_deadline);
// Count amount of time sleeping for analytics
const TimePoint time_after_sleep = Clock::now();
g_perf_metrics.CountThrottleSleep(time_after_sleep - time);
}
} }
void CoreTimingManager::ResetThrottle(s64 cycle) void CoreTimingManager::ResetThrottle(s64 cycle)

View file

@ -24,6 +24,7 @@
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/SPSCQueue.h" #include "Common/SPSCQueue.h"
#include "Common/Timer.h"
#include "Core/CPUThreadConfigCallback.h" #include "Core/CPUThreadConfigCallback.h"
class PointerWrap; class PointerWrap;
@ -214,6 +215,9 @@ private:
int DowncountToCycles(int downcount) const; int DowncountToCycles(int downcount) const;
int CyclesToDowncount(int cycles) const; int CyclesToDowncount(int cycles) const;
bool m_use_precision_timer = false;
Common::PrecisionTimer m_precision_timer;
}; };
} // namespace CoreTiming } // namespace CoreTiming

View file

@ -36,7 +36,6 @@
GeneralWidget::GeneralWidget(GraphicsWindow* parent) GeneralWidget::GeneralWidget(GraphicsWindow* parent)
{ {
CreateWidgets(); CreateWidgets();
LoadSettings();
ConnectWidgets(); ConnectWidgets();
AddDescriptions(); AddDescriptions();
@ -50,7 +49,6 @@ GeneralWidget::GeneralWidget(GraphicsWindow* parent)
GeneralWidget::GeneralWidget(GameConfigWidget* parent, Config::Layer* layer) : m_game_layer(layer) GeneralWidget::GeneralWidget(GameConfigWidget* parent, Config::Layer* layer) : m_game_layer(layer)
{ {
CreateWidgets(); CreateWidgets();
LoadSettings();
ConnectWidgets(); ConnectWidgets();
AddDescriptions(); AddDescriptions();
} }
@ -61,7 +59,7 @@ void GeneralWidget::CreateWidgets()
// Basic Section // Basic Section
auto* m_video_box = new QGroupBox(tr("Basic")); auto* m_video_box = new QGroupBox(tr("Basic"));
m_video_layout = new QGridLayout(); auto* const video_layout = new QGridLayout{m_video_box};
std::vector<std::pair<QString, QString>> options; std::vector<std::pair<QString, QString>> options;
for (auto& backend : VideoBackendBase::GetAvailableBackends()) for (auto& backend : VideoBackendBase::GetAvailableBackends())
@ -76,38 +74,41 @@ void GeneralWidget::CreateWidgets()
tr("Stretch to Window"), tr("Custom"), tr("Custom (Stretch)")}, tr("Stretch to Window"), tr("Custom"), tr("Custom (Stretch)")},
Config::GFX_ASPECT_RATIO, m_game_layer); Config::GFX_ASPECT_RATIO, m_game_layer);
m_custom_aspect_label = new QLabel(tr("Custom Aspect Ratio:")); m_custom_aspect_label = new QLabel(tr("Custom Aspect Ratio:"));
m_custom_aspect_label->setHidden(true);
constexpr int MAX_CUSTOM_ASPECT_RATIO_RESOLUTION = 10000; constexpr int MAX_CUSTOM_ASPECT_RATIO_RESOLUTION = 10000;
m_custom_aspect_width = new ConfigInteger(1, MAX_CUSTOM_ASPECT_RATIO_RESOLUTION, m_custom_aspect_width = new ConfigInteger(1, MAX_CUSTOM_ASPECT_RATIO_RESOLUTION,
Config::GFX_CUSTOM_ASPECT_RATIO_WIDTH, m_game_layer); Config::GFX_CUSTOM_ASPECT_RATIO_WIDTH, m_game_layer);
m_custom_aspect_width->setEnabled(false);
m_custom_aspect_width->setHidden(true);
m_custom_aspect_height = new ConfigInteger(1, MAX_CUSTOM_ASPECT_RATIO_RESOLUTION, m_custom_aspect_height = new ConfigInteger(1, MAX_CUSTOM_ASPECT_RATIO_RESOLUTION,
Config::GFX_CUSTOM_ASPECT_RATIO_HEIGHT, m_game_layer); Config::GFX_CUSTOM_ASPECT_RATIO_HEIGHT, m_game_layer);
m_custom_aspect_height->setEnabled(false);
m_custom_aspect_height->setHidden(true);
m_adapter_combo = new ToolTipComboBox; m_adapter_combo = new ToolTipComboBox;
m_enable_vsync = new ConfigBool(tr("V-Sync"), Config::GFX_VSYNC, m_game_layer); m_enable_vsync = new ConfigBool(tr("V-Sync"), Config::GFX_VSYNC, m_game_layer);
m_enable_fullscreen = m_enable_fullscreen =
new ConfigBool(tr("Start in Fullscreen"), Config::MAIN_FULLSCREEN, m_game_layer); new ConfigBool(tr("Start in Fullscreen"), Config::MAIN_FULLSCREEN, m_game_layer);
m_video_box->setLayout(m_video_layout); video_layout->addWidget(new QLabel(tr("Backend:")), 0, 0);
video_layout->addWidget(m_backend_combo, 0, 1, 1, -1);
m_video_layout->addWidget(new QLabel(tr("Backend:")), 0, 0); video_layout->addWidget(new QLabel(tr("Adapter:")), 1, 0);
m_video_layout->addWidget(m_backend_combo, 0, 1, 1, -1); video_layout->addWidget(m_adapter_combo, 1, 1, 1, -1);
m_video_layout->addWidget(new QLabel(tr("Adapter:")), 1, 0); video_layout->addWidget(new QLabel(tr("Aspect Ratio:")), 2, 0);
m_video_layout->addWidget(m_adapter_combo, 1, 1, 1, -1); video_layout->addWidget(m_aspect_combo, 2, 1, 1, -1);
m_video_layout->addWidget(new QLabel(tr("Aspect Ratio:")), 3, 0); video_layout->addWidget(m_custom_aspect_label, 3, 0);
m_video_layout->addWidget(m_aspect_combo, 3, 1, 1, -1); video_layout->addWidget(m_custom_aspect_width, 3, 1);
video_layout->addWidget(m_custom_aspect_height, 3, 2);
m_video_layout->addWidget(m_custom_aspect_label, 4, 0); auto* const basic_grid = new QGridLayout;
m_video_layout->addWidget(m_custom_aspect_width, 4, 1); video_layout->addLayout(basic_grid, video_layout->rowCount(), 0, 1, -1);
m_video_layout->addWidget(m_custom_aspect_height, 4, 2); basic_grid->addWidget(m_enable_vsync, 0, 0);
basic_grid->addWidget(m_enable_fullscreen, 0, 1);
m_video_layout->addWidget(m_enable_vsync, 5, 0); auto* const precision_timing =
m_video_layout->addWidget(m_enable_fullscreen, 5, 1, 1, -1); new ConfigBool(tr("Precision Frame Timing"), Config::MAIN_PRECISION_FRAME_TIMING);
precision_timing->SetDescription(
tr("Uses high resolution timers and \"busy waiting\" for improved frame pacing."
"<br><br>This will marginally increase power usage."
"<br><br><dolphin_emphasis>If unsure, leave this checked.</dolphin_emphasis>"));
basic_grid->addWidget(precision_timing, 1, 0);
// Other // Other
auto* m_options_box = new QGroupBox(tr("Other")); auto* m_options_box = new QGroupBox(tr("Other"));
@ -171,24 +172,11 @@ void GeneralWidget::ConnectWidgets()
connect(m_aspect_combo, qOverload<int>(&QComboBox::currentIndexChanged), this, [&](int index) { connect(m_aspect_combo, qOverload<int>(&QComboBox::currentIndexChanged), this, [&](int index) {
const bool is_custom_aspect_ratio = (index == static_cast<int>(AspectMode::Custom)) || const bool is_custom_aspect_ratio = (index == static_cast<int>(AspectMode::Custom)) ||
(index == static_cast<int>(AspectMode::CustomStretch)); (index == static_cast<int>(AspectMode::CustomStretch));
m_custom_aspect_width->setEnabled(is_custom_aspect_ratio);
m_custom_aspect_height->setEnabled(is_custom_aspect_ratio);
m_custom_aspect_label->setHidden(!is_custom_aspect_ratio); m_custom_aspect_label->setHidden(!is_custom_aspect_ratio);
m_custom_aspect_width->setHidden(!is_custom_aspect_ratio); m_custom_aspect_width->setHidden(!is_custom_aspect_ratio);
m_custom_aspect_height->setHidden(!is_custom_aspect_ratio); m_custom_aspect_height->setHidden(!is_custom_aspect_ratio);
}); });
} m_aspect_combo->currentIndexChanged(m_aspect_combo->currentIndex());
void GeneralWidget::LoadSettings()
{
const bool is_custom_aspect_ratio =
(Config::Get(Config::GFX_ASPECT_RATIO) == AspectMode::Custom) ||
(Config::Get(Config::GFX_ASPECT_RATIO) == AspectMode::CustomStretch);
m_custom_aspect_width->setEnabled(is_custom_aspect_ratio);
m_custom_aspect_height->setEnabled(is_custom_aspect_ratio);
m_custom_aspect_label->setHidden(!is_custom_aspect_ratio);
m_custom_aspect_width->setHidden(!is_custom_aspect_ratio);
m_custom_aspect_height->setHidden(!is_custom_aspect_ratio);
} }
void GeneralWidget::BackendWarning() void GeneralWidget::BackendWarning()

View file

@ -37,7 +37,6 @@ signals:
void BackendChanged(const QString& backend); void BackendChanged(const QString& backend);
private: private:
void LoadSettings();
void BackendWarning(); void BackendWarning();
void CreateWidgets(); void CreateWidgets();
@ -48,7 +47,6 @@ private:
void OnEmulationStateChanged(bool running); void OnEmulationStateChanged(bool running);
// Video // Video
QGridLayout* m_video_layout;
ConfigStringChoice* m_backend_combo; ConfigStringChoice* m_backend_combo;
ToolTipComboBox* m_adapter_combo; ToolTipComboBox* m_adapter_combo;
ConfigChoice* m_aspect_combo; ConfigChoice* m_aspect_combo;