Fixed memory leak when a renderer fails to be created

The supported texture formats were leaking. In order to catch future issues, we'll just do a full teardown of the renderer in the failure case, and make sure it's safe to do so with a partially initialized renderer.
This commit is contained in:
Sam Lantinga 2024-07-27 13:36:12 -07:00
parent da035142b2
commit 7eb2605630
1 changed files with 27 additions and 17 deletions

View File

@ -1144,10 +1144,7 @@ error:
#endif
if (renderer) {
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE);
SDL_free(renderer->texture_formats);
SDL_free(renderer);
SDL_DestroyRenderer(renderer);
}
return NULL;
@ -5059,10 +5056,15 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer)
renderer->destroyed = SDL_TRUE;
SDL_DestroyProperties(renderer->props);
SDL_DelEventWatch(SDL_RendererEventWatch, renderer);
if (renderer->window) {
SDL_PropertiesID props = SDL_GetWindowProperties(renderer->window);
if (SDL_GetPointerProperty(props, SDL_PROP_WINDOW_RENDERER_POINTER, NULL) == renderer) {
SDL_ClearProperty(props, SDL_PROP_WINDOW_RENDERER_POINTER);
}
}
SDL_DiscardAllCommands(renderer);
/* Free existing textures for this renderer */
@ -5072,18 +5074,27 @@ void SDL_DestroyRendererWithoutFreeing(SDL_Renderer *renderer)
SDL_assert(tex != renderer->textures); /* satisfy static analysis. */
}
SDL_free(renderer->vertex_data);
if (renderer->window) {
SDL_ClearProperty(SDL_GetWindowProperties(renderer->window), SDL_PROP_WINDOW_RENDERER_POINTER);
/* Clean up renderer-specific resources */
if (renderer->DestroyRenderer) {
renderer->DestroyRenderer(renderer);
}
/* Free the target mutex */
SDL_DestroyMutex(renderer->target_mutex);
renderer->target_mutex = NULL;
/* Clean up renderer-specific resources */
renderer->DestroyRenderer(renderer);
if (renderer->target_mutex) {
SDL_DestroyMutex(renderer->target_mutex);
renderer->target_mutex = NULL;
}
if (renderer->vertex_data) {
SDL_free(renderer->vertex_data);
renderer->vertex_data = NULL;
}
if (renderer->texture_formats) {
SDL_free(renderer->texture_formats);
renderer->texture_formats = NULL;
}
if (renderer->props) {
SDL_DestroyProperties(renderer->props);
renderer->props = 0;
}
}
void SDL_DestroyRenderer(SDL_Renderer *renderer)
@ -5114,7 +5125,6 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer)
SDL_SetObjectValid(renderer, SDL_OBJECT_TYPE_RENDERER, SDL_FALSE); // It's no longer magical...
SDL_free(renderer->texture_formats);
SDL_free(renderer);
}