SetVideoMode and Previous Surface

The SetVidoeMode documentation makes no mention of the fate of any previous
surface in the case of a re-call (toggle full/windowed or resized for example).

I’m seeing both behaviors right now (Win32).
In the case of resizing the window or changing from windowed to fullscreen,
there is a massive multi-megabyte memory leak, clearly the surface isn’t
being freed. The current video surface cannot be freed so I started doing:
pOldSurface = surface
SetVideoMode(new settings)
FreeSurface(pOldSurface)

Which worked great, but now in the 3rd case, Fullscreen to Windowed, the
previous surface IS being freed, thus my FreeSurface crashes. Alas, I
don’t run FullScreen much, so I can’t pinpoint what SDL version started
doing this.

Surely one of these behaviors is a bug, but the documentation doesn’t make
it clear which.

The SetVidoeMode documentation makes no mention of the fate of any previous
surface in the case of a re-call (toggle full/windowed or resized for example).

I’m seeing both behaviors right now (Win32).
In the case of resizing the window or changing from windowed to fullscreen,
there is a massive multi-megabyte memory leak, clearly the surface isn’t
being freed. The current video surface cannot be freed so I started doing:
pOldSurface = surface
SetVideoMode(new settings)
FreeSurface(pOldSurface)

This is a bug. The screen surface should be freed internally.
Can you give a very simple test program which exhibits this behavior?

Thanks!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software

This is a bug. The screen surface should be freed internally.
Can you give a very simple test program which exhibits this behavior?

That’s as simple as I could manage. Resizeable with an ALT-ENTER toggle
It just grows and grows and grows.
I’m running Win2k and watching the memory in the Task Manager.
I traced it through, and it’s using the direct x driver
Thanks,
–Manny
-------------- next part --------------
#include <stdlib.h>
#include <stdio.h>

#include “SDL.h”

SDL_Surface *pScreen;
int bIsFullscreen;
int bDone;

void CreateScreen(int nWidth, int nHeight, int bFullscreen)
{
int nFlags;

if(bFullscreen)	nFlags = SDL_SWSURFACE | SDL_FULLSCREEN;
else nFlags = SDL_SWSURFACE | SDL_RESIZABLE;

pScreen = SDL_SetVideoMode(nWidth, nHeight, bFullscreen ? 16 : 0, nFlags);
bIsFullscreen = bFullscreen;

}

void HandleKeyDown(void pEvent)
{
SDL_KeyboardEvent
pKeyEvent = (SDL_KeyboardEvent*)pEvent;
int key = pKeyEvent->keysym.sym;
int mod = pKeyEvent->keysym.mod;

if(key == SDLK_ESCAPE || key == SDLK_q)
{
	bDone = 1;
}
else if(key == SDLK_RETURN && (mod & KMOD_ALT))
{
	CreateScreen(800, 600, !bIsFullscreen);
}

}

void HandleVideoResize(void pEvent)
{
SDL_ResizeEvent
pResizeEvent = (SDL_ResizeEvent*)pEvent;
if(!bIsFullscreen) CreateScreen(pResizeEvent->w, pResizeEvent->h, 0);
}

void EventLoop()
{
SDL_Event event;
SDL_Event* pEvent = &event;
while(!bDone) while(SDL_PollEvent(pEvent)) switch(event.type)
{
case SDL_KEYDOWN:
HandleKeyDown(pEvent);
break;

	case SDL_QUIT:
		bDone = 1;
		break;

	case SDL_VIDEORESIZE:
		HandleVideoResize(pEvent);
		break;
}

}

int main(int argc, char *argv[])
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf(“Couldn’t initialize SDL: %s\n”, SDL_GetError());
return 1;
}
CreateScreen(800, 600, 0);
EventLoop();
SDL_Quit();
return 0;
}