Blank drawing using SDL_FillRect()

Hi guys, I’m currently maintaining a Go binding to SDL2. A person reported that he can’t display a rectangle on the screen on specific device running Ubuntu 17.04 using the native C code below. On other devices, it seems to work fine. Does anyone know a possible reason for this? I’m sorry if there’s an obvious mistake in advance as I’m not knowledgable in this matter.

Here’s the related issue on Github if you guys need more information: https://github.com/veandco/go-sdl2/issues/231

#include <SDL2/SDL.h>

int main()
{
    SDL_Window *window;
    SDL_Surface *surface;
    SDL_Rect rect = {0, 0, 200, 200};

    SDL_Init(SDL_INIT_EVERYTHING);

    window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
    if (!window) {
        fprintf(stderr, "main: %s\n", SDL_GetError());
        return -1;
    }

    surface = SDL_GetWindowSurface(window);
    if (!surface) {
        fprintf(stderr, "main: %s\n", SDL_GetError());
        return -1;
    }

    if (SDL_FillRect(surface, &rect, 0xffff0000) != 0) {
        fprintf(stderr, "main: %s\n", SDL_GetError());
        return -1;
    }

    if (SDL_UpdateWindowSurface(window) != 0) {
        fprintf(stderr, "main: %s\n", SDL_GetError());
        return -1;
    }

    SDL_Delay(1000);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

Tried it on Ubuntu 17.04 with Xorg and the nouveau driver. No problem there. I’ll try the proprietary driver and see if that makes a difference.

Ubuntu’s SDL2 package is recent (2.0.5). The screenshot looks like KDE, so maybe it’s Kubuntu? I can try that too, if it’s really something specific to that. Is Mir already a default now? There could be an issue with the Mir window surface.

Speaking of the window surface (very likely unrelated to this issue): You’re probably supposed to check the pixel format of the surface and get the pixel value with SDL_MapRGB.

Uint32 color;

/* ... */

if (surface->format->format == SDL_PIXELFORMAT_UNKNOWN) {
    fprintf(stderr, "main: Window surface has unknown pixel format\n");
    return -1;
}

color = SDL_MapRGB(surface->format, 0xff, 0x00, 0x00);
if (SDL_FillRect(surface, &rect, color) != 0) {
    fprintf(stderr, "main: %s\n", SDL_GetError());
    return -1;
}

Well, this doesn’t check for paletted formats, but I hope nothing returns that kind of madness today.

I have tested this now on Kubuntu and I get the behavior described in the github issue. The window only stays 1 and not 10 seconds, though. Let’s see where this breaks…

2 Likes

I assume this is KWin’s behavior, but something seems to drop the framebuffer data if the window isn’t fully visible yet. (I don’t know X well enough to get the terminology right.) If you wait after window creation or just keep redrawing in a loop, then the window shows the red square.

Perhaps SDL can do something different here, but I don’t know Xlib and have no idea what that could be.

1 Like

You’re right. I just tested it on Kubuntu 17.04 on Virtualbox and it does produce the same issue, and adding delay after creating the window or put the drawing in a loop does workaround it. Thanks!