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

Stuttering on Windows (windowed) #1628

Closed
HDPLocust opened this issue Sep 27, 2020 · 17 comments
Closed

Stuttering on Windows (windowed) #1628

HDPLocust opened this issue Sep 27, 2020 · 17 comments
Labels
11.3 bug Something isn't working library dependency Related to a library used by LÖVE

Comments

@HDPLocust
Copy link

HDPLocust commented Sep 27, 2020

Love2d with or without vsync has issues with render stuttering/jittering (may be checked with double love.graphics.present: rendered stuff looks like stroboscope) because Windows DWM gets frames in unknown timing.
Some people sync opengl/dx apps with DwmFlush:
https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmflush
And it works (also on fullscreen apps)

I use it with ffi:

if love.system.getOS() == "Windows" then
	local ffi = require'ffi'
	local dwm = ffi.load("dwmapi")
	ffi.cdef"void DwmFlush();"
	local oldpresent = love.graphics.present
	function love.graphics.present()
		oldpresent()
		dwm.DwmFlush()
	end
end

But it may be useful if someone puts it in LOVE.

@HDPLocust HDPLocust changed the title Stuttering on windows/windowed Stuttering on Windows (windowed) Sep 27, 2020
@thegrb93
Copy link
Contributor

I don't get any stuttering. wdym?

@slime73
Copy link
Member

slime73 commented Sep 27, 2020

And it works (also on fullscreen apps)

Does that mean you had stuttering in fullscreen that this prevents? Or it just doesn't do anything negative in fullscreen on your system? Was that with desktop-fullscreen or exclusive fullscreen, or both?

@thegrb93
Copy link
Contributor

One thing I did notice is using timer.getTime() for physics updates leads to jitter so I fixed that to the screen refresh rate. Never seen any fps problems though. Maybe try logging an fps counter's results and post them here?

@slime73
Copy link
Member

slime73 commented Sep 27, 2020

I fixed that to the screen refresh rate.

This is off-topic but that sounds like a bad idea.. for example I use a 120hz monitor and a 60hz monitor on one of my computers. I would expect all games to run at the same rate no matter which monitor the game is in. The typical approach to stable physics simulation is to use an accumulator method to run physics at a fixed rate without depending on frame rate.

@thegrb93
Copy link
Contributor

thegrb93 commented Sep 27, 2020

So if you move the window between those two monitors, the refresh rate will change? That's interesting. Yeah, I might look into that.

@HDPLocust
Copy link
Author

HDPLocust commented Sep 27, 2020

And it works (also on fullscreen apps)

Does that mean you had stuttering in fullscreen that this prevents? Or it just doesn't do anything negative in fullscreen on your system? Was that with desktop-fullscreen or exclusive fullscreen, or both?

"It works" means "it makes 60fps on fullscreen with love-vsync off" also stuttering is disabled, instead of "love makes >9000fps burst on fullscreen".

UPD: Stuttering does not appears on desktop fullscreen mode, because DWM is works in another mode. Borderless window leads to stuttering just like a regular window.

@HDPLocust
Copy link
Author

HDPLocust commented Sep 27, 2020

I don't get any stuttering. wdym?

You might not have noticed it.
What it looks like on the video is what it looks like in the game. It looks like dropped frames or something similar.
https://player.vimeo.com/video/462438403

Also you can check it with modified love.run:

if love.graphics and love.graphics.isActive() then
	love.graphics.origin()
	love.graphics.clear(love.graphics.getBackgroundColor())
 
	if love.draw then love.draw() end
	love.graphics.present() -- add another present
	love.graphics.present() -- and it starts looks stroboscopic
end

With DwmFlush-present it looks ok.

@slime73
Copy link
Member

slime73 commented Sep 27, 2020

You might not have noticed it.

The issue is specific to certain GPUs and graphics drivers, I believe.

@HDPLocust
Copy link
Author

HDPLocust commented Sep 27, 2020

You might not have noticed it.

The issue is specific to certain GPUs and graphics drivers, I believe.

I checked it with:

  1. Windows 7, Intel HD 4000
  2. Windows 8.1, Nvidia GT720 (old drivers)
  3. Windows 10 Nvidia GTX1660Ti (new drivers)

It also appears on my friends' Radeons.

The problem is Windows desktop window manager, it's not synced with sdl-window vsync.

GLFW also added DwmFlush in this commit

@HDPLocust
Copy link
Author

HDPLocust commented Sep 27, 2020

Gifs slowed down four times.
default love-vsync:
ezgif-6-78f652e3892c
DwmFlush sync (love-vsync is on, sync fighting but ~ok):
ezgif-6-97e9c7dfe651
DwmFlush sync (love-vsync is off, we can see 60fps like with vsync):
ezgif-6-681d11018af0

@endlesstravel
Copy link

endlesstravel commented Sep 28, 2020

i have the same issue on windows 10 / amd 2600x / gtx 1050 ti / vsync 60 hz , but i used the Love2dCS (C# version of love) :
the program will stuttering on love.graphics.present , about once every 5 seconds it will freeze 60 ms.
this is considered to be related to C# GC, the freeze status is different on C# implement .netframework 4.5 / dotnetcore 3.1 / .net5
but now:
after i call DwmFlush before love.graphics.present, i get 15 ~30 ms relieve on stuttering .:

  • the freeze frame record, [before]:
    image

  • the freeze frame record, [after]:
    image

I'm sure the problem has something to do with GC, but DWM has relevance to do with it as well after i test the api DwmFlush.

I am not very clear about this problem, so I think it can be used as the third delivery library to distribute it to people who have problems running on widnews at least.

@zorggn
Copy link

zorggn commented Sep 28, 2020

On Win7 x64 with GTX1650 latest drivers, this completely eliminated my visual (micro?)stutter issues... with or without löve's vsync being set to 0 or not, since this will force sync to 60Hz (maybe it'll force it to other values if other screens are set to use different refresh rates? i couldn't test that). Tested in windowed mode as well.

The only issue with it is that it does introduce momentary stutter when the window is un/re-focused, or if it's moved by mouse, which didn't happen without it.

slime73 added a commit that referenced this issue Sep 29, 2020
@slime73
Copy link
Member

slime73 commented Sep 29, 2020

I haven't been able to reproduce the issue to the degree that it happens in those gifs (that likely has to do with other things being composited on your system etc), but I've put in a change to use it here: 5dd4a46

It seems very delicate in terms of potential side effects, so I'd appreciate any sort of testing anyone wants to do. It only activates in windowed mode and desktop-fullscreen (not exclusive fullscreen), and only when non-adaptive vsync is enabled.

A build with it should be available here shortly: https://ci.appveyor.com/project/AlexSzpakowski/love/builds/35477235

@slime73 slime73 closed this as completed Sep 29, 2020
@MikuAuahDark
Copy link
Contributor

5dd4a46 caused heavy stuttering in my laptop running Windows 10 2004 using integrated graphics (Intel HD Graphics 620 with 27.20.100.8681 driver).

Printing the delta time to console, I can see it eratically alternate between 16.67ms and 33.33ms like

32.6911
18.162
15.8922
32.4313
17.9072
16.6764
33.9829
15.9993
32.2744
17.0747
17.2684
16.4797
33.0312
17.0406
17.0162
16.0592
33.0121
16.9929
16.8723
17.0406
16.9015
16.5148
32.763
17.0374
16.5379
32.9344
17.063
15.7637

This does not happen when using dGPU or iGPU without that commit applied.

@MikuAuahDark MikuAuahDark reopened this Sep 30, 2020
@HDPLocust
Copy link
Author

It seems very delicate in terms of potential side effects, so I'd appreciate any sort of testing anyone wants to do. It only activates in windowed mode and desktop-fullscreen (not exclusive fullscreen), and only when non-adaptive vsync is enabled.

Thank you, I will test it with all my stuff and a lot of people and also if something goes wrong, I will look for a better solution (set of solutions?).

@HDPLocust
Copy link
Author

Printing the delta time to console, I can see it eratically alternate between 16.67ms and 33.33ms like

It looks like two sync systems fighting: Love waits love-vsync (one frame) then dwm (second frame), and it alternates with normal rendering when it makes it in time.

@slime73
Copy link
Member

slime73 commented Sep 30, 2020

I'll probably have to revert the change, missing vsync on some systems isn't worth it.

It looks like two sync systems fighting: Love waits love-vsync (one frame) then dwm (second frame), and it alternates with normal rendering when it makes it in time.

Unfortunately turning vsync off and using DwmFlush as "vsync" isn't going to work - for example on my computer, DwmFlush syncs to my primary monitor's 120hz refresh rate no matter which display the window is on, but I have 60hz secondary monitors which vsync correctly syncs to when the window is in one of those displays. Plus, ultimately whether OpenGL's vsync is on or off is controlled by users via system graphics driver settings. Apps can only set a hint for what the driver should prefer if users leave it up to apps instead of overriding it.

@slime73 slime73 added 11.3 bug Something isn't working labels Oct 4, 2020
@slime73 slime73 added the library dependency Related to a library used by LÖVE label Oct 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
11.3 bug Something isn't working library dependency Related to a library used by LÖVE
Projects
None yet
Development

No branches or pull requests

6 participants