Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving the stability of rendering frame rate #3667

Closed
wants to merge 1 commit into from

Conversation

bohonghuang
Copy link
Contributor

@bohonghuang bohonghuang commented Dec 23, 2023

In the current rcore.c, the invocation of SwapScreenBuffer in the EndDrawing function is placed before the frame rate control. This causes the interval between the current frame and the next frame to actually depend on the rendering/update time of the previous frame, rather than the current frame. When the rendering/update time of each frame is inconsistent but still within the frame interval (which is common for triggering events or asset loading in games), FPS stuttering occurs. In this case, the frame rate still maintains the target frame rate, but it gives a sensation of unsmoothness, which becomes particularly noticeable at low frame rates:

frame-stutter.mp4

Here is the code snippet used in the mentioned video:

#include "raylib.h"
#include <math.h>

int main(void) {
  int screenWidth = 800;
  int screenHeight = 200;
  InitWindow(screenWidth, screenHeight, "SwapScreenBuffer() before/after WaitTime()");
  SetTargetFPS(30);
  Vector2 pos = { .x = 100.0f, .y = 100.0f };
  float step = 1000.0f;
  while (!WindowShouldClose()) {
    BeginDrawing();
    ClearBackground(RAYWHITE);
    if (pos.x > 700.0f) step = -fabsf(step);
    else if (pos.x < 100.0f) step = fabsf(step);
    pos.x += step * GetFrameTime();
    DrawCircleV(pos, 50.0f, RED);
    DrawFPS(2, 2);
    EndDrawing();
    if(GetRandomValue(0, 1)) WaitTime(0.03); // Simulate unstable update time
  }
  CloseWindow();
  return 0;
}

This PR moves the invocation to SwapScreenBuffer function after the frame rate control, ensuring that it is called at a consistent frequency to improve frame rate stability.

@veins1
Copy link
Contributor

veins1 commented Dec 25, 2023

This adds input lag. Waiting before swapbuffers is as if you had vsync on but without the sync part.

@bohonghuang
Copy link
Contributor Author

This adds input lag. Waiting before swapbuffers is as if you had vsync on but without the sync part.

Yes, it is apparent that it does introduce a 1-frame input delay. After giving it some thought, perhaps the content of this PR seems like something that can be implemented at the application level. That is, manually introducing a delay before calling EndDrawing to force each frame to have the same update time, thereby avoiding this stuttering issue without sacrificing the performance of applications that require real-time responsiveness. I will close this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants