gimp_layer_update_mode_node(): when showing the mask, set mode to
NORMAL, and make sure that the composite space is PERCEPTUAL for
LEGACY layers, and LINEAR (or whatever is chosen in layer attibutes)
otherwise.
this commit changes just those which make no difference to
functionality: property and object member defaults that get overridden
anyway, return values of g_return_val_if_fail(), some other stuff.
Looked a bit deeper into heal: while I didn't try to understand what
it's actually doing, this is strange: there is a comment that says
that healing should done in perceptual space, and the code uses
R'G'B'A float (at least it completely did before the last commit).
On the other hand, the code adds and subtracts temporary buffers,
which screams "gamma artifacts" unless done in linear space.
This commit changes everything to use linear float buffers,
and removes the comment. It "looks" right to me now, please test.
Split libappgegl into libappgegl-generic and libappgegl-sse2, and
move the SSE2 code (part of the newly added smudge code) to the
latter, so that the rest of the code can be compiled without SSE2
compiler flags. This allows building GIMP with SSE acceleration
enabled, while running the resulting binary on a target with no
SSE accelration.
Commit 3635cf04ab moved the special
handling of bottom-layer compositing to GimpOperationLayerMode.
This required giving the op more control over the process()
function of its subclasses. As a temporary workaround, the commit
bypassed the subclasses entirely, using "gimp:layer-mode" for all
modes. This is the reckoning :)
Add a process() virtual function to GimpOperationLayerMode, which
its subclasses should override instead of
GeglOperationPointComposer3's process() functions. Reinstate the
subclasses (by returning the correct op in
gimp_layer_mode_get_oepration()), and have them override this
function.
Improve the way gimp_operation_layer_mode_process() dispatches to
the actual process function, to slightly lower its overhead and
fix some thread-safety issues.
Remove the "function" field of the layer-mode info array, and have
gimp_layer_mode_get_function() return the
GimpOperationLayerMode::process() function of the corresponding
op's class (caching the result, to keep it cheap.) This reduces
redundancy, allows us to make the ops' process() functions private,
and simplifies SSE dispatching (only used by NORMAL mode,
currently.)
Move the blend and composite functions of the non-specialized
layer modes to gimpoperationlayermode-{blend,composite}.[hc],
respectively, to improve code organization.
Move the SSE2 composite functions to a separate file, so that they
can be built as part of libapplayermodes_sse2, allowing
libapplayermodes to be built without SSE2 compiler flags. This
allows building GIMP with SSE acceleration enabled, while running
the resulting binary on a target with no SSE accelration.
Add a "blend_function" field to the layer-mode info array, and use
it to specify the blend function for the non-specialized modes.
This replaces the separate switch() statement that we used
previously.
Remove the "affected_region" field of the layer-mode info array.
We don't need it anymore, since we can go back to using
GimpOperationLayerMode's virtual get_affected_region() function.
Last but not least, a bunch of code cleanups and consistency
adjustments.
...protocol calls.
Some calls are waiting for answers, for instance plugin procedures, and
tiles which expects data and acknoledgement.
This would result in error messages such as:
"expected tile ack and received: 5" (5 is GP_PROC_RUN)
Typically because a thread would run a procedure while another would
receive tiles.
Paint tools in straight line mode (shift click) will now display the
angle in status bar. Angle 0 is considered as the horizontal line from
left to right, and angle is measured counterclockwise from there, which
is the most common convention.
Use GIMP_LAYER_MODE_NORMAL (not NORMAL_LEGACY) when falling back from
gimp_paint_core_replace() to gimp_paint_core_paste() for layers
without alpha. Adapt the format of the used paint buffers accordingly.
Initialize GimpColorHexEntry's text (to "000000") in constructed(),
instead of init(). Otherwise, it gets cleared during construction,
so that color entries set initially to black are empty.
Use SRC_OVER, instead of SRC_ATOP, as the composite mode for all
layers (or use AUTO, when it results in SRC_OVER), to match
Photoshop's behavior. Use RGB_PERCEPTUAL as the blend and composite
space, instead of AUTO, whose interpretation depends on the specific
layer mode, to match Photoshop's behavior for RGB images. Use NORMAL
mode, instead of NORMAL_LEGACY, with the above properties, for normal
layers, for consistency with the other layer modes, which don't (and,
indeed, can't) use the legacy modes.
The section-divider (lsct) layer resource may contain blend mode
information, which apparently overrides the blend mode specified in
the layer record. When reading such a resource, replace the layer's
blend mode with the one specified by the resource.
It seems like pass-through group layers specify normal mode in their
layer record, but pass-through in their section-divider resource, so
this commit allows correctly loading such layers.
... and fix flatten-image along the way. *And* do some cleanup.
Currently, gimp_image_merge_layers() combines the layers on its own,
one by one. This is incompatible with pass-through groups, because
the group's buffer is rendered independently of its backdrop, while
we need to take the backdrop into account when mergeing the group.
Instead, render the subgraph of the parent graph, corresponding to
the set of merged layers, directly into the new layer. Since the
layers we merge are always visible and continuous, all we need is a
minor massage to the parent graph to make it work. This takes care
of pass-through groups intrinsicly.
This commit also changes the behavior of flatten-image: Currently,
the flattened layers are rendered directly on top of the opaque
background, which can make previously-hidden areas (due to layers
using composite modes other than src-over, or legacy layer modes)
visible. This is almost certainly not desirable.
Instead, construct the graph such that the flattened layers are
combined with the background only after being merged with one
another.
GimpFilter's is_last_node field only reflects the item's position
within the parent stack. When a layer is contained in a pass-
through group, it can be the last layer of the group, while not
being the last layer in the graph as a whole (paticularly, if
there are visible layers below the group). In fact, when we have
nested pass-through groups, whether or not a layer is the last
node depends on which group we're considering as the root (since
we exclude the backdrop from the group's projection, resulting in
different graphs for different groups).
Instead of rolling our own graph traversal, just move the relevant
logic to GimpOperationLayerMode, and let GEGL do the work for us.
At processing time, we can tell if we're the last node by checking
if we have any input.
For this to work, GimpOperationLayerMode's process() function needs
to have control over what's going on. Replace the derived op
classes, which override process(), with a call to the layer mode's
function (as per gimp_layer_mode_get_function()) in
GimpOperationLayerMode's process() function. (Well, actually, this
commit keeps the ops around, and just hacks around them in
gimp_layer_mode_get_operation(), because laziness :P)
Keep using the layer's is_last_node property to do the invalidation.
GimpTileHandlerProjectable is similar to GimpTileHandlerValidate,
except that it calls {begin,end}_render() on its associated
projectable before validating.
In pass-through mode, the group layer-stack's input is connected to
the backdrop. However, when rendering the group's projection, we
want to render the stack independently of the backdrop.
Unfortunately, we can't use the stack's graph as a subgraph of two
different graphs.
To work around that, the next few commits add a mechanism for a
projectable to be notified before and after its graph is being
rendered. We use this mechanism to disconnect the stack's graph
from the backdrop before rendering the projection, and reconnect
it afterwards. Yep, it's ugly, but it's better than having to
maintain n copies of (each node of) the graph (each nesting level
requires an extra copy.)
This commit adds {begin,end}_render() functions to GimpProjectable.
These functions should be called right before/after rendering the
projectable's graph.