Commit 64bf77ae authored by Ell's avatar Ell

app: render layer-group preview in chunks

In gimp_drawable_get_sub_preview_async(), when the drawable buffer
has a validate handler (i.e., when it's a group layer), use a chunk
iterator to validate the buffer in chunks, where each chunk is
validated in a separate invocation of the async function.  This
prevents validation from blocking the main thread for too long when
the buffer is not already fully validated.
parent 919ddce7
Pipeline #160842 failed with stages
in 25 minutes and 15 seconds
......@@ -39,6 +39,7 @@
#include "gimp-utils.h"
#include "gimpasync.h"
#include "gimpchannel.h"
#include "gimpchunkiterator.h"
#include "gimpimage.h"
#include "gimpimage-color-profile.h"
#include "gimpdrawable-preview.h"
......@@ -51,10 +52,12 @@
typedef struct
{
const Babl *format;
GeglBuffer *buffer;
GeglRectangle rect;
gdouble scale;
const Babl *format;
GeglBuffer *buffer;
GeglRectangle rect;
gdouble scale;
GimpChunkIterator *iter;
} SubPreviewData;
......@@ -84,6 +87,8 @@ sub_preview_data_new (const Babl *format,
data->rect = *rect;
data->scale = scale;
data->iter = NULL;
return data;
}
......@@ -92,6 +97,9 @@ sub_preview_data_free (SubPreviewData *data)
{
g_object_unref (data->buffer);
if (data->iter)
gimp_chunk_iterator_stop (data->iter, TRUE);
g_slice_free (SubPreviewData, data);
}
......@@ -337,18 +345,44 @@ gimp_drawable_get_sub_preview_async_func (GimpAsync *async,
if (validate)
{
GeglRectangle rect;
rect.x = floor (data->rect.x / data->scale);
rect.y = floor (data->rect.y / data->scale);
rect.width = ceil ((data->rect.x + data->rect.width) / data->scale) -
rect.x;
rect.height = ceil ((data->rect.x + data->rect.height) / data->scale) -
rect.y;
gimp_tile_handler_validate_validate (validate,
data->buffer, &rect,
TRUE, TRUE);
if (! data->iter)
{
cairo_region_t *region;
cairo_rectangle_int_t rect;
rect.x = floor (data->rect.x / data->scale);
rect.y = floor (data->rect.y / data->scale);
rect.width = ceil ((data->rect.x + data->rect.width) /
data->scale) - rect.x;
rect.height = ceil ((data->rect.x + data->rect.height) /
data->scale) - rect.y;
region = cairo_region_copy (validate->dirty_region);
cairo_region_intersect_rectangle (region, &rect);
data->iter = gimp_chunk_iterator_new (region);
}
if (gimp_chunk_iterator_next (data->iter))
{
GeglRectangle rect;
gimp_tile_handler_validate_begin_validate (validate);
while (gimp_chunk_iterator_get_rect (data->iter, &rect))
{
gimp_tile_handler_validate_validate (validate,
data->buffer, &rect,
FALSE, FALSE);
}
gimp_tile_handler_validate_end_validate (validate);
return;
}
data->iter = NULL;
}
gegl_buffer_get (data->buffer, &data->rect, data->scale,
......
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