[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [54381] trunk/blender/source/blender/imbuf /intern/colormanagement.c: Fix part #33935: Texture painting slow down with mouse, but not with tablet

Sergey Sharybin sergey.vfx at gmail.com
Fri Feb 8 09:18:45 CET 2013


Revision: 54381
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54381
Author:   nazgul
Date:     2013-02-08 08:18:44 +0000 (Fri, 08 Feb 2013)
Log Message:
-----------
Fix part #33935: Texture painting slow down with mouse, but not with tablet

Issue is solved for painting on byte buffer with default sRGB display enabled.
In this case it is possible to skip any color space transform and just apply
dither if needed.

Still not sure if there's a regression in painting on flaots or not, will
continue investigation.

Modified Paths:
--------------
    trunk/blender/source/blender/imbuf/intern/colormanagement.c

Modified: trunk/blender/source/blender/imbuf/intern/colormanagement.c
===================================================================
--- trunk/blender/source/blender/imbuf/intern/colormanagement.c	2013-02-08 08:02:05 UTC (rev 54380)
+++ trunk/blender/source/blender/imbuf/intern/colormanagement.c	2013-02-08 08:18:44 UTC (rev 54381)
@@ -1353,6 +1353,23 @@
 	                             display_buffer_init_handle, do_display_buffer_apply_thread);
 }
 
+static int is_ibuf_rect_in_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+                                         const ColorManagedDisplaySettings *display_settings)
+{
+	if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
+	    view_settings->exposure == 0.0f &&
+	    view_settings->gamma == 1.0f)
+	{
+		const char *from_colorspace = ibuf->rect_colorspace->name;
+		const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
+
+		if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
 static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_buffer, unsigned char *display_buffer_byte,
                                                   const ColorManagedViewSettings *view_settings,
                                                   const ColorManagedDisplaySettings *display_settings)
@@ -1366,16 +1383,7 @@
 	 * computation noticeable faster
 	 */
 	if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
-		if ((view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) == 0 &&
-		    view_settings->exposure == 0.0f &&
-		    view_settings->gamma == 1.0f)
-		{
-			const char *from_colorspace = ibuf->rect_colorspace->name;
-			const char *to_colorspace = display_transform_get_colorspace_name(view_settings, display_settings);
-
-			if (to_colorspace && !strcmp(from_colorspace, to_colorspace))
-				skip_transform = TRUE;
-		}
+		skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
 	}
 
 	if (skip_transform == FALSE)
@@ -2332,38 +2340,68 @@
 	int is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
 
 	if (dither != 0.0f) {
+		/* cm_processor is NULL in cases byte_buffer's space matches display
+		 * buffer's space
+		 * in this case we could skip extra transform and only apply dither
+		 * use 4 channels for easier byte->float->byte conversion here so
+		 * (this is only needed to apply dither, in other cases we'll convert
+		 * byte buffer to display directly)
+		 */
+		if (!cm_processor)
+			channels = 4;
+
 		display_buffer_float = MEM_callocN(channels * width * height * sizeof(float), "display buffer for dither");
 	}
 
-	for (y = ymin; y < ymax; y++) {
-		for (x = xmin; x < xmax; x++) {
-			int display_index = (y * display_stride + x) * channels;
-			int linear_index = ((y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
-			float pixel[4];
+	if (cm_processor) {
+		for (y = ymin; y < ymax; y++) {
+			for (x = xmin; x < xmax; x++) {
+				int display_index = (y * display_stride + x) * channels;
+				int linear_index = ((y - linear_offset_y) * linear_stride + (x - linear_offset_x)) * channels;
+				float pixel[4];
 
-			if (linear_buffer) {
-				copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
-			}
-			else if (byte_buffer) {
-				rgba_uchar_to_float(pixel, byte_buffer + linear_index);
-				IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
-				straight_to_premul_v4(pixel);
-			}
+				if (linear_buffer) {
+					copy_v4_v4(pixel, (float *) linear_buffer + linear_index);
+				}
+				else if (byte_buffer) {
+					rgba_uchar_to_float(pixel, byte_buffer + linear_index);
+					IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace);
+					straight_to_premul_v4(pixel);
+				}
 
-			if (!is_data) {
-				IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
+				if (!is_data) {
+					IMB_colormanagement_processor_apply_v4_predivide(cm_processor, pixel);
+				}
+
+				if (display_buffer_float) {
+					int index = ((y - ymin) * width + (x - xmin)) * channels;
+
+					copy_v4_v4(display_buffer_float + index, pixel);
+				}
+				else {
+					float pixel_straight[4];
+					premul_to_straight_v4_v4(pixel_straight, pixel);
+					rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+				}
 			}
+		}
+	}
+	else {
+		if (display_buffer_float) {
+			/* huh, for dither we need float buffer first, no cheaper way. currently */
+			IMB_buffer_float_from_byte(display_buffer_float, byte_buffer,
+			                           IB_PROFILE_SRGB, IB_PROFILE_SRGB, TRUE,
+			                           width, height, width, display_stride);
+		}
+		else {
+			int i, width = xmax - xmin;
 
-			if (display_buffer_float) {
-				int index = ((y - ymin) * width + (x - xmin)) * channels;
+			for (i = ymin; i < ymax; i++) {
+				int byte_offset = (linear_stride * i + xmin) * 4;
+				int display_offset = (display_stride * i + xmin) * 4;
 
-				copy_v4_v4(display_buffer_float + index, pixel);
+				memcpy(display_buffer + display_offset, byte_buffer + byte_offset, 4 * sizeof(char) * width);
 			}
-			else {
-				float pixel_straight[4];
-				premul_to_straight_v4_v4(pixel_straight, pixel);
-				rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
-			}
 		}
 	}
 
@@ -2426,14 +2464,24 @@
 		BLI_unlock_thread(LOCK_COLORMANAGE);
 
 		if (display_buffer) {
-			ColormanageProcessor *cm_processor;
+			ColormanageProcessor *cm_processor = NULL;
+			int skip_transform = 0;
 
-			cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+			/* byte buffer is assumed to be in imbuf's rect space, so if byte buffer
+			 * is known we could skip display->linear->display conversion in case
+			 * display color space matches imbuf's rect space
+			 */
+			if (byte_buffer != NULL)
+				skip_transform = is_ibuf_rect_in_display_space(ibuf, view_settings, display_settings);
 
+			if (!skip_transform)
+				cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+
 			partial_buffer_update_rect(ibuf, display_buffer, linear_buffer, byte_buffer, buffer_width, stride,
-			                           offset_x, offset_y, cm_processor, xmin, ymin, xmax, ymax);
+									   offset_x, offset_y, cm_processor, xmin, ymin, xmax, ymax);
 
-			IMB_colormanagement_processor_free(cm_processor);
+			if (cm_processor)
+				IMB_colormanagement_processor_free(cm_processor);
 
 			IMB_display_buffer_release(cache_handle);
 		}




More information about the Bf-blender-cvs mailing list