Skip to content

Commit 24a3674

Browse files
authored
Merge pull request #2575 from yunline/convert-fix
Set default convert format when `Window.get_surface()` is called
2 parents b560863 + 1d80df8 commit 24a3674

File tree

6 files changed

+57
-15
lines changed

6 files changed

+57
-15
lines changed

src_c/_pygame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ typedef enum {
485485
#define PYGAMEAPI_PIXELARRAY_NUMSLOTS 2
486486
#define PYGAMEAPI_COLOR_NUMSLOTS 5
487487
#define PYGAMEAPI_MATH_NUMSLOTS 2
488-
#define PYGAMEAPI_BASE_NUMSLOTS 27
488+
#define PYGAMEAPI_BASE_NUMSLOTS 29
489489
#define PYGAMEAPI_EVENT_NUMSLOTS 8
490490
#define PYGAMEAPI_WINDOW_NUMSLOTS 1
491491
#define PYGAMEAPI_GEOMETRY_NUMSLOTS 1

src_c/base.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2057,6 +2057,27 @@ pg_SetDefaultWindowSurface(pgSurfaceObject *screen)
20572057
pg_default_screen = screen;
20582058
}
20592059

2060+
SDL_PixelFormat *pg_default_convert_format = NULL;
2061+
2062+
static SDL_PixelFormat *
2063+
pg_GetDefaultConvertFormat(void)
2064+
{
2065+
if (pg_default_screen) {
2066+
return pg_default_screen->surf->format;
2067+
}
2068+
return pg_default_convert_format;
2069+
}
2070+
2071+
static SDL_PixelFormat *
2072+
pg_SetDefaultConvertFormat(Uint32 format)
2073+
{
2074+
if (pg_default_convert_format != NULL) {
2075+
SDL_FreeFormat(pg_default_convert_format);
2076+
}
2077+
pg_default_convert_format = SDL_AllocFormat(format);
2078+
return pg_default_convert_format; // returns for NULL error checking
2079+
}
2080+
20602081
static char *
20612082
pg_EnvShouldBlendAlphaSDL2(void)
20622083
{
@@ -2273,8 +2294,10 @@ MODINIT_DEFINE(base)
22732294
c_api[24] = pg_DoubleFromObj;
22742295
c_api[25] = pg_TwoDoublesFromObj;
22752296
c_api[26] = pg_TwoDoublesFromFastcallArgs;
2297+
c_api[27] = pg_GetDefaultConvertFormat;
2298+
c_api[28] = pg_SetDefaultConvertFormat;
22762299

2277-
#define FILLED_SLOTS 27
2300+
#define FILLED_SLOTS 29
22782301

22792302
#if PYGAMEAPI_BASE_NUMSLOTS != FILLED_SLOTS
22802303
#error export slot count mismatch

src_c/include/_pygame.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,12 @@ typedef struct pg_bufferinfo_s {
173173
#define pg_EnvShouldBlendAlphaSDL2 \
174174
(*(char *(*)(void))PYGAMEAPI_GET_SLOT(base, 23))
175175

176+
#define pg_GetDefaultConvertFormat \
177+
(*(SDL_PixelFormat * (*)(void)) PYGAMEAPI_GET_SLOT(base, 27))
178+
179+
#define pg_SetDefaultConvertFormat \
180+
(*(SDL_PixelFormat * (*)(Uint32)) PYGAMEAPI_GET_SLOT(base, 28))
181+
176182
#define import_pygame_base() IMPORT_PYGAME_MODULE(base)
177183
#endif /* ~PYGAMEAPI_BASE_INTERNAL */
178184

src_c/surface.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,32 +1590,33 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
15901590
static SDL_Surface *
15911591
pg_DisplayFormat(SDL_Surface *surface)
15921592
{
1593-
SDL_Surface *displaysurf;
1594-
if (!pg_GetDefaultWindowSurface()) {
1595-
SDL_SetError("No video mode has been set");
1593+
SDL_PixelFormat *default_format = pg_GetDefaultConvertFormat();
1594+
if (!default_format) {
1595+
SDL_SetError(
1596+
"No convert format has been set, try display.set_mode()"
1597+
" or Window.get_surface().");
15961598
return NULL;
15971599
}
1598-
displaysurf = pgSurface_AsSurface(pg_GetDefaultWindowSurface());
1599-
return PG_ConvertSurface(surface, displaysurf->format);
1600+
return PG_ConvertSurface(surface, default_format);
16001601
}
16011602

16021603
static SDL_Surface *
16031604
pg_DisplayFormatAlpha(SDL_Surface *surface)
16041605
{
1605-
SDL_Surface *displaysurf;
16061606
SDL_PixelFormat *dformat;
16071607
Uint32 pfe;
16081608
Uint32 amask = 0xff000000;
16091609
Uint32 rmask = 0x00ff0000;
16101610
Uint32 gmask = 0x0000ff00;
16111611
Uint32 bmask = 0x000000ff;
16121612

1613-
if (!pg_GetDefaultWindowSurface()) {
1614-
SDL_SetError("No video mode has been set");
1613+
dformat = pg_GetDefaultConvertFormat();
1614+
if (!dformat) {
1615+
SDL_SetError(
1616+
"No convert format has been set, try display.set_mode()"
1617+
" or Window.get_surface().");
16151618
return NULL;
16161619
}
1617-
displaysurf = pgSurface_AsSurface(pg_GetDefaultWindowSurface());
1618-
dformat = displaysurf->format;
16191620

16201621
switch (dformat->BytesPerPixel) {
16211622
case 2:

src_c/window.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,22 @@ window_get_surface(pgWindowObject *self)
157157
if (!_surf) {
158158
return RAISE(pgExc_SDLError, SDL_GetError());
159159
}
160+
161+
if (pg_GetDefaultConvertFormat() == NULL) {
162+
if (pg_SetDefaultConvertFormat(_surf->format->format) == NULL) {
163+
/* This is very unlikely, I think only would happen if SDL runs
164+
* out of memory when allocating the format. */
165+
return RAISE(pgExc_SDLError, SDL_GetError());
166+
}
167+
}
168+
160169
if (self->surf == NULL) {
161170
self->surf = pgSurface_New2(_surf, SDL_FALSE);
162171
if (!self->surf)
163172
return NULL;
164173
}
165174
self->surf->surf = _surf;
175+
166176
Py_INCREF(self->surf);
167177
return (PyObject *)self->surf;
168178
}

test/surface_test.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,8 +1245,8 @@ def test_convert_init(self):
12451245
except pygame.error:
12461246
self.fail("convert() should not raise an exception here.")
12471247

1248-
self.assertRaisesRegex(pygame.error, "No video mode", surf.convert)
1249-
self.assertRaisesRegex(pygame.error, "No video mode", surf8bit.convert)
1248+
self.assertRaisesRegex(pygame.error, "No convert format", surf.convert)
1249+
self.assertRaisesRegex(pygame.error, "No convert format", surf8bit.convert)
12501250

12511251
pygame.display.set_mode((640, 480))
12521252
try:
@@ -1266,7 +1266,9 @@ def test_convert_alpha_init(self):
12661266

12671267
pygame.display.init()
12681268
try:
1269-
self.assertRaisesRegex(pygame.error, "No video mode", surf.convert_alpha)
1269+
self.assertRaisesRegex(
1270+
pygame.error, "No convert format", surf.convert_alpha
1271+
)
12701272

12711273
pygame.display.set_mode((640, 480))
12721274
try:

0 commit comments

Comments
 (0)