macOS Fix potential memory leaks in the Metal renderer caught by clang's static analyzer.

This commit is contained in:
Alex Szpakowski 2019-10-26 14:39:50 -03:00
parent 1ce1364b29
commit a9b867ab07

View File

@ -173,6 +173,7 @@ typedef struct METAL_ShaderPipelines
[_mtltexture release]; [_mtltexture release];
[_mtltexture_uv release]; [_mtltexture_uv release];
[_mtlsampler release]; [_mtlsampler release];
[_lockedbuffer release];
[super dealloc]; [super dealloc];
} }
#endif #endif
@ -831,6 +832,7 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata; METAL_TextureData *texturedata = (__bridge METAL_TextureData *)texture->driverdata;
int buffersize = 0; int buffersize = 0;
id<MTLBuffer> lockedbuffer = nil;
if (rect->w <= 0 || rect->h <= 0) { if (rect->w <= 0 || rect->h <= 0) {
return SDL_SetError("Invalid rectangle dimensions for LockTexture."); return SDL_SetError("Invalid rectangle dimensions for LockTexture.");
@ -844,13 +846,19 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
buffersize = (*pitch) * rect->h; buffersize = (*pitch) * rect->h;
} }
texturedata.lockedrect = *rect; lockedbuffer = [data.mtldevice newBufferWithLength:buffersize options:MTLResourceStorageModeShared];
texturedata.lockedbuffer = [data.mtldevice newBufferWithLength:buffersize options:MTLResourceStorageModeShared]; if (lockedbuffer == nil) {
if (texturedata.lockedbuffer == nil) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
*pixels = [texturedata.lockedbuffer contents]; texturedata.lockedrect = *rect;
texturedata.lockedbuffer = lockedbuffer;
*pixels = [lockedbuffer contents];
/* METAL_TextureData.lockedbuffer retains. */
#if !__has_feature(objc_arc)
[lockedbuffer release];
#endif
return 0; return 0;
}} }}
@ -934,11 +942,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
[data.mtlcmdbuffer commit]; [data.mtlcmdbuffer commit];
data.mtlcmdbuffer = nil; data.mtlcmdbuffer = nil;
#if !__has_feature(objc_arc) texturedata.lockedbuffer = nil; /* Retained property, so it calls release. */
[texturedata.lockedbuffer release];
#endif
texturedata.lockedbuffer = nil;
texturedata.hasdata = YES; texturedata.hasdata = YES;
}} }}
@ -1299,6 +1303,8 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
{ @autoreleasepool { { @autoreleasepool {
METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata; METAL_RenderData *data = (__bridge METAL_RenderData *) renderer->driverdata;
METAL_DrawStateCache statecache; METAL_DrawStateCache statecache;
SDL_zero(statecache);
id<MTLBuffer> mtlbufvertex = nil; id<MTLBuffer> mtlbufvertex = nil;
statecache.pipeline = nil; statecache.pipeline = nil;
@ -1586,6 +1592,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
view = SDL_Metal_CreateView(window); view = SDL_Metal_CreateView(window);
if (view == NULL) { if (view == NULL) {
#if !__has_feature(objc_arc)
[mtldevice release];
#endif
SDL_free(renderer); SDL_free(renderer);
return NULL; return NULL;
} }
@ -1594,6 +1603,9 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
data = [[METAL_RenderData alloc] init]; data = [[METAL_RenderData alloc] init];
if (data == nil) { if (data == nil) {
#if !__has_feature(objc_arc)
[mtldevice release];
#endif
SDL_Metal_DestroyView(view); SDL_Metal_DestroyView(view);
SDL_free(renderer); SDL_free(renderer);
return NULL; return NULL;