1. 03 Sep, 2017 1 commit
  2. 02 Sep, 2017 2 commits
  3. 31 Aug, 2017 1 commit
    • Ell's avatar
      app: add dedicated op for pass through mode, with shortcuts · 5effdd03
      Ell authored
      Pass through mode uses the same compositing logic as REPLACE mode,
      however, it's a special case of REPLACE, where the layer is already
      composited against the backdrop.  This allows us to take a few
      shortcuts that aren't generally applicable to REPLACE mode.
      Add a dedicated op class for pass through mode, derived from the
      REPLACE mode op, implementing these shortcuts.
  4. 30 Aug, 2017 1 commit
  5. 28 Aug, 2017 2 commits
  6. 27 Aug, 2017 1 commit
    • Ell's avatar
      */Makefile.am: work around a bug in the new glib-genmarshal · 0ef3795f
      Ell authored
      glib-genmarshal was rewritten in glib 2.53.4, and as of now (2.53.6)
      it has a bug where it unconditionally generates marshaler bodies,
      even for standard marshalers, even with --stdinc.  This causes
      libgimpwidgets to define and export g_cclosure_marshal_VOID__INT()
      and g_cclosure_marshal_VOID__OBJECT(), which upsets defcheck, and
      breaks the build.
      Work around this for now by using --header --body when generating
      the marshal.c files, which includes the prototypes in the source,
      instead of including the header ourselves.  This is the only code
      path where the new glib-genmarshal doesn't generate bodies for
      standard marshalers.  Note, however, that this usage is deprecated,
      so we'll probably want to change it back once it's fixed.
  7. 24 Aug, 2017 2 commits
  8. 21 Aug, 2017 1 commit
    • Michael Natterer's avatar
      Move the new "default_new_layer_mode" APIs to the image... · e16c8a23
      Michael Natterer authored
      ...in both the core and libgimp.
      Images now know what the default mode for new layers is:
      - NORMAL for empty images
      - NORMAL for images with any non-legacy layer
      - NORMAL_LEGAVY for images with only legacy layers
      This changes behavior when layers are created from the UI, but *also*
      when created by plug-ins (yes there is a compat issue here):
      - Most (all?) single-layer file importers now create NORMAL layers
      - Screenshot, Webpage etc also create NORMAL layers
      Scripts that create images from scratch (logos etc) should not be
      affected because they usually have NORMAL_LEGACY hardcoded.
      3rd party plug-ins and scripts will also behave old-style unless they
      get ported to gimp_image_get_default_new_layer_mode().
  9. 20 Aug, 2017 7 commits
  10. 19 Aug, 2017 4 commits
  11. 18 Aug, 2017 1 commit
    • Michael Natterer's avatar
      Bug 783755 - Smudge should blend the smudged colors using linear RGB · 94c6bb46
      Michael Natterer authored
      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.
  12. 17 Aug, 2017 2 commits
    • Ell's avatar
      app: move libappgegl's SSE2 bits to a separate library · 64ade977
      Ell authored
      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.
    • Ell's avatar
      app: layer mode code shuffling · 71bbd88e
      Ell authored
      Commit 3635cf04 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
      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,
      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
      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
  13. 15 Aug, 2017 4 commits
  14. 12 Aug, 2017 1 commit
  15. 08 Aug, 2017 10 commits
    • Michael Natterer's avatar
      app: default the number of threads used to g_get_num_processors() · 26a238c5
      Michael Natterer authored
      Let the bug reporting begin.
    • Ell's avatar
      app: adapt gimp_image_merge_layers() to handle pass-through groups ... · 67fc418c
      Ell authored
      ... 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
    • Ell's avatar
      app: move bottom-layer special casing to GimpOperationLayerMode · 3635cf04
      Ell authored
      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.
    • Ell's avatar
      app: implement {begin,end}_render() for GimpGroupLayer · 1ca1e15d
      Ell authored
      Use them to connect/disconnect the stack graph when the group is
      in pass-through mode.
    • Ell's avatar
      app: use {begin,end}_render() and GimpTileHandlerProjectable ... · 1c686173
      Ell authored
      ... in GimpProjection and gimp_display_shell_render() (the latter
      is not really necessary, but whatever.)
    • Ell's avatar
      app: add GimpTileHandlerProjectable · 426bc371
      Ell authored
      GimpTileHandlerProjectable is similar to GimpTileHandlerValidate,
      except that it calls {begin,end}_render() on its associated
      projectable before validating.
    • Ell's avatar
      app: add gimp_projectable_{begin,end}_render() · f0aec02d
      Ell authored
      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.
    • Ell's avatar
      app: handle excludes_backdrop in GimpGroupLayer · dc1d61ff
      Ell authored
      When any of the children of a pass-through group excludes its
      backdrop, the group itself should exclude the backdrop too.  Override
      get_excludes_backdrop() to follow this logic, and call
      update_excludes_backdrop() when this condition might change.
      Note that we always composite pass-through groups using src-over mode,
      so to actually hide the backdrop, we need to disconnect it from the
      group's mode node's input pad (and reconnect it, when the backdrop is
      no longer hidden).
    • Ell's avatar
      app: implement pass-through mode in GimpGroupLayer · 10371ec2
      Ell authored
      Override GimpDrawable::get_source_node() for GimpGroupLayer.  Use
      a node that contains both the drawable's buffer-source node, and the
      layer stack's graph node.  Choose which one of these to connect to
      the source node's output based on the group's layer mode: the stack
      graph for pass-through mode, and the buffer-source node for all the
      When in pass-through mode, connect the source node's input (which
      receives the backdrop) to the stack graph's input.  Keep maintaining
      the projection in pass-through mode.  ATM, the projection uses the
      same graph as the source node, so it's rendered against the group's
      backdrop -- we don't want that.  The next few commits fix it.
      Update the group's drawable directly upon filter stack update in
      pass-though mode, because the group's graph doesn't go through the
      TODO: if any of the group's children (or a child of a nested pass-
      through group, etc.) uses dst-atop/src-in, this needs special
    • Ell's avatar
      app: connect layer backdrop to source node's input · ac319021
      Ell authored
      Make sure the input of the layer's filter node is connected to its
      source node (when it has an input pad), so that, once we implement
      pass-though mode, the group's source node can see the backdrop.