[gimp] app: render layer-group preview in chunks
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: render layer-group preview in chunks
- Date: Sat, 14 Mar 2020 14:06:46 +0000 (UTC)
commit 64bf77aed88667d0f7b05205e33a19c50e5f3887
Author: Ell <ell_se yahoo com>
Date: Sat Mar 14 16:02:14 2020 +0200
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.
app/core/gimpdrawable-preview.c | 66 +++++++++++++++++++++++++++++++----------
1 file changed, 50 insertions(+), 16 deletions(-)
---
diff --git a/app/core/gimpdrawable-preview.c b/app/core/gimpdrawable-preview.c
index d3bb3136f0..570865e5e0 100644
--- a/app/core/gimpdrawable-preview.c
+++ b/app/core/gimpdrawable-preview.c
@@ -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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]