From afec9d35b9a5e1a76b12c713e570fec80a5568a1 Mon Sep 17 00:00:00 2001 From: PeachyPeachSM64 <72323920+PeachyPeachSM64@users.noreply.github.com> Date: Mon, 28 Jul 2025 22:31:40 +0200 Subject: [PATCH] Revert "much better frame pacing" - No one complained about framerate since several updates now; don't fix what isn't broken - Too much frames are drawn at low framerates when Vsync is enabled - FPS and delay calculation are wrong with Vsync: 60 FPS looks like 30 with a 120+Hz monitor - Fixed Auto mode that was broken - Kept precise_delay_f64 as I have observed no noticeable impact on CPU --- src/pc/gfx/gfx_pc.c | 12 ++--------- src/pc/gfx/gfx_pc.h | 2 -- src/pc/pc_main.c | 49 +++++++++++++++++++-------------------------- 3 files changed, 23 insertions(+), 40 deletions(-) diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index f498eb5ef..0d898b5c5 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -1970,26 +1970,18 @@ void gfx_run(Gfx *commands) { //double t0 = gfx_wapi->get_time(); gfx_rapi->start_frame(); gfx_run_dl(commands); -} - -void gfx_end_frame_render(void) { gfx_flush(); gfx_rapi->end_frame(); + gfx_wapi->swap_buffers_begin(); } -void gfx_display_frame(void) { - gfx_wapi->swap_buffers_begin(); +void gfx_end_frame(void) { if (!dropped_frame) { gfx_rapi->finish_render(); gfx_wapi->swap_buffers_end(); } } -void gfx_end_frame(void) { - gfx_end_frame_render(); - gfx_display_frame(); -} - void gfx_shutdown(void) { if (gfx_rapi) { if (gfx_rapi->shutdown) gfx_rapi->shutdown(); diff --git a/src/pc/gfx/gfx_pc.h b/src/pc/gfx/gfx_pc.h index 97fdca0cc..8469776f3 100644 --- a/src/pc/gfx/gfx_pc.h +++ b/src/pc/gfx/gfx_pc.h @@ -21,8 +21,6 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi, co struct GfxRenderingAPI *gfx_get_current_rendering_api(void); void gfx_start_frame(void); void gfx_run(Gfx *commands); -void gfx_end_frame_render(void); -void gfx_display_frame(void); void gfx_end_frame(void); void gfx_shutdown(void); void gfx_pc_precomp_shader(uint32_t rgb1, uint32_t alpha1, uint32_t rgb2, uint32_t alpha2, uint32_t flags); diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index ae1f98c28..2ad21c964 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -205,16 +205,20 @@ static s32 get_num_frames_to_draw(f64 t, u32 frameLimit) { static u32 get_refresh_rate() { if (configFramerateMode == RRM_MANUAL) { return configFrameLimit; } if (configFramerateMode == RRM_UNLIMITED) { return 3000; } // Has no effect - static u32 refreshRate = 60; + static u32 refreshRate = 0; #ifdef HAVE_SDL2 if (!refreshRate) { SDL_DisplayMode mode; if (SDL_GetCurrentDisplayMode(0, &mode) == 0) { refreshRate = (u32) mode.refresh_rate; + } else { + refreshRate = 60; } } -#endif return refreshRate; +#else + return 60; +#endif } void produce_interpolation_frames_and_delay(void) { @@ -223,53 +227,42 @@ void produce_interpolation_frames_and_delay(void) { gRenderingInterpolated = true; + f64 curTime = clock_elapsed_f64(); f64 targetTime = sFrameTimeStart + sFrameTime; s32 numFramesToDraw = get_num_frames_to_draw(sFrameTimeStart, refreshRate); - f64 curTime = clock_elapsed_f64(); f64 loopStartTime = curTime; f64 expectedTime = 0; - u16 frames = 0; - const f64 interpFrameTime = sFrameTime / (f64) numFramesToDraw; // interpolate and render // make sure to draw at least one frame to prevent the game from freezing completely // (including inputs and window events) if the game update duration is greater than 33ms do { - ++frames; - - // when we know how many frames to draw, use a precise delta - f64 idealTime = configFramerateMode != RRM_UNLIMITED ? (sFrameTimeStart + interpFrameTime * frames) : curTime; f32 delta = ( is30Fps ? 1.0f : - clamp((idealTime - sFrameTimeStart) / sFrameTime, 0.f, 1.f) + clamp((curTime - sFrameTimeStart) / sFrameTime, 0.f, 1.f) ); gRenderingDelta = delta; - // prepare interpolated frame gfx_start_frame(); if (!gSkipInterpolationTitleScreen) { patch_interpolations(delta); } send_display_list(gGfxSPTask); - gfx_end_frame_render(); - - // delay if our framerate is capped - if (configFramerateMode != RRM_UNLIMITED && !configWindow.vsync) { - f64 now = clock_elapsed_f64(); - f64 elapsedTime = now - loopStartTime; - expectedTime += (targetTime - curTime) / (f64) numFramesToDraw; - f64 delay = (expectedTime - elapsedTime); - - numFramesToDraw--; - if (delay > 0.0) { - precise_delay_f64(delay); - } - } - - // send the frame to the screen (should be directly after the delay for good frame pacing) - gfx_display_frame(); + gfx_end_frame(); sDrawnFrames++; + + if (!is30Fps && configFramerateMode == RRM_UNLIMITED) { continue; } + + // delay if our framerate is capped + f64 now = clock_elapsed_f64(); + f64 elapsedTime = now - loopStartTime; + expectedTime += (targetTime - curTime) / (f64) numFramesToDraw; + f64 delay = (expectedTime - elapsedTime); + if (delay > 0.0) { + precise_delay_f64(delay); + } + numFramesToDraw--; } while ((curTime = clock_elapsed_f64()) < targetTime && numFramesToDraw > 0); // compute and update the frame rate every second