render: Manage memory for SDL_Renderer* at higher level.

Previously, each backend would allocate and free the renderer struct. Now
the higher level does it, so the backends only manage their private resources.

This removes some boilerplate and avoids some potential accidents.
main
Ryan C. Gordon 2024-04-18 10:16:50 -04:00
parent 09e32faa68
commit 39c8434f5f
14 changed files with 100 additions and 241 deletions

View File

@ -900,12 +900,18 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
SDL_Window *window = (SDL_Window *)SDL_GetProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, NULL); SDL_Window *window = (SDL_Window *)SDL_GetProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, NULL);
SDL_Surface *surface = (SDL_Surface *)SDL_GetProperty(props, SDL_PROP_RENDERER_CREATE_SURFACE_POINTER, NULL); SDL_Surface *surface = (SDL_Surface *)SDL_GetProperty(props, SDL_PROP_RENDERER_CREATE_SURFACE_POINTER, NULL);
const char *name = SDL_GetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, NULL); const char *name = SDL_GetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, NULL);
SDL_Renderer *renderer = NULL;
const int n = SDL_GetNumRenderDrivers(); const int n = SDL_GetNumRenderDrivers();
const char *hint; const char *hint;
int i, attempted = 0; int i, attempted = 0;
SDL_PropertiesID new_props; SDL_PropertiesID new_props;
SDL_Renderer *renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
#ifdef SDL_PLATFORM_ANDROID #ifdef SDL_PLATFORM_ANDROID
Android_ActivityMutex_Lock_Running(); Android_ActivityMutex_Lock_Running();
#endif #endif
@ -932,15 +938,15 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
if (surface) { if (surface) {
#if SDL_VIDEO_RENDER_SW #if SDL_VIDEO_RENDER_SW
renderer = SW_CreateRendererForSurface(surface, props); const int rc = SW_CreateRendererForSurface(renderer, surface, props);
#else #else
renderer = NULL; const int rc = SDL_SetError("SDL not built with software renderer");
SDL_SetError("SDL not built with software renderer");
#endif #endif
if (!renderer) { if (rc == -1) {
goto error; goto error;
} }
} else { } else {
int rc = -1;
if (!name) { if (!name) {
name = SDL_GetHint(SDL_HINT_RENDER_DRIVER); name = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
} }
@ -949,26 +955,27 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
const SDL_RenderDriver *driver = render_drivers[i]; const SDL_RenderDriver *driver = render_drivers[i];
if (SDL_strcasecmp(name, driver->info.name) == 0) { if (SDL_strcasecmp(name, driver->info.name) == 0) {
/* Create a new renderer instance */ // Create a new renderer instance
++attempted; ++attempted;
renderer = driver->CreateRenderer(window, props); rc = driver->CreateRenderer(renderer, window, props);
break; break;
} }
} }
} else { } else {
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
const SDL_RenderDriver *driver = render_drivers[i]; const SDL_RenderDriver *driver = render_drivers[i];
/* Create a new renderer instance */ // Create a new renderer instance
++attempted; ++attempted;
renderer = driver->CreateRenderer(window, props); rc = driver->CreateRenderer(renderer, window, props);
if (renderer) { if (rc == 0) {
/* Yay, we got one! */ break; // Yay, we got one!
break;
} }
SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
renderer->magic = &SDL_renderer_magic;
} }
} }
if (!renderer) { if (rc == -1) {
if (!name || !attempted) { if (!name || !attempted) {
SDL_SetError("Couldn't find matching render driver"); SDL_SetError("Couldn't find matching render driver");
} }
@ -1072,6 +1079,7 @@ error:
#ifdef SDL_PLATFORM_ANDROID #ifdef SDL_PLATFORM_ANDROID
Android_ActivityMutex_Unlock(); Android_ActivityMutex_Unlock();
#endif #endif
SDL_free(renderer);
return NULL; return NULL;
#else #else
@ -4522,7 +4530,6 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer)
/* Free existing textures for this renderer */ /* Free existing textures for this renderer */
while (renderer->textures) { while (renderer->textures) {
SDL_Texture *tex = renderer->textures; SDL_Texture *tex = renderer->textures;
(void)tex;
SDL_DestroyTextureInternal(renderer->textures, SDL_TRUE /* is_destroying */); SDL_DestroyTextureInternal(renderer->textures, SDL_TRUE /* is_destroying */);
SDL_assert(tex != renderer->textures); /* satisfy static analysis. */ SDL_assert(tex != renderer->textures); /* satisfy static analysis. */
} }
@ -4540,8 +4547,10 @@ void SDL_DestroyRenderer(SDL_Renderer *renderer)
SDL_DestroyMutex(renderer->target_mutex); SDL_DestroyMutex(renderer->target_mutex);
renderer->target_mutex = NULL; renderer->target_mutex = NULL;
/* Free the renderer instance */ /* Clean up renderer-specific resources */
renderer->DestroyRenderer(renderer); renderer->DestroyRenderer(renderer);
SDL_free(renderer);
} }
void *SDL_GetRenderMetalLayer(SDL_Renderer *renderer) void *SDL_GetRenderMetalLayer(SDL_Renderer *renderer)

View File

@ -295,7 +295,7 @@ struct SDL_Renderer
/* Define the SDL render driver structure */ /* Define the SDL render driver structure */
struct SDL_RenderDriver struct SDL_RenderDriver
{ {
SDL_Renderer *(*CreateRenderer)(SDL_Window *window, SDL_PropertiesID props); int (*CreateRenderer)(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID props);
/* Info about the renderer capabilities */ /* Info about the renderer capabilities */
SDL_RendererInfo info; SDL_RendererInfo info;

View File

@ -1469,7 +1469,6 @@ static void D3D_DestroyRenderer(SDL_Renderer *renderer)
} }
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
static int D3D_Reset(SDL_Renderer *renderer) static int D3D_Reset(SDL_Renderer *renderer)
@ -1567,9 +1566,8 @@ static int D3D_SetVSync(SDL_Renderer *renderer, const int vsync)
return 0; return 0;
} }
SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) int D3D_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
D3D_RenderData *data; D3D_RenderData *data;
HRESULT result; HRESULT result;
D3DPRESENT_PARAMETERS pparams; D3DPRESENT_PARAMETERS pparams;
@ -1580,31 +1578,20 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
SDL_DisplayID displayID; SDL_DisplayID displayID;
const SDL_DisplayMode *fullscreen_mode = NULL; const SDL_DisplayMode *fullscreen_mode = NULL;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
data = (D3D_RenderData *)SDL_calloc(1, sizeof(*data)); data = (D3D_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
SDL_free(renderer); return -1;
return NULL;
} }
if (!D3D_LoadDLL(&data->d3dDLL, &data->d3d)) { if (!D3D_LoadDLL(&data->d3dDLL, &data->d3d)) {
SDL_SetError("Unable to create Direct3D interface");
SDL_free(renderer);
SDL_free(data); SDL_free(data);
return NULL; return SDL_SetError("Unable to create Direct3D interface");
} }
renderer->WindowEvent = D3D_WindowEvent; renderer->WindowEvent = D3D_WindowEvent;
@ -1685,23 +1672,20 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
&pparams, &data->device); &pparams, &data->device);
if (FAILED(result)) { if (FAILED(result)) {
D3D_DestroyRenderer(renderer); D3D_DestroyRenderer(renderer);
D3D_SetError("CreateDevice()", result); return D3D_SetError("CreateDevice()", result);
return NULL;
} }
/* Get presentation parameters to fill info */ /* Get presentation parameters to fill info */
result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain); result = IDirect3DDevice9_GetSwapChain(data->device, 0, &chain);
if (FAILED(result)) { if (FAILED(result)) {
D3D_DestroyRenderer(renderer); D3D_DestroyRenderer(renderer);
D3D_SetError("GetSwapChain()", result); return D3D_SetError("GetSwapChain()", result);
return NULL;
} }
result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams); result = IDirect3DSwapChain9_GetPresentParameters(chain, &pparams);
if (FAILED(result)) { if (FAILED(result)) {
IDirect3DSwapChain9_Release(chain); IDirect3DSwapChain9_Release(chain);
D3D_DestroyRenderer(renderer); D3D_DestroyRenderer(renderer);
D3D_SetError("GetPresentParameters()", result); return D3D_SetError("GetPresentParameters()", result);
return NULL;
} }
IDirect3DSwapChain9_Release(chain); IDirect3DSwapChain9_Release(chain);
if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) { if (pparams.PresentationInterval == D3DPRESENT_INTERVAL_ONE) {
@ -1741,7 +1725,7 @@ SDL_Renderer *D3D_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
SDL_SetProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_D3D9_DEVICE_POINTER, data->device); SDL_SetProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_D3D9_DEVICE_POINTER, data->device);
return renderer; return 0;
} }
SDL_RenderDriver D3D_RenderDriver = { SDL_RenderDriver D3D_RenderDriver = {

View File

@ -413,7 +413,6 @@ static void D3D11_DestroyRenderer(SDL_Renderer *renderer)
if (data) { if (data) {
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
static D3D11_BLEND GetBlendFunc(SDL_BlendFactor factor) static D3D11_BLEND GetBlendFunc(SDL_BlendFactor factor)
@ -2741,31 +2740,21 @@ static int D3D11_SetVSync(SDL_Renderer *renderer, const int vsync)
} }
#endif #endif
SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int D3D11_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
D3D11_RenderData *data; D3D11_RenderData *data;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB && if (renderer->output_colorspace != SDL_COLORSPACE_SRGB &&
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR
/*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) { /*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
data = (D3D11_RenderData *)SDL_calloc(1, sizeof(*data)); data = (D3D11_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
SDL_free(renderer); return -1;
return NULL;
} }
data->identity = MatrixIdentity(); data->identity = MatrixIdentity();
@ -2825,14 +2814,14 @@ SDL_Renderer *D3D11_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
/* Initialize Direct3D resources */ /* Initialize Direct3D resources */
if (FAILED(D3D11_CreateDeviceResources(renderer))) { if (FAILED(D3D11_CreateDeviceResources(renderer))) {
D3D11_DestroyRenderer(renderer); D3D11_DestroyRenderer(renderer);
return NULL; return -1;
} }
if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) { if (FAILED(D3D11_CreateWindowSizeDependentResources(renderer))) {
D3D11_DestroyRenderer(renderer); D3D11_DestroyRenderer(renderer);
return NULL; return -1;
} }
return renderer; return 0;
} }
SDL_RenderDriver D3D11_RenderDriver = { SDL_RenderDriver D3D11_RenderDriver = {

View File

@ -587,7 +587,6 @@ static void D3D12_DestroyRenderer(SDL_Renderer *renderer)
if (data) { if (data) {
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
static D3D12_BLEND GetBlendFunc(SDL_BlendFactor factor) static D3D12_BLEND GetBlendFunc(SDL_BlendFactor factor)
@ -3173,37 +3172,26 @@ static int D3D12_SetVSync(SDL_Renderer *renderer, const int vsync)
return 0; return 0;
} }
SDL_Renderer *D3D12_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) int D3D12_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
D3D12_RenderData *data; D3D12_RenderData *data;
if (SDL_GetWindowFlags(window) & SDL_WINDOW_TRANSPARENT) { if (SDL_GetWindowFlags(window) & SDL_WINDOW_TRANSPARENT) {
/* D3D12 removed the swap effect needed to support transparent windows, use D3D11 instead */ /* D3D12 removed the swap effect needed to support transparent windows, use D3D11 instead */
SDL_SetError("The direct3d12 renderer doesn't work with transparent windows"); return SDL_SetError("The direct3d12 renderer doesn't work with transparent windows");
return NULL;
} }
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB && if (renderer->output_colorspace != SDL_COLORSPACE_SRGB &&
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR
/*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) { /*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
data = (D3D12_RenderData *)SDL_calloc(1, sizeof(*data)); data = (D3D12_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
SDL_free(renderer); return -1;
return NULL;
} }
data->identity = MatrixIdentity(); data->identity = MatrixIdentity();
@ -3248,14 +3236,14 @@ SDL_Renderer *D3D12_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_p
/* Initialize Direct3D resources */ /* Initialize Direct3D resources */
if (FAILED(D3D12_CreateDeviceResources(renderer))) { if (FAILED(D3D12_CreateDeviceResources(renderer))) {
D3D12_DestroyRenderer(renderer); D3D12_DestroyRenderer(renderer);
return NULL; return -1;
} }
if (FAILED(D3D12_CreateWindowSizeDependentResources(renderer))) { if (FAILED(D3D12_CreateWindowSizeDependentResources(renderer))) {
D3D12_DestroyRenderer(renderer); D3D12_DestroyRenderer(renderer);
return NULL; return -1;
} }
return renderer; return 0;
} }
SDL_RenderDriver D3D12_RenderDriver = { SDL_RenderDriver D3D12_RenderDriver = {

View File

@ -1800,8 +1800,6 @@ static void METAL_DestroyRenderer(SDL_Renderer *renderer)
/* SDL_Metal_DestroyView(data.mtlview); */ /* SDL_Metal_DestroyView(data.mtlview); */
CFBridgingRelease(data.mtlview); CFBridgingRelease(data.mtlview);
} }
SDL_free(renderer);
} }
} }
@ -1874,10 +1872,9 @@ static SDL_MetalView GetWindowView(SDL_Window *window)
return nil; return nil;
} }
static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int METAL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
@autoreleasepool { @autoreleasepool {
SDL_Renderer *renderer = NULL;
METAL_RenderData *data = NULL; METAL_RenderData *data = NULL;
id<MTLDevice> mtldevice = nil; id<MTLDevice> mtldevice = nil;
SDL_MetalView view = NULL; SDL_MetalView view = NULL;
@ -1939,15 +1936,9 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
const size_t YCbCr_shader_matrix_size = 4 * 4 * sizeof(float); const size_t YCbCr_shader_matrix_size = 4 * 4 * sizeof(float);
if (!IsMetalAvailable()) { if (!IsMetalAvailable()) {
return NULL; return -1;
} }
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
#ifndef SDL_PLATFORM_TVOS #ifndef SDL_PLATFORM_TVOS
@ -1959,9 +1950,7 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
if (renderer->output_colorspace == SDL_COLORSPACE_SRGB_LINEAR && scRGB_supported) { if (renderer->output_colorspace == SDL_COLORSPACE_SRGB_LINEAR && scRGB_supported) {
/* This colorspace is supported */ /* This colorspace is supported */
} else { } else {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
} }
@ -1983,9 +1972,7 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
} }
if (mtldevice == nil) { if (mtldevice == nil) {
SDL_free(renderer); return SDL_SetError("Failed to obtain Metal device");
SDL_SetError("Failed to obtain Metal device");
return NULL;
} }
view = GetWindowView(window); view = GetWindowView(window);
@ -1994,8 +1981,7 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
} }
if (view == NULL) { if (view == NULL) {
SDL_free(renderer); return -1;
return NULL;
} }
// !!! FIXME: error checking on all of this. // !!! FIXME: error checking on all of this.
@ -2007,8 +1993,7 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
*/ */
/* SDL_Metal_DestroyView(view); */ /* SDL_Metal_DestroyView(view); */
CFBridgingRelease(view); CFBridgingRelease(view);
SDL_free(renderer); return SDL_SetError("METAL_RenderData alloc/init failed");
return NULL;
} }
renderer->driverdata = (void *)CFBridgingRetain(data); renderer->driverdata = (void *)CFBridgingRetain(data);
@ -2205,7 +2190,7 @@ static SDL_Renderer *METAL_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
renderer->info.max_texture_width = maxtexsize; renderer->info.max_texture_width = maxtexsize;
renderer->info.max_texture_height = maxtexsize; renderer->info.max_texture_height = maxtexsize;
return renderer; return 0;
} }
} }

View File

@ -1583,7 +1583,6 @@ static void GL_DestroyRenderer(SDL_Renderer *renderer)
} }
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
static int GL_SetVSync(SDL_Renderer *renderer, const int vsync) static int GL_SetVSync(SDL_Renderer *renderer, const int vsync)
@ -1612,10 +1611,9 @@ static int GL_SetVSync(SDL_Renderer *renderer, const int vsync)
return retval; return retval;
} }
static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int GL_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer; GL_RenderData *data = NULL;
GL_RenderData *data;
GLint value; GLint value;
SDL_WindowFlags window_flags; SDL_WindowFlags window_flags;
int profile_mask = 0, major = 0, minor = 0; int profile_mask = 0, major = 0, minor = 0;
@ -1644,22 +1642,15 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
} }
#endif #endif
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
goto error;
}
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace"); SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
goto error; goto error;
} }
data = (GL_RenderData *)SDL_calloc(1, sizeof(*data)); data = (GL_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
SDL_free(renderer);
goto error; goto error;
} }
@ -1695,21 +1686,15 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
data->context = SDL_GL_CreateContext(window); data->context = SDL_GL_CreateContext(window);
if (!data->context) { if (!data->context) {
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
if (SDL_GL_MakeCurrent(window, data->context) < 0) { if (SDL_GL_MakeCurrent(window, data->context) < 0) {
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
if (GL_LoadFunctions(data) < 0) { if (GL_LoadFunctions(data) < 0) {
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
@ -1844,8 +1829,6 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
} else { } else {
SDL_SetError("Can't create render targets, GL_EXT_framebuffer_object not available"); SDL_SetError("Can't create render targets, GL_EXT_framebuffer_object not available");
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
@ -1870,9 +1853,10 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
data->drawstate.clear_color.b = 1.0f; data->drawstate.clear_color.b = 1.0f;
data->drawstate.clear_color.a = 1.0f; data->drawstate.clear_color.a = 1.0f;
return renderer; return 0;
error: error:
SDL_free(data);
if (changed_window) { if (changed_window) {
/* Uh oh, better try to put it back... */ /* Uh oh, better try to put it back... */
char *error = SDL_strdup(SDL_GetError()); char *error = SDL_strdup(SDL_GetError());
@ -1883,7 +1867,7 @@ error:
SDL_SetError("%s", error); SDL_SetError("%s", error);
SDL_free(error); SDL_free(error);
} }
return NULL; return -1;
} }
SDL_RenderDriver GL_RenderDriver = { SDL_RenderDriver GL_RenderDriver = {

View File

@ -1445,7 +1445,6 @@ static void GLES2_DestroyRenderer(SDL_Renderer *renderer)
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props) static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
@ -2041,10 +2040,9 @@ static int GLES2_SetVSync(SDL_Renderer *renderer, const int vsync)
* Renderer instantiation * * Renderer instantiation *
*************************************************************************************************/ *************************************************************************************************/
static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int GLES2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer; GLES2_RenderData *data = NULL;
GLES2_RenderData *data;
SDL_WindowFlags window_flags = 0; /* -Wconditional-uninitialized */ SDL_WindowFlags window_flags = 0; /* -Wconditional-uninitialized */
GLint window_framebuffer; GLint window_framebuffer;
GLint value; GLint value;
@ -2078,24 +2076,15 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
} }
} }
/* Create the renderer struct */
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
if (!renderer) {
goto error;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace"); SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
goto error; goto error;
} }
data = (GLES2_RenderData *)SDL_calloc(1, sizeof(GLES2_RenderData)); data = (GLES2_RenderData *)SDL_calloc(1, sizeof(GLES2_RenderData));
if (!data) { if (!data) {
SDL_free(renderer);
goto error; goto error;
} }
renderer->info = GLES2_RenderDriver.info; renderer->info = GLES2_RenderDriver.info;
@ -2106,28 +2095,20 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
/* Create an OpenGL ES 2.0 context */ /* Create an OpenGL ES 2.0 context */
data->context = SDL_GL_CreateContext(window); data->context = SDL_GL_CreateContext(window);
if (!data->context) { if (!data->context) {
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
if (SDL_GL_MakeCurrent(window, data->context) < 0) { if (SDL_GL_MakeCurrent(window, data->context) < 0) {
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
if (GLES2_LoadFunctions(data) < 0) { if (GLES2_LoadFunctions(data) < 0) {
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
if (GLES2_CacheShaders(data) < 0) { if (GLES2_CacheShaders(data) < 0) {
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
SDL_free(renderer);
SDL_free(data);
goto error; goto error;
} }
@ -2244,9 +2225,10 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
GL_CheckError("", renderer); GL_CheckError("", renderer);
return renderer; return 0;
error: error:
SDL_free(data);
if (changed_window) { if (changed_window) {
/* Uh oh, better try to put it back... */ /* Uh oh, better try to put it back... */
char *error = SDL_strdup(SDL_GetError()); char *error = SDL_strdup(SDL_GetError());
@ -2257,7 +2239,7 @@ error:
SDL_SetError("%s", error); SDL_SetError("%s", error);
SDL_free(error); SDL_free(error);
} }
return NULL; return -1;
} }
SDL_RenderDriver GLES2_RenderDriver = { SDL_RenderDriver GLES2_RenderDriver = {

View File

@ -602,8 +602,6 @@ static void PS2_DestroyRenderer(SDL_Renderer *renderer)
if (vsync_sema_id >= 0) { if (vsync_sema_id >= 0) {
DeleteSema(vsync_sema_id); DeleteSema(vsync_sema_id);
} }
SDL_free(renderer);
} }
static int PS2_SetVSync(SDL_Renderer *renderer, const int vsync) static int PS2_SetVSync(SDL_Renderer *renderer, const int vsync)
@ -614,32 +612,23 @@ static int PS2_SetVSync(SDL_Renderer *renderer, const int vsync)
return 0; return 0;
} }
static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int PS2_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
PS2_RenderData *data; PS2_RenderData *data;
GSGLOBAL *gsGlobal; GSGLOBAL *gsGlobal;
ee_sema_t sema; ee_sema_t sema;
SDL_bool dynamicVsync; SDL_bool dynamicVsync;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace");
SDL_free(renderer); SDL_free(renderer);
return NULL; return SDL_SetError("Unsupported output colorspace");
} }
data = (PS2_RenderData *)SDL_calloc(1, sizeof(*data)); data = (PS2_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
PS2_DestroyRenderer(renderer); return -1;
return NULL;
} }
/* Specific gsKit init */ /* Specific gsKit init */
@ -711,7 +700,7 @@ static SDL_Renderer *PS2_CreateRenderer(SDL_Window *window, SDL_PropertiesID cre
if (data->vsync) { if (data->vsync) {
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
} }
return renderer; return 0;
} }
SDL_RenderDriver PS2_RenderDriver = { SDL_RenderDriver PS2_RenderDriver = {

View File

@ -1277,7 +1277,6 @@ static void PSP_DestroyRenderer(SDL_Renderer *renderer)
data->displayListAvail = SDL_FALSE; data->displayListAvail = SDL_FALSE;
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
static int PSP_SetVSync(SDL_Renderer *renderer, const int vsync) static int PSP_SetVSync(SDL_Renderer *renderer, const int vsync)
@ -1287,31 +1286,21 @@ static int PSP_SetVSync(SDL_Renderer *renderer, const int vsync)
return 0; return 0;
} }
SDL_Renderer *PSP_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int PSP_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
PSP_RenderData *data; PSP_RenderData *data;
int pixelformat; int pixelformat;
void *doublebuffer = NULL; void *doublebuffer = NULL;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
data = (PSP_RenderData *)SDL_calloc(1, sizeof(*data)); data = (PSP_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
PSP_DestroyRenderer(renderer); return -1;
return NULL;
} }
renderer->WindowEvent = PSP_WindowEvent; renderer->WindowEvent = PSP_WindowEvent;
@ -1406,7 +1395,7 @@ SDL_Renderer *PSP_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_pro
if (data->vsync) { if (data->vsync) {
renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC; renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
} }
return renderer; return 0;
} }
SDL_RenderDriver PSP_RenderDriver = { SDL_RenderDriver PSP_RenderDriver = {

View File

@ -1018,7 +1018,6 @@ static void SW_DestroyRenderer(SDL_Renderer *renderer)
SDL_DestroyWindowSurface(window); SDL_DestroyWindowSurface(window);
} }
SDL_free(data); SDL_free(data);
SDL_free(renderer);
} }
static void SW_SelectBestFormats(SDL_Renderer *renderer, SDL_PixelFormatEnum format) static void SW_SelectBestFormats(SDL_Renderer *renderer, SDL_PixelFormatEnum format)
@ -1116,27 +1115,20 @@ static void SW_SelectBestFormats(SDL_Renderer *renderer, SDL_PixelFormatEnum for
} }
} }
SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface, SDL_PropertiesID create_props) int SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
SW_RenderData *data; SW_RenderData *data;
if (!surface) { if (!surface) {
SDL_InvalidParamError("surface"); return SDL_InvalidParamError("surface");
return NULL;
} }
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
renderer->software = SDL_TRUE; renderer->software = SDL_TRUE;
data = (SW_RenderData *)SDL_calloc(1, sizeof(*data)); data = (SW_RenderData *)SDL_calloc(1, sizeof(*data));
if (!data) { if (!data) {
SW_DestroyRenderer(renderer); SW_DestroyRenderer(renderer);
return NULL; return -1;
} }
data->surface = surface; data->surface = surface;
data->window = surface; data->window = surface;
@ -1172,27 +1164,18 @@ SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface, SDL_PropertiesID
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace");
SW_DestroyRenderer(renderer); SW_DestroyRenderer(renderer);
return NULL; return SDL_SetError("Unsupported output colorspace");
} }
return renderer; return 0;
} }
static SDL_Renderer *SW_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int SW_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
const char *hint;
SDL_Surface *surface;
SDL_bool no_hint_set;
/* Set the vsync hint based on our flags, if it's not already set */ /* Set the vsync hint based on our flags, if it's not already set */
hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC); const char *hint = SDL_GetHint(SDL_HINT_RENDER_VSYNC);
if (!hint || !*hint) { const SDL_bool no_hint_set = (!hint || !*hint);
no_hint_set = SDL_TRUE;
} else {
no_hint_set = SDL_FALSE;
}
if (no_hint_set) { if (no_hint_set) {
if (SDL_GetBooleanProperty(create_props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_BOOLEAN, SDL_FALSE)) { if (SDL_GetBooleanProperty(create_props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_BOOLEAN, SDL_FALSE)) {
@ -1202,7 +1185,7 @@ static SDL_Renderer *SW_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
} }
} }
surface = SDL_GetWindowSurface(window); SDL_Surface *surface = SDL_GetWindowSurface(window);
/* Reset the vsync hint if we set it above */ /* Reset the vsync hint if we set it above */
if (no_hint_set) { if (no_hint_set) {
@ -1210,10 +1193,10 @@ static SDL_Renderer *SW_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
} }
if (!surface) { if (!surface) {
return NULL; return -1;
} }
return SW_CreateRendererForSurface(surface, create_props); return SW_CreateRendererForSurface(renderer, surface, create_props);
} }
SDL_RenderDriver SW_RenderDriver = { SDL_RenderDriver SW_RenderDriver = {

View File

@ -22,6 +22,6 @@
#ifndef SDL_render_sw_c_h_ #ifndef SDL_render_sw_c_h_
#define SDL_render_sw_c_h_ #define SDL_render_sw_c_h_
extern SDL_Renderer *SW_CreateRendererForSurface(SDL_Surface *surface, SDL_PropertiesID create_props); extern int SW_CreateRendererForSurface(SDL_Renderer *renderer, SDL_Surface *surface, SDL_PropertiesID create_props);
#endif /* SDL_render_sw_c_h_ */ #endif /* SDL_render_sw_c_h_ */

View File

@ -42,7 +42,7 @@
#include <psp2/sysmodule.h> #include <psp2/sysmodule.h>
#endif #endif
static SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props); static int VITA_GXM_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props);
static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event); static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event);
@ -210,29 +210,19 @@ static int VITA_GXM_SetVSync(SDL_Renderer *renderer, const int vsync)
return 0; return 0;
} }
SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int VITA_GXM_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
VITA_GXM_RenderData *data; VITA_GXM_RenderData *data;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) { if (renderer->output_colorspace != SDL_COLORSPACE_SRGB) {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
data = (VITA_GXM_RenderData *)SDL_calloc(1, sizeof(VITA_GXM_RenderData)); data = (VITA_GXM_RenderData *)SDL_calloc(1, sizeof(VITA_GXM_RenderData));
if (!data) { if (!data) {
SDL_free(renderer); return -1;
return NULL;
} }
renderer->WindowEvent = VITA_GXM_WindowEvent; renderer->WindowEvent = VITA_GXM_WindowEvent;
@ -281,11 +271,10 @@ SDL_Renderer *VITA_GXM_CreateRenderer(SDL_Window *window, SDL_PropertiesID creat
if (gxm_init(renderer) != 0) { if (gxm_init(renderer) != 0) {
SDL_free(data); SDL_free(data);
SDL_free(renderer); return SDL_SetError("gxm_init failed");
return NULL;
} }
return renderer; return 0;
} }
static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event) static void VITA_GXM_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
@ -1230,7 +1219,6 @@ static void VITA_GXM_DestroyRenderer(SDL_Renderer *renderer)
data->drawing = SDL_FALSE; data->drawing = SDL_FALSE;
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer);
} }
#endif /* SDL_VIDEO_RENDER_VITA_GXM */ #endif /* SDL_VIDEO_RENDER_VITA_GXM */

View File

@ -1061,14 +1061,13 @@ static VkResult VULKAN_IssueBatch(VULKAN_RenderData *rendererData)
static void VULKAN_DestroyRenderer(SDL_Renderer *renderer) static void VULKAN_DestroyRenderer(SDL_Renderer *renderer)
{ {
VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->driverdata; VULKAN_RenderData *rendererData = (VULKAN_RenderData *)renderer->driverdata;
if (rendererData->device != VK_NULL_HANDLE) {
vkDeviceWaitIdle(rendererData->device);
VULKAN_DestroyAll(renderer);
}
if (rendererData) { if (rendererData) {
if (rendererData->device != VK_NULL_HANDLE) {
vkDeviceWaitIdle(rendererData->device);
VULKAN_DestroyAll(renderer);
}
SDL_free(rendererData); SDL_free(rendererData);
} }
SDL_free(renderer);
} }
static VkBlendFactor GetBlendFactor(SDL_BlendFactor factor) static VkBlendFactor GetBlendFactor(SDL_BlendFactor factor)
@ -4037,30 +4036,21 @@ static int VULKAN_SetVSync(SDL_Renderer *renderer, const int vsync)
return 0; return 0;
} }
SDL_Renderer *VULKAN_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_props) static int VULKAN_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_PropertiesID create_props)
{ {
SDL_Renderer *renderer;
VULKAN_RenderData *rendererData; VULKAN_RenderData *rendererData;
renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(*renderer));
if (!renderer) {
return NULL;
}
renderer->magic = &SDL_renderer_magic;
SDL_SetupRendererColorspace(renderer, create_props); SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB && if (renderer->output_colorspace != SDL_COLORSPACE_SRGB &&
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR && renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR &&
renderer->output_colorspace != SDL_COLORSPACE_HDR10) { renderer->output_colorspace != SDL_COLORSPACE_HDR10) {
SDL_SetError("Unsupported output colorspace"); return SDL_SetError("Unsupported output colorspace");
SDL_free(renderer);
return NULL;
} }
rendererData = (VULKAN_RenderData *)SDL_calloc(1, sizeof(*rendererData)); rendererData = (VULKAN_RenderData *)SDL_calloc(1, sizeof(*rendererData));
if (!rendererData) { if (!rendererData) {
SDL_free(renderer); return -1;
return NULL;
} }
rendererData->identity = MatrixIdentity(); rendererData->identity = MatrixIdentity();
@ -4110,11 +4100,10 @@ SDL_Renderer *VULKAN_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_
/* Initialize Vulkan resources */ /* Initialize Vulkan resources */
if (VULKAN_CreateDeviceResources(renderer, create_props) != VK_SUCCESS) { if (VULKAN_CreateDeviceResources(renderer, create_props) != VK_SUCCESS) {
VULKAN_DestroyRenderer(renderer); VULKAN_DestroyRenderer(renderer);
return NULL; return -1;
} } else if (VULKAN_CreateWindowSizeDependentResources(renderer) != VK_SUCCESS) {
if (VULKAN_CreateWindowSizeDependentResources(renderer) != VK_SUCCESS) {
VULKAN_DestroyRenderer(renderer); VULKAN_DestroyRenderer(renderer);
return NULL; return -1;
} }
#if SDL_HAVE_YUV #if SDL_HAVE_YUV
@ -4127,7 +4116,7 @@ SDL_Renderer *VULKAN_CreateRenderer(SDL_Window *window, SDL_PropertiesID create_
} }
#endif #endif
return renderer; return 0;
} }
SDL_RenderDriver VULKAN_RenderDriver = { SDL_RenderDriver VULKAN_RenderDriver = {