Skip to content

Improvements to mask distort efficiency via incremental caching and reduced malloc/free cycles.#20729

Open
masterpiga wants to merge 1 commit intodarktable-org:masterfrom
masterpiga:mask_distortion
Open

Improvements to mask distort efficiency via incremental caching and reduced malloc/free cycles.#20729
masterpiga wants to merge 1 commit intodarktable-org:masterfrom
masterpiga:mask_distortion

Conversation

@masterpiga
Copy link
Copy Markdown
Contributor

@masterpiga masterpiga commented Apr 2, 2026

In the discussion of #20712 it was brought to my attention that a clear area for efficiency improvements in the pixelpipe would be mask distorts. @jenshannoschwalm @TurboGit

Co-authored with Claude.

Key efficiency gains:

  1. N detail mask consumers: no longer each re-distort from demosaic — downstream modules start from the nearest cached checkpoint
  2. No per-step alloc/free: two ping-pong buffers alternate, only resized when needed
  3. Hash-based staleness: caches are automatically skipped when module params change, no explicit invalidation plumbing needed

List of changes

pixelpipe_hb.h

  • Added dt_dev_distorted_mask_cache_t struct — holds cached distorted mask data, ROI, and hash at geometric module boundaries
  • Added detail_mask_cache and raster_mask_cache fields to dt_dev_pixelpipe_iop_t — per-piece cache slots
  • Added mask_distort_buf[2] and mask_distort_buf_size[2] to dt_dev_pixelpipe_t — reusable ping-pong buffers

pixelpipe_hb.c

  • Ping-pong helpers: _ensure_distort_buf() lazily grows buffers, _free_distort_bufs() cleans up
  • Hash functions: _detail_mask_cache_hash() and _raster_mask_cache_hash() compute invalidation-aware hashes combining source identity + cumulative pipe state
  • Cache update helpers: _update_detail_mask_cache(), _update_raster_mask_cache(), _clear_piece_mask_caches()
  • Refactored dt_dev_distort_detail_mask(): Searches backward from target for nearest valid cached intermediate result, walks forward from there using ping-pong buffers, stores results at each geometric boundary
  • Refactored dt_dev_get_raster_mask(): Same backward-search + ping-pong + caching pattern for raster masks
  • Init/cleanup: Ping-pong buffers initialized in init_cached(), freed in cleanup(). Per-piece caches cleaned in cleanup_nodes()
  • Invalidation: dt_dev_clear_scharr_mask() now clears all per-piece mask caches. Hash-based invalidation handles param changes naturally

develop.c

Fixed ABBA deadlock.

dt_dev_undo_end_record() (which raises DT_SIGNAL_DEVELOP_HISTORY_CHANGE) is moved to after the history_mutex unlock in _dev_add_history_item. Signal handlers triggered by that signal can call dt_control_get_mouse_over_id, which acquires global_mutex — doing so without holding history_mutex eliminates the inversion.

dt_dev_zoom_move is reverted to its original lock order (global_mutex → history_mutex), consistent with dt_dev_get_viewport_paramsdt_dev_distort_transform_plus.

@TurboGit TurboGit added feature: enhancement current features to improve priority: low core features work as expected, only secondary/optional features don't difficulty: hard big changes across different parts of the code base scope: performance doing everything the same but faster release notes: pending ai:generated labels Apr 2, 2026
@TurboGit TurboGit added this to the 5.6 milestone Apr 2, 2026
Copy link
Copy Markdown
Member

@TurboGit TurboGit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After activating lens correction module, try enabling another module (liquify in my case) and you'll see Darktable freeze.

Via incremental caching and reduced malloc/free cycles.
@masterpiga
Copy link
Copy Markdown
Contributor Author

Thanks, @TurboGit, PTAL. The fix for the deadlock introduced another deadlock. Can you break it again? 😅

@masterpiga masterpiga requested a review from TurboGit April 4, 2026 09:26
@TurboGit
Copy link
Copy Markdown
Member

TurboGit commented Apr 4, 2026

@masterpiga : How to best test this? In other word the best way to have a slow process with current master and check speed improvement the new version?

@jenshannoschwalm
Copy link
Copy Markdown
Collaborator

  1. For performance we have to test interactive usage while using plenty of masks that are generated early in the pipe.

For correctness:
2. Rastermasks must be stable even if the module is repositioned in the pipe.
3. Changing blending parameters in modules.
4. Details mask is a special case.
5. Distorting masks via crop/ashift/liquify/retouch or the expanding modules.

-d pipe will likely be sufficient, maybe masks too. The verbose switch might also be helping.
Interesting would be the mask distorting reports.

What happens when using space bar and coming back later?

Cache cleared when doing stuff via lighttable like orientation?

Haven't looked into code or any testing yet. We want to ask @s7habo, he knows how to stress-test masking stuff.

@TurboGit
Copy link
Copy Markdown
Member

TurboGit commented Apr 4, 2026

@masterpiga : I'm sad, I cannot break it :(

So it works, it feels fast but I'll let @s7habo test too.

My test has included at least one picture with lens correction, perspective correction, liquify and retouch, all together.

@jenshannoschwalm
Copy link
Copy Markdown
Collaborator

I'm sad, I cannot break it :(

Pascal, i'll do my very best being a bad-boy tomorrow :-)

@masterpiga
Copy link
Copy Markdown
Contributor Author

@masterpiga : I'm sad, I cannot break it :(

Awwww

How to best test this?

I was hoping that you had some kind of monster image specifically for mask testing. I basically did as you did: started editing images, adding a bunch of distortions and masks on top. I couldn't find any obvious issue but I am sure that there are infinite code paths that I did not hit.

Pascal, i'll do my very best being a bad-boy tomorrow :-)

Yes, please :)

@QorStorm
Copy link
Copy Markdown

QorStorm commented Apr 4, 2026

@masterpiga

Perhaps this will be of help to you?

https://darktable.info/en/system-ui-2/performance-analysis/dt-real-time-monitor/

If you need any further features, just let me know.

@jenshannoschwalm
Copy link
Copy Markdown
Collaborator

Yes, please :)

I did a first round of testing and indeed i couldn't break it (yet).

But - unfortunately i couldn't yet spot any cache hit of details or raster masks. Not sure if that is either due to a) looging insufficiacy or b) we invalidate pipecache data where we don't have to any longer with your pr.

Give me a few more days :-)

@s7habo
Copy link
Copy Markdown

s7habo commented Apr 5, 2026

When this appears in the master branch, I'd be happy to test it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:generated difficulty: hard big changes across different parts of the code base feature: enhancement current features to improve priority: low core features work as expected, only secondary/optional features don't release notes: pending scope: performance doing everything the same but faster

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants