edubart / sokol_gp

Minimal modern efficient cross platform 2D graphics painter in C
MIT No Attribution
455 stars 24 forks source link

Stuttering after a few minutes of running the app #18

Closed zeozeozeo closed 1 year ago

zeozeozeo commented 1 year ago

I've made this simple demo and I am experiencing stutters after it has been running for a minute or so. I am running Linux 6.1.9-arch1-2 with Intel UHD Graphics.

This is how it's running just after I started it:

https://user-images.githubusercontent.com/108888572/218251903-53d3e4c1-36e0-4dc2-a866-2d3d63d7cac8.mp4

But then it starts stuttering, like this (it gets worse over time):

https://user-images.githubusercontent.com/108888572/218251938-3b1f21cb-cc4b-448c-a79d-efd1d31ec146.mp4

Code: https://pastebin.com/3HphbJvs

edubart commented 1 year ago

I don't think the issue you are having is with this library. The cause could be your graphics driver, or your graphics hardware, or thermal throttling (as time go on the graphics card starts to heat more), or misconfigured display vertical synchronization.

It could be also the underlying implementation of you libc sin function, the sin function is not perfect due to float precision limitations and it starts to be less precise with large values, if you do something like float time = sapp_frame_count() * sapp_frame_duration() + 1000000.0f; this will become noticeable. Using double instead of float where possible can improve the situtation, but the ideal is to not use values too large in algorithms using sin,cos, etc, typically you want to mod values to keep then in a known interval and not let it explode. The fact you are stacking rotate at on top of other rotate will make any bad precision of sin more apparent.

zeozeozeo commented 1 year ago

I don't think the issue you are having is with this library. The cause could be your graphics driver, or your graphics hardware, or thermal throttling (as time go on the graphics card starts to heat more), or misconfigured display vertical synchronization.

It could be also the underlying implementation of you libc sin function, the sin function is not perfect due to float precision limitations and it starts to be less precise with large values, if you do something like float time = sapp_frame_count() * sapp_frame_duration() + 1000000.0f; this will become noticeable. Using double instead of float where possible can improve the situtation, but the ideal is to not use values too large in algorithms using sin,cos, etc, typically you want to mod values to keep then in a known interval and not let it explode. The fact you are stacking rotate at on top of other rotate will make any bad precision of sin more apparent.

I've changed the code to use doubles instead of floats and I kept it running for ~90 seconds. I've also simplified the code so it just draws one rectangle:

double time = sapp_frame_count() * sapp_frame_duration();
sgp_set_image(0, image);
printf("time: %f\n", time);
sgp_draw_textured_rect(sin(time) / 4, sin(time) / 4, 0.5, 0.5);
sgp_reset_image(0);

I added a print statement to keep track of the time variable and I kept the program running for 90 seconds. This is the result:

https://user-images.githubusercontent.com/108888572/218264053-85b1e78f-ad83-4e55-9ff5-7b68ba5de8e9.mp4

The movement is still stuttery.

Now, I changed it to this:

double time = sapp_frame_count() * sapp_frame_duration() + 90.0;
sgp_set_image(0, image);
printf("time: %f\n", time);
sgp_draw_textured_rect(sin(time) / 4, sin(time) / 4, 0.5, 0.5);
sgp_reset_image(0);

On the first line I add 90.0 to the time so the time variable is the same as in the previous run. But this time, it doesn't stutter, even though the time variable is the same:

https://user-images.githubusercontent.com/108888572/218264201-bc897e41-e586-443a-8f43-4dfa5d30d09d.mp4

However, after ~50 seconds the stuttering appears again. I don't think this is a floating point precision issue. I also don't think this is an issue with my graphics drivers, since this doesn't happen in other applications that use the GPU and it doesn't seem to happen if I only use sokol_app with sokol_gfx. I am not quite sure though.

iryont commented 1 year ago

Your GPU is thermal or power limit throttling. There is nothing wrong with the library itself.

zeozeozeo commented 1 year ago

Your GPU is thermal or power limit throttling. There is nothing wrong with the library itself.

The FPS stays constant and the temperatures seem okay. The issue still remains if I limit the framerate. This also doesn't happen in any other apps or games, so I don't think that's the case. If it was throttling, shouldn't the framerate be lower?

iryont commented 1 year ago

No, not really. I had this problem on some sort of iGPU some time ago. It was power limit throttling at 130 fps and while it was quite stable around that fps value, the stuttering was quite visible. I did check thermal limit and the iGPU was hitting it. At 100 fps it was fluent without any stuttering, below TDP limit.

edubart commented 1 year ago

I noticed now that sapp_frame_duration() is not constant, don't use it. This value keeps changing, and that will lead to stuttering in your algorithm. From the sokol_app documentation:

        double sapp_frame_duration(void)
            Returns the frame duration in seconds averaged over a number of
            frames to smooth out any jittering spikes.

Change to a constant like 1.0f/60.0f.

zeozeozeo commented 1 year ago

I noticed now that sapp_frame_duration() is not constant, don't use it. This value keeps changing, and that will lead to stuttering in your algorithm. From the sokol_app documentation:

        double sapp_frame_duration(void)
            Returns the frame duration in seconds averaged over a number of
            frames to smooth out any jittering spikes.

Change to a constant like 1.0f/60.0f.

Woah, that fixed it! Thank you so much :D