SDL_RENDERER_PRESENTVSYNC behaviour

Hi all,

I’m quite a newbie of SDL and my current task is to port an application written for SDL 1.2 (+ SGE) to SDL 1.3.

This because after some testing it turned out that 1.3 using SDL_Window + SDL_Renderer is the only one that makes me able to draw in double-buffered mode respecting the VSYNC of the display.

What is strange and that I don’t understand is why if I start my application inside a Window Manager environment (namely KDE or Gnome), a call to SDL_CreateRenderer with SDL_RENDERER_PRESENTVSYNC enabled returns a pointer to a renderer object that actually present that flag enabled. If vice-versa I start the same application outside a Window Manager environment (i.e. starting only a simple X server without any other addition) the SDL_RENDERER_PRESENTVSYNC is not enabled.

I tried also setting some HINT environmental variable but without success.

Can anyone help me?

Many thanks,
Lorenzo Buzzi

PS: some platform information: the HW is an embedded board with an Atom + an Intel 945 chipset; the SW is Fedora 14 (I tried also with Slackware 13.37 with the same result)------------------------
Lorenzo Buzzi

Just to help people to understand what’s my problem and to make easier rooting it, this is the code I use to init the system:

Code:
#if SDL_VERSION_ATLEAST(1,3,0)
/* SDL 1.3 code */

    // Init the application window
    printf("GTx: cerated a %u x %u window at [%u:%u]\n", ScreenWidth, ScreenHeight, ScreenXPos, ScreenYPos);
    if ((win = SDL_CreateWindow("GTX", ScreenXPos, ScreenYPos, ScreenWidth, ScreenHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_BORDERLESS)) == 0) {
            fprintf(stderr, "Couldn't create the required SDL Window: %s\n", SDL_GetError());
            quit(1);
    }
    printf("\nCheck SDL Window enabled flags:\n");
    flags = SDL_GetWindowFlags(win);
    printf("    SDL_WINDOW_FULLSCREEN    [%c]\n", (flags & SDL_WINDOW_FULLSCREEN) ? 'X' : ' ');
    printf("    SDL_WINDOW_OPENGL        [%c]\n", (flags & SDL_WINDOW_OPENGL) ? 'X' : ' ');
    printf("    SDL_WINDOW_SHOWN         [%c]\n", (flags & SDL_WINDOW_SHOWN) ? 'X' : ' ');
    printf("    SDL_WINDOW_HIDDEN        [%c]\n", (flags & SDL_WINDOW_HIDDEN) ? 'X' : ' ');
    printf("    SDL_WINDOW_BORDERLESS    [%c]\n", (flags & SDL_WINDOW_BORDERLESS) ? 'X' : ' ');
    printf("    SDL_WINDOW_RESIZABLE     [%c]\n", (flags & SDL_WINDOW_RESIZABLE) ? 'X' : ' ');
    printf("    SDL_WINDOW_MINIMIZED     [%c]\n", (flags & SDL_WINDOW_MINIMIZED) ? 'X' : ' ');
    printf("    SDL_WINDOW_MAXIMIZED     [%c]\n", (flags & SDL_WINDOW_MAXIMIZED) ? 'X' : ' ');
    printf("    SDL_WINDOW_INPUT_GRABBED [%c]\n", (flags & SDL_WINDOW_INPUT_GRABBED) ? 'X' : ' ');
    printf("    SDL_WINDOW_INPUT_FOCUS   [%c]\n", (flags & SDL_WINDOW_INPUT_FOCUS) ? 'X' : ' ');
    printf("    SDL_WINDOW_MOUSE_FOCUS   [%c]\n", (flags & SDL_WINDOW_MOUSE_FOCUS) ? 'X' : ' ');
    printf("    SDL_WINDOW_FOREIGN       [%c]\n", (flags & SDL_WINDOW_FOREIGN) ? 'X' : ' ');

    // Allocate a renderer info struct
    rend_info = (SDL_RendererInfo *) malloc(sizeof(SDL_RendererInfo));
    if (!rend_info) {
            fprintf(stderr, "Couldn't allocate memory for the renderer info data structure\n");
            quit(1);
    }
    // Print the list of the available renderers
    printf("\nAvailable 2D rendering drivers:\n");
    for (i = 0; i < SDL_GetNumRenderDrivers(); i++) {
            if (SDL_GetRenderDriverInfo(i, rend_info) < 0) {
                    fprintf(stderr, "Couldn't get SDL 2D render driver information: %s\n", SDL_GetError());
                    quit(1);
            }
            printf("%2d: %s\n", i, rend_info->name);
            printf("    SDL_RENDERER_SOFTWARE     [%c]\n", (rend_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
            printf("    SDL_RENDERER_ACCELERATED  [%c]\n", (rend_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
            printf("    SDL_RENDERER_PRESENTVSYNC [%c]\n", (rend_info->flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' ');
    }

    // Init a renderer associated with the window
    if ((rend = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)) == NULL) {
            fprintf(stderr, "Couldn't create an SDL 2D rendering driver: %s\n", SDL_GetError());
            quit(1);
    }
    // Print the name of the current rendering driver
    if (SDL_GetRendererInfo(rend, rend_info) < 0) {
            fprintf(stderr, "Couldn't get SDL 2D rendering driver information: %s\n", SDL_GetError());
            quit(1);
    }
    printf("Rendering driver in use: %s\n", rend_info->name);
    printf("    SDL_RENDERER_SOFTWARE     [%c]\n", (rend_info->flags & SDL_RENDERER_SOFTWARE) ? 'X' : ' ');
    printf("    SDL_RENDERER_ACCELERATED  [%c]\n", (rend_info->flags & SDL_RENDERER_ACCELERATED) ? 'X' : ' ');
    printf("    SDL_RENDERER_PRESENTVSYNC [%c]\n", (rend_info->flags & SDL_RENDERER_PRESENTVSYNC) ? 'X' : ' ');

#else
/* SDL 1.2 code */

    ...

#endif

Then this is the output I get under KDE (and in this case moving text on the display respects VSYNC and there is no tearing):

Code:
GTx: cerated a 232 x 199 window at [2071:257]

Check SDL Window enabled flags:
SDL_WINDOW_FULLSCREEN [ ]
SDL_WINDOW_OPENGL [ ]
SDL_WINDOW_SHOWN [X]
SDL_WINDOW_HIDDEN [ ]
SDL_WINDOW_BORDERLESS [X]
SDL_WINDOW_RESIZABLE [ ]
SDL_WINDOW_MINIMIZED [ ]
SDL_WINDOW_MAXIMIZED [ ]
SDL_WINDOW_INPUT_GRABBED [ ]
SDL_WINDOW_INPUT_FOCUS [ ]
SDL_WINDOW_MOUSE_FOCUS [ ]
SDL_WINDOW_FOREIGN [ ]

Available 2D rendering drivers:
0: opengl
SDL_RENDERER_SOFTWARE [ ]
SDL_RENDERER_ACCELERATED [X]
SDL_RENDERER_PRESENTVSYNC [X]
1: software
SDL_RENDERER_SOFTWARE [X]
SDL_RENDERER_ACCELERATED [ ]
SDL_RENDERER_PRESENTVSYNC [ ]
Rendering driver in use: opengl
SDL_RENDERER_SOFTWARE [ ]
SDL_RENDERER_ACCELERATED [X]
SDL_RENDERER_PRESENTVSYNC [X]

This is the output I get under a naked X (and in this case moving text on the display doesn’t respects VSYNC and there is tearing):

Code:
GTx: cerated a 232 x 199 window at [2071:257]

Check SDL Window enabled flags:
SDL_WINDOW_FULLSCREEN [ ]
SDL_WINDOW_OPENGL [ ]
SDL_WINDOW_SHOWN [X]
SDL_WINDOW_HIDDEN [ ]
SDL_WINDOW_BORDERLESS [X]
SDL_WINDOW_RESIZABLE [ ]
SDL_WINDOW_MINIMIZED [ ]
SDL_WINDOW_MAXIMIZED [ ]
SDL_WINDOW_INPUT_GRABBED [ ]
SDL_WINDOW_INPUT_FOCUS [ ]
SDL_WINDOW_MOUSE_FOCUS [ ]
SDL_WINDOW_FOREIGN [ ]

Available 2D rendering drivers:
0: opengl
SDL_RENDERER_SOFTWARE [ ]
SDL_RENDERER_ACCELERATED [X]
SDL_RENDERER_PRESENTVSYNC [X]
1: software
SDL_RENDERER_SOFTWARE [X]
SDL_RENDERER_ACCELERATED [ ]
SDL_RENDERER_PRESENTVSYNC [ ]
Rendering driver in use: opengl
SDL_RENDERER_SOFTWARE [ ]
SDL_RENDERER_ACCELERATED [X]
SDL_RENDERER_PRESENTVSYNC [ ]

Please note the difference between what the library reports as available and what “rend_info->flags” reports after the renderer has been created------------------------
Lorenzo Buzzi

Please note the difference between what the library reports as available
and what “rend_info->flags” reports after the renderer has been created

The OpenGL renderer always reports VSYNC support at the moment, but
doesn’t know if you can actually have it until you create the renderer.

This is where it finds out you can’t have vsync:

http://hg.libsdl.org/SDL/file/c1ed57cbfd66/src/video/x11/SDL_x11opengl.c#l518

You might be missing a GL extension, or the GL is reporting an error.

It’s not clear to me why you get it with KDE but not with the naked X
server, unless you’re loading a different X server or somehow you’re
getting a wrong libGL in your library path or something.

It’s also not clear to me that we should report VSYNC by default in
SDL_GetRenderDriverInfo(). That might be a bug. In any case, you
shouldn’t count on having Vsync until you create the renderer and it
claims to support it.

–ryan.

Thank you for the suggestions.

I can confirm that KDE starts the same /usr/bin/X that I start manually.
I agree with you that there must be some difference in what KDE loads and what X does not.

Anyway at the moment I started experimenting with LXDE under my aplication. It guarantees VSYNC is enabled and is “light” enough for the requirements I have.

I remain open to any further suggestion.

Best regards,
Lorenzo Buzzi------------------------
Lorenzo Buzzi