How to avoid tearing with pygame on Linux/X11
Asked Answered
M

3

8

I've been playing with pygame (on Debian/Lenny). It seems to work nicely, except for annoying tearing of blits (fullscreen or windowed mode).

I'm using the default SDL X11 driver. Googling suggests that it's a known issue with SDL that X11 provides no vsync facility (even with a display created with FULLSCREEN|DOUBLEBUF|HWSURFACE flags), and I should use the "dga" driver instead.

However, running

SDL_VIDEODRIVER=dga ./mygame.py

throws in pygame initialisation with

pygame.error: No available video device

(despite xdpyinfo showing an XFree86-DGA extension present).

So: what's the trick to getting tear-free vsynced flips ? Either by getting this dga thing working or some other mechanism ?

Muirhead answered 4/7, 2009 at 16:53 Comment(2)
Do you have the appropriate kernel driver for your video card. For X11, you need both a kernel driver and an X11 lib to access it. If one is missing, the other will work, but will be unusable.Nutting
I'm a little surprised by this as packages.debian.org/lenny/libxxf86dga1 , which appears to provide the DGA stuff in X11, doesn't mention anything about kernel modules (what would it show up as in lsmod ?). For what it's worth, I'm using the nv xorg driver with an old 5-series AGP NVidia card.Muirhead
M
4

Well my eventual solution was to switch to Pyglet, which seems to support OpenGL much better than Pygame, and doesn't have any flicker problems.

Muirhead answered 8/10, 2009 at 22:40 Comment(2)
Pyglet is also a lot closer in terms of API and practice to other graphics libraries for other languages and modern technologies.Paratrooper
Gloss is another option if you don't want to go all the way. It wraps OpenGL in easy classes and methods, and plays nicely along Pygame.Below
G
5

The best way to keep tearing to a minimum is to keep your frame rate as close to the screen's frequency as possible. The SDL library doesn't have a vsync unless you're running OpenGL through it, so the only way is to approximate the frame rate yourself. The SDL hardware double buffer isn't guaranteed, although nice when it works. I've seldomly seen it in action.

In my experience with SDL you have to use OpenGL to completely eliminate tearing. It's a bit of an adjustment, but drawing simple 2D textures isn't all that complicated and you get a few other added bonuses that you're able to implement like rotation, scaling, blending and so on.

However, if you still want to use the software rendering, I'd recommend using dirty rectangle updating. It's also a bit difficult to get used to, but it saves loads of processing which may make it easier to keep the updates up to pace and it avoids the whole screen being teared (unless you're scrolling the whole play area or something). As well as the time it takes to draw to the buffer is at a minimum which may avoid the blitting taking place while the screen is updating, which is the cause of the tearing.

Gaylord answered 11/8, 2009 at 10:8 Comment(1)
This is now (mostly) incorrect. PyGame still needs a GPU surface to turn on vsync, but you can now easily get one that works with its existing API and doesn't require OpenGL via the SCALED flag in PyGame 2.Erymanthus
M
4

Well my eventual solution was to switch to Pyglet, which seems to support OpenGL much better than Pygame, and doesn't have any flicker problems.

Muirhead answered 8/10, 2009 at 22:40 Comment(2)
Pyglet is also a lot closer in terms of API and practice to other graphics libraries for other languages and modern technologies.Paratrooper
Gloss is another option if you don't want to go all the way. It wraps OpenGL in easy classes and methods, and plays nicely along Pygame.Below
E
0

Use the SCALED flag and vsync=True when calling set_mode and you should be all set (at least on any systems which actually support this; in some scenarios SDL still can't give you a VSync-capable surface but they are increasingly rare).

Erymanthus answered 6/2, 2022 at 7:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.