From 92571abf5645ea3156e892ecfa2a08f0ca88cad4 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 20 Oct 2020 13:43:20 +0200 Subject: GPU: Memory leak when scaling buffers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `imb_gpu_get_data` could reuse `data_rect` when it was already in used (double alloc). making the first use leak. This was detected after enabling OpenGL Texture Limit. Reviewed By: Clément Foucault Differential Revision: https://developer.blender.org/D9280 --- source/blender/imbuf/intern/util_gpu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 2826bd63cc1..607ab95f0b4 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -97,6 +97,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, { const bool is_float_rect = (ibuf->rect_float != NULL); void *data_rect = (is_float_rect) ? (void *)ibuf->rect_float : (void *)ibuf->rect; + bool freedata = false; if (is_float_rect) { /* Float image is already in scene linear colorspace or non-color data by @@ -104,7 +105,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, * currently. */ if (ibuf->channels != 4 || !store_premultiplied) { data_rect = MEM_mallocN(sizeof(float[4]) * ibuf->x * ibuf->y, __func__); - *r_freedata = true; + *r_freedata = freedata = true; if (data_rect == NULL) { return NULL; @@ -124,7 +125,7 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, * and consistency with float images. */ if (!IMB_colormanagement_space_is_data(ibuf->rect_colorspace)) { data_rect = MEM_mallocN(sizeof(uchar[4]) * ibuf->x * ibuf->y, __func__); - *r_freedata = true; + *r_freedata = freedata = true; if (data_rect == NULL) { return NULL; @@ -147,6 +148,10 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, ImBuf *scale_ibuf = IMB_allocFromBuffer(rect, rect_float, ibuf->x, ibuf->y, 4); IMB_scaleImBuf(scale_ibuf, UNPACK2(rescale_size)); + if (freedata) { + MEM_freeN(data_rect); + } + data_rect = (is_float_rect) ? (void *)scale_ibuf->rect_float : (void *)scale_ibuf->rect; *r_freedata = true; /* Steal the rescaled buffer to avoid double free. */ -- cgit v1.2.3