diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c index 9e31adb556..848d85c0c3 100644 --- a/app/core/gimpprojection.c +++ b/app/core/gimpprojection.c @@ -900,7 +900,7 @@ gimp_projection_paint_area (GimpProjection *proj, proj->priv->validate_handler, proj->priv->buffer, &rect, - FALSE); + FALSE, FALSE); } else { diff --git a/app/gegl/gimptilehandlervalidate.c b/app/gegl/gimptilehandlervalidate.c index 85195a70da..6d71011dde 100644 --- a/app/gegl/gimptilehandlervalidate.c +++ b/app/gegl/gimptilehandlervalidate.c @@ -25,6 +25,7 @@ #include "gimp-gegl-types.h" +#include "core/gimpchunkiterator.h" #include "core/gimpmarshal.h" #include "gimp-gegl-loops.h" @@ -532,9 +533,11 @@ void gimp_tile_handler_validate_validate (GimpTileHandlerValidate *validate, GeglBuffer *buffer, const GeglRectangle *rect, - gboolean intersect) + gboolean intersect, + gboolean chunked) { GimpTileHandlerValidateClass *klass; + cairo_region_t *region = NULL; g_return_if_fail (GIMP_IS_TILE_HANDLER_VALIDATE (validate)); g_return_if_fail (gimp_tile_handler_validate_get_assigned (buffer) == @@ -547,30 +550,56 @@ gimp_tile_handler_validate_validate (GimpTileHandlerValidate *validate, if (intersect) { - cairo_region_t *region = cairo_region_copy (validate->dirty_region); + region = cairo_region_copy (validate->dirty_region); cairo_region_intersect_rectangle (region, (const cairo_rectangle_int_t *) rect); + } + else if (chunked) + { + region = cairo_region_create_rectangle ( + (const cairo_rectangle_int_t *) rect); + } + if (region) + { if (! cairo_region_is_empty (region)) { - gint n_rects; - gint i; - gimp_tile_handler_validate_begin_validate (validate); - n_rects = cairo_region_num_rectangles (region); - - for (i = 0; i < n_rects; i++) + if (chunked) { - cairo_rectangle_int_t blit_rect; + GimpChunkIterator *iter; - cairo_region_get_rectangle (region, i, &blit_rect); + iter = gimp_chunk_iterator_new (region); + region = NULL; - klass->validate_buffer (validate, - (const GeglRectangle *) &blit_rect, - buffer); + while (gimp_chunk_iterator_next (iter)) + { + GeglRectangle blit_rect; + + while (gimp_chunk_iterator_get_rect (iter, &blit_rect)) + klass->validate_buffer (validate, &blit_rect, buffer); + } } + else + { + gint n_rects; + gint i; + + n_rects = cairo_region_num_rectangles (region); + + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t blit_rect; + + cairo_region_get_rectangle (region, i, &blit_rect); + + klass->validate_buffer (validate, + (const GeglRectangle *) &blit_rect, + buffer); + } + } gimp_tile_handler_validate_end_validate (validate); @@ -579,7 +608,7 @@ gimp_tile_handler_validate_validate (GimpTileHandlerValidate *validate, (const cairo_rectangle_int_t *) rect); } - cairo_region_destroy (region); + g_clear_pointer (®ion, cairo_region_destroy); } else { diff --git a/app/gegl/gimptilehandlervalidate.h b/app/gegl/gimptilehandlervalidate.h index 86973be33b..998430fd8d 100644 --- a/app/gegl/gimptilehandlervalidate.h +++ b/app/gegl/gimptilehandlervalidate.h @@ -95,7 +95,8 @@ void gimp_tile_handler_validate_end_validate (GimpTile void gimp_tile_handler_validate_validate (GimpTileHandlerValidate *validate, GeglBuffer *buffer, const GeglRectangle *rect, - gboolean intersect); + gboolean intersect, + gboolean chunked); gboolean gimp_tile_handler_validate_buffer_set_extent (GeglBuffer *buffer, const GeglRectangle *extent); diff --git a/app/operations/gimpoperationbuffersourcevalidate.c b/app/operations/gimpoperationbuffersourcevalidate.c index ce8745882a..d27765385d 100644 --- a/app/operations/gimpoperationbuffersourcevalidate.c +++ b/app/operations/gimpoperationbuffersourcevalidate.c @@ -286,7 +286,7 @@ gimp_operation_buffer_source_validate_process (GeglOperation *operation, gimp_tile_handler_validate_validate (validate_handler, buffer_source_validate->buffer, &rect, - TRUE); + TRUE, FALSE); } gegl_operation_context_set_object (context, "output", G_OBJECT (buffer));