Do I need a SDL_DestroySurface
when I get a new Surface?
In my example, when you change the size of the window.
case SDL_EVENT_WINDOW_RESIZED:
if (winSurface) {
SDL_DestroySurface(winSurface); // necessary ?
}
winSurface = SDL_GetWindowSurface(win);
SDL_FillSurfaceRect(winSurface, nullptr, 0);
break;
I should have mentioned that I mean SDL3.
But according to the wiki there doesn’t seem to be any difference, except that SDL2 mentions that you should re-get WindowsSurface after every UpdateWindowSurface.
It’s a shame that the examples in the wiki don’t show how to do it with SDL_PollEvent
.
What makes the use of this function inside a SDL_PollEvent
loop special that it would motivate a special explanation and/or example?
Both the SDL2 and SDL3 wiki page clearly says “Do not free this surface”. This is always the case.
I would like to clarify for anyone who’s mind jumped to “but wouldn’t that be a memory leak?”:
If it detects that the said window surface is no longer valid (such as when the screen size has changed) the function SDL_GetWindowSurface calls SDL_DestroyWindowSurface to destroy the internal surface pointer held by the window .
SDL_Surface *SDL_GetWindowSurface(SDL_Window *window)
{
CHECK_WINDOW_MAGIC(window, NULL);
if (!window->surface_valid) {
SDL_DestroyWindowSurface(window);
window->surface = SDL_CreateWindowFramebuffer(window);
if (window->surface) {
window->surface_valid = SDL_TRUE;
window->surface->flags |= SDL_DONTFREE;
}
}
return window->surface;
}
No leak, the memory block is recovered by SDL_GetWindowSurface() before the new surface framebuffer is created and returned.
Edit: Also, the SDL_DONTFREE flag ensures that if you do try to destroy the surface before calling SDL_GetWindowSurface, the function SDL_DestroySurface will ignore the call, so it won’t crash your program due to a double deallocation. So you could do it either way, but doing it the “right way” will likely save about one or two dozen CPU cycles each time the event fires.
1 Like