From 1f5c063ecb2120be028b63342ba2eab19d97a4ec Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 30 Sep 2024 18:52:54 -0700
Subject: [PATCH] Fixed renderer text engine memory leaks
---
src/SDL_renderer_textengine.c | 39 +++++++++++++++++++++++++++--------
1 file changed, 30 insertions(+), 9 deletions(-)
diff --git a/src/SDL_renderer_textengine.c b/src/SDL_renderer_textengine.c
index a367a1d7..1eb6c907 100644
--- a/src/SDL_renderer_textengine.c
+++ b/src/SDL_renderer_textengine.c
@@ -49,7 +49,6 @@ struct AtlasTexture
SDL_Texture *texture;
stbrp_context packer;
stbrp_node *packing_nodes;
- int num_free_glyphs;
AtlasGlyph *free_glyphs;
AtlasTexture *next;
};
@@ -156,12 +155,27 @@ static int SDLCALL SortOperations(const void *a, const void *b)
return 0;
}
+static void DestroyGlyph(AtlasGlyph* glyph)
+{
+ if (!glyph) {
+ return;
+ }
+
+ SDL_free(glyph);
+}
+
static void DestroyAtlas(AtlasTexture *atlas)
{
if (!atlas) {
return;
}
+ AtlasGlyph *next;
+ for (AtlasGlyph *glyph = atlas->free_glyphs; glyph; glyph = next) {
+ next = glyph->next;
+ DestroyGlyph(glyph);
+ }
+
SDL_DestroyTexture(atlas->texture);
SDL_free(atlas->packing_nodes);
SDL_free(atlas);
@@ -212,7 +226,6 @@ static void ReleaseGlyph(AtlasGlyph *glyph)
prev = entry;
}
- ++glyph->atlas->num_free_glyphs;
if (prev) {
prev->next = glyph;
} else {
@@ -220,7 +233,7 @@ static void ReleaseGlyph(AtlasGlyph *glyph)
}
glyph->next = entry;
} else {
- SDL_free(glyph);
+ DestroyGlyph(glyph);
}
}
}
@@ -267,7 +280,6 @@ static AtlasGlyph *FindUnusedGlyph(AtlasTexture *atlas, int width, int height)
} else {
atlas->free_glyphs = glyph->next;
}
- --atlas->num_free_glyphs;
++glyph->refcount;
return glyph;
}
@@ -502,6 +514,7 @@ static void DestroyDrawSequence(AtlasDrawSequence *data)
if (data->next) {
DestroyDrawSequence(data->next);
}
+ SDL_free(data->rects);
SDL_free(data->texcoords);
SDL_free(data->positions);
SDL_free(data->indices);
@@ -728,12 +741,20 @@ static TTF_RendererTextEngineFontData *CreateFontData(TTF_RendererTextEngineData
static void DestroyEngineData(TTF_RendererTextEngineData *data)
{
- if (data) {
- if (data->fonts) {
- SDL_DestroyHashTable(data->fonts);
- }
- SDL_free(data);
+ if (!data) {
+ return;
+ }
+
+ if (data->fonts) {
+ SDL_DestroyHashTable(data->fonts);
}
+
+ AtlasTexture *next;
+ for (AtlasTexture *atlas = data->atlas; atlas; atlas = next) {
+ next = atlas->next;
+ DestroyAtlas(atlas);
+ }
+ SDL_free(data);
}
static void NukeFontData(const void *key, const void *value, void *unused)