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?