Search code examples
c++linuxraspberry-pisdlsdl-2

SDL2 KMSDRM starts but draws nothing on Raspberry Pi 3B


I wrote this simple test program that clear to grey, using KMSDRM support of SDL2:

#include <SDL.h>

#include <cstring>
#include <iostream>
#include <thread>

#include <SDL_opengles2.h>

using namespace std::chrono_literals;
using std::clog;
using std::endl;

int main()
{
    auto init_re = SDL_VideoInit("KMSDRM");
    if (init_re != 0)
        exit(EXIT_FAILURE);

    SDL_Window *window = SDL_CreateWindow("SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480,
                                          SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
    if (nullptr == window)
    {
        std::cerr << "SDL_CreateWindow(): " << SDL_GetError() << '\n';
        exit(EXIT_FAILURE);
    }
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
    auto gl = SDL_GL_CreateContext(window);
    clog << "create OpenGL context " << gl << endl;
    auto make_current_re = SDL_GL_MakeCurrent(window, gl);
    clog << "make current ctx returned " << make_current_re << endl;
    clog << "OpenGL version: " << (const char *)glGetString(GL_VERSION) << ", GLSL "
         << (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;

    glClearColor(0.5, 0.5, 0.5, 1.0);
    size_t frame_count = 0;
    SDL_Event e;
    bool should_break = false;
    while (!should_break)
    {
        while (SDL_PollEvent(&e))
        {
            if (e.type == SDL_QUIT)
                should_break = true;
            else if (e.type == SDL_KEYDOWN)
                if (e.key.keysym.sym == SDLK_ESCAPE)
                    should_break = true;
        }

        frame_count += 1;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
        clog << "frame " << frame_count << endl;
        std::this_thread::sleep_for(2ms);
    }

    SDL_GL_DeleteContext(gl);
    SDL_DestroyWindow(window);
    SDL_Quit();
}

The test program runs and prints frame count log, but does not draw a 640x480 piece of grey.

Is there any further things for KMS that is required to do to make it draw?

In addition, it draws a mouse pointer on top left corner, which is really out of my expectation. But the pointer does not move with my mouse. How to make the mouse run in KMSDRM mode?

Below are system/config I run:

  • 32-bit Raspbian bullseye, newest update.

  • To make the world clean, I uninstalled the whole X server.

  • SDL2 installed from Raspbian repo by apt.

  • Related settings in config.txt:

    dtoverlay=vc4-kms-v3d,composite
    max_framebuffers=2
    gpu_mem=256
    

Solution

  • I'm so stupid that I forgot to call swap buffers SDL_GL_SwapWindow(window) at the end of each frame. That's the reason why everything is not refreshed.