Skip to content

Commit dbe3b58

Browse files
committed
SDL3: display+window: runtime fixes
1 parent ee899f3 commit dbe3b58

File tree

2 files changed

+120
-16
lines changed

2 files changed

+120
-16
lines changed

src_c/display.c

Lines changed: 97 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,19 @@ _display_state_cleanup(_DisplayState *state)
9999
#endif
100100
}
101101

102+
/* This macro defines the pixel format we use for pg_renderer.
103+
* On our SDL2 code we used to use SDL_PIXELFORMAT_ARGB8888 but on SDL3 it
104+
* gives incorrect results because it includes alpha when we don't need it, so
105+
* we use the XRGB variant.
106+
* TODO: can consider using XRGB unconditionally on both SDL2 and SDL3
107+
* codepaths
108+
*/
109+
#if SDL_VERSION_ATLEAST(3, 0, 0)
110+
#define PG_TEXTURE_FMT SDL_PIXELFORMAT_XRGB8888
111+
#else
112+
#define PG_TEXTURE_FMT SDL_PIXELFORMAT_ARGB8888
113+
#endif
114+
102115
// prevent this code block from being linked twice
103116
// (this code block is copied by window.c)
104117
#ifndef BUILD_STATIC
@@ -464,7 +477,12 @@ pg_GetVideoInfo(pg_VideoInfo *info)
464477
}
465478
else {
466479
#if SDL_VERSION_ATLEAST(3, 0, 0)
467-
if ((mode_ptr = SDL_GetCurrentDisplayMode(0))) {
480+
SDL_DisplayID primary_display = SDL_GetPrimaryDisplay();
481+
if (primary_display == 0) {
482+
PyErr_SetString(pgExc_SDLError, SDL_GetError());
483+
return (pg_VideoInfo *)NULL;
484+
}
485+
if ((mode_ptr = SDL_GetCurrentDisplayMode(primary_display))) {
468486
info->current_w = mode_ptr->w;
469487
info->current_h = mode_ptr->h;
470488
formatenum = mode_ptr->format;
@@ -942,9 +960,8 @@ pg_ResizeEventWatch(void *userdata, SDL_Event *event)
942960

943961
SDL_DestroyTexture(pg_texture);
944962

945-
pg_texture =
946-
SDL_CreateTexture(pg_renderer, SDL_PIXELFORMAT_ARGB8888,
947-
SDL_TEXTUREACCESS_STREAMING, w, h);
963+
pg_texture = SDL_CreateTexture(pg_renderer, PG_TEXTURE_FMT,
964+
SDL_TEXTUREACCESS_STREAMING, w, h);
948965
}
949966
return 0;
950967
}
@@ -1166,6 +1183,7 @@ PG_SetWindowFullscreen(SDL_Window *window, bool fullscreen,
11661183
}
11671184
}
11681185

1186+
SDL_SyncWindow(window);
11691187
ret = true;
11701188
end:
11711189
SDL_free(modes);
@@ -1261,6 +1279,16 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
12611279
}
12621280
}
12631281

1282+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1283+
/* In SDL2, display == 0 meant primary display, so compat code for it */
1284+
if (display == 0) {
1285+
display = SDL_GetPrimaryDisplay();
1286+
if (display == 0) {
1287+
return RAISE(pgExc_SDLError, SDL_GetError());
1288+
}
1289+
}
1290+
#endif
1291+
12641292
if ((vsync == -1) && ((flags & PGS_OPENGL) == 0)) {
12651293
return RAISE(PyExc_ValueError,
12661294
"requested adaptive vsync without OpenGL");
@@ -1751,9 +1779,9 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
17511779
}
17521780
#endif
17531781

1754-
pg_texture = SDL_CreateTexture(
1755-
pg_renderer, SDL_PIXELFORMAT_ARGB8888,
1756-
SDL_TEXTUREACCESS_STREAMING, w, h);
1782+
pg_texture =
1783+
SDL_CreateTexture(pg_renderer, PG_TEXTURE_FMT,
1784+
SDL_TEXTUREACCESS_STREAMING, w, h);
17571785
}
17581786
surf = PG_CreateSurface(w, h, SDL_PIXELFORMAT_XRGB8888);
17591787
newownedsurf = surf;
@@ -1875,6 +1903,9 @@ pg_set_mode(PyObject *self, PyObject *arg, PyObject *kwds)
18751903
}
18761904
}
18771905
}
1906+
#if SDL_VERSION_ATLEAST(3, 0, 0)
1907+
SDL_SyncWindow(win);
1908+
#endif
18781909

18791910
/*return the window's surface (screen)*/
18801911
Py_INCREF(surface);
@@ -1973,6 +2004,9 @@ pg_set_window_position(PyObject *self, PyObject *arg)
19732004
if (win) {
19742005
/* Will raise errors with SDL 3, deal with it during the porting */
19752006
SDL_SetWindowPosition(win, x, y);
2007+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2008+
SDL_SyncWindow(win);
2009+
#endif
19762010
}
19772011

19782012
Py_RETURN_NONE;
@@ -1999,7 +2033,16 @@ pg_mode_ok(PyObject *self, PyObject *args, PyObject *kwds)
19992033
&display_index)) {
20002034
return NULL;
20012035
}
2002-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
2036+
2037+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2038+
/* In SDL2, display == 0 meant primary display, so compat code for it */
2039+
if (display_index == 0) {
2040+
display_index = SDL_GetPrimaryDisplay();
2041+
if (display_index == 0) {
2042+
return RAISE(pgExc_SDLError, SDL_GetError());
2043+
}
2044+
}
2045+
#else
20032046
/* Display ID is not bounded by number of displays in SDL3 */
20042047
if (display_index < 0 || display_index >= SDL_GetNumVideoDisplays()) {
20052048
return RAISE(PyExc_ValueError,
@@ -2026,6 +2069,15 @@ pg_mode_ok(PyObject *self, PyObject *args, PyObject *kwds)
20262069
}
20272070

20282071
#if SDL_VERSION_ATLEAST(3, 0, 0)
2072+
/* Compat with SDL2 behaviour */
2073+
const SDL_DisplayMode *curmode;
2074+
if (!(curmode = SDL_GetCurrentDisplayMode(display_index))) {
2075+
return RAISE(pgExc_SDLError, SDL_GetError());
2076+
}
2077+
if (curmode->w == desired.w && curmode->h == desired.h) {
2078+
return PyLong_FromLong(SDL_BITSPERPIXEL(curmode->format));
2079+
}
2080+
20292081
if (!SDL_GetClosestFullscreenDisplayMode(display_index, desired.w,
20302082
desired.h, desired.refresh_rate,
20312083
1, &closest)) {
@@ -2065,7 +2117,15 @@ pg_list_modes(PyObject *self, PyObject *args, PyObject *kwds)
20652117
return NULL;
20662118
}
20672119

2068-
#if !SDL_VERSION_ATLEAST(3, 0, 0)
2120+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2121+
/* In SDL2, display == 0 meant primary display, so compat code for it */
2122+
if (display_index == 0) {
2123+
display_index = SDL_GetPrimaryDisplay();
2124+
if (display_index == 0) {
2125+
return RAISE(pgExc_SDLError, SDL_GetError());
2126+
}
2127+
}
2128+
#else
20692129
/* Display ID is not bounded by number of displays in SDL3 */
20702130
if (display_index < 0 || display_index >= SDL_GetNumVideoDisplays()) {
20712131
return RAISE(PyExc_ValueError,
@@ -2077,19 +2137,31 @@ pg_list_modes(PyObject *self, PyObject *args, PyObject *kwds)
20772137
#pragma PG_WARN(Ignoring flags)
20782138

20792139
#if SDL_VERSION_ATLEAST(3, 0, 0)
2140+
const SDL_DisplayMode *curmode;
2141+
if (!(curmode = SDL_GetCurrentDisplayMode(display_index))) {
2142+
return RAISE(pgExc_SDLError, SDL_GetError());
2143+
}
20802144
if (bpp == 0) {
2081-
const SDL_DisplayMode *curmode;
2082-
if (!(curmode = SDL_GetCurrentDisplayMode(display_index))) {
2083-
return RAISE(pgExc_SDLError, SDL_GetError());
2084-
}
20852145
bpp = SDL_BITSPERPIXEL(curmode->format);
20862146
}
20872147

20882148
SDL_DisplayMode **modes =
20892149
SDL_GetFullscreenDisplayModes(display_index, &nummodes);
2090-
if (nummodes < 0) {
2150+
if (!modes || nummodes < 0) {
20912151
return RAISE(pgExc_SDLError, SDL_GetError());
20922152
}
2153+
2154+
/* SDL3 can return empty list here but SDL2 didn't. In that case, use
2155+
* curmode. */
2156+
if (nummodes == 0) {
2157+
SDL_free(modes);
2158+
modes = SDL_malloc(sizeof(SDL_DisplayMode **));
2159+
if (!modes) {
2160+
return PyErr_NoMemory();
2161+
}
2162+
modes[0] = (SDL_DisplayMode *)curmode;
2163+
nummodes = 1;
2164+
}
20932165
#else
20942166
if (bpp == 0) {
20952167
SDL_DisplayMode curmode;
@@ -2726,6 +2798,9 @@ pg_iconify(PyObject *self, PyObject *_null)
27262798
return RAISE(pgExc_SDLError, "No open window");
27272799
}
27282800
SDL_MinimizeWindow(win);
2801+
#if SDL_VERSION_ATLEAST(3, 0, 0)
2802+
SDL_SyncWindow(win);
2803+
#endif
27292804
return PyBool_FromLong(1);
27302805
}
27312806

@@ -3219,7 +3294,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
32193294
SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
32203295
#endif
32213296
pg_texture =
3222-
SDL_CreateTexture(pg_renderer, SDL_PIXELFORMAT_ARGB8888,
3297+
SDL_CreateTexture(pg_renderer, PG_TEXTURE_FMT,
32233298
SDL_TEXTUREACCESS_STREAMING, w, h);
32243299
}
32253300
#if SDL_VERSION_ATLEAST(3, 0, 0)
@@ -3372,7 +3447,7 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
33723447
SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
33733448
#endif
33743449
pg_texture =
3375-
SDL_CreateTexture(pg_renderer, SDL_PIXELFORMAT_ARGB8888,
3450+
SDL_CreateTexture(pg_renderer, PG_TEXTURE_FMT,
33763451
SDL_TEXTUREACCESS_STREAMING, w, h);
33773452
}
33783453

@@ -3453,6 +3528,9 @@ pg_toggle_fullscreen(PyObject *self, PyObject *_null)
34533528
}
34543529
}
34553530
}
3531+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3532+
SDL_SyncWindow(win);
3533+
#endif
34563534
return PyLong_FromLong(1);
34573535
}
34583536

@@ -3531,6 +3609,9 @@ pg_display_resize_event(PyObject *self, PyObject *event)
35313609
/* do not do anything that would invalidate a display surface! */
35323610
return PyLong_FromLong(-1);
35333611
}
3612+
#if SDL_VERSION_ATLEAST(3, 0, 0)
3613+
SDL_SyncWindow(win);
3614+
#endif
35343615
Py_RETURN_FALSE;
35353616
}
35363617

src_c/window.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ window_set_windowed(pgWindowObject *self, PyObject *_null)
305305
if (!SDL_SetWindowFullscreen(self->_win, 0)) {
306306
return RAISE(pgExc_SDLError, SDL_GetError());
307307
}
308+
SDL_SyncWindow(self->_win);
308309
#else
309310
if (SDL_SetWindowFullscreen(self->_win, 0)) {
310311
return RAISE(pgExc_SDLError, SDL_GetError());
@@ -345,6 +346,7 @@ pg_window_set_fullscreen(SDL_Window *window, int desktop)
345346
goto end;
346347
}
347348

349+
SDL_SyncWindow(window);
348350
ret = 1;
349351
end:
350352
SDL_free(modes);
@@ -429,20 +431,29 @@ static PyObject *
429431
window_restore(pgWindowObject *self, PyObject *_null)
430432
{
431433
SDL_RestoreWindow(self->_win);
434+
#if SDL_VERSION_ATLEAST(3, 0, 0)
435+
SDL_SyncWindow(self->_win);
436+
#endif
432437
Py_RETURN_NONE;
433438
}
434439

435440
static PyObject *
436441
window_maximize(pgWindowObject *self, PyObject *_null)
437442
{
438443
SDL_MaximizeWindow(self->_win);
444+
#if SDL_VERSION_ATLEAST(3, 0, 0)
445+
SDL_SyncWindow(self->_win);
446+
#endif
439447
Py_RETURN_NONE;
440448
}
441449

442450
static PyObject *
443451
window_minimize(pgWindowObject *self, PyObject *_null)
444452
{
445453
SDL_MinimizeWindow(self->_win);
454+
#if SDL_VERSION_ATLEAST(3, 0, 0)
455+
SDL_SyncWindow(self->_win);
456+
#endif
446457
Py_RETURN_NONE;
447458
}
448459

@@ -745,6 +756,9 @@ window_set_size(pgWindowObject *self, PyObject *arg, void *v)
745756
}
746757

747758
SDL_SetWindowSize(self->_win, w, h);
759+
#if SDL_VERSION_ATLEAST(3, 0, 0)
760+
SDL_SyncWindow(self->_win);
761+
#endif
748762
if (self->surf) {
749763
/* Ensure that the underlying surf is immediately updated, instead of
750764
* relying on the event callback */
@@ -797,6 +811,9 @@ window_set_minimum_size(pgWindowObject *self, PyObject *arg, void *v)
797811
}
798812

799813
SDL_SetWindowMinimumSize(self->_win, w, h);
814+
#if SDL_VERSION_ATLEAST(3, 0, 0)
815+
SDL_SyncWindow(self->_win);
816+
#endif
800817

801818
return 0;
802819
}
@@ -837,6 +854,9 @@ window_set_maximum_size(pgWindowObject *self, PyObject *arg, void *v)
837854
}
838855

839856
SDL_SetWindowMaximumSize(self->_win, w, h);
857+
#if SDL_VERSION_ATLEAST(3, 0, 0)
858+
SDL_SyncWindow(self->_win);
859+
#endif
840860

841861
return 0;
842862
}
@@ -868,6 +888,9 @@ window_set_position(pgWindowObject *self, PyObject *arg, void *v)
868888
}
869889

870890
SDL_SetWindowPosition(self->_win, x, y);
891+
#if SDL_VERSION_ATLEAST(3, 0, 0)
892+
SDL_SyncWindow(self->_win);
893+
#endif
871894

872895
return 0;
873896
}

0 commit comments

Comments
 (0)