Browse Source

Do a full cleanup if renderer creation fails during autodetection

Sam Lantinga 8 months ago
parent
commit
95dd8781ce

+ 1 - 0
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.
             }
         }

+ 0 - 4
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);

+ 2 - 4
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;
     }
 

+ 2 - 4
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;
     }
 

+ 0 - 4
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());

+ 0 - 4
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());

+ 0 - 1
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");
     }
 

+ 0 - 2
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");
     }
 

+ 0 - 1
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");
     }
 

+ 0 - 2
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;
     }