perf_stats.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // Copyright 2017 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <chrono>
  6. #include <mutex>
  7. #include "common/common_types.h"
  8. namespace Core {
  9. /**
  10. * Class to manage and query performance/timing statistics. All public functions of this class are
  11. * thread-safe unless stated otherwise.
  12. */
  13. class PerfStats {
  14. public:
  15. using Clock = std::chrono::high_resolution_clock;
  16. struct Results {
  17. /// System FPS (LCD VBlanks) in Hz
  18. double system_fps;
  19. /// Game FPS (GSP frame submissions) in Hz
  20. double game_fps;
  21. /// Walltime per system frame, in seconds, excluding any waits
  22. double frametime;
  23. /// Ratio of walltime / emulated time elapsed
  24. double emulation_speed;
  25. };
  26. void BeginSystemFrame();
  27. void EndSystemFrame();
  28. void EndGameFrame();
  29. Results GetAndResetStats(u64 current_system_time_us);
  30. /**
  31. * Gets the ratio between walltime and the emulated time of the previous system frame. This is
  32. * useful for scaling inputs or outputs moving between the two time domains.
  33. */
  34. double GetLastFrameTimeScale();
  35. private:
  36. std::mutex object_mutex;
  37. /// Point when the cumulative counters were reset
  38. Clock::time_point reset_point = Clock::now();
  39. /// System time when the cumulative counters were reset
  40. u64 reset_point_system_us = 0;
  41. /// Cumulative duration (excluding v-sync/frame-limiting) of frames since last reset
  42. Clock::duration accumulated_frametime = Clock::duration::zero();
  43. /// Cumulative number of system frames (LCD VBlanks) presented since last reset
  44. u32 system_frames = 0;
  45. /// Cumulative number of game frames (GSP frame submissions) since last reset
  46. u32 game_frames = 0;
  47. /// Point when the previous system frame ended
  48. Clock::time_point previous_frame_end = reset_point;
  49. /// Point when the current system frame began
  50. Clock::time_point frame_begin = reset_point;
  51. /// Total visible duration (including frame-limiting, etc.) of the previous system frame
  52. Clock::duration previous_frame_length = Clock::duration::zero();
  53. };
  54. class FrameLimiter {
  55. public:
  56. using Clock = std::chrono::high_resolution_clock;
  57. void DoFrameLimiting(u64 current_system_time_us);
  58. private:
  59. /// Emulated system time (in microseconds) at the last limiter invocation
  60. u64 previous_system_time_us = 0;
  61. /// Walltime at the last limiter invocation
  62. Clock::time_point previous_walltime = Clock::now();
  63. /// Accumulated difference between walltime and emulated time
  64. std::chrono::microseconds frame_limiting_delta_err{0};
  65. };
  66. } // namespace Core