I have some very simple drawing going on with SDL2 that was working perfectly under Windows but now that I've ported it over to Linux, isn't drawing from the different threads I've spawned.
I'm controlling access to the renderer using mutex's.
The functions process and output logging as expected, the only thing that doesn't appear to be working is that the renderer never updates the display under Linux.
If I comment out the threading, and run the function from main I get the expected result. The code hasn't changed between the Linux and Windows versions.
The code compiles without warnings under -wall and -pedantic. Since I've started compiling with Linux I've added -pthread flag in case that was required (hasn't made any difference).
If anyone is aware of any gotchas or might have an inkling why this isn't working you would be doing me an enormous favour.
static int thread_processing(void* data)
{
srand(time(NULL)); //randomize
ThreadData *td = data;
Bucket *bucket;
int b_Id = -1;
Color threadColor;
//unique color for each respective thread
color_randomize(&threadColor);
threadColor.a = 255;
fprintf(stderr, "%d Buckets to process..\n", td->bArray->size);
while (1) {
//check there are buckets left to process
if (td->bArray->rendered >= td->bArray->size)
break;
//acquie/lock access to bucket array
SDL_LockMutex(td->b_mutex);
//retrieve buucket id to process
b_Id = td->bArray->rendered;
td->bArray->rendered++;
fprintf(stderr, "Rendering bucket: %d\n", b_Id);
//release access to bucket array
SDL_UnlockMutex(td->b_mutex);
//retrieve addr of bucket to process
bucket = &(td->bArray->buckets[b_Id]);
//lock access to renderer
SDL_LockMutex(td->r_mutex);
//draw rect on screen where bucket will be processed
draw_bucketOutline(td->renderer, bucket, &threadColor);
SDL_RenderPresent(td->renderer);
//release access to renderer object
SDL_UnlockMutex(td->r_mutex);
//process the bucket
process_bucket(td->scene, bucket);
//acquire/lock acess to renderer object
SDL_LockMutex(td->r_mutex);
//draw the processed data ot the screen
draw_bucket(td->renderer, bucket);
SDL_RenderPresent(td->renderer);
//release access to renderer object
SDL_UnlockMutex(td->r_mutex);
}
return 0;
}
void draw_bucketOutline(SDL_Renderer *renderer, Bucket *b, Color *color)
{
//set the colour of the outline
SDL_SetRenderDrawColor(renderer, 125, 125, 125, 255);
//set the outline position
SDL_Rect rect;
rect.w = b->resolution.width;
rect.h = b->resolution.height;
rect.x = b->start.x;
rect.y = b->start.y;
//draw the outline
SDL_RenderDrawRect(renderer, &rect);
//crop rectangle inwards for filling inside of outline
rect.w -= 2;
rect.h -= 2;
rect.x += 1;
rect.y += 1;
//set colour for fill area
SDL_SetRenderDrawColor(renderer, color->r, color->g, color->b, color->a);
//draw fill area
SDL_RenderFillRect(renderer, &rect);
}
Main.....
//iterate over threads, do the processing
int t;
for (t = 0; t < THREAD_COUNT; t++) {
threads[t] = SDL_CreateThread(thread_processing, NULL, &td);
}
//iterate over threads, clean them up
for (t = 0; t < THREAD_COUNT; t++) {
int status;
SDL_WaitThread(threads[t], &status);
}
Compiling with
gcc -Wall -pedantic -lm -I/usr/include/SDL2 -D_REENTRANT -lX11 -pthread raytracer.c -lSDL2 -o raytracer