slavko
February 2, 2022, 7:02pm
1
When I take a screenshot in my simple pong game the game freezes for half a second while taking the screenshot. I’ve tried making it a multi threaded function, but “SDL_RenderReadPixels()” almost always makes my game crash. The console output on crash is “i965: Failed to submit batchbuffer: Invalid argument” on my laptop (Asus X55A) on Fedora 33.
int pong_Screenshot(void *renderer)
{
SDL_Surface *sshot = SDL_CreateRGBSurface(0, w, h, 32, BLACK);
SDL_RenderReadPixels((SDL_Renderer *)renderer, NULL, 0, sshot->pixels, sshot->pitch);
char text[30];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(text, sizeof(text), "%d-%m-%Y_%H-%M-%S.bmp", t);
SDL_SaveBMP(sshot, text);
SDL_FreeSurface(sshot);
return 0;
}
The code block above doesn’t crash if not used on a separate thread.
slime
February 2, 2022, 7:09pm
2
You could keep the SaveBMP call on a separate thread, but SDL_Render APIs can only be used on the main thread.
slavko
February 12, 2022, 10:19pm
3
Thanks for the info. This is how I wrote the screenshot function:
int pong_SaveFile(void *surface)
{
char filename[30];
time_t now = time(NULL);
struct tm *t = localtime(&now);
strftime(filename, sizeof(filename), "%d-%m-%Y_%H-%M-%S.png", t);
FILE *file = fopen(filename, "r");
if (file == NULL)
IMG_SavePNG((SDL_Surface *) surface, filename);
else
fclose(file);
SDL_FreeSurface((SDL_Surface *) surface);
return 0;
}
void pong_Screenshot(SDL_Renderer *renderer)
{
int width = 0, height = 0;
SDL_GetRendererOutputSize(renderer , &width, &height);
SDL_Surface *screenshot = SDL_CreateRGBSurface(0, width, height, 32, BLACK);
SDL_RenderReadPixels(renderer, NULL, 0, screenshot->pixels, screenshot->pitch);
SDL_Thread *thread = SDL_CreateThread(pong_SaveFile, "SaveFile", (void *) screenshot);
SDL_DetachThread(thread);
}
Is there anything I can do to improve this in terms of multi threading?