Skip to content

Commit 7717c26

Browse files
committed
Allocate video surface object statically as a global
The SDL Perl bindings incorrectly call SDL_FreeSurface() on the result of functions that return a "borrowed" pointer to the video surface, namely SDL_SetVideoMode() and SDL_GetVideoSurface(). (See PerlGameDev/SDL#305) When we would previously have allocated or freed the video surface wrapper object, instead allocate or free its contents in-place. When checking whether the video surface exists, because we never destroy it, we must now also check whether its underlying SDL2 video surface exists. Resolves: libsdl-org#305 Signed-off-by: Simon McVittie <[email protected]>
1 parent b5703c2 commit 7717c26

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/SDL12_compat.c

+30-18
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ static SDL_Window *VideoWindow20 = NULL;
980980
static SDL_Renderer *VideoRenderer20 = NULL;
981981
static SDL_mutex *VideoRendererLock = NULL;
982982
static SDL_Texture *VideoTexture20 = NULL;
983+
static SDL12_Surface VideoSurface12Location;
983984
static SDL12_Surface *VideoSurface12 = NULL;
984985
static SDL_Palette *VideoPhysicalPalette20 = NULL;
985986
static Uint32 VideoSurfacePresentTicks = 0;
@@ -4714,7 +4715,7 @@ EventFilter20to12(void *data, SDL_Event *event20)
47144715
}
47154716

47164717
case SDL_MOUSEMOTION:
4717-
if (!VideoSurface12) {
4718+
if (!VideoSurface12 || !VideoSurface12->surface20) {
47184719
return 1; /* we don't have a screen surface yet? Don't send this on to the app. */
47194720
}
47204721

@@ -5569,11 +5570,9 @@ EndVidModeCreate(void)
55695570
VideoPhysicalPalette20 = NULL;
55705571
}
55715572
if (VideoSurface12) {
5572-
SDL12_Surface *screen12 = VideoSurface12;
55735573
SDL20_free(VideoSurface12->pixels);
55745574
VideoSurface12->pixels = NULL;
5575-
VideoSurface12 = NULL; /* SDL_FreeSurface will ignore the screen surface, so NULL the global variable out. */
5576-
SDL_FreeSurface(screen12);
5575+
FreeSurfaceContents(VideoSurface12);
55775576
}
55785577
if (VideoConvertSurface20) {
55795578
SDL20_FreeSurface(VideoConvertSurface20);
@@ -5607,16 +5606,27 @@ EndVidModeCreate(void)
56075606
return NULL;
56085607
}
56095608

5610-
5611-
static SDL12_Surface *
5612-
CreateSurface12WithFormat(const int w, const int h, const Uint32 fmt)
5609+
/* Essentially the same as SDL_CreateRGBSurface, but in-place */
5610+
static void
5611+
CreateVideoSurface(const Uint32 fmt)
56135612
{
56145613
Uint32 rmask, gmask, bmask, amask;
56155614
int bpp;
5615+
SDL_Surface *surface20;
5616+
56165617
if (!SDL20_PixelFormatEnumToMasks(fmt, &bpp, &rmask, &gmask, &bmask, &amask)) {
5617-
return NULL;
5618+
return;
56185619
}
5619-
return SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
5620+
5621+
SDL20_zerop(VideoSurface12);
5622+
surface20 = CreateRGBSurface(0, 0, 0, bpp, rmask, gmask, bmask, amask);
5623+
5624+
if (!Surface20to12InPlace(surface20, VideoSurface12)) {
5625+
FreeSurfaceContents(VideoSurface12);
5626+
return;
5627+
}
5628+
5629+
Surface12SetMasks(VideoSurface12, rmask, gmask, bmask, amask);
56205630
}
56215631

56225632
static SDL_Surface *
@@ -5953,6 +5963,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
59535963
int scaled_height = height;
59545964
const char *fromwin_env = NULL;
59555965

5966+
VideoSurface12 = &VideoSurface12Location;
5967+
59565968
if (flags12 & SDL12_OPENGL) {
59575969
/* For now we default GL scaling to ENABLED. If an app breaks or is linked directly
59585970
to glBindFramebuffer, they'll need to turn it off with this environment variable.
@@ -6042,11 +6054,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
60426054
default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL;
60436055
}
60446056

6045-
SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL));
6057+
SDL_assert((VideoSurface12->surface20 != NULL) == (VideoWindow20 != NULL));
60466058

6047-
if (VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) {
6059+
if (VideoSurface12->surface20 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) {
60486060
EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */
6049-
} else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) {
6061+
} else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) {
60506062
EndVidModeCreate(); /* rebuild the window if changing pixel format */
60516063
} else if (VideoGLContext20) {
60526064
/* SDL 1.2 (infuriatingly!) destroys the GL context on each resize in some cases, on various platforms. Try to match that. */
@@ -6188,11 +6200,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
61886200
SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE);
61896201
}
61906202

6191-
if (VideoSurface12) {
6203+
if (VideoSurface12->surface20) {
61926204
SDL20_free(VideoSurface12->pixels);
61936205
} else {
6194-
VideoSurface12 = CreateSurface12WithFormat(0, 0, appfmt);
6195-
if (!VideoSurface12) {
6206+
CreateVideoSurface(appfmt);
6207+
if (!VideoSurface12->surface20) {
61966208
return EndVidModeCreate();
61976209
}
61986210
}
@@ -6708,7 +6720,7 @@ DECLSPEC12 SDL12_Surface * SDLCALL
67086720
SDL_DisplayFormat(SDL12_Surface *surface12)
67096721
{
67106722
const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK);
6711-
if (!VideoSurface12) {
6723+
if (!VideoSurface12 || !VideoSurface12->surface20) {
67126724
SDL20_SetError("No video mode has been set");
67136725
return NULL;
67146726
}
@@ -6724,7 +6736,7 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12)
67246736
SDL_PixelFormat *fmt20 = NULL;
67256737
SDL12_PixelFormat fmt12;
67266738

6727-
if (!VideoSurface12) {
6739+
if (!VideoSurface12 || !VideoSurface12->surface20) {
67286740
SDL20_SetError("No video mode has been set");
67296741
return NULL;
67306742
}
@@ -7309,7 +7321,7 @@ static void
73097321
HandleInputGrab(SDL12_GrabMode mode)
73107322
{
73117323
/* SDL 1.2 always grabbed input if the video mode was fullscreen. */
7312-
const SDL_bool isfullscreen = (VideoSurface12 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE;
7324+
const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE;
73137325
const SDL_bool wantgrab = (isfullscreen || (mode == SDL12_GRAB_ON)) ? SDL_TRUE : SDL_FALSE;
73147326
if (VideoWindowGrabbed != wantgrab) {
73157327
if (VideoWindow20) {

0 commit comments

Comments
 (0)