From de257d72bc51626378190f63d83aa97756bc72c4 Mon Sep 17 00:00:00 2001 From: Starbuck5 <46412508+Starbuck5@users.noreply.github.com> Date: Thu, 31 Oct 2024 00:51:51 -0700 Subject: [PATCH] Adjust pg_(Get/Set)DefaultConvertFormat for SDL3 This reworks the functions to work on pixel format enums instead of structs, because in SDL3 the enums are much easier to get than the structs. This required involved changes to surface.c, but I think the previous mask logic is much clearer now that it is expressed using format enums. --- src_c/_pygame.h | 6 +++- src_c/base.c | 20 +++++++------ src_c/include/_pygame.h | 4 +-- src_c/meson.build | 3 -- src_c/surface.c | 66 +++++++++++++++++------------------------ src_c/window.c | 8 ++--- 6 files changed, 48 insertions(+), 59 deletions(-) diff --git a/src_c/_pygame.h b/src_c/_pygame.h index d5bdf7fe40..46fe2d966d 100644 --- a/src_c/_pygame.h +++ b/src_c/_pygame.h @@ -75,7 +75,9 @@ #define PG_CreateSurface SDL_CreateSurface #define PG_CreateSurfaceFrom SDL_CreateSurfaceFrom #define PG_ConvertSurface SDL_ConvertSurface -#define PG_ConvertSurfaceFormat SDL_ConvertSurfaceFormat +#define PG_ConvertSurfaceFormat SDL_ConvertSurface + +#define PG_PixelFormatEnum SDL_PixelFormat #define PG_SurfaceHasRLE SDL_SurfaceHasRLE @@ -146,6 +148,8 @@ PG_UnlockMutex(SDL_mutex *mutex) #define PG_ConvertSurfaceFormat(src, pixel_format) \ SDL_ConvertSurfaceFormat(src, pixel_format, 0) +#define PG_PixelFormatEnum SDL_PixelFormatEnum + #define PG_SoftStretchNearest(src, srcrect, dst, dstrect) \ SDL_SoftStretch(src, srcrect, dst, dstrect) diff --git a/src_c/base.c b/src_c/base.c index 04379ba0f2..37e392b694 100644 --- a/src_c/base.c +++ b/src_c/base.c @@ -2075,25 +2075,27 @@ pg_SetDefaultWindowSurface(pgSurfaceObject *screen) pg_default_screen = screen; } -SDL_PixelFormat *pg_default_convert_format = NULL; +PG_PixelFormatEnum pg_default_convert_format = 0; -static SDL_PixelFormat * +static PG_PixelFormatEnum pg_GetDefaultConvertFormat(void) { +#if SDL_VERSION_ATLEAST(3, 0, 0) if (pg_default_screen) { return pg_default_screen->surf->format; } +#else + if (pg_default_screen) { + return pg_default_screen->surf->format->format; + } +#endif return pg_default_convert_format; } -static SDL_PixelFormat * -pg_SetDefaultConvertFormat(Uint32 format) +static void +pg_SetDefaultConvertFormat(PG_PixelFormatEnum format) { - if (pg_default_convert_format != NULL) { - SDL_FreeFormat(pg_default_convert_format); - } - pg_default_convert_format = SDL_AllocFormat(format); - return pg_default_convert_format; // returns for NULL error checking + pg_default_convert_format = format; } static int diff --git a/src_c/include/_pygame.h b/src_c/include/_pygame.h index 8158fe68df..b3548a66ee 100644 --- a/src_c/include/_pygame.h +++ b/src_c/include/_pygame.h @@ -184,10 +184,10 @@ typedef struct pg_bufferinfo_s { (*(int (*)(void))PYGAMEAPI_GET_SLOT(base, 23)) #define pg_GetDefaultConvertFormat \ - (*(SDL_PixelFormat * (*)(void)) PYGAMEAPI_GET_SLOT(base, 27)) + (*(PG_PixelFormatEnum(*)(void))PYGAMEAPI_GET_SLOT(base, 27)) #define pg_SetDefaultConvertFormat \ - (*(SDL_PixelFormat * (*)(Uint32)) PYGAMEAPI_GET_SLOT(base, 28)) + (*(void (*)(Uint32))PYGAMEAPI_GET_SLOT(base, 28)) #define import_pygame_base() IMPORT_PYGAME_MODULE(base) #endif /* ~PYGAMEAPI_BASE_INTERNAL */ diff --git a/src_c/meson.build b/src_c/meson.build index ca10cca737..fb43a584eb 100644 --- a/src_c/meson.build +++ b/src_c/meson.build @@ -1,7 +1,5 @@ # first the "required" modules -# TODO: support SDL3 -if sdl_api != 3 base = py.extension_module( 'base', 'base.c', @@ -10,7 +8,6 @@ base = py.extension_module( install: true, subdir: pg, ) -endif color = py.extension_module( 'color', diff --git a/src_c/surface.c b/src_c/surface.c index b9e3008ae3..c0f64e4ab1 100644 --- a/src_c/surface.c +++ b/src_c/surface.c @@ -1582,27 +1582,25 @@ surf_convert(pgSurfaceObject *self, PyObject *args) static SDL_Surface * pg_DisplayFormat(SDL_Surface *surface) { - SDL_PixelFormat *default_format = pg_GetDefaultConvertFormat(); + PG_PixelFormatEnum default_format = pg_GetDefaultConvertFormat(); if (!default_format) { SDL_SetError( "No convert format has been set, try display.set_mode()" " or Window.get_surface()."); return NULL; } - return PG_ConvertSurface(surface, default_format); +#if SDL_VERSION_ATLEAST(3, 0, 0) + return SDL_ConvertSurface(surface, default_format); +#else + return SDL_ConvertSurfaceFormat(surface, default_format, 0); +#endif } static SDL_Surface * pg_DisplayFormatAlpha(SDL_Surface *surface) { - SDL_PixelFormat *dformat; - Uint32 pfe; - Uint32 amask = 0xff000000; - Uint32 rmask = 0x00ff0000; - Uint32 gmask = 0x0000ff00; - Uint32 bmask = 0x000000ff; - - dformat = pg_GetDefaultConvertFormat(); + PG_PixelFormatEnum pfe = SDL_PIXELFORMAT_ARGB8888; + PG_PixelFormatEnum dformat = pg_GetDefaultConvertFormat(); if (!dformat) { SDL_SetError( "No convert format has been set, try display.set_mode()" @@ -1610,37 +1608,29 @@ pg_DisplayFormatAlpha(SDL_Surface *surface) return NULL; } - switch (PG_FORMAT_BytesPerPixel(dformat)) { - case 2: - /* same behavior as SDL1 */ - if ((dformat->Rmask == 0x1f) && - (dformat->Bmask == 0xf800 || dformat->Bmask == 0x7c00)) { - rmask = 0xff; - bmask = 0xff0000; - } + switch (dformat) { +#if SDL_VERSION_ATLEAST(3, 0, 0) + case SDL_PIXELFORMAT_XBGR1555: +#else + case SDL_PIXELFORMAT_BGR555: +#endif + case SDL_PIXELFORMAT_ABGR1555: + case SDL_PIXELFORMAT_BGR565: + pfe = SDL_PIXELFORMAT_ABGR8888; break; - case 3: - case 4: - /* keep the format if the high bits are free */ - if ((dformat->Rmask == 0xff) && (dformat->Bmask == 0xff0000)) { - rmask = 0xff; - bmask = 0xff0000; - } - else if (dformat->Rmask == 0xff00 && - (dformat->Bmask == 0xff000000)) { - amask = 0x000000ff; - rmask = 0x0000ff00; - gmask = 0x00ff0000; - bmask = 0xff000000; - } + + case PG_PIXELFORMAT_XBGR8888: + case SDL_PIXELFORMAT_ABGR8888: + pfe = SDL_PIXELFORMAT_ABGR8888; break; - default: /* ARGB8888 */ + + case SDL_PIXELFORMAT_BGRX8888: + case SDL_PIXELFORMAT_BGRA8888: + pfe = SDL_PIXELFORMAT_BGRA8888; + break; + + default: break; - } - pfe = SDL_MasksToPixelFormatEnum(32, rmask, gmask, bmask, amask); - if (pfe == SDL_PIXELFORMAT_UNKNOWN) { - SDL_SetError("unknown pixel format"); - return NULL; } return PG_ConvertSurfaceFormat(surface, pfe); } diff --git a/src_c/window.c b/src_c/window.c index f2217cd20c..63b7270d06 100644 --- a/src_c/window.c +++ b/src_c/window.c @@ -157,12 +157,8 @@ window_get_surface(pgWindowObject *self, PyObject *_null) return RAISE(pgExc_SDLError, SDL_GetError()); } - if (pg_GetDefaultConvertFormat() == NULL) { - if (pg_SetDefaultConvertFormat(_surf->format->format) == NULL) { - /* This is very unlikely, I think only would happen if SDL runs - * out of memory when allocating the format. */ - return RAISE(pgExc_SDLError, SDL_GetError()); - } + if (pg_GetDefaultConvertFormat() == 0) { + pg_SetDefaultConvertFormat(_surf->format->format); } if (self->surf == NULL) {