diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-09-06 13:04:26 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-09-06 13:05:58 +0300 |
commit | 687f70ceca88324fb8f376e086a55b341dd34e6f (patch) | |
tree | 1d9b467aecc63dbb78c77d67d046e3a86527cef1 /source/blender | |
parent | a0912ff5663b950222ef00485a3853bfb6001db4 (diff) |
ImBuf: add IMB_allocFromBufferOwn that takes ownership of the buffer
Avoids duplicating the image buffer when saving thumbnails.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/studiolight.c | 17 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf.h | 8 | ||||
-rw-r--r-- | source/blender/imbuf/intern/allocimbuf.c | 35 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 3 |
4 files changed, 51 insertions, 12 deletions
diff --git a/source/blender/blenkernel/intern/studiolight.c b/source/blender/blenkernel/intern/studiolight.c index 95436372a65..29f726ece71 100644 --- a/source/blender/blenkernel/intern/studiolight.c +++ b/source/blender/blenkernel/intern/studiolight.c @@ -439,17 +439,15 @@ static void studiolight_load_equirect_image(StudioLight *sl) if (ctx.diffuse_pass != NULL) { float *converted_pass = studiolight_multilayer_convert_pass( ibuf, ctx.diffuse_pass, ctx.num_diffuse_channels); - diffuse_ibuf = IMB_allocFromBuffer( + diffuse_ibuf = IMB_allocFromBufferOwn( NULL, converted_pass, ibuf->x, ibuf->y, ctx.num_diffuse_channels); - MEM_freeN(converted_pass); } if (ctx.specular_pass != NULL) { float *converted_pass = studiolight_multilayer_convert_pass( ibuf, ctx.specular_pass, ctx.num_specular_channels); - specular_ibuf = IMB_allocFromBuffer( + specular_ibuf = IMB_allocFromBufferOwn( NULL, converted_pass, ibuf->x, ibuf->y, ctx.num_specular_channels); - MEM_freeN(converted_pass); } IMB_exr_close(ibuf->userdata); @@ -1148,12 +1146,11 @@ static void studiolight_calculate_irradiance_equirect_image(StudioLight *sl) } ITER_PIXELS_END; - sl->equirect_irradiance_buffer = IMB_allocFromBuffer(NULL, - colbuf, - STUDIOLIGHT_IRRADIANCE_EQUIRECT_WIDTH, - STUDIOLIGHT_IRRADIANCE_EQUIRECT_HEIGHT, - 4); - MEM_freeN(colbuf); + sl->equirect_irradiance_buffer = IMB_allocFromBufferOwn(NULL, + colbuf, + STUDIOLIGHT_IRRADIANCE_EQUIRECT_WIDTH, + STUDIOLIGHT_IRRADIANCE_EQUIRECT_HEIGHT, + 4); } sl->flag |= STUDIOLIGHT_EQUIRECT_IRRADIANCE_IMAGE_CALCULATED; } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 4ad7aa98484..dd8e6549e24 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -150,6 +150,14 @@ bool IMB_initImBuf( /** * Create a copy of a pixel buffer and wrap it to a new ImBuf + * (transferring ownership to the in imbuf). + * \attention Defined in allocimbuf.c + */ +struct ImBuf *IMB_allocFromBufferOwn( + unsigned int *rect, float *rectf, unsigned int w, unsigned int h, unsigned int channels); + +/** + * Create a copy of a pixel buffer and wrap it to a new ImBuf * \attention Defined in allocimbuf.c */ struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index d327981f583..c2bff9ddc51 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -430,6 +430,41 @@ bool imb_addrectImBuf(ImBuf *ibuf) return false; } +/** + * \param take_ownership: When true, the buffers become owned by the resulting image. + */ +struct ImBuf *IMB_allocFromBufferOwn( + unsigned int *rect, float *rectf, unsigned int w, unsigned int h, unsigned int channels) +{ + ImBuf *ibuf = NULL; + + if (!(rect || rectf)) { + return NULL; + } + + ibuf = IMB_allocImBuf(w, h, 32, 0); + + ibuf->channels = channels; + + /* Avoid #MEM_dupallocN since the buffers might not be allocated using guarded-allocation. */ + if (rectf) { + BLI_assert(MEM_allocN_len(rectf) == sizeof(float[4]) * w * h); + ibuf->rect_float = rectf; + + ibuf->flags |= IB_rectfloat; + ibuf->mall |= IB_rectfloat; + } + if (rect) { + BLI_assert(MEM_allocN_len(rect) == sizeof(uchar[4]) * w * h); + ibuf->rect = rect; + + ibuf->flags |= IB_rect; + ibuf->mall |= IB_rect; + } + + return ibuf; +} + struct ImBuf *IMB_allocFromBuffer(const unsigned int *rect, const float *rectf, unsigned int w, diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 30b76fd110b..2b796e60cdc 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1539,7 +1539,7 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu int win_size[2]; uint *buffer = WM_window_pixels_read(CTX_wm_manager(C), win, win_size); - ImBuf *ibuf = IMB_allocFromBuffer(buffer, NULL, win_size[0], win_size[1], 24); + ImBuf *ibuf = IMB_allocFromBufferOwn(buffer, NULL, win_size[0], win_size[1], 24); if (ibuf) { int ex, ey; @@ -1561,7 +1561,6 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **thu BlendThumbnail *thumb = BKE_main_thumbnail_from_imbuf(NULL, thumb_ibuf); IMB_freeImBuf(thumb_ibuf); - MEM_freeN(buffer); *thumb_pt = thumb; } WM_cursor_wait(false); |