[gimp/gimp-2-10] Issue #3994 - Artifacts when committing half-cached filters
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] Issue #3994 - Artifacts when committing half-cached filters
- Date: Mon, 30 Sep 2019 07:25:46 +0000 (UTC)
commit 08f59073dedf40ae87ea982d5c8b640bc0371310
Author: Ell <ell_se yahoo com>
Date: Mon Sep 30 10:07:57 2019 +0300
Issue #3994 - Artifacts when committing half-cached filters
In gimp_gegl_apply_cached_operation(), when applying a non-point
filter with the same source and destination buffers, render the
result to a temporary buffer to avoid chunking artifacts. We'd
previously duplicate the source buffer instead (with commit
35729ee02a6679d8dd525001546f5ca57a926a6a erroneously copying the
cached results to the source/destination buffer before duplicating
it, causing this bug), but we now use a temporary result buffer
instead; this has roughly the same overhead, but would allow us to
keep the original operation-node input when committing a drawable
filter in a future commit, which would avoid dropping any cached
data.
(cherry picked from commit 88c6f8296da25c826b0c2972669bc8377d31e381)
app/gegl/gimp-gegl-apply-operation.c | 76 +++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 23 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index 443a27356d..b0b485247a 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -94,6 +94,7 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
GeglNode *dest_node;
GeglNode *underlying_operation;
GeglNode *operation_src_node = NULL;
+ GeglBuffer *result_buffer;
GimpChunkIterator *iter;
cairo_region_t *region;
gboolean progress_started = FALSE;
@@ -141,12 +142,48 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
gegl_buffer_freeze_changed (dest_buffer);
+ underlying_operation = gimp_gegl_node_get_underlying_operation (operation);
+
+ result_buffer = dest_buffer;
+
+ if (result_buffer == src_buffer &&
+ ! (gimp_gegl_node_is_point_operation (underlying_operation) ||
+ gimp_gegl_node_is_source_operation (underlying_operation)))
+ {
+ /* Write the result to a temporary buffer, instead of directly to
+ * dest_buffer, since reading and writing the same buffer doesn't
+ * generally work with non-point ops when working in chunks.
+ *
+ * See bug #701875.
+ */
+
+ if (cache)
+ {
+ /* If we have a cache, use it directly as the temporary result
+ * buffer, and skip copying the cached results to result_buffer
+ * below. Instead, the cached results are copied together with the
+ * newly rendered results in a single step at the end of processing.
+ */
+
+ g_warn_if_fail (cache != dest_buffer);
+
+ result_buffer = g_object_ref (cache);
+
+ cache = NULL;
+ }
+ else
+ {
+ result_buffer = gegl_buffer_new (
+ dest_rect, gegl_buffer_get_format (dest_buffer));
+ }
+ }
+
all_pixels = dest_rect->width * dest_rect->height;
done_pixels = 0;
region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) dest_rect);
- if (cache)
+ if (n_valid_rects > 0)
{
gint i;
@@ -160,8 +197,12 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
continue;
}
- gimp_gegl_buffer_copy (cache, &valid_rect, GEGL_ABYSS_NONE,
- dest_buffer, &valid_rect);
+ if (cache)
+ {
+ gimp_gegl_buffer_copy (
+ cache, &valid_rect, GEGL_ABYSS_NONE,
+ result_buffer, &valid_rect);
+ }
cairo_region_subtract_rectangle (region,
(cairo_rectangle_int_t *)
@@ -185,34 +226,15 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
effect = operation;
- underlying_operation = gimp_gegl_node_get_underlying_operation (operation);
-
if (src_buffer)
{
GeglNode *src_node;
- /* dup() because reading and writing the same buffer doesn't
- * generally work with non-point ops when working in chunks.
- * See bug #701875.
- */
- if (src_buffer == dest_buffer &&
- ! (gimp_gegl_node_is_point_operation (underlying_operation) ||
- gimp_gegl_node_is_source_operation (underlying_operation)))
- {
- src_buffer = gimp_gegl_buffer_dup (src_buffer);
- }
- else
- {
- g_object_ref (src_buffer);
- }
-
src_node = gegl_node_new_child (gegl,
"operation", "gegl:buffer-source",
"buffer", src_buffer,
NULL);
- g_object_unref (src_buffer);
-
if (crop_input)
{
GeglNode *crop_node;
@@ -249,7 +271,7 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
dest_node = gegl_node_new_child (gegl,
"operation", "gegl:write-buffer",
- "buffer", dest_buffer,
+ "buffer", result_buffer,
NULL);
gegl_node_connect_to (effect, "output",
@@ -315,6 +337,14 @@ gimp_gegl_apply_cached_operation (GeglBuffer *src_buffer,
}
}
+ if (result_buffer != dest_buffer)
+ {
+ gimp_gegl_buffer_copy (result_buffer, dest_rect, GEGL_ABYSS_NONE,
+ dest_buffer, dest_rect);
+
+ g_object_unref (result_buffer);
+ }
+
gegl_buffer_thaw_changed (dest_buffer);
g_object_unref (gegl);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]