diff --git a/app/display/gimpdisplayshell-filter.c b/app/display/gimpdisplayshell-filter.c index 773ce75ab3..b1fa58358e 100644 --- a/app/display/gimpdisplayshell-filter.c +++ b/app/display/gimpdisplayshell-filter.c @@ -89,6 +89,10 @@ gimp_display_shell_filter_new (GimpDisplayShell *shell, g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL); g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL); +#if 0 + /* disabled because we use gimpdisplayshell-profile now, keep + * the code around for reference. + */ if (config->display_module) { GType type = g_type_from_name (config->display_module); @@ -111,6 +115,7 @@ gimp_display_shell_filter_new (GimpDisplayShell *shell, return stack; } } +#endif return NULL; } diff --git a/app/display/gimpdisplayshell-profile.c b/app/display/gimpdisplayshell-profile.c index c0fc41b063..ad070ee372 100644 --- a/app/display/gimpdisplayshell-profile.c +++ b/app/display/gimpdisplayshell-profile.c @@ -38,6 +38,7 @@ #include "gimpdisplay.h" #include "gimpdisplayshell.h" +#include "gimpdisplayshell-filter.h" #include "gimpdisplayshell-profile.h" #include "gimpdisplayxfer.h" @@ -89,16 +90,10 @@ gimp_display_shell_profile_update (GimpDisplayShell *shell) src_format = gimp_pickable_get_format (GIMP_PICKABLE (image)); - if (shell->filter_stack && shell->filter_stack->filters) - dest_format = gimp_babl_format (GIMP_RGB, - gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT, - gimp_babl_format_get_linear (src_format)), - TRUE); + if (gimp_display_shell_has_filter (shell)) + dest_format = babl_format ("R'G'B'A float"); else - dest_format = gimp_babl_format (GIMP_RGB, - gimp_babl_precision (GIMP_COMPONENT_TYPE_FLOAT, - gimp_babl_format_get_linear (src_format)), - TRUE); + dest_format = babl_format ("R'G'B'A u8"); g_printerr ("src_format: %s\n", babl_get_name (src_format)); g_printerr ("dest_format: %s\n", babl_get_name (dest_format)); diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c index af63f9003c..d8f8f1bcc2 100644 --- a/app/display/gimpdisplayshell-render.c +++ b/app/display/gimpdisplayshell-render.c @@ -41,6 +41,7 @@ #include "gimpdisplayshell.h" #include "gimpdisplayshell-transform.h" #include "gimpdisplayshell-filter.h" +#include "gimpdisplayshell-profile.h" #include "gimpdisplayshell-render.h" #include "gimpdisplayshell-scroll.h" #include "gimpdisplayxfer.h" @@ -62,9 +63,10 @@ gimp_display_shell_render (GimpDisplayShell *shell, #ifdef USE_NODE_BLIT GeglNode *node; #endif - gdouble scale_x = 1.0; - gdouble scale_y = 1.0; - gdouble buffer_scale = 1.0; + const Babl *filter_format = babl_format ("R'G'B'A float"); + gdouble scale_x = 1.0; + gdouble scale_y = 1.0; + gdouble buffer_scale = 1.0; gint viewport_offset_x; gint viewport_offset_y; gint viewport_width; @@ -78,8 +80,9 @@ gimp_display_shell_render (GimpDisplayShell *shell, gint xfer_src_y; gint mask_src_x = 0; gint mask_src_y = 0; - gint stride; - guchar *data; + gint cairo_stride; + guchar *cairo_data; + GeglBuffer *cairo_buffer; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (cr != NULL); @@ -146,16 +149,29 @@ gimp_display_shell_render (GimpDisplayShell *shell, &xfer_src_y); } - stride = cairo_image_surface_get_stride (xfer); - data = cairo_image_surface_get_data (xfer); - data += xfer_src_y * stride + xfer_src_x * 4; + cairo_stride = cairo_image_surface_get_stride (xfer); + cairo_data = cairo_image_surface_get_data (xfer) + + xfer_src_y * cairo_stride + xfer_src_x * 4; - /* apply filters to the rendered projection */ - if (shell->filter_stack) + cairo_buffer = gegl_buffer_linear_new_from_data (cairo_data, + babl_format ("cairo-ARGB32"), + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height), + cairo_stride, + NULL, NULL); + + if (shell->profile_transform || + gimp_display_shell_has_filter (shell)) { - const Babl *filter_format = babl_format ("R'G'B'A float"); + /* if there is a profile transform or a display filter, we need + * to use temp buffers + */ - if (! shell->filter_buffer) + /* create the filter buffer if we have filters + */ + if (gimp_display_shell_has_filter (shell) && + ! shell->filter_buffer) { gint w = GIMP_DISPLAY_RENDER_BUF_WIDTH * GIMP_DISPLAY_RENDER_MAX_SCALE; gint h = GIMP_DISPLAY_RENDER_BUF_HEIGHT * GIMP_DISPLAY_RENDER_MAX_SCALE; @@ -163,7 +179,8 @@ gimp_display_shell_render (GimpDisplayShell *shell, shell->filter_data = gegl_malloc (w * h * babl_format_get_bytes_per_pixel (filter_format)); - shell->filter_stride = w * babl_format_get_bytes_per_pixel (filter_format); + shell->filter_stride = + w * babl_format_get_bytes_per_pixel (filter_format); shell->filter_buffer = gegl_buffer_linear_new_from_data (shell->filter_data, @@ -174,48 +191,118 @@ gimp_display_shell_render (GimpDisplayShell *shell, shell->filter_data); } + if (shell->profile_transform) + { + /* if there is a profile transform, load the projection + * pixels into the profile_buffer + */ #ifndef USE_NODE_BLIT - gegl_buffer_get (buffer, - GEGL_RECTANGLE (scaled_x, scaled_y, - scaled_width, scaled_height), - buffer_scale, - filter_format, - shell->filter_data, shell->filter_stride, - GEGL_ABYSS_CLAMP); + gegl_buffer_get (buffer, + GEGL_RECTANGLE (scaled_x, scaled_y, + scaled_width, scaled_height), + buffer_scale, + shell->profile_src_format, + shell->profile_data, shell->profile_stride, + GEGL_ABYSS_CLAMP); #else - gegl_node_blit (node, - buffer_scale, - GEGL_RECTANGLE (scaled_x, scaled_y, - scaled_width, scaled_height), - filter_format, - shell->filter_data, shell->filter_stride, - GEGL_BLIT_CACHE); + gegl_node_blit (node, + buffer_scale, + GEGL_RECTANGLE (scaled_x, scaled_y, + scaled_width, scaled_height), + shell->profile_src_format, + shell->profile_data, shell->profile_stride, + GEGL_BLIT_CACHE); #endif - gimp_color_display_stack_convert_buffer (shell->filter_stack, - shell->filter_buffer, - GEGL_RECTANGLE (0, 0, - scaled_width, - scaled_height)); + if (gimp_display_shell_has_filter (shell)) + { + /* if there are filters, convert the pixels from the + * profile_buffer to the filter_buffer + */ + gimp_display_shell_profile_convert_buffer (shell, + shell->profile_buffer, + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height), + shell->filter_buffer, + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height)); + } + else + { + /* otherwise, convert the profile_buffer directly into + * the cairo_buffer + */ + gimp_display_shell_profile_convert_buffer (shell, + shell->profile_buffer, + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height), + cairo_buffer, + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height)); + } + } + else + { + /* otherwise, load the projection pixels directly into the + * filter_buffer + */ +#ifndef USE_NODE_BLIT + gegl_buffer_get (buffer, + GEGL_RECTANGLE (scaled_x, scaled_y, + scaled_width, scaled_height), + buffer_scale, + filter_format, + shell->filter_data, shell->filter_stride, + GEGL_ABYSS_CLAMP); +#else + gegl_node_blit (node, + buffer_scale, + GEGL_RECTANGLE (scaled_x, scaled_y, + scaled_width, scaled_height), + filter_format, + shell->filter_data, shell->filter_stride, + GEGL_BLIT_CACHE); +#endif + } - gegl_buffer_get (shell->filter_buffer, - GEGL_RECTANGLE (0, 0, - scaled_width, - scaled_height), - 1.0, - babl_format ("cairo-ARGB32"), - data, stride, - GEGL_ABYSS_CLAMP); + if (gimp_display_shell_has_filter (shell)) + { + /* convert the filter_buffer in place + */ + gimp_color_display_stack_convert_buffer (shell->filter_stack, + shell->filter_buffer, + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height)); + + /* finally, copy the filter buffer to the cairo-ARGB32 buffer + */ + gegl_buffer_get (shell->filter_buffer, + GEGL_RECTANGLE (0, 0, + scaled_width, + scaled_height), + 1.0, + babl_format ("cairo-ARGB32"), + cairo_data, cairo_stride, + GEGL_ABYSS_CLAMP); + } } else { + /* otherwise we can copy the projection pixels straight to the + * cairo-ARGB32 buffer + */ #ifndef USE_NODE_BLIT gegl_buffer_get (buffer, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, babl_format ("cairo-ARGB32"), - data, stride, + cairo_data, cairo_stride, GEGL_ABYSS_CLAMP); #else gegl_node_blit (node, @@ -223,11 +310,13 @@ gimp_display_shell_render (GimpDisplayShell *shell, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), babl_format ("cairo-ARGB32"), - data, stride, + cairo_data, cairo_stride, GEGL_BLIT_CACHE); #endif } + g_object_unref (cairo_buffer); + if (shell->mask) { if (! shell->mask_surface) @@ -242,16 +331,16 @@ gimp_display_shell_render (GimpDisplayShell *shell, cairo_surface_mark_dirty (shell->mask_surface); - stride = cairo_image_surface_get_stride (shell->mask_surface); - data = cairo_image_surface_get_data (shell->mask_surface); - data += mask_src_y * stride + mask_src_x * 4; + cairo_stride = cairo_image_surface_get_stride (shell->mask_surface); + cairo_data = cairo_image_surface_get_data (shell->mask_surface) + + mask_src_y * cairo_stride + mask_src_x * 4; gegl_buffer_get (shell->mask, GEGL_RECTANGLE (scaled_x, scaled_y, scaled_width, scaled_height), buffer_scale, babl_format ("Y u8"), - data, stride, + cairo_data, cairo_stride, GEGL_ABYSS_CLAMP); if (shell->mask_inverted) @@ -261,7 +350,7 @@ gimp_display_shell_render (GimpDisplayShell *shell, while (mask_height--) { gint mask_width = scaled_width; - guchar *d = data; + guchar *d = cairo_data; while (mask_width--) { @@ -270,7 +359,7 @@ gimp_display_shell_render (GimpDisplayShell *shell, *d++ = inv; } - data += stride; + cairo_data += cairo_stride; } } }