Skip to content

Commit 468d89a

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 a0d3e8e commit 468d89a

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;
@@ -4689,7 +4690,7 @@ EventFilter20to12(void *data, SDL_Event *event20)
46894690
}
46904691

46914692
case SDL_MOUSEMOTION:
4692-
if (!VideoSurface12) {
4693+
if (!VideoSurface12 || !VideoSurface12->surface20) {
46934694
return 1; /* we don't have a screen surface yet? Don't send this on to the app. */
46944695
}
46954696

@@ -5541,11 +5542,9 @@ EndVidModeCreate(void)
55415542
VideoPhysicalPalette20 = NULL;
55425543
}
55435544
if (VideoSurface12) {
5544-
SDL12_Surface *screen12 = VideoSurface12;
55455545
SDL20_free(VideoSurface12->pixels);
55465546
VideoSurface12->pixels = NULL;
5547-
VideoSurface12 = NULL; /* SDL_FreeSurface will ignore the screen surface, so NULL the global variable out. */
5548-
SDL_FreeSurface(screen12);
5547+
FreeSurfaceContents(VideoSurface12);
55495548
}
55505549
if (VideoConvertSurface20) {
55515550
SDL20_FreeSurface(VideoConvertSurface20);
@@ -5579,16 +5578,27 @@ EndVidModeCreate(void)
55795578
return NULL;
55805579
}
55815580

5582-
5583-
static SDL12_Surface *
5584-
CreateSurface12WithFormat(const int w, const int h, const Uint32 fmt)
5581+
/* Essentially the same as SDL_CreateRGBSurface, but in-place */
5582+
static void
5583+
CreateVideoSurface(const Uint32 fmt)
55855584
{
55865585
Uint32 rmask, gmask, bmask, amask;
55875586
int bpp;
5587+
SDL_Surface *surface20;
5588+
55885589
if (!SDL20_PixelFormatEnumToMasks(fmt, &bpp, &rmask, &gmask, &bmask, &amask)) {
5589-
return NULL;
5590+
return;
55905591
}
5591-
return SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);
5592+
5593+
SDL20_zerop(VideoSurface12);
5594+
surface20 = CreateRGBSurface(0, 0, 0, bpp, rmask, gmask, bmask, amask);
5595+
5596+
if (!Surface20to12InPlace(surface20, VideoSurface12)) {
5597+
FreeSurfaceContents(VideoSurface12);
5598+
return;
5599+
}
5600+
5601+
Surface12SetMasks(VideoSurface12, rmask, gmask, bmask, amask);
55925602
}
55935603

55945604
static SDL_Surface *
@@ -5925,6 +5935,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
59255935
int scaled_height = height;
59265936
const char *fromwin_env = NULL;
59275937

5938+
VideoSurface12 = &VideoSurface12Location;
5939+
59285940
if (flags12 & SDL12_OPENGL) {
59295941
/* For now we default GL scaling to ENABLED. If an app breaks or is linked directly
59305942
to glBindFramebuffer, they'll need to turn it off with this environment variable.
@@ -6014,11 +6026,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
60146026
default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL;
60156027
}
60166028

6017-
SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL));
6029+
SDL_assert((VideoSurface12->surface20 != NULL) == (VideoWindow20 != NULL));
60186030

6019-
if (VideoSurface12 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) {
6031+
if (VideoSurface12->surface20 && ((VideoSurface12->flags & SDL12_OPENGL) != (flags12 & SDL12_OPENGL))) {
60206032
EndVidModeCreate(); /* rebuild the window if moving to/from a GL context */
6021-
} else if (VideoSurface12 && (VideoSurface12->surface20->format->format != appfmt)) {
6033+
} else if (VideoSurface12->surface20 && (VideoSurface12->surface20->format->format != appfmt)) {
60226034
EndVidModeCreate(); /* rebuild the window if changing pixel format */
60236035
} else if (VideoGLContext20) {
60246036
/* SDL 1.2 (infuriatingly!) destroys the GL context on each resize in some cases, on various platforms. Try to match that. */
@@ -6160,11 +6172,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
61606172
SDL20_SetWindowResizable(VideoWindow20, (flags12 & SDL12_RESIZABLE) ? SDL_TRUE : SDL_FALSE);
61616173
}
61626174

6163-
if (VideoSurface12) {
6175+
if (VideoSurface12->surface20) {
61646176
SDL20_free(VideoSurface12->pixels);
61656177
} else {
6166-
VideoSurface12 = CreateSurface12WithFormat(0, 0, appfmt);
6167-
if (!VideoSurface12) {
6178+
CreateVideoSurface(appfmt);
6179+
if (!VideoSurface12->surface20) {
61686180
return EndVidModeCreate();
61696181
}
61706182
}
@@ -6680,7 +6692,7 @@ DECLSPEC12 SDL12_Surface * SDLCALL
66806692
SDL_DisplayFormat(SDL12_Surface *surface12)
66816693
{
66826694
const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK);
6683-
if (!VideoSurface12) {
6695+
if (!VideoSurface12 || !VideoSurface12->surface20) {
66846696
SDL20_SetError("No video mode has been set");
66856697
return NULL;
66866698
}
@@ -6696,7 +6708,7 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12)
66966708
SDL_PixelFormat *fmt20 = NULL;
66976709
SDL12_PixelFormat fmt12;
66986710

6699-
if (!VideoSurface12) {
6711+
if (!VideoSurface12 || !VideoSurface12->surface20) {
67006712
SDL20_SetError("No video mode has been set");
67016713
return NULL;
67026714
}
@@ -7281,7 +7293,7 @@ static void
72817293
HandleInputGrab(SDL12_GrabMode mode)
72827294
{
72837295
/* SDL 1.2 always grabbed input if the video mode was fullscreen. */
7284-
const SDL_bool isfullscreen = (VideoSurface12 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE;
7296+
const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE;
72857297
const SDL_bool wantgrab = (isfullscreen || (mode == SDL12_GRAB_ON)) ? SDL_TRUE : SDL_FALSE;
72867298
if (VideoWindowGrabbed != wantgrab) {
72877299
if (VideoWindow20) {

0 commit comments

Comments
 (0)