From 5e9c1feb8aff0ca40eff6689f9bf6a9678711a9e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 1 Mar 2022 08:40:08 +0100 Subject: Image Engine: Performance 8 byte images. Previously we used to cache a float image representation of the image in rect_float. This adds some incorrect behavior as many areas only expect one of these buffers to be used. This patch stores float buffers inside the image engine. This is done per instance. In the future we should consider making a global cache. --- source/blender/imbuf/IMB_imbuf.h | 3 ++ source/blender/imbuf/intern/divers.c | 83 ++++++++++++++++++++++++++---------- 2 files changed, 63 insertions(+), 23 deletions(-) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index a557d7dc6d1..2f0dc6345e5 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -576,6 +576,9 @@ bool IMB_alpha_affects_rgb(const struct ImBuf *ibuf); * Create char buffer, color corrected if necessary, for ImBufs that lack one. */ void IMB_rect_from_float(struct ImBuf *ibuf); +void IMB_float_from_rect_ex(struct ImBuf *dst, + const struct ImBuf *src, + const struct rcti *region_to_update); void IMB_float_from_rect(struct ImBuf *ibuf); /** * No profile conversion. diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index f23748e59a2..c4de30660e2 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -23,6 +23,7 @@ */ #include "BLI_math.h" +#include "BLI_rect.h" #include "BLI_utildefines.h" #include "IMB_filter.h" @@ -769,6 +770,61 @@ void IMB_rect_from_float(ImBuf *ibuf) ibuf->userflags &= ~IB_RECT_INVALID; } +void IMB_float_from_rect_ex(struct ImBuf *dst, + const struct ImBuf *src, + const rcti *region_to_update) +{ + BLI_assert_msg(dst->rect_float != NULL, + "Destination buffer should have a float buffer assigned."); + BLI_assert_msg(src->rect != NULL, "Source buffer should have a byte buffer assigned."); + BLI_assert_msg(dst->x == src->x, "Source and destination buffer should have the same dimension"); + BLI_assert_msg(dst->y == src->y, "Source and destination buffer should have the same dimension"); + BLI_assert_msg(dst->channels = 4, "Destination buffer should have 4 channels."); + BLI_assert_msg(region_to_update->xmin >= 0, + "Region to update should be clipped to the given buffers."); + BLI_assert_msg(region_to_update->ymin >= 0, + "Region to update should be clipped to the given buffers."); + BLI_assert_msg(region_to_update->xmax < dst->x, + "Region to update should be clipped to the given buffers."); + BLI_assert_msg(region_to_update->ymax < dst->y, + "Region to update should be clipped to the given buffers."); + + float *rect_float = dst->rect_float; + rect_float += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4; + unsigned char *rect = (unsigned char *)src->rect; + rect += (region_to_update->xmin + region_to_update->ymin * dst->x) * 4; + const int region_width = BLI_rcti_size_x(region_to_update); + const int region_height = BLI_rcti_size_y(region_to_update); + + /* Convert byte buffer to float buffer without color or alpha conversion. */ + IMB_buffer_float_from_byte(rect_float, + rect, + IB_PROFILE_SRGB, + IB_PROFILE_SRGB, + false, + region_width, + region_height, + src->x, + dst->x); + + /* Perform color space conversion from rect color space to linear. */ + float *float_ptr = rect_float; + for (int i = 0; i < region_height; i++) { + IMB_colormanagement_colorspace_to_scene_linear( + float_ptr, region_width, 1, dst->channels, src->rect_colorspace, false); + float_ptr += 4 * dst->x; + } + + /* Perform alpha conversion. */ + if (IMB_alpha_affects_rgb(src)) { + float_ptr = rect_float; + for (int i = 0; i < region_height; i++) { + IMB_premultiply_rect_float(float_ptr, dst->channels, region_width, 1); + float_ptr += 4 * dst->x; + } + } +} + void IMB_float_from_rect(ImBuf *ibuf) { float *rect_float; @@ -792,33 +848,14 @@ void IMB_float_from_rect(ImBuf *ibuf) } ibuf->channels = 4; - } - - /* first, create float buffer in non-linear space */ - IMB_buffer_float_from_byte(rect_float, - (unsigned char *)ibuf->rect, - IB_PROFILE_SRGB, - IB_PROFILE_SRGB, - false, - ibuf->x, - ibuf->y, - ibuf->x, - ibuf->x); - - /* then make float be in linear space */ - IMB_colormanagement_colorspace_to_scene_linear( - rect_float, ibuf->x, ibuf->y, ibuf->channels, ibuf->rect_colorspace, false); - - /* byte buffer is straight alpha, float should always be premul */ - if (IMB_alpha_affects_rgb(ibuf)) { - IMB_premultiply_rect_float(rect_float, ibuf->channels, ibuf->x, ibuf->y); - } - - if (ibuf->rect_float == NULL) { ibuf->rect_float = rect_float; ibuf->mall |= IB_rectfloat; ibuf->flags |= IB_rectfloat; } + + rcti region_to_update; + BLI_rcti_init(®ion_to_update, 0, ibuf->x, 0, ibuf->y); + IMB_float_from_rect_ex(ibuf, ibuf, ®ion_to_update); } /** \} */ -- cgit v1.2.3 From 34f6a9943333f4b6c9727efb5db7bca1ffc7c531 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 1 Mar 2022 08:56:58 +0100 Subject: Fix crash triggered by an introduced assert. --- source/blender/imbuf/intern/divers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/imbuf') diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index c4de30660e2..5b4b731027d 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -784,9 +784,9 @@ void IMB_float_from_rect_ex(struct ImBuf *dst, "Region to update should be clipped to the given buffers."); BLI_assert_msg(region_to_update->ymin >= 0, "Region to update should be clipped to the given buffers."); - BLI_assert_msg(region_to_update->xmax < dst->x, + BLI_assert_msg(region_to_update->xmax <= dst->x, "Region to update should be clipped to the given buffers."); - BLI_assert_msg(region_to_update->ymax < dst->y, + BLI_assert_msg(region_to_update->ymax <= dst->y, "Region to update should be clipped to the given buffers."); float *rect_float = dst->rect_float; -- cgit v1.2.3