Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-02-08 12:18:44 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-02-08 12:18:44 +0400
commitbc5df753aaaf116520d15df0aa53a054e6b1606a (patch)
treed21ede8cd1625a2861fd42821aed3e3084338fa6 /source/blender/imbuf
parent52df65b137ebcebb2b693a905cb4ee49a6d8fbcb (diff)
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.
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r--source/blender/imbuf/intern/colormanagement.c126
1 files changed, 87 insertions, 39 deletions
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 00a4699676d..23804291a65 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -1353,6 +1353,23 @@ static void display_buffer_apply_threaded(ImBuf *ibuf, float *buffer, unsigned c
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 @@ static void colormanage_display_buffer_process_ex(ImBuf *ibuf, float *display_bu
* 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,37 +2340,67 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe
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 (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 (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 (!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);
- }
- else {
- float pixel_straight[4];
- premul_to_straight_v4_v4(pixel_straight, pixel);
- rgba_float_to_uchar(display_buffer + display_index, pixel_straight);
+ memcpy(display_buffer + display_offset, byte_buffer + byte_offset, 4 * sizeof(char) * width);
}
}
}
@@ -2426,14 +2464,24 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
BLI_unlock_thread(LOCK_COLORMANAGE);
if (display_buffer) {
- ColormanageProcessor *cm_processor;
+ ColormanageProcessor *cm_processor = NULL;
+ int skip_transform = 0;
+
+ /* 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);
- cm_processor = IMB_colormanagement_display_processor_new(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);
}