-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
SDL2: vsync document and test existing behaviour #735
Comments
How will vsync flag work in pygame+sdl1? |
Good question. Maybe it will just do the current behavior, and it will be ignored. I'm not sure if SDL supports vsync in a way where it can be enabled or not. |
Previously in SDL1, OpenGL contexts are vsync'd by SDL_GL_SWAP_CONTROL and surfaces are vsync'd by HWSURFACE | DOUBLEBUF + clock.tick(). But windowed surfaces can only use clock.tick(), which may cause screen jitters. Probably related? #304 |
The hint has no effect for me. Perhaps it only works for SDL_Renderer. |
Talking about this some more, I agree it should probably be left "as is" for pygame 2. Since this is a new feature, it should be moved to pygame 2.1+ (if we do it at all). |
My question; is there a way to enable vsynch at all in Pygame 2? The pygame 1.9 method is no longer available. |
Sorry, which method was that? |
In Pygame 1 you can enable v-sync (on windows) by:
On my computer this locks the frame rate to 60 FPS and if you scroll sprites or surfaces around they will move smoothly with no hitching. As far as I know this is the only way to enable v-sync/smooth graphic movement in pygame 1 so it's not ideal (doesn't work in windowed mode, no idea what the situation is on mac or linux) but it's better than nothing. Step 1 is the one we can no longer do in pygame 2 as 'directx' is no longer an option for the SDL_VIDEODRIVER environment variable. I got this method from issue #304 talking about the pygame clock. I'm not sure if the clock can be made any better, discussion elsewhere seems to indicate the hitching that we get without v-sync is likely to be an SDL wide issue (see: https://forums.libsdl.org/viewtopic.php?p=51727). However, to me, having an option to enable v-sync in some manner in pygame 2 seems a necessary feature. In short; we have v-sync available in pygame 1 (albeit in a slightly crappy manner, but its there on the biggest platform for games) so we should have it in pygame 2, or if not that some other method (not sure there actually is one) that lets us have properly smooth scrolling graphics. |
Perhaps the best way to add it would be just by adding an extra flag 'VSYNC' to display.set_mode(), much like the 'SCALED' one that was already added? I mean people are already going to have to deal with that difference between pygame 1 and pygame 2 when making cross pygame version applications. I'm currently dealing with version specific differences with code like: But the best way to reduce people needing/wanting pygame 1 compatibility code is to make sure pygame 2 has all the capabilities of pygame 1 + more. And that includes some kind of v sync. |
I never noticed any hitching on Windows or Linux and I don't use v-sync(can't in Linux Mate for some reason). I use the clock.tick(30) on all my games and base movement on that framerate. Some might say that 30fps is too low, but if 24 is enough for film, than 30 is enough for a solo indie platformer. The first version of Flyboy ran at 18.2 fps on DOS because it was the only reliable clock available to me without a liscence for a DOS extender, since matching the 60Hz v-sync was unattainable on 16-bit processor. That said, I see no reason why v-sync should not be an option in 2.0, even if the request cannot be honored by the host OS / window manager. |
|
I don't think vsync should default to on, and we'd need an API to get the vsync FPS to make it useful. |
I've been playing with SCALED and the new sdl2 stuff on mac os and the "NO" you said at the end confuses me because, on my end, using SCALED does turn on VSYNC by default.
Same for me. Since it's on by default, I can't disable it. Changing the default renderer driver using SDL_HINT_RENDER_DRIVER also doesn't work (but it does using the new Renderer class). On mac os, renderer or not, I always have smooth movements and I can't have a higher FPS than my monitor refresh rate. It dosen't seem to be the case on other platforms. |
Oh no. I worked on this and didn't update here. I talked to some SDL devs and reported this in the Discord. I should write it here too: VSync cannot be made to work reliably cross-platform with SDL2
On Linux, I need to enable VSync support for my NVidia drivers in the xorg.conf. If it's disabled, SDL_Renderer will happily request VSync and set the VSync flag. There is no way to query whether VSync is actually happening. SDL_Renderer just knows VSync is a thing the driver supports, and might prefer Metal to OpenGL if the OpenGL on mac is known to SDL2 not to support VSync. This is a one-way street. It's only possible to query whether there's an API available to set the VSync flags. The SDL dev told me to just set the flag to be sure. It gets worse. It looks like VSync on MacOS defaults to blocking double buffering. One frame is rendered, the second frame is rendered, and pygame.display.flip() will block until the buffers are swapped and the first frame is actually displayed on the screen. This means the third call to It depends entirely on your drivers. The driver could use VSync or GSync internally, SDL2 supports that, and the driver could use triple buffering. In the triple buffering case, there are But at the same time, there is no way to ensure I'll keep you updated. Maybe in the future there will be an API to query this. But for now, in order to ensure the old behaviour cross-platform, VSync MUST default to off. I could put a test case that requests VSync in in the examples directory, but that cannot to my knowledge be automated. You have to run it on your machine, and eyeball if you see any tearing on the screen. That can be easily detected if you just draw a pattern of vertical moving lines. Framerate limiting can be detected programmatically, but even that is finnicky. Maybe the test case runs too slow, and I don't think it can do anything sensible in a headless test environment without a dedicated graphics card. I propose to close this as WONTFIX or similar, especially for PyGame 2.0. Even if we can enable VSync by default, which we can, we can't guarantee it will do the right thing, and it might harm backward compatibility with old PyGame 1.X games. |
sounds like the main things left to do here are:
|
Looks like in pygame 2.0.0.dev8 with SDL 2.0.12 adding:
before calling display.set_mode() and adding |
I added the vsync enabling method above that seems to work on both mac and windows to the docs in the linked pull request. |
There's a vsync keyword now... thanks to @robertpfeiffer and @MyreMylar. I'd like to continue on with this stuff after the next release:
|
Hello, I'd like to make a request for enabling vsync without the SCALED flag. Would this be possible? Because my problem with the SCALED flag is that I have no control over the size of the window. Or if there is no way of using vsync without SCALED, make it possible to set the size of the resulting scaled window myself? |
@BastiHz It would be possible to create another mode for pygame.display.set_mode that always uses the GPU, but doesn't do any automatic scaling, but for backwards compatibility reasons, we can't use a GPU by default. |
Ok, thank you.
That would be awesome. Maybe in a future version where backwards compatibility is not an issue anymore. |
Looking at the code in display.c, it seems that when using an OpenGL context, currently vsync=1 always tries to set adaptive vsync first, and uses this if successful. This, however, should not be the default behaviour! It is currently not clear to me how to force normal vsync (i.e. have the the same behaviour as in Pygame 1). |
At the moment pygame+sdl2 vsync defaults to off, but we should change it to default to on to be backwards compatible with pygame+sdl1.
https://wiki.libsdl.org/SDL_HINT_RENDER_VSYNC
Also, we should perhaps expose a display.set_mode(vsync=True) option.
Related Docs: https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode
The text was updated successfully, but these errors were encountered: