Skip to content

Commit f98dab9

Browse files
authoredFeb 7, 2025··
Merge pull request #18362 from jenshannoschwalm/reverting_pipe_stuff_501
Reverting pipe stuff 501
2 parents 02d4239 + 98d2505 commit f98dab9

File tree

9 files changed

+84
-63
lines changed

9 files changed

+84
-63
lines changed
 

‎src/common/image.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -862,9 +862,9 @@ void dt_image_update_final_size(const dt_imgid_t imgid)
862862
dt_image_cache_write_release(darktable.image_cache, imgtmp, DT_IMAGE_CACHE_RELAXED);
863863
DT_CONTROL_SIGNAL_RAISE(DT_SIGNAL_METADATA_UPDATE);
864864
DT_CONTROL_SIGNAL_RAISE(DT_SIGNAL_DEVELOP_IMAGE_CHANGED);
865+
dt_print(DT_DEBUG_PIPE, "updated final size for ID=%i to %ix%i", imgid, ww, hh);
865866
}
866867
}
867-
dt_print(DT_DEBUG_PIPE, "[dt_image_update_final_size] for ID=%i, updated to %ix%i", imgid, ww, hh);
868868
}
869869

870870
gboolean dt_image_get_final_size(const dt_imgid_t imgid, int *width, int *height)

‎src/develop/develop.c

+8-5
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ void dt_dev_process_image_job(dt_develop_t *dev,
346346
dt_dev_pixelpipe_set_input(pipe, dev, (float *)buf.buf, buf.width, buf.height,
347347
port ? 1.0 : buf.iscale);
348348

349+
// We require calculation of pixelpipe dimensions via dt_dev_pixelpipe_change() in these cases
350+
const gboolean initial = pipe->loading || dev->image_force_reload || pipe->input_changed;
351+
349352
if(pipe->loading)
350353
{
351354
// init pixel pipeline
@@ -398,10 +401,10 @@ void dt_dev_process_image_job(dt_develop_t *dev,
398401
if(port == &dev->full)
399402
pipe->input_timestamp = dev->timestamp;
400403

401-
// dt_dev_pixelpipe_change() will clear the changed value
402-
const dt_dev_pixelpipe_change_t pipe_changed = pipe->changed;
403-
// this locks dev->history_mutex.
404-
dt_dev_pixelpipe_change(pipe, dev);
404+
const gboolean pipe_changed = pipe->changed != DT_DEV_PIPE_UNCHANGED;
405+
// dt_dev_pixelpipe_change() locks history mutex while syncing nodes and finally calculates dimensions
406+
if(pipe_changed || initial || (port && port->pipe->loading))
407+
dt_dev_pixelpipe_change(pipe, dev);
405408

406409
float scale = 1.0f;
407410
int window_width = G_MAXINT;
@@ -414,7 +417,7 @@ void dt_dev_process_image_job(dt_develop_t *dev,
414417
// if just changed to an image with a different aspect ratio or
415418
// altered image orientation, the prior zoom xy could now be beyond
416419
// the image boundary
417-
if(port->pipe->loading || pipe_changed != DT_DEV_PIPE_UNCHANGED)
420+
if(port->pipe->loading || pipe_changed)
418421
dt_dev_zoom_move(port, DT_ZOOM_MOVE, 0.0f, 0, 0.0f, 0.0f, TRUE);
419422

420423
// determine scale according to new dimensions

‎src/develop/pixelpipe_cache.c

+20-22
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
This file is part of darktable,
3-
Copyright (C) 2009-2025 darktable developers.
3+
Copyright (C) 2009-2024 darktable developers.
44
55
darktable is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -104,39 +104,37 @@ void dt_dev_pixelpipe_cache_cleanup(dt_dev_pixelpipe_t *pipe)
104104

105105
static dt_hash_t _dev_pixelpipe_cache_basichash(const dt_imgid_t imgid,
106106
dt_dev_pixelpipe_t *pipe,
107-
const int order)
107+
const int position)
108108
{
109109
/* What do we use for the basic hash
110110
1) imgid as all structures using the hash might possibly contain data from other images
111-
2) pipe->type as we want to keep status of fast mode included
112-
3) pipe->want_detail_mask makes sure old cachelines from before activating details are
111+
2) pipe->type for the cache it's important to keep status of fast mode included here
112+
also, we might use the hash also for different pipe.
113+
3) pipe->want_detail_mask make sure old cachelines from before activating details are
113114
not valid any more.
114-
Do we have to keep the roi of details mask? No, as that is always defined by roi_in
115+
Do we have to keep the roi of details mask? No as that is always defined by roi_in
115116
of the mask writing module (rawprepare or demosaic)
116-
4) The piece->hash of modules within the given limit excluding the skipped
117117
*/
118118
const uint32_t hashing_pipemode[3] = {(uint32_t)imgid,
119119
(uint32_t)pipe->type,
120120
(uint32_t)pipe->want_detail_mask };
121121
dt_hash_t hash = dt_hash(DT_INITHASH, &hashing_pipemode, sizeof(hashing_pipemode));
122122

123-
// go through all modules up to iop_order and compute a hash using the operation and params.
123+
// go through all modules up to position and compute a hash using the operation and params.
124124
GList *pieces = pipe->nodes;
125-
while(pieces)
125+
for(int k = 0; k < position && pieces; k++)
126126
{
127-
const dt_dev_pixelpipe_iop_t *piece = pieces->data;
128-
const dt_iop_module_t *module = piece->module;
129-
130-
if(module->iop_order > order) break;
131-
127+
dt_dev_pixelpipe_iop_t *piece = pieces->data;
128+
// As this runs through all pipe nodes - also the ones not commited -
129+
// we can safely avoid disabled modules/pieces
130+
const gboolean included = piece->module->enabled || piece->enabled;
132131
// don't take skipped modules into account
133-
const gboolean skipped = dt_iop_module_is_skipped(module->dev, module)
134-
&& (pipe->type & DT_DEV_PIXELPIPE_BASIC);
135-
136-
if(!skipped)
132+
const gboolean skipped = dt_iop_module_is_skipped(piece->module->dev, piece->module)
133+
&& (pipe->type & DT_DEV_PIXELPIPE_BASIC);
134+
if(!skipped && included)
137135
{
138136
hash = dt_hash(hash, &piece->hash, sizeof(piece->hash));
139-
if(module->request_color_pick != DT_REQUEST_COLORPICK_OFF)
137+
if(piece->module->request_color_pick != DT_REQUEST_COLORPICK_OFF)
140138
{
141139
if(darktable.lib->proxy.colorpicker.primary_sample->size == DT_LIB_COLORPICKER_SIZE_BOX)
142140
{
@@ -156,9 +154,9 @@ static dt_hash_t _dev_pixelpipe_cache_basichash(const dt_imgid_t imgid,
156154
dt_hash_t dt_dev_pixelpipe_cache_hash(const dt_imgid_t imgid,
157155
const dt_iop_roi_t *roi,
158156
dt_dev_pixelpipe_t *pipe,
159-
const int order)
157+
const int position)
160158
{
161-
dt_hash_t hash = _dev_pixelpipe_cache_basichash(imgid, pipe, order);
159+
dt_hash_t hash = _dev_pixelpipe_cache_basichash(imgid, pipe, position);
162160
// also include roi data
163161
// FIXME include full roi data in cachelines
164162
hash = dt_hash(hash, roi, sizeof(dt_iop_roi_t));
@@ -191,7 +189,7 @@ gboolean dt_dev_pixelpipe_cache_available(dt_dev_pixelpipe_t *pipe,
191189
// While looking for the oldest cacheline we always ignore the first two lines as they are used
192190
// for swapping buffers while in entries==DT_PIPECACHE_MIN or masking mode
193191
static int _get_oldest_cacheline(dt_dev_pixelpipe_cache_t *cache,
194-
const dt_dev_pixelpipe_cache_test_t mode)
192+
dt_dev_pixelpipe_cache_test_t mode)
195193
{
196194
// we never want the latest used cacheline! It was <= 0 and the weight has increased just now
197195
int age = 1;
@@ -241,7 +239,7 @@ static int _get_cacheline(dt_dev_pixelpipe_t *pipe)
241239

242240
// return TRUE in case of a hit
243241
static gboolean _get_by_hash(dt_dev_pixelpipe_t *pipe,
244-
const dt_iop_module_t *module,
242+
dt_iop_module_t *module,
245243
const dt_hash_t hash,
246244
const size_t size,
247245
void **data,

‎src/develop/pixelpipe_cache.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
This file is part of darktable,
3-
Copyright (C) 2009-2024 darktable developers.
3+
Copyright (C) 2009-2022 darktable developers.
44
55
darktable is free software: you can redistribute it and/or modify
66
it under the terms of the GNU General Public License as published by
@@ -65,9 +65,9 @@ typedef enum dt_dev_pixelpipe_cache_test_t
6565
gboolean dt_dev_pixelpipe_cache_init(struct dt_dev_pixelpipe_t *pipe, const int entries, const size_t size, const size_t limit);
6666
void dt_dev_pixelpipe_cache_cleanup(struct dt_dev_pixelpipe_t *pipe);
6767

68-
/** creates a hopefully unique hash from the complete module stack up to the modules iop_order, including current viewport. */
68+
/** creates a hopefully unique hash from the complete module stack up to the module-th, including current viewport. */
6969
dt_hash_t dt_dev_pixelpipe_cache_hash(const dt_imgid_t imgid, const struct dt_iop_roi_t *roi,
70-
struct dt_dev_pixelpipe_t *pipe, const int order);
70+
struct dt_dev_pixelpipe_t *pipe, const int position);
7171

7272
/** returns a float data buffer in 'data' for the given hash from the cache, dsc is updated too.
7373
If the hash does not match any cache line, use an old buffer or allocate a fresh one.

‎src/develop/pixelpipe_hb.c

+36-28
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ static void _dev_pixelpipe_synch(dt_dev_pixelpipe_t *pipe,
521521
if(active && hist->iop_order == INT_MAX)
522522
{
523523
piece->enabled = FALSE;
524-
dt_print_pipe(DT_DEBUG_PARAMS | DT_DEBUG_PIPE | DT_DEBUG_IOPORDER, "dt_dev_pixelpipe_synch",
524+
dt_print_pipe(DT_DEBUG_PARAMS | DT_DEBUG_PIPE, "dt_dev_pixelpipe_synch",
525525
pipe, piece->module, DT_DEVICE_NONE, NULL, NULL,
526526
"enabled module with iop_order of INT_MAX is disabled");
527527
}
@@ -633,34 +633,42 @@ void dt_dev_pixelpipe_synch_top(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
633633
void dt_dev_pixelpipe_change(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
634634
{
635635
dt_pthread_mutex_lock(&dev->history_mutex);
636-
637-
dt_print_pipe(DT_DEBUG_PIPE, "pipe state changing",
638-
pipe, NULL, DT_DEVICE_NONE, NULL, NULL, "%s%s%s%s",
636+
dt_print_pipe(DT_DEBUG_PIPE, "dev_pixelpipe_change",
637+
pipe, NULL, DT_DEVICE_NONE, NULL, NULL, "%s%s%s%s%s",
639638
pipe->changed & DT_DEV_PIPE_ZOOMED ? "zoomed, " : "",
640639
pipe->changed & DT_DEV_PIPE_TOP_CHANGED ? "top changed, " : "",
641640
pipe->changed & DT_DEV_PIPE_SYNCH ? "synch all, " : "",
642-
pipe->changed & DT_DEV_PIPE_REMOVE ? "pipe remove" : "");
643-
// case DT_DEV_PIPE_UNCHANGED: case DT_DEV_PIPE_ZOOMED:
644-
if(pipe->changed & DT_DEV_PIPE_TOP_CHANGED)
645-
{
646-
// only top history item changed.
647-
dt_dev_pixelpipe_synch_top(pipe, dev);
648-
}
649-
if(pipe->changed & DT_DEV_PIPE_SYNCH)
650-
{
651-
// pipeline topology remains intact, only change all params.
652-
dt_dev_pixelpipe_synch_all(pipe, dev);
653-
}
654-
if(pipe->changed & DT_DEV_PIPE_REMOVE)
641+
pipe->changed & DT_DEV_PIPE_REMOVE ? "pipe remove" : "",
642+
pipe->changed == DT_DEV_PIPE_UNCHANGED ? "dimension" : "");
643+
644+
if(pipe->changed & (DT_DEV_PIPE_TOP_CHANGED | DT_DEV_PIPE_SYNCH | DT_DEV_PIPE_REMOVE))
655645
{
656-
// modules have been added in between or removed. need to rebuild
657-
// the whole pipeline.
658-
dt_dev_pixelpipe_cleanup_nodes(pipe);
659-
dt_dev_pixelpipe_create_nodes(pipe, dev);
660-
dt_dev_pixelpipe_synch_all(pipe, dev);
646+
const gboolean sync_all = pipe->changed & (DT_DEV_PIPE_SYNCH | DT_DEV_PIPE_REMOVE);
647+
const gboolean sync_remove = pipe->changed & DT_DEV_PIPE_REMOVE;
648+
649+
if((pipe->changed & DT_DEV_PIPE_TOP_CHANGED) && !sync_all)
650+
{
651+
// only top history item changed. Not required if we synch_all
652+
dt_dev_pixelpipe_synch_top(pipe, dev);
653+
}
654+
655+
if((pipe->changed & DT_DEV_PIPE_SYNCH) && !sync_remove)
656+
{
657+
// pipeline topology remains intact but change all params. Not required if we rebuild all nodes
658+
dt_dev_pixelpipe_synch_all(pipe, dev);
659+
}
660+
661+
if(pipe->changed & DT_DEV_PIPE_REMOVE)
662+
{
663+
// modules have been added in between or removed. need to rebuild the whole pipeline.
664+
dt_dev_pixelpipe_cleanup_nodes(pipe);
665+
dt_dev_pixelpipe_create_nodes(pipe, dev);
666+
dt_dev_pixelpipe_synch_all(pipe, dev);
667+
}
661668
}
662669
pipe->changed = DT_DEV_PIPE_UNCHANGED;
663670
dt_pthread_mutex_unlock(&dev->history_mutex);
671+
664672
dt_dev_pixelpipe_get_dimensions(pipe, dev,
665673
pipe->iwidth, pipe->iheight,
666674
&pipe->processed_width,
@@ -1413,7 +1421,7 @@ static gboolean _dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe,
14131421
if(dt_atomic_get_int(&pipe->shutdown))
14141422
return TRUE;
14151423

1416-
const dt_hash_t hash = dt_dev_pixelpipe_cache_hash(pipe->image.id, roi_out, pipe, module ? module->iop_order : 0);
1424+
dt_hash_t hash = dt_dev_pixelpipe_cache_hash(pipe->image.id, roi_out, pipe, pos);
14171425

14181426
// we do not want data from the preview pixelpipe cache
14191427
// for gamma so we can compute the final scope
@@ -2256,7 +2264,7 @@ static gboolean _dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe,
22562264
*/
22572265
important_cl =
22582266
(pipe->mask_display == DT_DEV_PIXELPIPE_DISPLAY_NONE)
2259-
&& (pipe->type & DT_DEV_PIXELPIPE_BASIC)
2267+
&& pipe->type & DT_DEV_PIXELPIPE_BASIC
22602268
&& dev->gui_attached
22612269
&& ((module == dt_dev_gui_module())
22622270
|| darktable.develop->history_last_module == module
@@ -2859,7 +2867,7 @@ gboolean dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe,
28592867

28602868
// terminate
28612869
dt_pthread_mutex_lock(&pipe->backbuf_mutex);
2862-
pipe->backbuf_hash = dt_dev_pixelpipe_cache_hash(pipe->image.id, &roi, pipe, INT_MAX);
2870+
pipe->backbuf_hash = dt_dev_pixelpipe_cache_hash(pipe->image.id, &roi, pipe, pos);
28632871

28642872
//FIXME lock/release cache line instead of copying
28652873
if(pipe->type & DT_DEV_PIXELPIPE_SCREEN)
@@ -2906,6 +2914,8 @@ void dt_dev_pixelpipe_get_dimensions(dt_dev_pixelpipe_t *pipe,
29062914
{
29072915
dt_pthread_mutex_lock(&pipe->busy_mutex);
29082916
dt_iop_roi_t roi_in = (dt_iop_roi_t){ 0, 0, width_in, height_in, 1.0 };
2917+
dt_print_pipe(DT_DEBUG_PIPE,
2918+
"get dimensions", pipe, NULL, DT_DEVICE_NONE, &roi_in, NULL, "ID=%i", pipe->image.id);
29092919
dt_iop_roi_t roi_out;
29102920
GList *modules = pipe->iop;
29112921
GList *pieces = pipe->nodes;
@@ -2922,8 +2932,7 @@ void dt_dev_pixelpipe_get_dimensions(dt_dev_pixelpipe_t *pipe,
29222932
module->modify_roi_out(module, piece, &roi_out, &roi_in);
29232933
if((darktable.unmuted & DT_DEBUG_PIPE) && memcmp(&roi_out, &roi_in, sizeof(dt_iop_roi_t)))
29242934
dt_print_pipe(DT_DEBUG_PIPE,
2925-
"modify roi OUT", piece->pipe, module, DT_DEVICE_NONE, &roi_in, &roi_out, "ID=%i",
2926-
pipe->image.id);
2935+
"modify roi OUT", pipe, module, DT_DEVICE_NONE, &roi_in, &roi_out);
29272936
}
29282937
else
29292938
{
@@ -3054,7 +3063,6 @@ float *dt_dev_get_raster_mask(dt_dev_pixelpipe_iop_t *piece,
30543063
if(!_skip_piece_on_tags(it_piece))
30553064
{
30563065
if(it_piece->module->distort_mask
3057-
&& it_piece->enabled
30583066
// hack against pipes not using finalscale
30593067
&& !(dt_iop_module_is(it_piece->module->so, "finalscale")
30603068
&& it_piece->processed_roi_in.width == 0

‎src/iop/ashift.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ void modify_roi_out(struct dt_iop_module_t *self,
12051205
if(roi_out->width < 4 || roi_out->height < 4)
12061206
{
12071207
dt_print_pipe(DT_DEBUG_PIPE,
1208-
"insane data", piece->pipe, self, DT_DEVICE_NONE, roi_in, roi_out);
1208+
"safety check", piece->pipe, self, DT_DEVICE_NONE, roi_in, roi_out);
12091209

12101210
roi_out->width = roi_in->width;
12111211
roi_out->height = roi_in->height;

‎src/iop/clipping.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,7 @@ void modify_roi_out(dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, dt_iop
908908
if(roi_out->width < 4 || roi_out->height < 4)
909909
{
910910
dt_print_pipe(DT_DEBUG_PIPE,
911-
"insane data", piece->pipe, self, DT_DEVICE_NONE, roi_in, roi_out);
911+
"safety check", piece->pipe, self, DT_DEVICE_NONE, roi_in, roi_out);
912912

913913
roi_out->x = roi_in->x;
914914
roi_out->y = roi_in->y;

‎src/iop/toneequal.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,16 @@ void toneeq_process(dt_iop_module_t *self,
10121012
const size_t num_elem = width * height;
10131013

10141014
// Get the hash of the upstream pipe to track changes
1015-
const int position = self->iop_order;
1015+
int position = 0;
1016+
GList *pieces = piece->pipe->nodes;
1017+
while(pieces)
1018+
{
1019+
position++;
1020+
const dt_dev_pixelpipe_iop_t *node = pieces->data;
1021+
if(piece == node) break;
1022+
1023+
pieces = g_list_next(pieces);
1024+
}
10161025
const dt_hash_t hash = dt_dev_pixelpipe_cache_hash(piece->pipe->image.id,
10171026
roi_out, piece->pipe, position);
10181027

‎src/libs/history.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1305,8 +1305,11 @@ static gboolean _lib_history_button_clicked_callback(GtkWidget *widget,
13051305
Yet - there are modules that require fresh data for internal visualizing.
13061306
As there is currently no way to know about that we do a brute-force way and simply
13071307
invalidate cachelines.
1308+
(we might want an additional iop module flag and keep track of that in pixelpipe cache code ???)
1309+
For raws we have at least rawprepare and demosaic
13081310
*/
1309-
dt_dev_pixelpipe_cache_invalidate_later(darktable.develop->preview_pipe, 0);
1311+
const int order = dt_image_is_raw(&darktable.develop->image_storage) ? 2 : 0;
1312+
dt_dev_pixelpipe_cache_invalidate_later(darktable.develop->preview_pipe, order);
13101313

13111314
/* signal history changed */
13121315
dt_dev_undo_end_record(darktable.develop);

0 commit comments

Comments
 (0)
Please sign in to comment.