Comment 30 for bug 1280665

Revision history for this message
In , 7-ajax (7-ajax) wrote :

Since I'm the person most nearly responsible for the X side of this problem, I'll add some background here.

Way back in 2007 (a bit before xserver 1.4) I rewrote X's bs implementation in terms of some of the Composite extension's internal machinery; automatic redirection in the Composite sense is equivalent to core backing store's WhenMapped state, so it made sense to do the one in terms of the other. What I didn't do then, though I'd intended to, was automatically advertise that backing store support if the Composite extension was enabled; you needed to still explicitly enable it in xorg.conf for the server to advertise the support.

In 1.15 I finally fixed that up, so now the server claims to support backing store if the Composite extension is enabled (and it usually is). This was intended to be a convenience for legacy applications that - arguably brokenly - require backing store support to work correctly because they don't bother to implement an Expose handler.

The automatic redirection code, however, is basically just XCopyArea. It doesn't know what a vblank is, it can't synchronize updates with the retrace, hence the tearing. The old pre-1.4 BS code was not any better in that respect. The only reason you _might_ want BS is if you're not running a compositor (hence wouldn't have vsync anyway), and even then it's a tradeoff, implicit double-buffering on the server side versus marginally less tearing and possibly not needing a proper Expose handler. I can't speak to whether working Expose handlers are common for SDL apps, but naively I would expect they're not common, that SDL apps default to being "like fullscreen" and don't expect to repaint things due to window system events.

So at a bare minimum I would suggest checking whether there's a compositor running on the screen already, and defaulting BS to off if there is. The code to do that is approximately:

    char *s = asprintf("_NET_WM_CM_S%d", screen);
    Atom a = XInternAtom(dpy, s);
    Window w = XGetSelectionOwner(dpy, a);

    if (w) /* compositor running */ ;

If possible I would suggest deferring the decision about BS-or-not to the point where you know what kind of rendering you're going to do, if that's a thing you can know. It's almost never going to be useful for GL clients.