From 95dd8781cefa4d045da5854b0172feb14cd3d3da Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 27 Jul 2024 16:19:05 -0700 Subject: [PATCH] Do a full cleanup if renderer creation fails during autodetection --- src/render/SDL_render.c | 1 + src/render/direct3d/SDL_render_d3d.c | 4 ---- src/render/direct3d11/SDL_render_d3d11.c | 6 ++---- src/render/direct3d12/SDL_render_d3d12.c | 6 ++---- src/render/opengl/SDL_render_gl.c | 4 ---- src/render/opengles2/SDL_render_gles2.c | 4 ---- src/render/ps2/SDL_render_ps2.c | 1 - src/render/software/SDL_render_sw.c | 2 -- src/render/vitagxm/SDL_render_vita_gxm.c | 1 - src/render/vulkan/SDL_render_vulkan.c | 2 -- 10 files changed, 5 insertions(+), 26 deletions(-) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index b3b31e2cf6..5759cd6b89 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -1029,6 +1029,7 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props) if (rc == 0) { break; // Yay, we got one! } + SDL_DestroyRendererWithoutFreeing(renderer); SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct. } } diff --git a/src/render/direct3d/SDL_render_d3d.c b/src/render/direct3d/SDL_render_d3d.c index 9e2e67670a..a2b01f40bc 100644 --- a/src/render/direct3d/SDL_render_d3d.c +++ b/src/render/direct3d/SDL_render_d3d.c @@ -1703,7 +1703,6 @@ int D3D_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Propertie result = IDirect3D9_GetDeviceCaps(data->d3d, data->adapter, D3DDEVTYPE_HAL, &caps); if (FAILED(result)) { - D3D_DestroyRenderer(renderer); return D3D_SetError("GetDeviceCaps()", result); } @@ -1724,20 +1723,17 @@ int D3D_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Propertie device_flags, &pparams, &data->device); if (FAILED(result)) { - D3D_DestroyRenderer(renderer); return D3D_SetError("CreateDevice()", result); } /* Get presentation parameters to fill info */ result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); if (FAILED(result)) { - D3D_DestroyRenderer(renderer); return D3D_SetError("GetSwapChain()", result); } result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); if (FAILED(result)) { IDirect3DSwapChain9_Release(chain); - D3D_DestroyRenderer(renderer); return D3D_SetError("GetPresentParameters()", result); } IDirect3DSwapChain9_Release(chain); diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c index e18301d0d9..885d66ce14 100644 --- a/src/render/direct3d11/SDL_render_d3d11.c +++ b/src/render/direct3d11/SDL_render_d3d11.c @@ -421,8 +421,8 @@ static void D3D11_ReleaseAll(SDL_Renderer *renderer) static void D3D11_DestroyRenderer(SDL_Renderer *renderer) { D3D11_RenderData *data = (D3D11_RenderData *)renderer->internal; - D3D11_ReleaseAll(renderer); if (data) { + D3D11_ReleaseAll(renderer); SDL_free(data); } } @@ -744,7 +744,7 @@ static HRESULT D3D11_CreateDeviceResources(SDL_Renderer *renderer) } /* Create samplers to use when drawing textures: */ - static struct + static struct { D3D11_FILTER filter; D3D11_TEXTURE_ADDRESS_MODE address; @@ -2880,11 +2880,9 @@ static int D3D11_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_ /* Initialize Direct3D resources */ if (FAILED(D3D11_CreateDeviceResources(renderer))) { - D3D11_DestroyRenderer(renderer); return -1; } if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) { - D3D11_DestroyRenderer(renderer); return -1; } diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index 26a21e5a3e..765e082da0 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -644,9 +644,9 @@ static int D3D12_IssueBatch(D3D12_RenderData *data) static void D3D12_DestroyRenderer(SDL_Renderer *renderer) { D3D12_RenderData *data = (D3D12_RenderData *)renderer->internal; - D3D12_WaitForGPU(data); - D3D12_ReleaseAll(renderer); if (data) { + D3D12_WaitForGPU(data); + D3D12_ReleaseAll(renderer); SDL_free(data); } } @@ -3343,11 +3343,9 @@ int D3D12_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Propert /* Initialize Direct3D resources */ if (FAILED(D3D12_CreateDeviceResources(renderer))) { - D3D12_DestroyRenderer(renderer); return -1; } if (FAILED(D3D12_CreateWindowSizeDependentResources(renderer))) { - D3D12_DestroyRenderer(renderer); return -1; } diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index baaebfb3c5..af1a2af7f0 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -1698,12 +1698,10 @@ static int GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pro goto error; } if (SDL_GL_MakeCurrent(window, data->context) < 0) { - SDL_GL_DestroyContext(data->context); goto error; } if (GL_LoadFunctions(data) < 0) { - SDL_GL_DestroyContext(data->context); goto error; } @@ -1819,7 +1817,6 @@ static int GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pro SDL_GL_GetProcAddress("glCheckFramebufferStatusEXT"); } else { SDL_SetError("Can't create render targets, GL_EXT_framebuffer_object not available"); - SDL_GL_DestroyContext(data->context); goto error; } @@ -1847,7 +1844,6 @@ static int GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pro return 0; error: - SDL_free(data); if (changed_window) { /* Uh oh, better try to put it back... */ char *error = SDL_strdup(SDL_GetError()); diff --git a/src/render/opengles2/SDL_render_gles2.c b/src/render/opengles2/SDL_render_gles2.c index 8df52b1f15..f52e56af5b 100644 --- a/src/render/opengles2/SDL_render_gles2.c +++ b/src/render/opengles2/SDL_render_gles2.c @@ -2133,17 +2133,14 @@ static int GLES2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_ goto error; } if (SDL_GL_MakeCurrent(window, data->context) < 0) { - SDL_GL_DestroyContext(data->context); goto error; } if (GLES2_LoadFunctions(data) < 0) { - SDL_GL_DestroyContext(data->context); goto error; } if (GLES2_CacheShaders(data) < 0) { - SDL_GL_DestroyContext(data->context); goto error; } @@ -2237,7 +2234,6 @@ static int GLES2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_ return 0; error: - SDL_free(data); if (changed_window) { /* Uh oh, better try to put it back... */ char *error = SDL_strdup(SDL_GetError()); diff --git a/src/render/ps2/SDL_render_ps2.c b/src/render/ps2/SDL_render_ps2.c index a3944bb3f9..6d76f1494e 100644 --- a/src/render/ps2/SDL_render_ps2.c +++ b/src/render/ps2/SDL_render_ps2.c @@ -643,7 +643,6 @@ static int PS2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_Pr SDL_SetupRendererColorspace(renderer, create_props); if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { - SDL_free(renderer); return SDL_SetError("Unsupported output colorspace"); } diff --git a/src/render/software/SDL_render_sw.c b/src/render/software/SDL_render_sw.c index 1225e756ac..cbabcfff30 100644 --- a/src/render/software/SDL_render_sw.c +++ b/src/render/software/SDL_render_sw.c @@ -1124,7 +1124,6 @@ int SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, SD data = (SW_RenderData *)SDL_calloc(1, sizeof(*data)); if (!data) { - SW_DestroyRenderer(renderer); return -1; } data->surface = surface; @@ -1162,7 +1161,6 @@ int SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, SD SDL_SetupRendererColorspace(renderer, create_props); if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { - SW_DestroyRenderer(renderer); return SDL_SetError("Unsupported output colorspace"); } diff --git a/src/render/vitagxm/SDL_render_vita_gxm.c b/src/render/vitagxm/SDL_render_vita_gxm.c index 440e05ea35..79142d5dc7 100644 --- a/src/render/vitagxm/SDL_render_vita_gxm.c +++ b/src/render/vitagxm/SDL_render_vita_gxm.c @@ -254,7 +254,6 @@ static int VITA_GXM_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, S #endif if (gxm_init(renderer) != 0) { - SDL_free(data); return SDL_SetError("gxm_init failed"); } diff --git a/src/render/vulkan/SDL_render_vulkan.c b/src/render/vulkan/SDL_render_vulkan.c index a3b63d2d67..1d4a22d105 100644 --- a/src/render/vulkan/SDL_render_vulkan.c +++ b/src/render/vulkan/SDL_render_vulkan.c @@ -4151,10 +4151,8 @@ static int VULKAN_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL /* Initialize Vulkan resources */ if (VULKAN_CreateDeviceResources(renderer, create_props) != VK_SUCCESS) { - VULKAN_DestroyRenderer(renderer); return -1; } else if (VULKAN_CreateWindowSizeDependentResources(renderer) != VK_SUCCESS) { - VULKAN_DestroyRenderer(renderer); return -1; }