1. 31 Aug, 2018 4 commits
  2. 30 Aug, 2018 1 commit
    • Ell's avatar
      long-shadow: fix accelerating fading-fixed-length shadow value calculation · 828597e3
      Ell authored
      In shadow_[collation_]value(), don't scale the current shadow value
      by the fade-curve LUT when the value is 0, and just return 0
      directly.  When the value is 0, the shadow is "inactive" and its
      y-coordinate is meaningless, which can result in an out-of-bounds
      access to the LUT.
      828597e3
  3. 29 Aug, 2018 1 commit
    • Ell's avatar
      long-shadow: add midpoint parameter to finite fading styles · 74a673cf
      Ell authored
      Add a "midpoint-rel" property, which acts as the fade midpoint
      parameter, instead of the "midpoint" property, for the fadinig-
      fixed-length and fading-fixed-rate styles.  Unlike the latter,
      "midpoint-rel" is specified as a factor of the shadow length,
      instead of as an absolute distance.  When using GUM, as GIMP does,
      the label of both properties is "midpoint", so they appear to be a
      single property.
      
      The midpoint value determines the gamma curve to use as the drop-
      off function of the shadow.  When it is 0.5, the drop-off is
      linear, as before; when it is < 0.5, the drop-off decelerates; and,
      when it is > 0.5, the drop-off accelerates.
      
      Note that in the fixed-rate style, higher midpoint values result in
      darker but *shorter* shadows, and a 1.0 midpoint results in no
      shadow at all.
      74a673cf
  4. 26 Aug, 2018 1 commit
  5. 22 Aug, 2018 4 commits
    • Ell's avatar
      color-overlay: fix output for semi-transparent color parameters · dc32b352
      Ell authored
      Premultiply the color-parameter components by the alpha before
      processing.  Got lost during space invasion.
      dc32b352
    • Hussam Al-Tayeb's avatar
      c1c3541c
    • Ell's avatar
      long-shadow: add "fading-fixed-length" and "fading-fixed-rate" styles · 7febad8a
      Ell authored
      Add two finite fading shadow styles: "fading-fixed-length", and
      "fading-fixed-rate".  Both styles produce the same result for
      fully-opaque input pixels, but diverge for partially-transparent
      pixels.  "fading-fixed-length" produces a shadow of the same length
      regardless of the input pixel's alpha value, such that the shadow
      fading rate of pixels with lower alpha values is lower, while
      "fading-fixed-rate" produces a shadow with a fixed fade rate,
      regardless of the input pixel's alpha value, such that the shadow
      of pixels with lower alpha values is shorter.
      
      Currently, finite fading shadows don't support user-defined
      midpoint values, and their drop-off curve is always linear (as if
      the midpoint were 0.5, in relative terms).  Nonlinear fixed-length
      fading shadows break some of the algorithm's invariants, and
      addressing that would increase the computational complexity.
      7febad8a
    • Ell's avatar
      text: fix bounding box when wrap-height is specified · 525f9ef0
      Ell authored
      Take the "vertical-wrap" and "vertical-alignment" properties into
      account when deciding if the bounding box needs to be recalculated.
      525f9ef0
  6. 21 Aug, 2018 1 commit
  7. 19 Aug, 2018 8 commits
    • Ell's avatar
      buffer: use gegl_tile_backend_command() in tile backends · 35806a4e
      Ell authored
      In all tile-backend command handlers, forward unhandled commands to
      gegl_tile_backend_command(), instead of asserting that the command
      is within range.  See the previous commit for a rationale.
      35806a4e
    • Ell's avatar
      buffer: add gegl_tile_backend_command(); pre-0.4.10 compatibility · 30047e65
      Ell authored
      Tile backends currently assert in their command handlers that the
      input command is between 0 and GEGL_TILE_LAST_COMMAND (this is true
      for the built-in backends, but we can assume it's also true for
      custom backends.)  This prevents us from adding new tile commands
      without breaking the ABI.
      
      Instead, add a new gegl_tile_backend_command() function, which acts
      as a default command handler for tile backends, and to which their
      handlers should forward unhandled commands (this function currently
      simply performs the range check for the command -- however, against
      the GEGL_TILE_LAST_COMMAND value of the runtime GEGL -- and returns
      NULL; we can add differet default behaviors for different commands
      as necessary.)
      
      In order to remain backward compatible with tile backends compiled
      against older versions of GEGL, which still contain the above
      assertion, we replace the subclass's command handler with a thunk
      upon construction, which tests whether the original handler
      forwards unhandled commands to gegl_tile_backend_command(), and re-
      replaces the handler with either the original handler if it does,
      or a compatibility shim, which only forwards pre-0.4.10 commands to
      the original handler, if it doesn't.
      30047e65
    • Ell's avatar
      buffer, stats: limit maximal pending data size in the swap backend queue · 64021786
      Ell authored
      In GeglTileBackendSwap, limit the maximal data size allowed to be
      pending in the queue at any given time.  The limit is currently set
      to 10% of the cache size.  If data is attempted to be written to
      the swap while the queue is full, the operation blocks until the
      queued data size drops below the limit.
      
      Add new "swap-queue-total", "swap-queue-full", and "swap-queue-
      stalls" properties to GeglStats, reporting the total queued data
      size, whether or not the queue is full, and the number of times a
      write operation has been blocked due to a full queue, respectively.
      64021786
    • Ell's avatar
      buffer: implement TILE_COPY in the buffer backend · 04011ae6
      Ell authored
      In GeglTileBackendBuffer, implement the TILE_COPY command, by
      simply forwarding it to the underlying buffer (unless the
      underlying buffer has user-provided tile handlers, in which case we
      can't use TILE_COPY for the same reason as in gegl_buffer_copy()).
      04011ae6
    • Ell's avatar
      buffer, stats: implement TILE_COPY in the swap backend; cleanup; new stat · 185f4450
      Ell authored
      In GeglTileBackendSwap, implement the TILE_COPY command between a
      pair of swap backends, but decoupling swap data blocks,
      representing an allocated block in the common swap file, from swap
      entries, representing stored tiles in an individual swap backend.
      Have data blocks be ref-counted, such that each swap entry
      corresponds to a single data block, but each data block may be
      shared among multiple entries.  When copying a tile, we simply
      assign the data block of the source entry to the destination entry,
      and increment its reference count.  When modifying a tile, upon a
      TILE_SET command, if the corresponding data block isn't uniquely
      owned by the entry (i.e., if its ref-count is greater than 1), we
      allocate a new data block for the tile.
      
      Some all-around cleanup in gegl-tile-backend-swap.c.
      
      In GeglStats, add a "swap-total-uncloned" stat, analogous to
      "cache-total-uncloned", reporting the total size of the data that
      would have been stored in the swap, if each tile occupied a unique
      data block.
      185f4450
    • Ell's avatar
      buffer: implement TILE_COPY in the cache handler · e9dce12c
      Ell authored
      If the tile exists in the cache, we start by copying it directly to
      the destination.  Then, if the tile doesn't exist in the cache, or
      if it's already stored -- i.e., if it might exist in the backend in
      an up-to-date state -- we try letting the backend copy the tile as
      well, and, if this succeeds, we either mark the tile copied from
      the cache as stored, or void any existing tile in the destination
      cache.  The copy is considered successful if either the cache or
      the backend copied the tile.
      e9dce12c
    • Ell's avatar
      buffer: use TILE_COPY in gegl_buffer_copy() · 44c258bf
      Ell authored
      In gegl_buffer_copy(), use the TILE_COPY command, added in the
      previous commit, when copying tiles directly between the buffers,
      and fall back to a simple TILE_GET + cache_insert() if the
      TILE_COPY command fails.  See the previous commit for a rationale.
      
      We currently avoid this optimization for source buffers that have
      user-provided tile handlers, since they might interfere with the
      TILE_COPY mechanism.  See the comment in the code for more
      details.
      
      Additionally, lock/unlock the source buffer's tile-storage mutex
      before/after copying the entire set of tiles, and use an unlocked
      gegl_tile_source_get_tile() call to fetch the tiles, instead of
      locking the mutex once per tile.  In addition to being more
      efficient, this allows us to properly order the source/destination
      buffer locks, to avoid a potential deadlock when copying between
      two swapped pairs of buffers concurrently.
      44c258bf
    • Ell's avatar
      buffer: add GEGL_TILE_COPY tile-source command · c5045711
      Ell authored
      GEGL_TILE_COPY requests a tile source to copy a tile to a given
      destination buffer (or to the same buffer to which the tile source
      belongs), at given destination tile coordinates.  The tile source
      and the destination buffer are assumed to be tile-compatible (i.e.,
      having the same tile dimensions and format).  The tile source
      should return a boolean value, indicating whether the tile has been
      copied.
      
      This is mostly meant to be implemented by the cache handler, and by
      tile backends (the swap backend, in particular).  It allows
      backends to implement a cheap copy operation, avoiding the need to
      actually fetch the tile.  For example, at the moment, copying a
      swapped-out tile between two buffers, both of which are using the
      swap backend, requires reading the tile from disk into memory
      first, only to COW the result.  This might not be an issue if the
      same tile is known to be accessed shortly after, but when doing a
      tentative copy, usually of an entire buffer (as is done in GIMP in
      several cases), this incurs a very noticeable overhead.
      c5045711
  8. 18 Aug, 2018 4 commits
  9. 17 Aug, 2018 4 commits
  10. 16 Aug, 2018 3 commits
  11. 14 Aug, 2018 3 commits
    • Øyvind "pippin" Kolås's avatar
      configure: depend on babl 0.1.56 · 7ab21c10
      Øyvind "pippin" Kolås authored
      7ab21c10
    • Ell's avatar
      buffer: don't store empty tiles in the swap · f6b5b17a
      Ell authored
      In GeglTileBackendSwap, void any existing tile upon SETting an
      empty tile, instead of writing the empty tile data to disk.  The
      empty tile will be recreated by the empty-tile handler upon
      request.
      f6b5b17a
    • Ell's avatar
      buffer: always increase revision of duplicate tiles, even empty · 5a8c84e7
      Ell authored
      In gegl_tile_dup(), increate the revision of the newly-created
      duplicate tile unconditionally, even if it's empty, so that it gets
      stored.
      
      Instead of special-casing empty tiles in the above function, mark
      newly-craeted empty tiles as stored in the empty-tile handler.
      This way, newly-created empty tiles are not stored, but copied
      empty tiles are, since we might need them to replace outdated data
      in the tile backend.  Tile backends may, in turn, test for empty
      tiles upon a SET command, and drop the existing tile instead of
      storing the empty tile.
      
      Remove the now-unnecessary revision bump in gegl_buffer_copy().
      5a8c84e7
  12. 11 Aug, 2018 2 commits
    • Ell's avatar
      buffer: in GeglTileBackendSwap, move reused OP_DESTROY to the top · 3275239e
      Ell authored
      In gegl_tile_backend_swap_entry_destroy(), when reusing an existing
      queued op as an OP_DESTROY, move the op to the top of the queue, so
      that the corresponding storage is reclaimed before any pending
      WRITE ops.  This used to be the behavior before last commit, which
      accidentally removed it.
      3275239e
    • Ell's avatar
      buffer: fix potential race condition during tile-swap entry destruction · 4241b0fd
      Ell authored
      In gegl_tile_backend_swap_entry_destroy(), don't free the entry in
      the calling thread when it has a pending op in the queue, but no
      allocated storage, since the test for whether the entry has
      allocated storage introduces a race condition between the calling
      thread and the writer thread, where storage allocation happens.
      Instead, always convert the existing op to an OP_DESTROY.
      
      In particular, this could lead to a use-after-free and/or swap-
      space leak, if a TILE_SET command is issued for a tile while it is
      being written to the swap by the writer thread (after the
      corresponding OP_WRITE has been dequeued).  In this case, another
      OP_WRITE is pushed to the queue.  If the corresponding entry
      doesn't have storage allocated yet, and is then destroyed, the
      entry will be freed while the writer thread is still potentially
      using it while serving the earlier OP_WRITE, and the storage
      subsequently allocated for it will never be reclaimed.
      4241b0fd
  13. 10 Aug, 2018 2 commits
  14. 09 Aug, 2018 2 commits