From 9063cb221f198082771e5a87d33856625c71f666 Mon Sep 17 00:00:00 2001 From: Ryan Holtz Date: Fri, 18 Nov 2011 06:23:04 +0000 Subject: [PATCH] - Fixed HLSL memory leak and crash on exit on 32-bit targets. [Ryan Holtz, Bat Country Entertainment] Word around the campfire is this totally works and stuff. More technically, it eliminates a number of double-frees and also now cleans up the shadow mask PNG and hlsl_options allocations. (nw) --- src/osd/windows/d3dhlsl.c | 58 +++++++++++++++++++++++---------------- src/osd/windows/drawd3d.c | 17 +++++++++--- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/src/osd/windows/d3dhlsl.c b/src/osd/windows/d3dhlsl.c index 6fb51026c90..0a3447354ea 100644 --- a/src/osd/windows/d3dhlsl.c +++ b/src/osd/windows/d3dhlsl.c @@ -1,6 +1,6 @@ //============================================================ // -// drawd3d.c - Win32 Direct3D HLSL implementation +// d3dhlsl.c - Win32 Direct3D HLSL implementation // //============================================================ // @@ -213,6 +213,13 @@ hlsl_info::hlsl_info() hlsl_info::~hlsl_info() { + global_free(options); + + if(shadow_bitmap != NULL) + { + global_free(shadow_bitmap); + shadow_bitmap = NULL; + } } @@ -1734,34 +1741,37 @@ void hlsl_info::end() if(target_in_use[index] != NULL) { d3d_texture_info *tex = target_in_use[index]; - - if(d3d->texlist == tex) + bool found_in_active_list = false; + d3d_texture_info *test_tex = d3d->texlist; + while (test_tex != NULL) { - d3d->texlist = tex->next; - if(d3d->texlist != NULL) + if(test_tex == tex) { - d3d->texlist->prev = NULL; - } - } - else - { - if(tex->next != NULL) - { - tex->next->prev = tex->prev; - } - if(tex->prev != NULL) - { - tex->prev->next = tex->next; + found_in_active_list = true; + break; } + test_tex = test_tex->next; } - if (tex->d3dfinaltex != NULL) - (*d3dintf->texture.release)(tex->d3dfinaltex); - if (tex->d3dtex != NULL && tex->d3dtex != tex->d3dfinaltex) - (*d3dintf->texture.release)(tex->d3dtex); - if (tex->d3dsurface != NULL) - (*d3dintf->surface.release)(tex->d3dsurface); - global_free(tex); + // only clean up a texture if it won't be cleaned up by drawd3d + if(!found_in_active_list) + { + if (tex->d3dfinaltex != NULL) + { + (*d3dintf->texture.release)(tex->d3dfinaltex); + tex->d3dfinaltex = NULL; + } + if (tex->d3dtex != NULL && tex->d3dtex != tex->d3dfinaltex) + { + (*d3dintf->texture.release)(tex->d3dtex); + tex->d3dtex = NULL; + } + if (tex->d3dsurface != NULL) + { + (*d3dintf->surface.release)(tex->d3dsurface); + } + global_free(tex); + } } if (prescaletexture0[index] != NULL) diff --git a/src/osd/windows/drawd3d.c b/src/osd/windows/drawd3d.c index fd494f8560c..6f193be9974 100644 --- a/src/osd/windows/drawd3d.c +++ b/src/osd/windows/drawd3d.c @@ -892,15 +892,15 @@ static int device_create_resources(d3d_info *d3d) static void device_delete(d3d_info *d3d) { - // free our effects - d3d->hlsl->delete_resources(); - // delete the HLSL interface global_free(d3d->hlsl); - // free resources + // free our base resources device_delete_resources(d3d); + // free our effects + d3d->hlsl->delete_resources(); + // free the device itself if (d3d->device != NULL) (*d3dintf->device.release)(d3d->device); @@ -921,11 +921,20 @@ static void device_delete_resources(d3d_info *d3d) d3d_texture_info *tex = d3d->texlist; d3d->texlist = tex->next; if (tex->d3dfinaltex != NULL) + { (*d3dintf->texture.release)(tex->d3dfinaltex); + tex->d3dfinaltex = NULL; + } if (tex->d3dtex != NULL && tex->d3dtex != tex->d3dfinaltex) + { (*d3dintf->texture.release)(tex->d3dtex); + tex->d3dtex = NULL; + } if (tex->d3dsurface != NULL) + { (*d3dintf->surface.release)(tex->d3dsurface); + tex->d3dsurface = NULL; + } global_free(tex); }