Search code examples
clinuxopenglsdlintel

Strange effects with OpenGL app when compositing is enabled on Linux + Intel driver


I'm having a problem with this very simple SDL2+OpenGL code:

#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>

int main() {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,    SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
    SDL_Window *window = SDL_CreateWindow("OpenGL", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_OPENGL);
    SDL_GLContext context = SDL_GL_CreateContext(window);
    SDL_Event windowEvent;

    while(true) {
        if(SDL_PollEvent(&windowEvent)) {
            if(windowEvent.type == SDL_QUIT) break;
        }
        SDL_GL_SwapWindow(window);
    }

    SDL_GL_DeleteContext(context);
    SDL_Quit();
    return 0;
}

This code should just show a blank window. When running it with an NVidia driver it works (even with window manager compositor enabled), but when I run it with an Intel driver and compositor enabled I randomly get a full black screen for about a second, then the window shows, then the black screen comes back etc. When I disable my compositor (KWin 5.10.4) with Alt+Shift+F12 before running the program, it works. I also tested it with Mutter (the GNOME compositor) and the same happens. The program works if I comment out all the SDL_GL_SetAttribute part, the SDL_GLContext variable declaration, and change SDL_WINDOW_OPENGL with SDL_WINDOW_SHOWN (basically if I set the window to be managed by SDL).

I even tried with glfw instead of SDL, but I got the same problem.

How should I solve it?

Update: the program also works if I disable vsync in the KDE compositor settings.


Solution

  • You're swapping a framebuffer which you never cleared or drawn a framebuffer covering primitive to. Hence the outcome is undefined and any kind of output might appear.

    Add a glClear(GL_COLOR_BUFFER_BIT) to your inner drawing loop and see what it does.