From c75ae6c585f651a1b7c162c2e1ecccd22a1c587d Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 19 Feb 2017 14:34:47 -0800 Subject: Add performance statistics to status bar --- src/core/perf_stats.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/core/perf_stats.h (limited to 'src/core/perf_stats.h') diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h new file mode 100644 index 000000000..566a1419a --- /dev/null +++ b/src/core/perf_stats.h @@ -0,0 +1,43 @@ +// Copyright 2017 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "common/common_types.h" + +namespace Core { + +class PerfStats { +public: + using Clock = std::chrono::high_resolution_clock; + + struct Results { + /// System FPS (LCD VBlanks) in Hz + double system_fps; + /// Game FPS (GSP frame submissions) in Hz + double game_fps; + /// Walltime per system frame, in seconds, excluding any waits + double frametime; + /// Ratio of walltime / emulated time elapsed + double emulation_speed; + }; + + void BeginSystemFrame(); + void EndSystemFrame(); + void EndGameFrame(); + + Results GetAndResetStats(u64 current_system_time_us); + +private: + Clock::time_point reset_point = Clock::now(); + + Clock::time_point frame_begin; + Clock::duration accumulated_frametime = Clock::duration::zero(); + u64 reset_point_system_us = 0; + u32 system_frames = 0; + u32 game_frames = 0; +}; + +} // namespace Core -- cgit v1.2.3 From 92c8bd4b1f650438274e50303a6d3f668924d071 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 19 Feb 2017 18:18:26 -0800 Subject: PerfStats: Add method to get the instantaneous time ratio --- src/core/perf_stats.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/core/perf_stats.h') diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 566a1419a..8a03c511a 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -30,11 +30,19 @@ public: Results GetAndResetStats(u64 current_system_time_us); + /** + * Gets the ratio between walltime and the emulated time of the previous system frame. This is + * useful for scaling inputs or outputs moving between the two time domains. + */ + double GetLastFrameTimeScale(); + private: Clock::time_point reset_point = Clock::now(); - Clock::time_point frame_begin; + Clock::time_point frame_begin = reset_point; + Clock::time_point previous_frame_end = reset_point; Clock::duration accumulated_frametime = Clock::duration::zero(); + Clock::duration previous_frame_length = Clock::duration::zero(); u64 reset_point_system_us = 0; u32 system_frames = 0; u32 game_frames = 0; -- cgit v1.2.3 From b285c2a4ed29a126b5bcfe46e2784bd1870bdf82 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 20 Feb 2017 13:56:58 -0800 Subject: Core: Make PerfStats internally locked More ergonomic to use and will be required for upcoming changes. --- src/core/perf_stats.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/core/perf_stats.h') diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 8a03c511a..4098fc1f2 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -5,10 +5,15 @@ #pragma once #include +#include #include "common/common_types.h" namespace Core { +/** + * Class to manage and query performance/timing statistics. All public functions of this class are + * thread-safe unless stated otherwise. + */ class PerfStats { public: using Clock = std::chrono::high_resolution_clock; @@ -37,6 +42,8 @@ public: double GetLastFrameTimeScale(); private: + std::mutex object_mutex; + Clock::time_point reset_point = Clock::now(); Clock::time_point frame_begin = reset_point; -- cgit v1.2.3 From fb1979d7e26c20fe2b8d2c3d3dc998e5e00f2f61 Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Mon, 20 Feb 2017 16:31:59 -0800 Subject: Core: Re-write frame limiter Now based on std::chrono, and also works in terms of emulated time instead of frames, so we can in the future frame-limit even when the display is disabled, etc. The frame limiter can also be enabled along with v-sync now, which should be useful for those with displays running at more than 60 Hz. --- src/core/perf_stats.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/core/perf_stats.h') diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index 4098fc1f2..b03adab68 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -55,4 +55,20 @@ private: u32 game_frames = 0; }; +class FrameLimiter { +public: + using Clock = std::chrono::high_resolution_clock; + + void DoFrameLimiting(u64 current_system_time_us); + +private: + /// Emulated system time (in microseconds) at the last limiter invocation + u64 previous_system_time_us = 0; + /// Walltime at the last limiter invocation + Clock::time_point previous_walltime = Clock::now(); + + /// Accumulated difference between walltime and emulated time + std::chrono::microseconds frame_limiting_delta_err{0}; +}; + } // namespace Core -- cgit v1.2.3 From 174464a87f2e1709597bc1e0cb08c877487a771b Mon Sep 17 00:00:00 2001 From: Yuri Kunde Schlesner Date: Sun, 26 Feb 2017 17:13:12 -0800 Subject: PerfStats: Re-order and document members better --- src/core/perf_stats.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/core/perf_stats.h') diff --git a/src/core/perf_stats.h b/src/core/perf_stats.h index b03adab68..362b205c8 100644 --- a/src/core/perf_stats.h +++ b/src/core/perf_stats.h @@ -44,15 +44,24 @@ public: private: std::mutex object_mutex; + /// Point when the cumulative counters were reset Clock::time_point reset_point = Clock::now(); + /// System time when the cumulative counters were reset + u64 reset_point_system_us = 0; - Clock::time_point frame_begin = reset_point; - Clock::time_point previous_frame_end = reset_point; + /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset Clock::duration accumulated_frametime = Clock::duration::zero(); - Clock::duration previous_frame_length = Clock::duration::zero(); - u64 reset_point_system_us = 0; + /// Cumulative number of system frames (LCD VBlanks) presented since last reset u32 system_frames = 0; + /// Cumulative number of game frames (GSP frame submissions) since last reset u32 game_frames = 0; + + /// Point when the previous system frame ended + Clock::time_point previous_frame_end = reset_point; + /// Point when the current system frame began + Clock::time_point frame_begin = reset_point; + /// Total visible duration (including frame-limiting, etc.) of the previous system frame + Clock::duration previous_frame_length = Clock::duration::zero(); }; class FrameLimiter { -- cgit v1.2.3