[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [48434] branches/soc-2011-tomato/source/ blender/imbuf/intern/colormanagement.c: Color management: multithreaded transformation apply

Sergey Sharybin sergey.vfx at gmail.com
Sat Jun 30 14:36:43 CEST 2012


Revision: 48434
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=48434
Author:   nazgul
Date:     2012-06-30 12:36:41 +0000 (Sat, 30 Jun 2012)
Log Message:
-----------
Color management: multithreaded transformation apply

Since RRT can't be baked into 3D LUT it's the only way to increase
speed of transformation and make image / clip loading in acceptable
time.

Modified Paths:
--------------
    branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c

Modified: branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c
===================================================================
--- branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c	2012-06-30 12:36:31 UTC (rev 48433)
+++ branches/soc-2011-tomato/source/blender/imbuf/intern/colormanagement.c	2012-06-30 12:36:41 UTC (rev 48434)
@@ -50,6 +50,7 @@
 #include "BLI_math_color.h"
 #include "BLI_path_util.h"
 #include "BLI_string.h"
+#include "BLI_threads.h"
 
 #include "BKE_utildefines.h"
 #include "BKE_main.h"
@@ -429,14 +430,125 @@
 /*********************** Public display buffers interfaces *************************/
 
 #ifdef WITH_OCIO
+typedef struct DisplayBufferThread {
+	void *processor;
+
+	float *buffer;
+	unsigned char *display_buffer;
+
+	int width;
+	int start_line;
+	int tot_line;
+
+	int channels;
+	int dither;
+	int predivide;
+} DisplayBufferThread;
+
+static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned char *display_buffer,
+                                          void *processor, void *(do_thread) (void *))
+{
+	DisplayBufferThread handles[BLENDER_MAX_THREADS];
+	ListBase threads;
+
+	int predivide = ibuf->flags & IB_cm_predivide;
+	int i, tot_thread = BLI_system_thread_count();
+	int start_line, tot_line;
+
+	BLI_init_threads(&threads, do_thread, tot_thread);
+
+	start_line = 0;
+	tot_line = ((float)(ibuf->y / tot_thread)) + 0.5f;
+
+	for (i = 0; i < tot_thread; i++) {
+		int offset = ibuf->channels * start_line * ibuf->x;
+
+		handles[i].processor = processor;
+
+		handles[i].buffer = buffer + offset;
+		handles[i].display_buffer = display_buffer + offset;
+		handles[i].width = ibuf->x;
+
+		handles[i].start_line = start_line;
+
+		if (i < tot_thread - 1) {
+			handles[i].tot_line = tot_line;
+		}
+		else {
+			handles[i].tot_line = ibuf->y - start_line;
+		}
+
+		handles[i].channels = ibuf->channels;
+		handles[i].dither = ibuf->dither;
+		handles[i].predivide = predivide;
+
+		if (tot_thread > 1)
+			BLI_insert_thread(&threads, &handles[i]);
+
+		start_line += tot_line;
+	}
+
+	if (tot_thread > 1)
+		BLI_end_threads(&threads);
+	else
+		do_thread(&handles[0]);
+}
+
+static void *do_display_buffer_apply_tonemap_thread(void *handle_v)
+{
+	DisplayBufferThread *handle = (DisplayBufferThread *) handle_v;
+	imb_tonecurveCb tonecurve_func = (imb_tonecurveCb) handle->processor;
+
+	float *buffer = handle->buffer;
+	unsigned char *display_buffer = handle->display_buffer;
+
+	int channels = handle->channels;
+	int width = handle->width;
+	int height = handle->tot_line;
+	int dither = handle->dither;
+	int predivide = handle->predivide;
+
+	IMB_buffer_byte_from_float_tonecurve(display_buffer, buffer, channels, dither,
+	                                     IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
+	                                     predivide, width, height, width, width,
+										 tonecurve_func);
+
+	return NULL;
+}
+
 static void display_buffer_apply_tonemap(ImBuf *ibuf, unsigned char *display_buffer,
                                          imb_tonecurveCb tonecurve_func)
 {
-	int predivide = ibuf->flags & IB_cm_predivide;
+	display_buffer_apply_threaded(ibuf, ibuf->rect_float, display_buffer, tonecurve_func,
+	                              do_display_buffer_apply_tonemap_thread);
+}
 
-	IMB_buffer_byte_from_float_tonecurve(display_buffer, ibuf->rect_float,
-	                                      ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB,
-	                                      predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x, tonecurve_func);
+static void *do_display_buffer_apply_ocio_thread(void *handle_v)
+{
+	DisplayBufferThread *handle = (DisplayBufferThread *) handle_v;
+	ConstProcessorRcPtr *processor = (ConstProcessorRcPtr *) handle->processor;
+	PackedImageDesc *img;
+	float *buffer = handle->buffer;
+	unsigned char *display_buffer = handle->display_buffer;
+	int channels = handle->channels;
+	int width = handle->width;
+	int height = handle->tot_line;
+	int dither = handle->dither;
+	int predivide = handle->predivide;
+
+	img = OCIO_createPackedImageDesc(buffer, width, height, channels, sizeof(float),
+	                                 channels * sizeof(float), channels * sizeof(float) * width);
+
+	OCIO_processorApply(processor, img);
+
+	OCIO_packedImageDescRelease(img);
+
+	/* do conversion */
+	IMB_buffer_byte_from_float(display_buffer, buffer,
+	                           channels, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+							   predivide, width, height, width, width);
+
+	return NULL;
 }
 
 static void display_buffer_apply_ocio(ImBuf *ibuf, unsigned char *display_buffer,
@@ -445,13 +557,10 @@
 	ConstConfigRcPtr *config = OCIO_getCurrentConfig();
 	DisplayTransformRcPtr *dt = OCIO_createDisplayTransform();
 	ConstProcessorRcPtr *processor;
+
 	float *rect_float;
-	int predivide = ibuf->flags & IB_cm_predivide;
-	PackedImageDesc *img;
 
 	rect_float = MEM_dupallocN(ibuf->rect_float);
-	img = OCIO_createPackedImageDesc(rect_float, ibuf->x, ibuf->y, ibuf->channels, sizeof(float),
-	                                 ibuf->channels * sizeof(float), ibuf->channels * sizeof(float)*ibuf->x);
 
 	/* OCIO_TODO: get rid of hardcoded input and display spaces */
 	OCIO_displayTransformSetInputColorSpaceName(dt, "aces");
@@ -459,18 +568,13 @@
 	OCIO_displayTransformSetView(dt, view_transform);
 	OCIO_displayTransformSetDisplay(dt, display);
 
-	processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr*)dt);
+	processor = OCIO_configGetProcessor(config, (ConstTransformRcPtr *) dt);
 
 	if (processor) {
-		OCIO_processorApply(processor, img);
-
-		/* do conversion */
-		IMB_buffer_byte_from_float(display_buffer, rect_float,
-		                           ibuf->channels, ibuf->dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
-								   predivide, ibuf->x, ibuf->y, ibuf->x, ibuf->x);
+		display_buffer_apply_threaded(ibuf, rect_float, display_buffer, processor,
+		                              do_display_buffer_apply_ocio_thread);
 	}
 
-	OCIO_packedImageDescRelease(img);
 	OCIO_displayTransformRelease(dt);
 	OCIO_processorRelease(processor);
 	OCIO_configRelease(config);




More information about the Bf-blender-cvs mailing list