Skip to content

Commit ab5cdbd

Browse files
authored
Merge pull request #18523 from jenshannoschwalm/shutdown_fixes_3
Fix some pixelpipe shutdown issues
2 parents bfa6680 + 52c98f0 commit ab5cdbd

File tree

2 files changed

+67
-44
lines changed

2 files changed

+67
-44
lines changed

Diff for: src/develop/develop.c

+41-20
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ void dt_dev_process_image_job(dt_develop_t *dev,
338338
port ? 1.0 : buf.iscale);
339339

340340
// We require calculation of pixelpipe dimensions via dt_dev_pixelpipe_change() in these cases
341-
const gboolean initial = pipe->loading || dev->image_force_reload || pipe->input_changed;
341+
gboolean initial = pipe->loading || dev->image_force_reload || pipe->input_changed;
342342

343343
if(pipe->loading)
344344
{
@@ -391,11 +391,21 @@ void dt_dev_process_image_job(dt_develop_t *dev,
391391
if(port == &dev->full)
392392
pipe->input_timestamp = dev->timestamp;
393393

394-
const gboolean pipe_changed = pipe->changed != DT_DEV_PIPE_UNCHANGED;
395-
// dt_dev_pixelpipe_change() locks history mutex while syncing nodes and finally calculates dimensions
396-
if(pipe_changed || initial || (port && port->pipe->loading))
394+
const gboolean changing = (pipe->changed != DT_DEV_PIPE_UNCHANGED) || initial;
395+
396+
// to be checked: can we possibly restrict later dt_dev_zoom_move() calls
397+
const gboolean require_zoom_test = ((pipe->changed & ~DT_DEV_PIPE_ZOOMED) != DT_DEV_PIPE_UNCHANGED) || initial;
398+
399+
/* dt_dev_pixelpipe_change()
400+
locks history mutex while syncing nodes
401+
finally calculates dimensions
402+
leaves clean pipe->changed
403+
*/
404+
if(changing || (port && port->pipe->loading))
397405
dt_dev_pixelpipe_change(pipe, dev);
398406

407+
initial = FALSE; // don't enforce dt_dev_pixelpipe_change() for restarts
408+
399409
float scale = 1.0f;
400410
int window_width = G_MAXINT;
401411
int window_height = G_MAXINT;
@@ -407,8 +417,11 @@ void dt_dev_process_image_job(dt_develop_t *dev,
407417
// if just changed to an image with a different aspect ratio or
408418
// altered image orientation, the prior zoom xy could now be beyond
409419
// the image boundary
410-
if(port->pipe->loading || pipe_changed)
420+
if(port->pipe->loading || require_zoom_test)
421+
{
422+
dt_print_pipe(DT_DEBUG_PIPE | DT_DEBUG_VERBOSE, "[dt_dev_zoom_move]", pipe, NULL, DT_DEVICE_NONE, NULL, NULL);
411423
dt_dev_zoom_move(port, DT_ZOOM_MOVE, 0.0f, 0, 0.0f, 0.0f, TRUE);
424+
}
412425

413426
// determine scale according to new dimensions
414427
dt_dev_zoom_t zoom;
@@ -418,13 +431,6 @@ void dt_dev_process_image_job(dt_develop_t *dev,
418431
window_width = port->width * port->ppd / (1<<closeup);
419432
window_height = port->height * port->ppd / (1<<closeup);
420433
}
421-
// else
422-
// {
423-
// // FIXME full pipe may be busy, so update processed sizes here
424-
// // make sure preview pipe is newer than full/preview2 pipes
425-
// dev->full.pipe->processed_width = pipe->processed_width * pipe->iscale;
426-
// dev->full.pipe->processed_height = pipe->processed_height * pipe->iscale;
427-
// }
428434

429435
const int wd = MIN(window_width, scale * pipe->processed_width);
430436
const int ht = MIN(window_height, scale * pipe->processed_height);
@@ -435,8 +441,25 @@ void dt_dev_process_image_job(dt_develop_t *dev,
435441

436442
if(dt_dev_pixelpipe_process(pipe, dev, x, y, wd, ht, scale, devid))
437443
{
444+
const gboolean img_changed = dev->image_force_reload || pipe->loading || pipe->input_changed;
445+
// As image_force_reload could be set while we are restarting we clear it and possibly flush the cache too.
446+
if(dev->image_force_reload) dt_dev_pixelpipe_cache_flush(pipe);
447+
dev->image_force_reload = FALSE;
448+
const dt_dev_pixelpipe_stopper_t shutdown = dt_atomic_exch_int(&pipe->shutdown, DT_DEV_PIXELPIPE_STOP_NO);
449+
if(shutdown != DT_DEV_PIXELPIPE_STOP_NO || img_changed)
450+
dt_print_pipe(DT_DEBUG_PIPE,
451+
shutdown == DT_DEV_PIXELPIPE_STOP_NODES ? "DT_DEV_PIXELPIPE_STOP_NODES shutdown"
452+
: shutdown == DT_DEV_PIXELPIPE_STOP_HQ ? "DT_DEV_PIXELPIPE_STOP_HQ shutdown"
453+
: shutdown == DT_DEV_PIXELPIPE_STOP_NO ? "pixelpipe_process ERR"
454+
: "PROCESS shutdown",
455+
pipe, NULL, DT_DEVICE_NONE, NULL, NULL,
456+
"%s%s%sshutdown=%d",
457+
dev->image_force_reload ? "image_force_reload, " : "",
458+
pipe->loading ? "pipe loading, " : "",
459+
pipe->input_changed ? "input_changed, " : "",
460+
shutdown);
438461
// interrupted because image changed?
439-
if(dev->image_force_reload || pipe->loading || pipe->input_changed)
462+
if(img_changed)
440463
{
441464
dt_mipmap_cache_release(&buf);
442465
dt_control_busy_leave();
@@ -447,12 +470,6 @@ void dt_dev_process_image_job(dt_develop_t *dev,
447470
// or because the pipeline changed or shutdown?
448471
else
449472
{
450-
const dt_dev_pixelpipe_stopper_t downer = dt_atomic_exch_int(&pipe->shutdown, DT_DEV_PIXELPIPE_STOP_NO);
451-
if(downer)
452-
dt_print_pipe(DT_DEBUG_PIPE, downer == DT_DEV_PIXELPIPE_STOP_NODES ? "DT_DEV_PIXELPIPE_STOP_NODES shutdown"
453-
: downer == DT_DEV_PIXELPIPE_STOP_HQ ? "DT_DEV_PIXELPIPE_STOP_HQ shutdown"
454-
: "PROCESS shutdown",
455-
pipe, NULL, DT_DEVICE_NONE, NULL, NULL, "downer=%d", downer);
456473
if(port && port->widget) dt_control_queue_redraw_widget(port->widget);
457474
goto restart;
458475
}
@@ -463,7 +480,11 @@ void dt_dev_process_image_job(dt_develop_t *dev,
463480
_dev_average_delay_update(&start, &pipe->average_delay);
464481

465482
// maybe we got zoomed/panned in the meantime?
466-
if(port && pipe->changed != DT_DEV_PIPE_UNCHANGED) goto restart;
483+
if(port && pipe->changed != DT_DEV_PIPE_UNCHANGED)
484+
{
485+
dt_atomic_set_int(&pipe->shutdown, DT_DEV_PIXELPIPE_STOP_NO);
486+
goto restart;
487+
}
467488

468489
pipe->status = DT_DEV_PIXELPIPE_VALID;
469490
pipe->loading = FALSE;

Diff for: src/develop/pixelpipe_hb.c

+26-24
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,24 @@ static inline float *_get_fast_blendcache(const size_t nfloats,
11991199
return pipe->bcache_data;
12001200
}
12011201

1202+
/* use _module_pipe_stop to test for the just processed module leaving a flag to shutdown the pipeline
1203+
immediately.
1204+
This requires extra care as we want pipecache data after the module and it's input data to be invalided.
1205+
*/
1206+
static inline gboolean _module_pipe_stop(dt_dev_pixelpipe_t *pipe, float *input)
1207+
{
1208+
const dt_dev_pixelpipe_stopper_t stopper = dt_atomic_get_int(&pipe->shutdown);
1209+
if(stopper != DT_DEV_PIXELPIPE_STOP_NO)
1210+
{
1211+
if(stopper > DT_DEV_PIXELPIPE_STOP_LAST)
1212+
{
1213+
dt_dev_pixelpipe_invalidate_cacheline(pipe, input);
1214+
dt_dev_pixelpipe_cache_invalidate_later(pipe, stopper);
1215+
}
1216+
}
1217+
return stopper != DT_DEV_PIXELPIPE_STOP_NO;
1218+
}
1219+
12021220
static gboolean _pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe,
12031221
dt_develop_t *dev,
12041222
float *input,
@@ -1229,7 +1247,7 @@ static gboolean _pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe,
12291247
"in module '%s'\nplease report on GitHub"),
12301248
module->op);
12311249
// this is a fundamental problem with severe problems ahead so good to finish
1232-
// the pipe as if good to avoid reprocessing and endless loop.
1250+
// the pipe as if good to avoid reprocessing in an endless loop.
12331251
return FALSE;
12341252
}
12351253

@@ -1362,7 +1380,7 @@ static gboolean _pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe,
13621380
if(module->process_plain)
13631381
{
13641382
dt_get_times(&start);
1365-
for(int i = 0; i < counter; i++)
1383+
for(int i = 0; i < counter && !dt_pipe_shutdown(pipe); i++)
13661384
module->process_plain(module, piece, input, *output, roi_in, roi_out);
13671385
dt_get_times(&end);
13681386
const float clock = (end.clock - start.clock) / (float) counter;
@@ -1399,15 +1417,10 @@ static gboolean _pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe,
13991417
| PIXELPIPE_FLOW_PROCESSED_WITH_TILING);
14001418
}
14011419

1402-
const dt_dev_pixelpipe_stopper_t stopper = dt_atomic_get_int(&pipe->shutdown);
1403-
if(stopper != DT_DEV_PIXELPIPE_STOP_NO)
1404-
{
1405-
if(stopper > DT_DEV_PIXELPIPE_STOP_LAST)
1406-
dt_dev_pixelpipe_cache_invalidate_later(pipe, stopper);
1420+
if(_module_pipe_stop(pipe, input))
14071421
return TRUE;
1408-
}
14091422

1410-
if(pfm_dump && !dt_pipe_shutdown(pipe))
1423+
if(pfm_dump)
14111424
{
14121425
dt_dump_pipe_pfm(module->op, *output,
14131426
roi_out->width, roi_out->height, bpp,
@@ -1474,7 +1487,7 @@ static gboolean _pixelpipe_process_on_CPU(dt_dev_pixelpipe_t *pipe,
14741487
}
14751488
}
14761489

1477-
if(dt_atomic_get_int(&pipe->shutdown))
1490+
if(dt_pipe_shutdown(pipe))
14781491
return TRUE;
14791492

14801493
/* process blending on CPU */
@@ -2070,7 +2083,7 @@ static gboolean _dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe,
20702083
const int counter = (pipe->type & DT_DEV_PIXELPIPE_FULL) ? 100 : 50;
20712084
gboolean success = TRUE;
20722085
dt_get_times(&bench);
2073-
for(int i = 0; i < counter; i++)
2086+
for(int i = 0; i < counter && !dt_pipe_shutdown(pipe); i++)
20742087
{
20752088
if(success)
20762089
success = module->process_cl(module, piece, cl_mem_input, *cl_mem_output,
@@ -2193,14 +2206,8 @@ static gboolean _dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe,
21932206
pipe->dsc.cst = module->output_colorspace(module, pipe, piece);
21942207
}
21952208

2196-
const dt_dev_pixelpipe_stopper_t stopper = dt_atomic_get_int(&pipe->shutdown);
2197-
if(stopper != DT_DEV_PIXELPIPE_STOP_NO)
2209+
if(_module_pipe_stop(pipe, input))
21982210
{
2199-
if(stopper > DT_DEV_PIXELPIPE_STOP_LAST)
2200-
{
2201-
dt_dev_pixelpipe_invalidate_cacheline(pipe, input);
2202-
dt_dev_pixelpipe_cache_invalidate_later(pipe, stopper);
2203-
}
22042211
dt_opencl_release_mem_object(cl_mem_input);
22052212
return TRUE;
22062213
}
@@ -2414,13 +2421,8 @@ static gboolean _dev_pixelpipe_process_rec(dt_dev_pixelpipe_t *pipe,
24142421
pipe->dsc.cst = module->output_colorspace(module, pipe, piece);
24152422
}
24162423

2417-
const dt_dev_pixelpipe_stopper_t stopper = dt_atomic_get_int(&pipe->shutdown);
2418-
if(stopper != DT_DEV_PIXELPIPE_STOP_NO)
2419-
{
2420-
if(stopper > DT_DEV_PIXELPIPE_STOP_LAST)
2421-
dt_dev_pixelpipe_cache_invalidate_later(pipe, stopper);
2424+
if(_module_pipe_stop(pipe, input))
24222425
return TRUE;
2423-
}
24242426

24252427
dt_iop_colorspace_type_t blend_cst =
24262428
dt_develop_blend_colorspace(piece, pipe->dsc.cst);

0 commit comments

Comments
 (0)