[gimp/gimp-2-10] app: render layer-group preview in chunks
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: render layer-group preview in chunks
- Date: Sat, 14 Mar 2020 14:06:41 +0000 (UTC)
commit fbaf3c4290d9e1a7a506250a6328102cb9e0189e
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.
(cherry picked from commit 64bf77aed88667d0f7b05205e33a19c50e5f3887)
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 93ff17d742..28ae1e224e 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);
}
@@ -340,18 +348,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]