Commit Graph

762 Commits

Author SHA1 Message Date
Ell
901b0e7211 app: add support for offset buffers in gimp_channel_select_buffer() ...
... and gimp_gegl_mask_combine_buffer()

Allow the functions to work with buffers whose top-left corner is
not at (0, 0).

(cherry picked from commit 24534338e7)
2020-02-03 21:21:16 +02:00
Ell
7b4fba243e app: suspend tile validation while setting extent of validate-handler buffer
In gimp_tile_handler_validate_buffer_set_extent(), suspend tile
validation while calling gimp_gegl_buffer_set_extent(), so that if
the call triggers clearing of partial tiles, these tiles don't get
unnecessarily validated.

(cherry picked from commit fcc1c3d380)
2020-01-18 12:43:08 +02:00
Ell
8a54c78e6b app: add gimp_gegl_node_get_key()
... which gets an operation-class key for the operation associated
with the node, if any.
2020-01-17 12:12:57 +02:00
Ell
456ede52e8 app: in GimpTileHandlerValidate, fix tile-data pointer for negative coords
In gimp_tile_handler_validate_validate_tile(), when validating a
partial tile with negative coordinates, make sure to adjust the
result of the modulo when calculating the tile-realtive coordinates
so that they're non-negative, to fix the tile-data pointer offset.

(cherry picked from commit d39822bcd7)
2020-01-16 01:58:58 +02:00
Ell
0a93f5609e app: add GimpTileHandlerValidate::invalidated signal
Add a new GimpTileHandlerValidate::invalidated signal, which is
emitted when a region of the buffer is invalidated.  This would
allow us to properly invalidate the graph in response; this
normally happens in response to GeglBuffer::changed, but this
signal is not emitted when a region is merely invalidated.

(cherry picked from commit 3ea391602e)
2020-01-15 21:50:20 +02:00
Ell
537ae20fa0 app: allow calling gimp_tile_handler_validate_validate() with a NULL rect
... and validate the entire buffer.

(cherry picked from commit ba6040bbcd)
2020-01-15 21:50:20 +02:00
Ell
b9c13c0900 app: fix integer overflow when reporting operation progress
In gimp_gegl_apply_cached_operation(), use gint64 for storing the
total and processed pixel counts used for reporting progress, to
avoid overflowing when applying an operation to a large image.

(cherry picked from commit f1c448e0f4)
2020-01-08 11:40:06 +02:00
Ell
4c55475af9 app: restore behavior of gimp_gegl_apply_operation() with NULL src_buffer
Restore the behavior of gimp_gegl_apply_operation() prior to
11629fde66 when src_buffer is NULL:
keep the existing operation-node input, instead of using an empty
input.  Unlike gimp_gegl_apply_cached_operation(),
gimp_gegl_apply_operation() doesn't have an explicit
connect_src_buffer parameter.

This fixes empty output when merging layers.

(cherry picked from commit 076d9b2a28)
2019-10-05 09:43:27 +03:00
Ell
97c549198e app: avoid dropping cached data when committing filters
In gimp_gegl_apply_cached_operation(), add a boolean
connect_src_buffer parameter, which determines whether to connect
the source buffer to the operation-node's input, or to use its
existing input.  In gimp_drawable_merge_filter(), pass FALSE for
connect_src_buffer, so that the existing filter-node input is used.
This produces an equivalent result, however, it avoids invalidating
the filter node, and dropping cached data as a result.  In
operations that cache larger areas than the ROI, this avoids
reprocessing already-cached data when processing the rest of the
operation.

Additionally, in gimp_gegl_apply_cached_operation(), use an empty
input for the operation if src_buffer is NULL and
connect_src_buffer is TRUE; previously, we'd use the operation-
node's existing input when src_buffer was NULL.  Furthermore, crop
the operation-node's input to the destination rect when crop_input
is TRUE, even if connect_src_buffer is FALSE.

(cherry picked from commit 11629fde66)
2019-10-03 20:12:23 +03:00
Ell
08f59073de 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
35729ee02a 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 88c6f8296d)
2019-09-30 10:25:19 +03:00
Ell
d5e78f1899 app: add "Swap compression" option to the preferences
Add a new "Swap compression" option to the preferences, allowing
explicit control over the tile-swap compression algorithm.
Previously, control over swap compression was only possible through
GEGL command-line options/environment variables.  Since the GEGL
API to list all available compression algorithms is still private
for now, we currently only list the three predefined compression
levels -- "best performance" (the default), "balanced", and "best
compression" -- and a "none" option, to disable compression
altogether.  Selecting a custom compression algorithm is possible
by entering its name manually.

(cherry picked from commit 1664ecbf1d)
2019-09-22 17:42:23 +03:00
Ell
d3e1f50b13 app, meson.build: fix a bunch of warnings in C++ files
(cherry picked from commit 4fc345183b)
2019-09-12 20:05:45 +03:00
Ell
f4b179c09e app: in gimp_gegl_mask_bounds(), add support for arbitrary buffer extents
(cherry picked from commit 6df0be91ba)
2019-09-05 18:04:21 +03:00
Ell
16c676809c app: fix gimp_gegl_mask_bounds()
(cherry picked from commit ddbff867a1)
2019-09-05 18:04:20 +03:00
Ell
e183b8e6ad app: in gimp_gegl_buffer_set_extent(), clear full OOB region
In gimp_gegl_buffer_set_extent(), clear the full now-out-of-bounds
region of the buffer, instead of only full out-of-bounds tiles;
however, we still make sure to clear full tiles, instead of partial
tiles, as much as possible.  This prevents (parts of) the old
content of the buffer from showing when it's enlarged again.  This
is especially relevant for the image projection, once we add
support for a dynamically-expanding canvas in the following
commits, since the projection of a reexpanded buffer can be
temporarily rendered to the display before it's fully
reconstructed, exposing parts of the old content.
2019-09-04 20:56:23 +03:00
Ell
d3af77890d app: add gimp_tile_handler_validate_buffer_set_extent()
... which sets the extent of a buffer with an assigned
GimpTileHandlerValidate, clipping the dirty region to the new
extent.

(cherry picked from commit b4ee9ff055)
2019-08-13 17:44:26 +03:00
Ell
56f6c35e30 app: add gimp_gegl_buffer_set_extent()
.... as a drop-in replacement for gegl_buffer_set_extent(), which,
in addition to setting the buffer's extent, clears any now-out-of-
bounds tiles, to free memory.

(cherry picked from commit 90610ac87e)
2019-08-13 17:44:25 +03:00
Ell
bba810a9e5 app: in gimp_gegl_apply_cached_operation(), copy cached result *before* rejigging graph
In gimp_gegl_apply_cached_operation(), copy the cached results to
the destination buffer *before* reconnecting the operation node, as
this may cause the cache to be cleared (see commit
gegl@4347255cd9d5031e6757c70fdde5c63539d5f508).

(cherry picked from commit 35729ee02a)
2019-08-02 00:40:27 +03:00
Ell
ca98ff3c27 app: use gimp_gegl_buffer_dup() everywhere
... instead of gegl_buffer_dup().

(cherry picked from commit 2d80d4d138)
2019-07-30 20:32:56 +03:00
Ell
c0e04c3b5f app: add gimp_gegl_buffer_dup()
... as a drop-in replacement for gegl_buffer_dup(), which COWs all
tiles of the source buffer, including ones that aren't fully
included within buffer's extent.

(cherry picked from commit 5798cefe1b)
2019-07-30 20:32:55 +03:00
Ell
6cc671074a app: in gimp_gegl_buffer_copy(), allow tiles outside the abyss to be COWed
In gimp_gegl_buffer_copy(), assume that the area outside the abyss
is empty, and so, when the abyss policy is NONE, allow data otuside
the source/destination abyss to be copied, by temporarily modifying
the abyss.  This allows tiles that aren't fully contained within
the abyss to be COWed, unlike gegl_buffer_copy(), which has to be
more general.

(cherry picked from commit 69ce5e7e02)
2019-07-30 20:32:55 +03:00
Ell
b72aad57f2 app: remove gimp_gegl_rectangle_align_to_tile_grid()
... and replace it with gegl_rectangle_align_to_buffer().

(cherry picked from commit ab94251ae9)
2019-07-30 20:32:54 +03:00
Ell
fc5a641d2e app: use longer iteration inteval (= bigger chunks) when applyng an op
In gimp_gegl_apply_[cached_]operation(), use a longer iteration
interval (resulying in bigger chunks) when processing the op, than
the iteration interval used for rendering the projection.  In
particular, use an even longer interval when processing area
filters, since their may be particularly sensitive to the chunk
size (see, for example, issue #3711).  Likewise, use the asme
longer interval when not showing progress indication, since we
don't need to stay responsive in this case (but don't avoid
chunking altogether, to reduce the space required for intermediate
results).

This allows us to process an op faster when committing a filter,
while still remaining responsive (if overall slower) during
preview.

(cherry picked from commit 5a500b4a12)
2019-07-28 12:10:29 +03:00
Ell
1e06f5df5c app: add gimp_gegl_node_is_area_filter_operation()
... which determines if a node is an area filter operation.  If the
node is a meta op, we conservatively return TRUE, as it may involve
an area-filter op.

(cherry picked from commit f6c4e4912a)
2019-07-28 12:10:29 +03:00
a65042aebf Issue #3512 - feather selection doesn't work at edges of images
Add a "gboolean edge_lock" parameter to GimpChannel::feather() and a
"Selected areas continue outside the image" toggle to the "Feather
Selection" dialog, just like they exist for shrink selection and
border selection. At the end, convert the boolean to the right abyss
policy for gegl:gaussian-blur.

(cherry picked from commit aace6b179b)
2019-06-16 16:55:03 +02:00
Ell
92bec259ac app: add support for offset buffers in gimp_gegl_apply_[cached_]operation()
In gimp_gegl_apply_[cached_]operation(), add support for output
buffers whose extent's top-left corner is not (0, 0).  This is
needed by the previous commit.

(cherry picked from commit a6393e6c55)
2019-05-29 05:39:03 -04:00
Ell
3868733ea3 app: add gimp_gegl_create_transform_node()
... which takes a GimpMatrix3, and returns a corresponding
gegl:transform node.

(cherry picked from commit 3895dc07a9)
2019-05-29 05:26:54 -04:00
Ell
7313686192 app: disregard composite space in non-union alpha-only layer modes
In gimp_layer_mode_get_format(), disregard the requested composite
space when selecting the format, if the input layer mode is alpha-
only, and the requested composite mode is not UNION, since, in this
case, the layer mode doesn't combine the layer/backdrop colors, and
rather only modifies the alpha of one of them.  This allows us to
use the preferred format, avoiding gamma conversion.

This particularly improves the performance of the Eraser tool in
perceptual images.

(cherry picked from commit a5962e4049)
2019-05-24 01:43:26 -04:00
Ell
3e2738e944 app: in gimp-gegl-nodes, set underlying operation
In the vairous gimp_gegl_create_foo_node() functions, set the
parent node's underlying operation node, so that
gimp_gegl_apply_cached_operation() avoids duplicating the source
buffer when applying these nodes (all underlying operations are
currently point ops.)

(cherry picked from commit 928e5957e3)
2019-04-30 14:32:21 -04:00
Ell
b5b5d71708 app: use underlying operation in gimp_gegl_apply_cached_operation()
In gimp_gegl_apply_cached_operation(), use the underlying
operation, as returned from
gimp_gegl_node_get_underlying_operation(), for testing whether the
operation is a point operation, for the purpose of avoiding
duplicating the input buffer.  Likewise, avoid duplicating the
buffer when the underlying operation is a source operation.

(cherry picked from commit 213b126c6e)
2019-03-27 15:48:19 -04:00
Ell
5e212fe0dd app: add gimp_gegl_node_{set,get}_underlying_oepration()
... which allow setting/getting the "underlying operation" node of
a graph node.  For example, GimpDrawableFilter constructs a complex
graph around a given operation node, which would be the underlying
operation of the graph.  This allows querying the properties of the
underlying operation, given only the graph.

In recursive cases, gimp_gegl_node_get_underlying_operation()
returns the most-nested underlying operation; when no underlying
operation has been set, gimp_gegl_node_get_underlying_operation()
returns the input node.

(cherry picked from commit eb5e473665)
2019-03-27 15:48:17 -04:00
Ell
3518ab9197 app: add gimp_gegl_node_is_source_operation()
... which determines if a node is a source operation.

(cherry picked from commit ff13e55c16)
2019-03-27 15:47:39 -04:00
Ell
269f2ca0fc app: skip cache and format conversion when merging a drawable filter
In gimp_drawable_merge_filter(), disable the filter applicator's
cache and output-format conversion nodes before processing the
uncached region of the filter, so that the result is written
directly to the drawable's buffer.

(cherry picked from commit 733a6ec01c)
2019-03-25 09:02:31 -04:00
Ell
fef2c3423a app: small fix to gimp_gegl_mask_combine_ellipse_rect()
(cherry picked from commit d4689441fe)
2019-03-24 14:45:59 -04:00
Ell
fa79923d4b app: improve gimp_gegl_mask_combine_buffer()
Simplify code, use gimp_gegl_buffer_copy() for CHANNEL_OP_REPLACE
when possible, improve value clipping, and parallelize processing.

(cherry picked from commit a227c8e94d)
2019-03-20 16:27:55 -04:00
Ell
9b76ea070d app: improve gimp_gegl_mask_combine_ellipse[_rect]()
Improve gimp_gegl_mask_combine_ellipse_rect() -- the funciton
responsible for rendering ellipse/rounded-rectangle selections.

Most notably, this commit significantly improves the function's
performance, by identifying whole tiles, whole rows, or parts of a
row, that are fully inside, or fully outside, the ellipse, and
filling them in bulk, instead of calculating the anti-aliasing
value at each pixel, which is now only done along the
circumference.

This commit also improves anti-aliasing, by more accurately
approximating the distance from a pixel to the ellipse, and by
normalizing the distance according to the pixel's cross-section
length in the direction of the said point.  In particular, we
guarantee that pixels that are fully inside/outside the ellipse
have a value of 1/0, respectively, facilitating the aforementioned
optimization.

Additionally, this commit fixes various edge cases where several
primitives coincide at a single pixel (in the rounded-rectangle
case), adds support for CHANNEL_OP_INTERSECT, and parallelizes
processing.

(cherry picked from commit 1044342393)
2019-03-20 16:27:55 -04:00
Ell
d0a3d81c4a app: improve gimp_gegl_mask_combine_rect()
Simplify the code, and add support for CHANNEL_OP_INTERSECT.

(cherry picked from commit 8a6e1c907d)
2019-03-20 16:27:55 -04:00
Ell
15e8b53f0c app: convert gimp-gegl-mask-combine to C++
... in preparation for next commits.

(cherry picked from commit 5198d3c32d)
2019-03-20 16:27:55 -04:00
Ell
2a2ad4324d app: add gimp_babl_format_change_{component_type,linear}()
... which change a format's component-type/TRC, without otherwise
affecting it.
2019-03-20 16:27:55 -04:00
Ell
5c70b827d2 app: add gimp_babl_is_bounded()
... which takes a GimpPrecision, and determines if its values are
bounded to the [0,1] range (which is currently only true for
integer precisions).

(cherry picked from commit d7f12c9d26)
2019-03-20 16:27:55 -04:00
Ell
d918502aac app: use gimp_gegl_buffer_copy() in various places
... instead of gegl_buffer_copy().  The former parallelizes the
format conversion.

(cherry picked from commit bb7f61c919)
2019-03-06 06:00:10 -05:00
Ell
3f1e91fa0b app: in gimp_gegl_create_flatten_node(), explicitly set color node format
In gimp_gegl_create_flatten_node(), explicitly set the output
format of the background gegl:color node according to the composite
space, so that no conversion is required during compositing.

(cherry picked from commit ebf2c2fef1)
2019-02-25 11:31:03 -05:00
Ell
83552620eb app: in gimp_gegl_apply_cached_operation(), don't dup src buffer for point ops
In gimp_gegl_apply_cached_operation(), when the source and
destination buffers are the same, avoid duplicating the source
buffer when the applied operation is a point operation, since
applying it in chunks from/to the same buffer is not a problem in
this case.

(cherry picked from commit 0d21f2469b)
2019-02-15 12:40:12 -05:00
Ell
bd67478b49 app: add gimp_gegl_node_is_point_operation()
... which takes a GeglNode, and determines if the associated
operation is a point operation.

Use in GimpFilterTool, instead of performing the same check
manually.

(cherry picked from commit 918f2e75bd)
2019-02-15 12:40:11 -05:00
Ell
f844965455 app: remove gimp_gegl_replace()
Remove gimp_gegl_replace(), which is not used anywhere since the
last commit.  It's redundant with the rest of our compositing code,
in particular, gimp:replace and gimp:mask-components.

(cherry picked from commit d2f8413173)
2019-02-14 11:05:20 -05:00
Ell
f5e652d762 app, pdb: use compat formats for brushes/patterns in plug-ins
Plug-ins are not prepared to handle high-precision brushes/
patterns, even when they're otherwise aware of high-precision
drawables, so make sure to always use compat formats when
communicating brush/pattern data to plug-ins.

Allowing plug-ins to handle high-precision brush/pattern data would
require some additional API.

(cherry picked from commit 82c449496e)
2019-02-07 09:19:27 -05:00
Ell
aa0df19af2 app: in gimp_gegl_apply_cached_operation(), s/cancellable/cancelable/
To align gimp-2-10 with master, and fix commit
50dc4571cb.
2019-01-12 05:11:47 -05:00
Ell
bb4b1e3f1f app: in gimp_tile_handler_validate_buffer_copy(), temporarily remove source handler
In gimp_tile_handler_validate_buffer_copy(), temporarily remove the
source buffer's validate handler, is exists, so that the subsequent
gegl_buffer_copy() can use fast tile copying, using the TILE_COPY
command.  GEGL currently only uses TILE_COPY when the source buffer
doesn't have any user-provided tile handlers.

(cherry picked from commit f4750a0ae7)
2019-01-12 04:54:18 -05:00
Ell
50dc4571cb 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.

(cherry picked from commit 4110f7b7b1)
2019-01-12 04:54:16 -05:00
Ell
e666041d72 app: in GimpTileHandlerValidate, avoid fetching/copying whole tiles
In GimpTileHandlerValidate, when rendering a whole tile in respone
to a TILE_GET command, use gegl_tile_handler_get_tile() to get the
tile without preserving its data, so that we avoid unnecessarily
fetching the tile from storage, or copying its data during
uncloning.

(cherry picked from commit 78ed038fca)
2019-01-02 07:41:44 -05:00