diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-26 01:00:38 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-10-26 01:00:38 +0200 |
commit | 3716c496b975e0205e0cb65466e02e919ab4741e (patch) | |
tree | 23c6ad2aa6c3de0963506d6a353ebd989a6e161d | |
parent | 22998e309dcf6c95c36730f86030bece0fca9667 (diff) |
work on frame limiter
-rw-r--r-- | main/events.cpp | 2 | ||||
-rw-r--r-- | main/main-impl.cpp | 43 | ||||
-rw-r--r-- | main/main-impl.hpp | 6 |
3 files changed, 39 insertions, 12 deletions
diff --git a/main/events.cpp b/main/events.cpp index 35340a21..8b94ba7b 100644 --- a/main/events.cpp +++ b/main/events.cpp @@ -77,7 +77,7 @@ void main_impl::anyEvent(SDL_Event& event) { if (event.type == SDL_WINDOWEVENT) { - update_from_window_flags(); + update_window_state(); switch (event.window.event) { case SDL_WINDOWEVENT_FOCUS_LOST: diff --git a/main/main-impl.cpp b/main/main-impl.cpp index 66388777..f4593344 100644 --- a/main/main-impl.cpp +++ b/main/main-impl.cpp @@ -69,6 +69,7 @@ auto main_impl::make_gl_conf(const fm_settings& s) -> GLConfiguration void main_impl::recalc_viewport(Vector2i size) noexcept { + update_window_state(); GL::defaultFramebuffer.setViewport({{}, size }); _msaa_framebuffer.detach(GL::Framebuffer::ColorAttachment{0}); _msaa_renderbuffer = Magnum::GL::Renderbuffer{}; @@ -95,7 +96,8 @@ main_impl::main_impl(floormat_app& app, fm_settings&& s, int& fake_argc) noexcep case fm_tristate::off: setSwapInterval(0); break; - default: break; + default: + break; } set_fp_mask(); fm_assert(framebufferSize() == windowSize()); @@ -155,15 +157,31 @@ void main_impl::draw_world() noexcept } } -void main_impl::update_from_window_flags() +static int get_window_refresh_rate(SDL_Window* window) +{ + fm_assert(window != nullptr); + if (int index = SDL_GetWindowDisplayIndex(window); index < 0) + fm_warn_once("SDL_GetWindowDisplayIndex: %s", SDL_GetError()); + else if (SDL_DisplayMode dpymode; SDL_GetCurrentDisplayMode(index, &dpymode) < 0) + fm_warn_once("SDL_GetCurrentDisplayMode: %s", SDL_GetError()); + else + return std::max(30, dpymode.refresh_rate); + return 30; +} + +void main_impl::update_window_state() { const auto flags = (SDL_WindowFlags)SDL_GetWindowFlags(window()); dt_expected.do_sleep = true; + dt_expected.jitter = 0; if (flags & SDL_WINDOW_HIDDEN) dt_expected.value = 1; else if (!(flags & SDL_WINDOW_INPUT_FOCUS)) dt_expected.value = 1.f / 30; + else if (int interval = std::abs(SDL_GL_GetSwapInterval()); + s.vsync >= fm_tristate::maybe && interval > 0) + dt_expected.value = 0.5f / (get_window_refresh_rate(window())); #if 1 else if (!(flags & SDL_WINDOW_MOUSE_FOCUS)) dt_expected.value = 1.f / 60; @@ -197,7 +215,7 @@ void main_impl::drawEvent() timeline.nextFrame(); } - dt = std::clamp(dt, 1e-5f, dt_expected.value); + dt = std::clamp(dt, 1e-5f, std::fmaxf(1e-1f, dt_expected.value)); app.update(dt); _shader.set_tint({1, 1, 1, 1}); @@ -223,12 +241,21 @@ void main_impl::drawEvent() if (dt_expected.do_sleep) { - constexpr float jitter_max_seconds = 1 + 1e-3f; - const float dt0 = timeline.currentFrameTime(), sleep_secs = dt_expected.value - dt0 - dt_expected.jitter; - if (sleep_secs > 0) +#ifdef _WIN32 + constexpr float eps = 1e-3f; +#else + constexpr float eps = 2e-4f; +#endif + + const float dt0 = timeline.currentFrameDuration(), sleep_secs = dt_expected.value - dt0 - dt_expected.jitter; + if (sleep_secs > eps) + { + //fm_debug("sleeping for %.1f <- %.1f\n", sleep_secs*1000, dt0*1000); std::this_thread::sleep_for(std::chrono::nanoseconds((long long)(sleep_secs * 1e9f))); - dt_expected.jitter += timeline.currentFrameTime() - dt_expected.value; - dt_expected.jitter = std::copysignf(std::fminf(jitter_max_seconds, std::fabsf(dt_expected.jitter)), dt_expected.jitter); + } + //fm_debug("jitter:%.1f sleep:%.0f", dt_expected.jitter*1000, sleep_secs*1000); + dt_expected.jitter += 0.1f * (timeline.currentFrameDuration() - dt_expected.value); + dt_expected.jitter = std::copysignf(std::fminf(dt_expected.value, std::fabsf(dt_expected.jitter)), dt_expected.jitter); } else dt_expected.jitter = 0; diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 202654db..d4a5af9a 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -51,7 +51,7 @@ struct main_impl final : Platform::Sdl2Application, floormat_main [[maybe_unused]] void anyEvent(SDL_Event& event) override; void drawEvent() override; - void update_from_window_flags(); + void update_window_state(); bool is_text_input_active() const noexcept override; void start_text_input() noexcept override; @@ -69,9 +69,9 @@ private: wall_mesh _wall_mesh; Magnum::Timeline timeline; struct { - float value = 1e-1f; + float value = 0; float jitter = 0; - bool do_sleep = true; + bool do_sleep = false; } dt_expected; struct draw_bounds final { std::int16_t minx, maxx, miny, maxy; }; |