[gimp] app: add gimp_gegl_apply_cached_operation()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_gegl_apply_cached_operation()
- Date: Wed, 18 Jun 2014 16:55:20 +0000 (UTC)
commit 14614cb34909827d8e383c3ba94aa76b2e36b577
Author: Michael Natterer <mitch gimp org>
Date: Wed Jun 18 18:42:17 2014 +0200
app: add gimp_gegl_apply_cached_operation()
which does the same as gimp_gegl_apply_operation() but takes
additional arguments which are a cache buffer and a list of rectangles
that specify the already computed region in the cache buffer.
app/gegl/gimp-gegl-apply-operation.c | 119 +++++++++++++++++++++++++++++++---
app/gegl/gimp-gegl-apply-operation.h | 26 +++++--
2 files changed, 128 insertions(+), 17 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index 059150d..ff6bcf8 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -22,6 +22,7 @@
#include "config.h"
+#include <cairo.h>
#include <gegl.h>
#include "gimp-gegl-types.h"
@@ -42,16 +43,39 @@ gimp_gegl_apply_operation (GeglBuffer *src_buffer,
GeglBuffer *dest_buffer,
const GeglRectangle *dest_rect)
{
+ gimp_gegl_apply_cached_operation (src_buffer,
+ progress, undo_desc,
+ operation,
+ dest_buffer,
+ dest_rect,
+ NULL, NULL, 0);
+}
+
+void
+gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglNode *operation,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ GeglBuffer *cache,
+ const GeglRectangle *valid_rects,
+ gint n_valid_rects)
+{
GeglNode *gegl;
GeglNode *dest_node;
GeglRectangle rect = { 0, };
- gdouble value;
+ GeglProcessor *processor = NULL;
gboolean progress_active = FALSE;
+ gdouble value;
g_return_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer));
g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));
g_return_if_fail (GEGL_IS_NODE (operation));
g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));
+ g_return_if_fail (cache == NULL || GEGL_IS_BUFFER (cache));
+ g_return_if_fail (valid_rects == NULL || cache != NULL);
+ g_return_if_fail (valid_rects == NULL || n_valid_rects != 0);
if (dest_rect)
{
@@ -96,14 +120,11 @@ gimp_gegl_apply_operation (GeglBuffer *src_buffer,
"buffer", dest_buffer,
NULL);
-
gegl_node_connect_to (operation, "output",
dest_node, "input");
if (progress)
{
- GeglProcessor *processor;
-
processor = gegl_node_new_processor (dest_node, &rect);
progress_active = gimp_progress_is_active (progress);
@@ -117,18 +138,98 @@ gimp_gegl_apply_operation (GeglBuffer *src_buffer,
{
gimp_progress_start (progress, undo_desc, FALSE);
}
+ }
+
+ if (cache)
+ {
+ cairo_region_t *region;
+ gint all_pixels;
+ gint done_pixels = 0;
+ gint n_rects;
+ gint i;
+
+ region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
+
+ all_pixels = rect.width * rect.height;
+
+ for (i = 0; i < n_valid_rects; i++)
+ {
+ gegl_buffer_copy (cache, valid_rects + i,
+ dest_buffer, valid_rects + i);
- while (gegl_processor_work (processor, &value))
- gimp_progress_set_value (progress, value);
+ cairo_region_subtract_rectangle (region,
+ (cairo_rectangle_int_t *)
+ valid_rects + i);
- g_object_unref (processor);
+ done_pixels += valid_rects[i].width * valid_rects[i].height;
+
+ if (progress)
+ gimp_progress_set_value (progress,
+ (gdouble) done_pixels /
+ (gdouble) all_pixels);
+ }
+
+ n_rects = cairo_region_num_rectangles (region);
+
+ for (i = 0; i < n_rects; i++)
+ {
+ cairo_rectangle_int_t render_rect;
+
+ cairo_region_get_rectangle (region, i, &render_rect);
+
+ 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 (gegl_processor_work (processor, &value))
+ {
+ gimp_progress_set_value (progress,
+ ((gdouble) done_pixels +
+ value * rect_pixels) /
+ (gdouble) all_pixels);
+ }
+
+ done_pixels += rect_pixels;
+ }
+ else
+ {
+ gegl_node_blit (dest_node, 1.0, (GeglRectangle *) &render_rect,
+ NULL, NULL, 0, GEGL_BLIT_DEFAULT);
+ }
+ }
+
+ cairo_region_destroy (region);
}
else
{
- gegl_node_blit (dest_node, 1.0, &rect,
- NULL, NULL, 0, GEGL_BLIT_DEFAULT);
+ if (progress)
+ {
+ while (gegl_processor_work (processor, &value))
+ {
+ gimp_progress_set_value (progress, value);
+ }
+
+ g_object_unref (processor);
+ }
+ else
+ {
+ gegl_node_blit (dest_node, 1.0, &rect,
+ NULL, NULL, 0, GEGL_BLIT_DEFAULT);
+ }
}
+ if (processor)
+ g_object_unref (processor);
+
g_object_unref (gegl);
if (progress && ! progress_active)
diff --git a/app/gegl/gimp-gegl-apply-operation.h b/app/gegl/gimp-gegl-apply-operation.h
index 06edaa5..b67e9c6 100644
--- a/app/gegl/gimp-gegl-apply-operation.h
+++ b/app/gegl/gimp-gegl-apply-operation.h
@@ -24,14 +24,24 @@
#define __GIMP_GEGL_APPLY_OPERATION_H__
-/* generic function, also used by the specific ones below */
-
-void gimp_gegl_apply_operation (GeglBuffer *src_buffer,
- GimpProgress *progress,
- const gchar *undo_desc,
- GeglNode *operation,
- GeglBuffer *dest_buffer,
- const GeglRectangle *dest_rect);
+/* generic functions, also used by the specific ones below */
+
+void gimp_gegl_apply_operation (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglNode *operation,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect);
+
+void gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
+ GimpProgress *progress,
+ const gchar *undo_desc,
+ GeglNode *operation,
+ GeglBuffer *dest_buffer,
+ const GeglRectangle *dest_rect,
+ GeglBuffer *cache,
+ const GeglRectangle *valid_rects,
+ gint n_valid_rects);
/* apply specific operations */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]