Page Menu
Home
Search
Configure Global Search
Log In
Paste
P3271
Alternative to D16317
Active
Public
Actions
Authored by
Lukas Stockner (lukasstockner97)
on Oct 22 2022, 7:29 PM.
Edit Paste
Archive Paste
View Raw File
Subscribe
Mute Notifications
Award Token
Tags
None
Subscribers
None
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 5e132826a4c..d539afc5570 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -31,6 +31,7 @@
#include "BLI_math_color.h"
#include "BLI_rect.h"
#include "BLI_string.h"
+#include "BLI_task.h"
#include "BLI_threads.h"
#include "BKE_appdir.h"
@@ -2249,6 +2250,79 @@ void IMB_colormanagement_imbuf_to_byte_texture(uchar *out_buffer,
}
}
+typedef struct ImbufByteToFloatData {
+ OCIO_ConstCPUProcessorRcPtr *processor;
+ int width, height;
+ int offset, stride;
+ const uchar *in_buffer;
+ float *out_buffer;
+ int slice_height;
+} ImbufByteToFloatData;
+
+static void imbuf_byte_to_float_convert_cb(void *__restrict userdata,
+ const int y,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ ImbufByteToFloatData *data = userdata;
+ const size_t in_offset = data->offset + y * data->stride;
+ const size_t out_offset = y * data->width;
+ const uchar *in = data->in_buffer + in_offset * 4;
+ float *out = data->out_buffer + out_offset * 4;
+
+ for (int x = 0; x < data->width; x++, in += 4, out += 4) {
+ rgba_uchar_to_float(out, in);
+ }
+}
+
+static void imbuf_byte_to_float_ocio_cb(void *__restrict userdata,
+ const int s,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ ImbufByteToFloatData *data = userdata;
+ int y = data->slice_height * s;
+ int slice_height = min_ii(data->height, y + data->slice_height) - y;
+ const size_t out_offset = y * data->width;
+ float *out = data->out_buffer + out_offset * 4;
+
+ OCIO_PackedImageDesc *img = OCIO_createOCIO_PackedImageDesc(out,
+ data->width,
+ slice_height,
+ 3,
+ sizeof(float),
+ 3 * sizeof(float),
+ 3 * sizeof(float) * data->width);
+
+ OCIO_cpuProcessorApply(data->processor, img);
+
+ OCIO_PackedImageDescRelease(img);
+}
+
+static void imbuf_byte_to_float_linearize_cb(void *__restrict userdata,
+ const int y,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ ImbufByteToFloatData *data = userdata;
+ const size_t out_offset = y * data->width;
+ float *out = data->out_buffer + out_offset * 4;
+
+ for (int x = 0; x < data->width; x++, out += 4) {
+ srgb_to_linearrgb_v3_v3(out, out);
+ }
+}
+
+static void imbuf_byte_to_float_premultiply_cb(void *__restrict userdata,
+ const int y,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ ImbufByteToFloatData *data = userdata;
+ const size_t out_offset = y * data->width;
+ float *out = data->out_buffer + out_offset * 4;
+
+ for (int x = 0; x < data->width; x++, out += 4) {
+ mul_v3_fl(out, out[3]);
+ }
+}
+
void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
const int offset_x,
const int offset_y,
@@ -2307,33 +2381,38 @@ void IMB_colormanagement_imbuf_to_float_texture(float *out_buffer,
const uchar *in_buffer = (uchar *)ibuf->rect;
const bool use_premultiply = IMB_alpha_affects_rgb(ibuf) && store_premultiplied;
- /* TODO(brecht): make this multi-threaded, or at least process in batches. */
OCIO_ConstCPUProcessorRcPtr *processor = (ibuf->rect_colorspace) ?
colorspace_to_scene_linear_cpu_processor(
ibuf->rect_colorspace) :
NULL;
- for (int y = 0; y < height; y++) {
- const size_t in_offset = (offset_y + y) * ibuf->x + offset_x;
- const size_t out_offset = y * width;
- const uchar *in = in_buffer + in_offset * 4;
- float *out = out_buffer + out_offset * 4;
-
- /* Convert to scene linear, to sRGB and premultiply. */
- for (int x = 0; x < width; x++, in += 4, out += 4) {
- float pixel[4];
- rgba_uchar_to_float(pixel, in);
- if (processor) {
- OCIO_cpuProcessorApplyRGB(processor, pixel);
- }
- else {
- srgb_to_linearrgb_v3_v3(pixel, pixel);
- }
- if (use_premultiply) {
- mul_v3_fl(pixel, pixel[3]);
- }
- copy_v4_v4(out, pixel);
- }
+ ImbufByteToFloatData data = {
+ .processor = processor,
+ .width = width,
+ .height = height,
+ .offset = offset_y * ibuf->x + offset_x,
+ .stride = ibuf->x,
+ .in_buffer = in_buffer,
+ .out_buffer = out_buffer,
+ .slice_height = 32,
+ };
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (height > 128);
+ BLI_task_parallel_range(0, height, &data, imbuf_byte_to_float_convert_cb, &settings);
+ if (processor != NULL) {
+ BLI_task_parallel_range(0,
+ (height + data.slice_height - 1) / data.slice_height,
+ &data,
+ imbuf_byte_to_float_ocio_cb,
+ &settings);
+ }
+ else {
+ BLI_task_parallel_range(0, height, &data, imbuf_byte_to_float_linearize_cb, &settings);
+ }
+ if (use_premultiply) {
+ BLI_task_parallel_range(0, height, &data, imbuf_byte_to_float_premultiply_cb, &settings);
}
}
}
Event Timeline
Lukas Stockner (lukasstockner97)
created this paste.
Oct 22 2022, 7:29 PM
Lukas Stockner (lukasstockner97)
mentioned this in
D16317: Color Management: Parallelize ImBuf conversion to float
.
Log In to Comment