video: put a spinlock around a global linked list.

This should only contend if you're allocating or freeing surfaces from
multiple threads at once, and then just for a short time.

Fixes Bugzilla #4084.
This commit is contained in:
Ryan C. Gordon 2018-02-16 14:56:28 -05:00
parent 8ddebfa06e
commit 6867f6189f

View File

@ -490,16 +490,20 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
} }
static SDL_PixelFormat *formats; static SDL_PixelFormat *formats;
static SDL_SpinLock formats_lock = 0;
SDL_PixelFormat * SDL_PixelFormat *
SDL_AllocFormat(Uint32 pixel_format) SDL_AllocFormat(Uint32 pixel_format)
{ {
SDL_PixelFormat *format; SDL_PixelFormat *format;
SDL_AtomicLock(&formats_lock);
/* Look it up in our list of previously allocated formats */ /* Look it up in our list of previously allocated formats */
for (format = formats; format; format = format->next) { for (format = formats; format; format = format->next) {
if (pixel_format == format->format) { if (pixel_format == format->format) {
++format->refcount; ++format->refcount;
SDL_AtomicUnlock(&formats_lock);
return format; return format;
} }
} }
@ -507,10 +511,12 @@ SDL_AllocFormat(Uint32 pixel_format)
/* Allocate an empty pixel format structure, and initialize it */ /* Allocate an empty pixel format structure, and initialize it */
format = SDL_malloc(sizeof(*format)); format = SDL_malloc(sizeof(*format));
if (format == NULL) { if (format == NULL) {
SDL_AtomicUnlock(&formats_lock);
SDL_OutOfMemory(); SDL_OutOfMemory();
return NULL; return NULL;
} }
if (SDL_InitFormat(format, pixel_format) < 0) { if (SDL_InitFormat(format, pixel_format) < 0) {
SDL_AtomicUnlock(&formats_lock);
SDL_free(format); SDL_free(format);
SDL_InvalidParamError("format"); SDL_InvalidParamError("format");
return NULL; return NULL;
@ -521,6 +527,9 @@ SDL_AllocFormat(Uint32 pixel_format)
format->next = formats; format->next = formats;
formats = format; formats = format;
} }
SDL_AtomicUnlock(&formats_lock);
return format; return format;
} }
@ -598,7 +607,11 @@ SDL_FreeFormat(SDL_PixelFormat *format)
SDL_InvalidParamError("format"); SDL_InvalidParamError("format");
return; return;
} }
SDL_AtomicLock(&formats_lock);
if (--format->refcount > 0) { if (--format->refcount > 0) {
SDL_AtomicUnlock(&formats_lock);
return; return;
} }
@ -614,6 +627,8 @@ SDL_FreeFormat(SDL_PixelFormat *format)
} }
} }
SDL_AtomicUnlock(&formats_lock);
if (format->palette) { if (format->palette) {
SDL_FreePalette(format->palette); SDL_FreePalette(format->palette);
} }