[gimp] app: use GimpChunkIterator in gimp_gegl_apply_cached_operation()
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: use GimpChunkIterator in gimp_gegl_apply_cached_operation()
- Date: Sat, 12 Jan 2019 09:55:20 +0000 (UTC)
commit 4110f7b7b186a609d9ca9882cf1f8a1e12b4169e
Author: Ell <ell_se yahoo com>
Date: Sat Jan 12 03:41:00 2019 -0500
app: use GimpChunkIterator in gimp_gegl_apply_cached_operation()
In gimp_gegl_apply_cached_operation(), replace the use of
GeglProcessor with GimpChunkIterator, so that we use the same
chunking logic as for rendering projections. This has the
advantage of better chunk alignment to the tile grid and dynamic
chunk sizing, which improve performance.
Use chunking even when there's no progress indication, since it
generally results in better cache locality.
app/gegl/gimp-gegl-apply-operation.c | 131 +++++++++++++++--------------------
1 file changed, 54 insertions(+), 77 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index df4f3dd96e..4b4f121f63 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -30,6 +30,7 @@
#include "core/gimp-transform-utils.h"
#include "core/gimp-utils.h"
+#include "core/gimpchunkiterator.h"
#include "core/gimpprogress.h"
#include "gimp-gegl-apply-operation.h"
@@ -77,15 +78,17 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
gint n_valid_rects,
gboolean cancelable)
{
- GeglNode *gegl;
- GeglNode *effect;
- GeglNode *dest_node;
- GeglNode *operation_src_node = NULL;
- GeglRectangle rect = { 0, };
- GeglProcessor *processor = NULL;
- gboolean progress_started = FALSE;
- gdouble value;
- gboolean cancel = FALSE;
+ GeglNode *gegl;
+ GeglNode *effect;
+ GeglNode *dest_node;
+ GeglNode *operation_src_node = NULL;
+ GimpChunkIterator *iter;
+ cairo_region_t *region;
+ GeglRectangle rect = { 0, };
+ gboolean progress_started = FALSE;
+ gboolean cancel = FALSE;
+ gint all_pixels;
+ gint done_pixels;
g_return_val_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer), FALSE);
g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
@@ -117,9 +120,9 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
GeglNode *src_node;
/* dup() because reading and writing the same buffer doesn't
- * work with area ops when using a processor. See bug #701875.
+ * work with area ops when working in chunks. See bug #701875.
*/
- if (progress && (src_buffer == dest_buffer))
+ if (src_buffer == dest_buffer)
src_buffer = gegl_buffer_dup (src_buffer);
else
g_object_ref (src_buffer);
@@ -175,8 +178,6 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
if (progress)
{
- processor = gegl_node_new_processor (dest_node, &rect);
-
if (gimp_progress_is_active (progress))
{
if (undo_desc)
@@ -197,18 +198,21 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
progress_started = TRUE;
}
}
-
- if (cache)
+ else
{
- cairo_region_t *region;
- gint all_pixels;
- gint done_pixels = 0;
- gint n_rects;
- gint i;
+ cancelable = FALSE;
+ }
+
+ gegl_buffer_freeze_changed (dest_buffer);
- region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
+ all_pixels = rect.width * rect.height;
+ done_pixels = 0;
- all_pixels = rect.width * rect.height;
+ region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
+
+ if (cache)
+ {
+ gint i;
for (i = 0; i < n_valid_rects; i++)
{
@@ -230,75 +234,48 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
done_pixels += valid_rect.width * valid_rect.height;
if (progress)
- gimp_progress_set_value (progress,
- (gdouble) done_pixels /
- (gdouble) all_pixels);
+ {
+ gimp_progress_set_value (progress,
+ (gdouble) done_pixels /
+ (gdouble) all_pixels);
+ }
}
+ }
- n_rects = cairo_region_num_rectangles (region);
+ iter = gimp_chunk_iterator_new (region);
- for (i = 0; ! cancel && (i < n_rects); i++)
- {
- cairo_rectangle_int_t render_rect;
+ while (gimp_chunk_iterator_next (iter))
+ {
+ GeglRectangle render_rect;
- cairo_region_get_rectangle (region, i, &render_rect);
+ if (progress)
+ {
+ while (! cancel && g_main_context_pending (NULL))
+ g_main_context_iteration (NULL, FALSE);
- if (progress)
- {
- gint rect_pixels = render_rect.width * render_rect.height;
-
-#ifdef REUSE_PROCESSOR
- gegl_processor_set_rectangle (processor,
- (GeglRectangle *) &render_rect);
-#else
- g_object_unref (processor);
- processor = gegl_node_new_processor (dest_node,
- (GeglRectangle *) &render_rect);
-#endif
-
- while (! cancel && gegl_processor_work (processor, &value))
- {
- gimp_progress_set_value (progress,
- ((gdouble) done_pixels +
- value * rect_pixels) /
- (gdouble) all_pixels);
-
- while (! cancel && g_main_context_pending (NULL))
- g_main_context_iteration (NULL, FALSE);
- }
-
- done_pixels += rect_pixels;
- }
- else
- {
- gegl_node_blit (dest_node, 1.0, (GeglRectangle *) &render_rect,
- NULL, NULL, 0, GEGL_BLIT_DEFAULT);
- }
+ if (cancel)
+ break;
}
- cairo_region_destroy (region);
- }
- else
- {
- if (progress)
+ while (gimp_chunk_iterator_get_rect (iter, &render_rect))
{
- while (! cancel && gegl_processor_work (processor, &value))
- {
- gimp_progress_set_value (progress, value);
+ gint rect_pixels = render_rect.width * render_rect.height;
- while (! cancel && g_main_context_pending (NULL))
- g_main_context_iteration (NULL, FALSE);
- }
+ gegl_node_blit (dest_node, 1.0, &render_rect, NULL, NULL, 0,
+ GEGL_BLIT_DEFAULT);
+
+ done_pixels += rect_pixels;
}
- else
+
+ if (progress)
{
- gegl_node_blit (dest_node, 1.0, &rect,
- NULL, NULL, 0, GEGL_BLIT_DEFAULT);
+ gimp_progress_set_value (progress,
+ (gdouble) done_pixels /
+ (gdouble) all_pixels);
}
}
- if (processor)
- g_object_unref (processor);
+ gegl_buffer_thaw_changed (dest_buffer);
g_object_unref (gegl);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]