Commit 83dd94ba authored by Ell's avatar Ell

app: use gimp_tile_handler_validate_validate() in gimp:buffer-source-validate

Use gimp_tile_handler_validate_validate(), added in the commit
before last, in gimp:buffer-source-validate, in order to pre-render
the necessary region of the buffer, instead of performing the
validation implicitly by iterating over the region.  This is both
simpler, and, more importantly, allows us to render the entire
region in a single chunk, instead of tile-by-tile, which can be
considerably more efficient, especially with high thread counts.

This essentially extends the dynamic sizing of rendered projection
chunks to layer groups, which are rendered through
gimp:buffer-source-validate, rather than just the main image
projection.
parent d6f0ca55
......@@ -18,7 +18,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#define GEGL_ITERATOR2_API
#include "config.h"
#include <cairo.h>
......@@ -239,25 +238,12 @@ gimp_operation_buffer_source_validate_process (GeglOperation *operation,
validate_handler = gimp_tile_handler_validate_get_assigned (buffer);
if (validate_handler)
{
gint n_threads;
g_object_get (gegl_config (),
"threads", &n_threads,
NULL);
/* the main reason to validate the buffer during processing is to
* avoid threading issues. skip validation if not using
* multithreading.
*/
if (n_threads > 1)
{
gint shift_x;
gint shift_y;
gint tile_width;
gint tile_height;
cairo_rectangle_int_t rect;
cairo_region_overlap_t overlap;
GeglRectangle rect;
g_object_get (buffer_source_validate->buffer,
"shift-x", &shift_x,
......@@ -272,57 +258,10 @@ gimp_operation_buffer_source_validate_process (GeglOperation *operation,
rect.width = (gint) ceil ((gdouble) (result->x + result->width + shift_x) / tile_width) * tile_width - rect.x;
rect.height = (gint) ceil ((gdouble) (result->y + result->height + shift_y) / tile_height) * tile_height - rect.y;
/* check if the rectangle interescts with the dirty region */
overlap = cairo_region_contains_rectangle (validate_handler->dirty_region,
&rect);
if (overlap != CAIRO_REGION_OVERLAP_OUT)
{
GeglBufferIterator *iter;
/* if the rectangle is not entirely within the dirty
* region ...
*/
if (overlap == CAIRO_REGION_OVERLAP_PART)
{
cairo_region_t *region;
cairo_rectangle_int_t intersection;
/* ... intersect it with region and use the result's
* bounds
*/
region = cairo_region_copy (validate_handler->dirty_region);
cairo_region_intersect_rectangle (region, &rect);
cairo_region_get_extents (region, &intersection);
cairo_region_destroy (region);
/* realign the rectangle to the tile grid */
rect.x = (gint) floor ((gdouble) (intersection.x ) / tile_width) * tile_width;
rect.y = (gint) floor ((gdouble) (intersection.y ) / tile_height) * tile_height;
rect.width = (gint) ceil ((gdouble) (intersection.x + intersection.width ) / tile_width) * tile_width - rect.x;
rect.height = (gint) ceil ((gdouble) (intersection.y + intersection.height) / tile_height) * tile_height - rect.y;
}
rect.x -= shift_x;
rect.y -= shift_y;
/* iterate over the rectangle -- this implicitly causes
* validation
*/
iter = gegl_buffer_iterator_new (buffer,
GEGL_RECTANGLE (rect.x,
rect.y,
rect.width,
rect.height),
level, NULL,
GEGL_BUFFER_READ,
GEGL_ABYSS_NONE, 1);
while (gegl_buffer_iterator_next (iter));
}
}
gimp_tile_handler_validate_validate (validate_handler,
buffer_source_validate->buffer,
&rect,
TRUE);
}
gegl_operation_context_set_object (context, "output", G_OBJECT (buffer));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment