Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allocate video surface object statically as a global #306

Merged
merged 4 commits into from
Aug 26, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 101 additions & 46 deletions src/SDL12_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ static SDL_Window *VideoWindow20 = NULL;
static SDL_Renderer *VideoRenderer20 = NULL;
static SDL_mutex *VideoRendererLock = NULL;
static SDL_Texture *VideoTexture20 = NULL;
static SDL12_Surface VideoSurface12Location;
static SDL12_Surface *VideoSurface12 = NULL;
static SDL_Palette *VideoPhysicalPalette20 = NULL;
static Uint32 VideoSurfacePresentTicks = 0;
Expand Down Expand Up @@ -2616,6 +2617,19 @@ SDL_WasInit(Uint32 sdl12flags)
return InitFlags20to12(SDL20_WasInit(sdl20flags)) | extraflags;
}

static void
FreeSurfaceContents(SDL12_Surface *surface12)
{
if (surface12->surface20) {
SDL20_FreeSurface(surface12->surface20);
surface12->surface20 = NULL;
}
if (surface12->format) {
SDL20_free(surface12->format->palette);
SDL20_free(surface12->format);
surface12->format = NULL;
}
}

static SDL12_Surface *EndVidModeCreate(void);
static void
Expand Down Expand Up @@ -4701,7 +4715,7 @@ EventFilter20to12(void *data, SDL_Event *event20)
}

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

Expand Down Expand Up @@ -4937,26 +4951,21 @@ Rect12to20(const SDL12_Rect *rect12, SDL_Rect *rect20)
return rect20;
}

static SDL12_Surface *
Surface20to12(SDL_Surface *surface20)
static SDL_bool
Surface20to12InPlace(SDL_Surface *surface20,
SDL12_Surface *surface12)
{
SDL_BlendMode blendmode = SDL_BLENDMODE_NONE;
SDL12_Surface *surface12 = NULL;
SDL12_Palette *palette12 = NULL;
SDL12_PixelFormat *format12 = NULL;
Uint32 flags = 0;

if (!surface20) {
return NULL;
return SDL_FALSE;
}
if (surface20->pitch > 65535) {
SDL20_SetError("Pitch is too large"); /* can't fit to 16-bits */
return NULL;
}

surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface));
if (!surface12) {
goto failed;
return SDL_FALSE;
}

if (surface20->format->palette) {
Expand Down Expand Up @@ -5029,12 +5038,33 @@ Surface20to12(SDL_Surface *surface20)
Rect20to12(&surface20->clip_rect, &surface12->clip_rect);
surface12->refcount = surface20->refcount;

return surface12;
return SDL_TRUE;

failed:
SDL20_free(surface12);
SDL20_free(palette12);
SDL20_free(format12);
return SDL_FALSE;
}

static SDL12_Surface *
Surface20to12(SDL_Surface *surface20)
{
SDL12_Surface *surface12 = NULL;

surface12 = (SDL12_Surface *) SDL20_malloc(sizeof (SDL12_Surface));
if (!surface12) {
goto failed;
}

SDL20_zerop(surface12);
if (!Surface20to12InPlace(surface20, surface12)) {
goto failed;
}

return surface12;

failed:
SDL20_free(surface12);
return NULL;
}

Expand Down Expand Up @@ -5102,11 +5132,10 @@ SetPalette12ForMasks(SDL12_Surface *surface12, const Uint32 Rmask, const Uint32
}
}

DECLSPEC12 SDL12_Surface * SDLCALL
SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
static SDL_Surface *
CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
SDL_Surface *surface20;
SDL12_Surface *surface12;

/* SDL 1.2 checks this. */
if ((width >= 16384) || (height >= 65536)) {
Expand Down Expand Up @@ -5152,21 +5181,38 @@ SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rm
surface20 = SDL20_CreateRGBSurface(0, width, height, depth, Rmask, Gmask, Bmask, Amask);
}

surface12 = Surface20to12(surface20);
if (!surface12) {
SDL20_FreeSurface(surface20);
return NULL;
}

SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == 0); /* shouldn't have prealloc, rleaccel, or dontfree. */
return surface20;
}

static void
Surface12SetMasks(SDL12_Surface *surface12, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
SetPalette12ForMasks(surface12, Rmask, Gmask, Bmask);

if (Amask != 0) {
surface12->flags |= SDL12_SRCALPHA;
SDL20_SetSurfaceBlendMode(surface20, SDL_BLENDMODE_BLEND);
SDL20_SetSurfaceBlendMode(surface12->surface20, SDL_BLENDMODE_BLEND);
}
}

DECLSPEC12 SDL12_Surface * SDLCALL
SDL_CreateRGBSurface(Uint32 flags12, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask)
{
SDL12_Surface *surface12;
SDL_Surface *surface20;

surface20 = CreateRGBSurface(flags12, width, height, depth, Rmask, Gmask, Bmask, Amask);
if (!surface20) {
return NULL;
}
surface12 = Surface20to12(surface20);
if (!surface12) {
SDL20_FreeSurface(surface20);
return NULL;
}

SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == 0); /* shouldn't have prealloc, rleaccel, or dontfree. */
Surface12SetMasks(surface12, Rmask, Gmask, Bmask, Amask);
return surface12;
}

Expand Down Expand Up @@ -5195,6 +5241,8 @@ SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pit

SDL_assert((surface12->flags & ~(SDL12_SRCCOLORKEY|SDL12_SRCALPHA)) == SDL12_PREALLOC); /* should _only_ have prealloc. */

/* TODO: Is it correct that this always ignored Amask, or should it be
* using Surface12SetMasks which takes Amask into account? */
SetPalette12ForMasks(surface12, Rmask, Gmask, Bmask);

return surface12;
Expand All @@ -5207,11 +5255,7 @@ SDL_FreeSurface(SDL12_Surface *surface12)
surface12->refcount--;
if (surface12->refcount)
return;
SDL20_FreeSurface(surface12->surface20);
if (surface12->format) {
SDL20_free(surface12->format->palette);
SDL20_free(surface12->format);
}
FreeSurfaceContents(surface12);
SDL20_free(surface12);
}
}
Expand Down Expand Up @@ -5526,11 +5570,9 @@ EndVidModeCreate(void)
VideoPhysicalPalette20 = NULL;
}
if (VideoSurface12) {
SDL12_Surface *screen12 = VideoSurface12;
SDL20_free(VideoSurface12->pixels);
VideoSurface12->pixels = NULL;
VideoSurface12 = NULL; /* SDL_FreeSurface will ignore the screen surface, so NULL the global variable out. */
SDL_FreeSurface(screen12);
FreeSurfaceContents(VideoSurface12);
}
if (VideoConvertSurface20) {
SDL20_FreeSurface(VideoConvertSurface20);
Expand Down Expand Up @@ -5564,16 +5606,27 @@ EndVidModeCreate(void)
return NULL;
}


static SDL12_Surface *
CreateSurface12WithFormat(const int w, const int h, const Uint32 fmt)
/* Essentially the same as SDL_CreateRGBSurface, but in-place */
static void
CreateVideoSurface(const Uint32 fmt)
{
Uint32 rmask, gmask, bmask, amask;
int bpp;
SDL_Surface *surface20;

if (!SDL20_PixelFormatEnumToMasks(fmt, &bpp, &rmask, &gmask, &bmask, &amask)) {
return NULL;
return;
}
return SDL_CreateRGBSurface(0, w, h, bpp, rmask, gmask, bmask, amask);

SDL20_zerop(VideoSurface12);
surface20 = CreateRGBSurface(0, 0, 0, bpp, rmask, gmask, bmask, amask);

if (!Surface20to12InPlace(surface20, VideoSurface12)) {
FreeSurfaceContents(VideoSurface12);
return;
}

Surface12SetMasks(VideoSurface12, rmask, gmask, bmask, amask);
}

static SDL_Surface *
Expand Down Expand Up @@ -5910,6 +5963,8 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
int scaled_height = height;
const char *fromwin_env = NULL;

VideoSurface12 = &VideoSurface12Location;

if (flags12 & SDL12_OPENGL) {
/* For now we default GL scaling to ENABLED. If an app breaks or is linked directly
to glBindFramebuffer, they'll need to turn it off with this environment variable.
Expand Down Expand Up @@ -5999,11 +6054,11 @@ SetVideoModeImpl(int width, int height, int bpp, Uint32 flags12)
default: SDL20_SetError("Unsupported bits-per-pixel"); return NULL;
}

SDL_assert((VideoSurface12 != NULL) == (VideoWindow20 != NULL));
SDL_assert((VideoSurface12->surface20 != NULL) == (VideoWindow20 != NULL));

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

if (VideoSurface12) {
if (VideoSurface12->surface20) {
SDL20_free(VideoSurface12->pixels);
} else {
VideoSurface12 = CreateSurface12WithFormat(0, 0, appfmt);
if (!VideoSurface12) {
CreateVideoSurface(appfmt);
if (!VideoSurface12->surface20) {
return EndVidModeCreate();
}
}
Expand Down Expand Up @@ -6665,7 +6720,7 @@ DECLSPEC12 SDL12_Surface * SDLCALL
SDL_DisplayFormat(SDL12_Surface *surface12)
{
const Uint32 flags = surface12->flags & (SDL12_SRCCOLORKEY|SDL12_SRCALPHA|SDL12_RLEACCELOK);
if (!VideoSurface12) {
if (!VideoSurface12 || !VideoSurface12->surface20) {
SDL20_SetError("No video mode has been set");
return NULL;
}
Expand All @@ -6681,7 +6736,7 @@ SDL_DisplayFormatAlpha(SDL12_Surface *surface12)
SDL_PixelFormat *fmt20 = NULL;
SDL12_PixelFormat fmt12;

if (!VideoSurface12) {
if (!VideoSurface12 || !VideoSurface12->surface20) {
SDL20_SetError("No video mode has been set");
return NULL;
}
Expand Down Expand Up @@ -7266,7 +7321,7 @@ static void
HandleInputGrab(SDL12_GrabMode mode)
{
/* SDL 1.2 always grabbed input if the video mode was fullscreen. */
const SDL_bool isfullscreen = (VideoSurface12 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE;
const SDL_bool isfullscreen = (VideoSurface12 && VideoSurface12->surface20 && (VideoSurface12->flags & SDL12_FULLSCREEN)) ? SDL_TRUE : SDL_FALSE;
const SDL_bool wantgrab = (isfullscreen || (mode == SDL12_GRAB_ON)) ? SDL_TRUE : SDL_FALSE;
if (VideoWindowGrabbed != wantgrab) {
if (VideoWindow20) {
Expand Down