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
This commit is contained in:
PeachyPeachSM64 2025-07-28 22:31:40 +02:00
parent 593eb9aafc
commit afec9d35b9
3 changed files with 23 additions and 40 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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();
gfx_end_frame();
sDrawnFrames++;
if (!is30Fps && configFramerateMode == RRM_UNLIMITED) { continue; }
// 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();
sDrawnFrames++;
numFramesToDraw--;
} while ((curTime = clock_elapsed_f64()) < targetTime && numFramesToDraw > 0);
// compute and update the frame rate every second