SDL2 rendering with multithreading on Raspberry Pi 2

So, we’re trying to build a Real-Time System with preemption within a process, executing each task as a separate thread. To build the GUI, SDL was the library chosen and we’ve separated the GUI initialization from the rendering so that the latter could be a different task. Even though SDL has threads itself, we used pthreads. Information found is contradictory as some sources state that rendering cannot be executed within a different process and others stating otherwise. However, using a virtual machine with Debian, the rendering was executed properly but doing so in the Raspberry Pi, through changing contexts betweeen the main and the rendering thread, SDL_GetError() does not return error but does not render anything leading to a black window with a cursor. It is important to state that rendering within the main thread works as intended.

In order to solve this issue, several alternatives were used in the Pi and SDL configuration. Regarding the Pi itself, using sudo raspi-config, both Full and Fake KMS to enable OpenGL do not work with different errors being presented:

Full KMS - Could not initialize OpenGL / GLES library
Fake KMS - * failed to add service - already in use? (keyboard stops working).
OpenGL disabled (origin) - No error, black window unrendered.

Following, the code is presented per threads:

Main thread:

SDL_Window* GUI_init(int w, int h) {
  if (SDL_Init(SDL_INIT_VIDEO) != 0) {
    fprintf(stderr, "Cannot initialise SDL: %s\n", SDL_GetError());
    exit(1);
  }

  window = SDL_CreateWindow(
    "Tron", 
    SDL_WINDOWPOS_CENTERED, 
    SDL_WINDOWPOS_CENTERED, 
    w, h,
    SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL
  );
  if (window == NULL) {
    fprintf(stderr, "Unable to create window: %s\n", SDL_GetError());
    exit(1);
  }

  globalRenderer = SDL_CreateRenderer(
    window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
  );
  if (globalRenderer == NULL) {
    fprintf(stderr, "Unable to create renderer: %s\n", SDL_GetError());
    exit(1);
  }

  if (SDL_SetRenderDrawBlendMode(globalRenderer, SDL_BLENDMODE_BLEND) != 0) {
    fprintf(stderr, "SDL_BlendMode failed: %s\n", SDL_GetError());
    exit(1);
  };

  ctx = SDL_GL_CreateContext(window);
  if(ctx == NULL) {
    fprintf(stderr, "Unable to create context: %s\n", SDL_GetError());
    exit(1);
  }

  int ctx1 = SDL_GL_MakeCurrent(window,NULL);
  if(ctx1!=0) {
    fprintf(stderr, "Unable to make currents context: %s\n", SDL_GetError());
    exit(1);
  }

  //return globalRenderer;
  return window;
}

Rendering Thread:

void* GUI_update(void* params) {
  SDL_GL_MakeCurrent(window,ctx);

  GUI_setRenderDrawColor(globalRenderer);

  SDL_RenderClear(globalRenderer);

  GUI_fillBoardBorders(globalRenderer);
  GUI_fillBoard(globalRenderer);

  SDL_RenderPresent(globalRenderer);
}

with use of 3 global variables:

SDL_Window *window = NULL;
SDL_GLContext ctx = NULL;
SDL_Renderer* globalRenderer = NULL;

We’re using Raspbian Jessie Lite as the OS. What could be the issue here?

I see someone already answered your questions on stackoverflow and I want to add a few things.

The main-thread restriction probably comes from one of the platforms SDL supports, kind of making it the lowest common denominator. It may be possible to get it to work on some platforms, but there are no guarantees and it could easily break with the next version of SDL.

Are you running your program from X11? Full KMS and Fake KMS are only supported through the x11 video driver of SDL. If you try using the rpi SDL video driver in this configuration you’ll see the “failed to add service” error and the broadcom driver just calls exit(1). The “Could not initialize” error could mean that it didn’t find libGL.so or libEGL.so. You can try pointing it to the right path with the SDL_VIDEO_GL_DRIVER environment variable, but I can’t say what that is without knowing how your system is setup.