132 const gint64 interval_us);
144 gboolean outer_loop);
145#if defined(_OPENMP) && OUTER_LOOP
146static guint _rasterize_dab_batch_outer_loop(
const GArray *dabs, guint max_dabs,
float distance_percent,
156#if defined(_OPENMP) && OUTER_LOOP
160#define DRAWLAYER_BATCH_TILE_SIZE 128
161#define DRAWLAYER_OUTER_LIVE_BATCH_MULTIPLIER 2u
162#define DRAWLAYER_OUTER_FULLRES_BATCH_MULTIPLIER 4u
168 if(!self || !state || !input || !dab)
return FALSE;
170 float lx = input->
lx;
171 float ly = input->
ly;
205 const float base_radius = radius;
206 const float base_opacity = opacity;
207 const float base_flow = flow;
208 const float base_hardness = hardness;
210 if(map_pressure_size) radius *= pressure_coeff;
211 if(map_pressure_opacity) opacity *= pressure_coeff;
212 if(map_pressure_flow) flow *= pressure_coeff;
213 if(map_pressure_softness) hardness *= pressure_coeff;
215 if(map_tilt_size) radius *= tilt_coeff;
216 if(map_tilt_opacity) opacity *= tilt_coeff;
217 if(map_tilt_flow) flow *= tilt_coeff;
218 if(map_tilt_softness) hardness *= tilt_coeff;
220 if(map_accel_size) radius *= accel_coeff;
221 if(map_accel_opacity) opacity *= accel_coeff;
222 if(map_accel_flow) flow *= accel_coeff;
223 if(map_accel_softness) hardness *= accel_coeff;
225 radius = fmaxf(radius, 0.5f);
233 const float dir_len = hypotf(dx, dy);
236 dir_x = dx / dir_len;
237 dir_y = dy / dir_len;
254 .hardness = hardness,
263 if((map_pressure_size || map_pressure_opacity || map_pressure_flow || map_pressure_softness || map_tilt_size
264 || map_tilt_opacity || map_tilt_flow || map_tilt_softness || map_accel_size || map_accel_opacity
265 || map_accel_flow || map_accel_softness)
270 "[drawlayer] map p=%.4f t=%.4f a=%.4f coeff[p=%.4f t=%.4f a=%.4f] "
271 "base[r=%.2f o=%.3f f=%.3f h=%.3f] out[r=%.2f o=%.3f f=%.3f h=%.3f] "
272 "flags[p=%d%d%d%d t=%d%d%d%d a=%d%d%d%d]\n",
273 pressure_norm, tilt_norm, accel_norm, pressure_coeff, tilt_coeff, accel_coeff, base_radius,
275 map_pressure_size ? 1 : 0, map_pressure_opacity ? 1 : 0, map_pressure_flow ? 1 : 0,
276 map_pressure_softness ? 1 : 0, map_tilt_size ? 1 : 0, map_tilt_opacity ? 1 : 0, map_tilt_flow ? 1 : 0,
277 map_tilt_softness ? 1 : 0, map_accel_size ? 1 : 0, map_accel_opacity ? 1 : 0, map_accel_flow ? 1 : 0,
278 map_accel_softness ? 1 : 0);
288 return (ctx && ctx->
self)
321 if(!ctx || !ctx->
self || !flush_pending)
return;
333 const int sample_count = (int)
g->stroke.stroke_sample_count;
349 if(!
g || !input || !stroke)
return;
364 const gint64 input_ts = input->
event_ts ? input->
event_ts : g_get_monotonic_time();
383 g->process.cache_dirty =
TRUE;
408 if(scratch)
return scratch;
410 scratch = g_malloc0(
sizeof(*scratch));
411 if(!scratch)
return NULL;
453 if(!buffer || !capacity_values || needed_values == 0)
return NULL;
454 if(*capacity_values < needed_values)
460 *capacity_values = 0;
463 *capacity_values = needed_values;
471 if(!
g || !raw_inputs || raw_inputs->len == 0)
return FALSE;
472 if(!
g->process.base_patch.pixels ||
g->process.base_patch.width <= 0 ||
g->process.base_patch.height <= 0)
486 g_array_set_size(stroke->
history, 0);
497 .worker =
g->stroke.worker,
506 for(guint
i = 0;
i < raw_inputs->len;
i++)
517 for(guint
i = 0;
i < stroke->
history->len;
i++)
520 const int x0 = CLAMP((
int)floorf(dab->
x - dab->
radius - 1.0f), 0,
g->process.base_patch.width - 1);
521 const int y0 = CLAMP((
int)floorf(dab->
y - dab->
radius - 1.0f), 0,
g->process.base_patch.height - 1);
522 const int x1 = CLAMP((
int)ceilf(dab->
x + dab->
radius + 1.0f), 0,
g->process.base_patch.width);
523 const int y1 = CLAMP((
int)ceilf(dab->
y + dab->
radius + 1.0f), 0,
g->process.base_patch.height);
533 const int replay_width = replay_bounds.
se[0] - replay_bounds.
nw[0];
534 const int replay_height = replay_bounds.
se[1] - replay_bounds.
nw[1];
535 if(replay_width <= 0 || replay_height <= 0)
return FALSE;
539 if(!replay_pixels)
return FALSE;
542 (
size_t)replay_width * replay_height);
543 if(!stroke_mask)
return FALSE;
544 memset(stroke_mask, 0, (
size_t)replay_width * replay_height *
sizeof(
float));
547 .
x = replay_bounds.
nw[0],
548 .y = replay_bounds.
nw[1],
549 .width = replay_width,
550 .height = replay_height,
551 .pixels = replay_pixels,
552 .external_alloc =
TRUE,
555 .
x = replay_bounds.
nw[0],
556 .y = replay_bounds.
nw[1],
557 .width = replay_width,
558 .height = replay_height,
559 .pixels = stroke_mask,
560 .external_alloc =
TRUE,
565#pragma omp parallel for default(none) schedule(static) \
566 dt_omp_firstprivate(g, replay_bounds, replay_height, replay_pixels, replay_width) if(replay_height > 8)
568 for(
int yy = 0; yy < replay_height; yy++)
570 const float *src =
g->process.base_patch.pixels
571 + ((size_t)(replay_bounds.
nw[1] + yy) *
g->process.base_patch.width + replay_bounds.
nw[0]) * 4;
572 float *dst = replay_pixels + (size_t)yy * replay_width * 4;
573 memcpy(dst, src, (
size_t)replay_width * 4 *
sizeof(
float));
577 gboolean wrote_replay_tile =
FALSE;
578#if defined(_OPENMP) && OUTER_LOOP
584 const guint batch_dabs
587 const guint processed_dabs = _rasterize_dab_batch_outer_loop(
589 &replay_stroke_mask, &batch_damage,
"fullres");
590 if(processed_dabs == 0)
break;
591 g_array_remove_range(stroke->
pending_dabs, 0, processed_dabs);
593 wrote_replay_tile = wrote_replay_tile || batch_damage.
valid;
602 &replay_patch, 1.0f, &replay_stroke_mask, &replay_damage,
604 if(wrote_replay_tile)
608 if(wrote_replay_tile)
612#pragma omp parallel for default(none) schedule(static) \
613 dt_omp_firstprivate(g, replay_bounds, replay_height, replay_pixels, replay_width) if(replay_height > 8)
615 for(
int yy = 0; yy < replay_height; yy++)
617 const float *src = replay_pixels + (size_t)yy * replay_width * 4;
618 float *dst =
g->process.base_patch.pixels
619 + ((size_t)(replay_bounds.
nw[1] + yy) *
g->process.base_patch.width + replay_bounds.
nw[0]) * 4;
620 memcpy(dst, src, (
size_t)replay_width * 4 *
sizeof(
float));
624 g->process.base_patch.cache_entry, -1);
628 return wrote_replay_tile;
636 if(!
g || !stroke || !stroke->
dab_window || !dab)
return;
638 gboolean have_process_damage =
FALSE;
643 if(
g->process.process_patch_valid &&
g->process.process_patch.pixels &&
g->process.process_patch.width > 0
644 &&
g->process.process_patch.height > 0 &&
g->process.process_combined_roi.scale > 1e-6f)
647 process_patch.
x =
g->process.process_combined_roi.x;
648 process_patch.
y =
g->process.process_combined_roi.y;
650 process_stroke_mask.
x = process_patch.
x;
651 process_stroke_mask.
y = process_patch.
y;
654 &process_stroke_mask, &process_step_path, stroke);
656 if(have_process_damage)
658 g->process.process_patch_dirty =
TRUE;
663 if(have_process_damage)
665 g->process.cache_dirty =
TRUE;
668 g->stroke.last_dab_valid =
TRUE;
669 g->stroke.last_dab_x = dab->
x;
670 g->stroke.last_dab_y = dab->
y;
707 if(!rt)
return FALSE;
732 if(!rt)
return FALSE;
793#if defined(_OPENMP) && OUTER_LOOP
802 if(!dabs || count == 0)
return FALSE;
803 for(guint
i = 0;
i < count;
i++)
812 const double elapsed_ms,
const gboolean outer_loop)
816 tag ? tag :
"unknown", processed_dabs, thread_count, outer_loop ? 1 : 0, elapsed_ms);
820 const gint64 interval_us)
835#if defined(_OPENMP) && OUTER_LOOP
840 if(!patch || !dab || !bounds || !patch->
pixels || patch->
width <= 0 || patch->
height <= 0
841 || dab->
radius <= 0.0f || dab->
opacity <= 0.0f || scale <= 0.0f)
844 const float support_radius = dab->
radius;
846 bounds->
nw[0] =
MAX(0, (
int)floorf((dab->
x - support_radius) * scale) - patch->
x);
847 bounds->
nw[1] =
MAX(0, (
int)floorf((dab->
y - support_radius) * scale) - patch->
y);
848 bounds->
se[0] =
MIN(patch->
width, (
int)ceilf((dab->
x + support_radius) * scale) - patch->
x + 1);
849 bounds->
se[1] =
MIN(patch->
height, (
int)ceilf((dab->
y + support_radius) * scale) - patch->
y + 1);
850 return bounds->
se[0] > bounds->
nw[0] && bounds->
se[1] > bounds->
nw[1];
856 if(!runtime)
return NULL;
868 if(!runtime || !*runtime)
return;
869 if((*runtime)->dab_window) g_array_free((*runtime)->dab_window,
TRUE);
870 (*runtime)->dab_window = NULL;
874static void _lock_batch_tiles(omp_lock_t *locks,
const int tile_cols,
const int tile_origin_x,
877 if(!locks || tile_cols <= 0 || !bounds || !bounds->valid)
return;
882 for(
int ty = ty0; ty <= ty1; ty++)
883 for(
int tx = tx0; tx <= tx1; tx++)
884 omp_set_lock(&locks[ty * tile_cols + tx]);
887static void _unlock_batch_tiles(omp_lock_t *locks,
const int tile_cols,
const int tile_origin_x,
890 if(!locks || tile_cols <= 0 || !bounds || !bounds->valid)
return;
895 for(
int ty = ty1; ty >= ty0; ty--)
896 for(
int tx = tx1; tx >= tx0; tx--)
897 omp_unset_lock(&locks[ty * tile_cols + tx]);
900static guint _rasterize_dab_batch_outer_loop(
const GArray *dabs,
const guint max_dabs,
const float distance_percent,
906 if(!dabs || max_dabs == 0 || !patch || !patch->
pixels || patch->
width <= 0 || patch->
height <= 0)
return 0;
910 for(guint
i = 0;
i < max_dabs;
i++)
914 if(_dab_bounds_in_patch(patch, scale, dab, &dab_bounds))
917 if(!batch_bounds.
valid)
return 0;
925 omp_lock_t *tile_locks = g_malloc0((
size_t)tile_cols * tile_rows *
sizeof(*tile_locks));
926 if(!thread_runtime || !thread_damage || !tile_locks)
928 g_free(thread_runtime);
929 g_free(thread_damage);
934 for(guint
i = 0;
i < thread_count;
i++)
936 thread_runtime[
i] = _create_batch_runtime();
937 if(!thread_runtime[
i])
939 for(guint k = 0;
k <
i;
k++) _destroy_batch_runtime(&thread_runtime[k]);
940 g_free(thread_runtime);
941 g_free(thread_damage);
947 for(
int i = 0;
i < tile_cols * tile_rows;
i++)
948 omp_init_lock(&tile_locks[
i]);
951#pragma omp parallel for schedule(static) default(none) \
952 shared(dabs, patch, stroke_mask, thread_runtime, thread_damage, tile_locks, tile_cols, tile_origin_x, tile_origin_y, max_dabs, distance_percent, scale)
953 for(guint
i = 0;
i < max_dabs;
i++)
965 if(!_dab_bounds_in_patch(patch, scale, dab, &bounds))
968 _lock_batch_tiles(tile_locks, tile_cols, tile_origin_x, tile_origin_y, &bounds);
970 &runtime_damage, runtime);
971 _unlock_batch_tiles(tile_locks, tile_cols, tile_origin_x, tile_origin_y, &bounds);
979 for(guint
i = 0;
i < thread_count;
i++)
982 _destroy_batch_runtime(&thread_runtime[
i]);
984 for(
int i = 0;
i < tile_cols * tile_rows;
i++)
985 omp_destroy_lock(&tile_locks[
i]);
987 g_free(thread_runtime);
988 g_free(thread_damage);
1002 const guint remaining_dabs = stroke->
pending_dabs->len;
1005#if defined(_OPENMP) && OUTER_LOOP
1008 const guint batch_dabs = (budget_us > 0)
1014 process_patch.
x =
g->process.process_combined_roi.x;
1015 process_patch.
y =
g->process.process_combined_roi.y;
1016 process_stroke_mask.
x = process_patch.
x;
1017 process_stroke_mask.
y = process_patch.
y;
1020 const guint processed_dabs = _rasterize_dab_batch_outer_loop(
1022 g->process.process_combined_roi.scale, &process_stroke_mask, &batch_damage,
"realtime");
1025 if(processed_dabs > 0)
1029 g_array_remove_range(stroke->
pending_dabs, 0, processed_dabs);
1030 if(batch_damage.
valid)
1032 g->process.process_patch_dirty =
TRUE;
1033 g->process.cache_dirty =
TRUE;
1037 g->stroke.last_dab_valid =
TRUE;
1038 g->stroke.last_dab_x = last_dab->
x;
1039 g->stroke.last_dab_y = last_dab->
y;
1042 return processed_dabs;
1047 guint processed_dabs = 0;
1049 while(processed_dabs < stroke->pending_dabs->len)
1058 const gint64 elapsed_us = (gint64)(1000000.0 * (
dt_get_wtime() - batch_t0));
1059 if(processed_dabs >= min_batch && elapsed_us >= budget_us)
break;
1062 if(processed_dabs > 0) g_array_remove_range(stroke->
pending_dabs, 0, processed_dabs);
1064 if(processed_dabs > 0)
1066 return processed_dabs;
1163 if(worker) worker->
state = state;
1169#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
1170 struct sched_param param = { 0 };
1171 const int max_prio = sched_get_priority_max(SCHED_FIFO);
1174 param.sched_priority =
MIN(max_prio, 80);
1175 pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
1213 gboolean active =
FALSE;
1214 if(!rt)
return FALSE;
1224 gboolean active =
FALSE;
1225 if(!rt)
return FALSE;
1237 if(!rt || !self || !self->
dev)
return G_SOURCE_REMOVE;
1239 gboolean should_commit =
FALSE;
1246 return G_SOURCE_REMOVE;
1279 if(!rt || !input)
return;
1334 if(!rt_out || !*rt_out)
return;
1357 gboolean *painting, gboolean *finish_commit_pending,
1358 guint *stroke_sample_count, uint32_t *current_stroke_batch,
1364 rt = g_malloc0(
sizeof(*rt));
1404 if(worker->
stop)
break;
1424 if(!self || !rt)
return NULL;
1469 if(!rt)
return FALSE;
1476 if(!ctx)
return FALSE;
1515 GQueue *new_queue = NULL;
1518 new_queue = g_queue_new();
1524 if(!next_raw_inputs)
1526 if(new_queue) g_queue_free(new_queue);
1533 if(new_queue) g_queue_free(new_queue);
1534 g_array_free(next_raw_inputs,
TRUE);
1538 gboolean queued =
FALSE;
1554 next_raw_inputs = NULL;
1560 if(new_queue) g_queue_free(new_queue);
1561 if(next_raw_inputs) g_array_free(next_raw_inputs,
TRUE);
1576 if(!self || !rt || !worker || !cb)
return NULL;
1584 gboolean have_event =
FALSE;
1585 gboolean have_backlog =
FALSE;
1652 if(!self || !rt || !worker)
return FALSE;
1663 if(!ctx)
return FALSE;
1683 guint source_id = 0;
1690 if(source_id != 0) g_source_remove(source_id);
1709 pthread_join(worker->
thread, NULL);
1763 if(!rt || !event)
return FALSE;
1777 if(!rt || !input)
return FALSE;
1782 gboolean ok =
FALSE;
1802 worker->
ring[last_index] = end_event;
1809 dt_control_log(_(
"drawing worker queue is full, stroke aborted"));
1820 if(!rt)
return FALSE;
1823 if(input) end_input = *input;
1835 gboolean *painting, gboolean *finish_commit_pending,
1836 guint *stroke_sample_count, uint32_t *current_stroke_batch,
1839 _rt_init_state(self, worker, painting, finish_commit_pending, stroke_sample_count, current_stroke_batch,
1840 finished_stroke_cb);
1876 if(!rt || !snapshot)
return;
1902 if(!worker || !worker->
self)
return;
1908 if(!worker || !worker->
self)
return;
1972 return worker ? worker->
stroke : NULL;
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
@ DT_DRAWLAYER_BRUSH_MODE_SMUDGE
Definition brush.h:53
const float i
Definition colorspaces_inline_conversions.h:669
const float g
Definition colorspaces_inline_conversions.h:925
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_control_log(const char *msg,...)
Definition control.c:530
gboolean dt_drawlayer_widget_to_layer_coords(dt_iop_module_t *self, const double wx, const double wy, float *lx, float *ly)
Definition coordinates.c:82
gboolean dt_drawlayer_layer_to_widget_coords(dt_iop_module_t *self, const float x, const float y, float *wx, float *wy)
Definition coordinates.c:95
darktable_t darktable
Definition darktable.c:178
void * dt_alloc_align(size_t size)
Definition darktable.c:447
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1528
#define dt_free_align(ptr)
Definition darktable.h:405
@ DT_DEBUG_INPUT
Definition darktable.h:649
@ DT_DEBUG_PERF
Definition darktable.h:639
#define omp_get_max_threads()
Definition darktable.h:260
#define dt_free(ptr)
Definition darktable.h:380
#define omp_get_thread_num()
Definition darktable.h:261
static double dt_get_wtime(void)
Definition darktable.h:845
uint64_t dt_dev_history_compute_hash(dt_develop_t *dev)
Get the integrity checksum of the whole history stack. This should be done ONLY when history is chang...
Definition dev_history.c:831
gboolean dt_dev_add_history_item_ext(dt_develop_t *dev, struct dt_iop_module_t *module, gboolean enable, gboolean force_new_item)
Append or update a history item for a module.
Definition dev_history.c:725
static void dt_dev_set_history_hash(dt_develop_t *dev, const uint64_t history_hash)
Definition develop.h:407
void dt_drawlayer_touch_stroke_commit_hash(dt_iop_drawlayer_params_t *params, const int dab_count, const gboolean have_last_dab, const float last_dab_x, const float last_dab_y, const uint32_t publish_serial)
Definition drawlayer.c:2299
#define _commit_dabs
Definition drawlayer.c:197
static float _mapping_profile_value(const drawlayer_mapping_profile_t profile, const float x)
Definition drawlayer.c:289
static float _clamp01(const float value)
Definition drawlayer.c:244
@ DRAWLAYER_INPUT_MAP_ACCEL_SIZE
Definition drawlayer.c:123
@ DRAWLAYER_INPUT_MAP_ACCEL_FLOW
Definition drawlayer.c:125
@ DRAWLAYER_INPUT_MAP_PRESSURE_SOFTNESS
Definition drawlayer.c:118
@ DRAWLAYER_INPUT_MAP_TILT_SOFTNESS
Definition drawlayer.c:122
@ DRAWLAYER_INPUT_MAP_TILT_OPACITY
Definition drawlayer.c:120
@ DRAWLAYER_INPUT_MAP_PRESSURE_OPACITY
Definition drawlayer.c:116
@ DRAWLAYER_INPUT_MAP_TILT_FLOW
Definition drawlayer.c:121
@ DRAWLAYER_INPUT_MAP_ACCEL_OPACITY
Definition drawlayer.c:124
@ DRAWLAYER_INPUT_MAP_TILT_SIZE
Definition drawlayer.c:119
@ DRAWLAYER_INPUT_MAP_PRESSURE_FLOW
Definition drawlayer.c:117
@ DRAWLAYER_INPUT_MAP_ACCEL_SOFTNESS
Definition drawlayer.c:126
@ DRAWLAYER_INPUT_MAP_PRESSURE_SIZE
Definition drawlayer.c:115
drawlayer_mapping_profile_t
Definition drawlayer.c:104
@ DRAWLAYER_PROFILE_INV_QUADRATIC
Definition drawlayer.c:110
@ DRAWLAYER_PROFILE_LINEAR
Definition drawlayer.c:105
#define DRAWLAYER_WORKER_RING_CAPACITY
Definition drawlayer.c:100
int dt_pthread_create(pthread_t *thread, void *(*start_routine)(void *), void *arg, const gboolean realtime)
Definition dtpthread.c:42
void dt_pthread_setname(const char *name)
Definition dtpthread.c:113
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:374
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Definition dtpthread.h:359
#define dt_pthread_rwlock_wrlock
Definition dtpthread.h:394
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
Definition dtpthread.h:379
static int dt_pthread_cond_wait(pthread_cond_t *cond, dt_pthread_mutex_t *mutex)
Definition dtpthread.h:384
#define dt_pthread_rwlock_unlock
Definition dtpthread.h:392
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:364
int dt_gui_throttle_get_pipe_runtime_us(const dt_dev_pixelpipe_type_t pipe_type)
Definition gui_throttle.c:217
void dt_iop_nap(int32_t usec)
Definition imageop.c:2525
void dt_drawlayer_cache_patch_wrunlock(const dt_drawlayer_cache_patch_t *patch)
Release write lock on shared patch cache entry.
Definition iop/drawlayer/cache.c:153
void dt_drawlayer_cache_patch_wrlock(const dt_drawlayer_cache_patch_t *patch)
Acquire write lock on shared patch cache entry.
Definition iop/drawlayer/cache.c:145
void dt_drawlayer_cache_patch_rdlock(const dt_drawlayer_cache_patch_t *patch)
Acquire read lock on shared patch cache entry.
Definition iop/drawlayer/cache.c:129
void dt_drawlayer_cache_patch_rdunlock(const dt_drawlayer_cache_patch_t *patch)
Release read lock on shared patch cache entry.
Definition iop/drawlayer/cache.c:137
void dt_drawlayer_paint_path_state_reset(dt_drawlayer_paint_stroke_t *state)
Reset full stroke state including queued raw input events.
Definition iop/drawlayer/paint.c:476
void dt_drawlayer_paint_runtime_state_destroy(dt_drawlayer_damaged_rect_t **state)
Destroy stroke-damage accumulator state and null pointer.
Definition iop/drawlayer/paint.c:821
gboolean dt_drawlayer_paint_queue_raw_input(dt_drawlayer_paint_stroke_t *state, const dt_drawlayer_paint_raw_input_t *input)
Queue one raw input event (FIFO).
Definition iop/drawlayer/paint.c:649
void dt_drawlayer_paint_runtime_private_destroy(dt_drawlayer_paint_stroke_t **state)
Destroy stroke runtime payload and null pointer.
Definition iop/drawlayer/paint.c:845
gboolean dt_drawlayer_paint_rasterize_segment_to_buffer(const dt_drawlayer_brush_dab_t *dab, const float distance_percent, dt_drawlayer_cache_patch_t *patch, const float scale, dt_drawlayer_cache_patch_t *stroke_mask, dt_drawlayer_damaged_rect_t *runtime_state, dt_drawlayer_paint_stroke_t *runtime_private)
Replay one emitted dab segment into a float buffer through brush API.
Definition iop/drawlayer/paint.c:741
void dt_drawlayer_paint_interpolate_path(dt_drawlayer_paint_stroke_t *state, const dt_drawlayer_paint_callbacks_t *callbacks, void *user_data)
Drain queued raw input events and append evenly spaced dabs to state->pending_dabs.
Definition iop/drawlayer/paint.c:673
void dt_drawlayer_paint_runtime_set_stroke_seed(dt_drawlayer_paint_stroke_t *state, const uint64_t seed)
Set deterministic stroke seed for noise-derived effects.
Definition iop/drawlayer/paint.c:864
void dt_drawlayer_paint_runtime_private_reset(dt_drawlayer_paint_stroke_t *state)
Reset transient stroke runtime payload between strokes.
Definition iop/drawlayer/paint.c:853
gboolean dt_drawlayer_paint_runtime_get_stroke_damage(const dt_drawlayer_damaged_rect_t *state, dt_drawlayer_damaged_rect_t *out_rect)
Read accumulated stroke damage rectangle.
Definition iop/drawlayer/paint.c:965
void dt_drawlayer_paint_runtime_state_reset(dt_drawlayer_damaged_rect_t *state)
Reset stroke-damage accumulator to empty/invalid.
Definition iop/drawlayer/paint.c:827
gboolean dt_drawlayer_paint_raster_path(const GArray *dabs, const float distance_percent, dt_drawlayer_cache_patch_t *patch, const float scale, dt_drawlayer_cache_patch_t *stroke_mask, dt_drawlayer_damaged_rect_t *runtime_state, dt_drawlayer_paint_stroke_t *runtime_private)
Rasterize a precomputed dab list into one float RGBA patch.
Definition iop/drawlayer/paint.c:691
void dt_drawlayer_paint_runtime_note_dab_damage(dt_drawlayer_damaged_rect_t *state, const dt_drawlayer_damaged_rect_t *dab_rect)
Merge one dab rectangle into an accumulator rectangle.
Definition iop/drawlayer/paint.c:947
dt_drawlayer_damaged_rect_t * dt_drawlayer_paint_runtime_state_create(void)
Allocate zero-initialized stroke-damage accumulator state.
Definition iop/drawlayer/paint.c:813
void dt_drawlayer_paint_finalize_path(dt_drawlayer_paint_stroke_t *state, const dt_drawlayer_paint_callbacks_t *callbacks, void *user_data)
Finalize stroke by force-emitting the pending first sample if needed.
Definition iop/drawlayer/paint.c:529
gboolean dt_drawlayer_paint_merge_runtime_stroke_damage(dt_drawlayer_damaged_rect_t *path_state, dt_drawlayer_damaged_rect_t *target_rect)
Merge path-state damage into target rectangle and clear path-state accumulator.
Definition iop/drawlayer/paint.c:992
dt_drawlayer_paint_stroke_t * dt_drawlayer_paint_runtime_private_create(void)
Allocate stroke runtime payload object used by paint+brush internals.
Definition iop/drawlayer/paint.c:837
@ DT_DRAWLAYER_PAINT_STROKE_MIDDLE
Definition iop/drawlayer/paint.h:38
@ DT_DRAWLAYER_PAINT_STROKE_FIRST
Definition iop/drawlayer/paint.h:37
@ DT_DRAWLAYER_PAINT_STROKE_END
Definition iop/drawlayer/paint.h:39
k
Definition derive_filmic_v6_gamut_mapping.py:67
@ DT_DEV_PIXELPIPE_FULL
Definition pixelpipe.h:39
void dt_dev_pixelpipe_cache_flush_host_pinned_image(dt_dev_pixelpipe_cache_t *cache, void *host_ptr, dt_pixel_cache_entry_t *entry_hint, int devid)
Drop cached pinned OpenCL images associated with a given host buffer.
Definition pixelpipe_cache.c:775
gboolean dt_drawlayer_process_state_publish_locked(dt_drawlayer_process_state_t *state, const dt_drawlayer_damaged_rect_t *damage, const gboolean full_copy)
Definition runtime.c:1068
unsigned __int64 uint64_t
Definition strptime.c:74
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
Definition darktable.h:717
int32_t unmuted
Definition darktable.h:687
One finished stroke queued for deferred full-resolution replay.
Definition worker.c:70
GArray * raw_inputs
Definition worker.c:71
dt_drawlayer_paint_stroke_t * stroke
Definition worker.c:114
size_t replay_pixels_capacity
Definition worker.c:111
float * replay_pixels
Definition worker.c:110
size_t stroke_mask_capacity
Definition worker.c:113
float * stroke_mask
Definition worker.c:112
dt_drawlayer_paint_stroke_t * stroke
Definition worker.c:105
dt_iop_module_t * self
Definition worker.c:103
dt_drawlayer_worker_t * worker
Definition worker.c:104
Per-worker callback vtable.
Definition worker.c:48
drawlayer_rt_sample_cb process_sample
Definition worker.c:50
const char * thread_name
Definition worker.c:49
drawlayer_rt_stroke_end_cb process_stroke_end
Definition worker.c:51
drawlayer_rt_idle_cb on_idle
Definition worker.c:52
dt_drawlayer_worker_t * rt
Definition worker.c:1413
One worker thread runtime including event ring buffer.
Definition worker.c:57
guint ring_head
Definition worker.c:61
guint ring_capacity
Definition worker.c:60
guint ring_count
Definition worker.c:63
pthread_t thread
Definition worker.c:58
guint ring_tail
Definition worker.c:62
gboolean stop
Definition worker.c:65
dt_drawlayer_worker_state_t state
Definition worker.c:64
dt_drawlayer_paint_raw_input_t * ring
Definition worker.c:59
dt_pthread_rwlock_t history_mutex
Definition develop.h:243
Fully resolved input dab descriptor.
Definition brush.h:66
float x
Definition brush.h:67
float radius
Definition brush.h:71
int mode
Definition brush.h:85
float y
Definition brush.h:68
float opacity
Definition brush.h:76
Generic float RGBA patch stored either in malloc memory or pixel cache.
Definition iop/drawlayer/cache.h:37
int y
Definition iop/drawlayer/cache.h:39
int x
Definition iop/drawlayer/cache.h:38
int height
Definition iop/drawlayer/cache.h:41
float * pixels
Definition iop/drawlayer/cache.h:42
int width
Definition iop/drawlayer/cache.h:40
Integer axis-aligned rectangle in buffer coordinates.
Definition iop/drawlayer/paint.h:87
int se[2]
Definition iop/drawlayer/paint.h:90
int nw[2]
Definition iop/drawlayer/paint.h:89
gboolean valid
Definition iop/drawlayer/paint.h:88
Callback bundle used by stroke processing entry points.
Definition iop/drawlayer/paint.h:147
dt_drawlayer_paint_build_dab_cb build_dab
Definition iop/drawlayer/paint.h:148
Mutable stroke runtime state owned by worker/backend code.
Definition iop/drawlayer/paint.h:100
GArray * pending_dabs
Definition iop/drawlayer/paint.h:103
GArray * history
Definition iop/drawlayer/paint.h:101
float distance_percent
Definition iop/drawlayer/paint.h:112
dt_drawlayer_brush_dab_t last_input_dab
Definition iop/drawlayer/paint.h:106
GArray * dab_window
Definition iop/drawlayer/paint.h:105
gboolean have_last_input_dab
Definition iop/drawlayer/paint.h:107
guint fullres_queue_count
Definition worker.h:43
dt_drawlayer_worker_state_t backend_state
Definition worker.h:40
guint backend_queue_count
Definition worker.h:41
gboolean commit_pending
Definition worker.h:44
dt_drawlayer_worker_state_t fullres_state
Definition worker.h:42
Drawlayer worker global state shared with drawlayer module.
Definition worker.c:76
dt_drawlayer_worker_state_t fullres_state
Definition worker.c:95
gboolean * finish_commit_pending
Definition worker.c:79
dt_drawlayer_damaged_rect_t * backend_path
Definition worker.c:89
uint32_t * current_stroke_batch
Definition worker.c:81
gboolean fullres_stop
Definition worker.c:96
guint * stroke_sample_count
Definition worker.c:80
GArray * stroke_raw_inputs
Definition worker.c:87
drawlayer_rt_worker_t workers[DRAWLAYER_RT_WORKER_COUNT]
Definition worker.c:84
pthread_cond_t worker_cond
Definition worker.c:83
pthread_t fullres_thread
Definition worker.c:93
dt_drawlayer_damaged_rect_t live_publish_damage
Definition worker.c:92
uint32_t live_publish_serial
Definition worker.c:91
gint64 live_publish_ts
Definition worker.c:90
dt_pthread_mutex_t worker_mutex
Definition worker.c:82
GArray * backend_history
Definition worker.c:86
dt_iop_module_t * self
Definition worker.c:77
GQueue * finished_stroke_queue
Definition worker.c:94
dt_drawlayer_paint_stroke_t * stroke
Definition worker.c:88
gboolean finished_stroke_queued
Definition worker.c:97
dt_drawlayer_worker_finished_stroke_cb finished_stroke_cb
Definition worker.c:98
guint finish_commit_source_id
Definition worker.c:85
gboolean * painting
Definition worker.c:78
Definition src/iop/drawlayer/common.h:14
struct dt_develop_t * dev
Definition imageop.h:262
dt_iop_gui_data_t * gui_data
Definition imageop.h:277
dt_iop_params_t * params
Definition imageop.h:273
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29
static void _backend_worker_on_idle(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Backend-worker idle hook.
Definition worker.c:1258
gboolean dt_drawlayer_worker_finished_stroke_queued(const dt_drawlayer_worker_t *worker)
Report whether current preserved stroke was already queued for deferred replay.
Definition worker.c:1988
static gboolean _stroke_create(dt_drawlayer_worker_t *rt)
Create stroke runtime if missing.
Definition worker.c:705
static void _finished_stroke_job_destroy(drawlayer_finished_stroke_job_t *job)
Destroy one finished-stroke replay job and owned history.
Definition worker.c:679
#define DRAWLAYER_BATCH_TILE_SIZE
Definition worker.c:160
void(* drawlayer_rt_stroke_end_cb)(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Callback signature for stroke-end event processing.
Definition worker.c:42
void dt_drawlayer_worker_get_snapshot(const dt_drawlayer_worker_t *worker, dt_drawlayer_worker_snapshot_t *snapshot)
Return a thread-safe worker snapshot for runtime scheduling.
Definition worker.c:1871
static void _backend_worker_process_stroke_end(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Handle backend stroke end: flush, reset, and request commit.
Definition worker.c:1291
static gboolean _workers_active_locked(const dt_drawlayer_worker_t *rt)
Check whether workers still have pending activity (lock must be held).
Definition worker.c:1181
static void _paint_emit_backend_dab_cb(void *user_data, const dt_drawlayer_brush_dab_t *dab)
Definition worker.c:300
static gboolean _dab_batch_supports_outer_loop(const GArray *dabs, guint count)
Definition worker.c:800
static gboolean _worker_is_busy(const drawlayer_rt_worker_t *worker)
Definition worker.c:1132
static void _pause_worker(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Pause worker processing after current callback returns.
Definition worker.c:1732
static float * _ensure_fullres_replay_float_buffer(float **buffer, size_t *capacity_values, size_t needed_values)
Definition worker.c:451
static gboolean _rt_queue_full(const dt_drawlayer_worker_t *rt)
Test whether event queue is full.
Definition worker.c:1097
void dt_drawlayer_worker_stop(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Stop realtime and full-resolution worker threads.
Definition worker.c:1866
static guint _worker_batch_min_size(void)
Definition worker.c:791
static void _rt_destroy_state(dt_iop_module_t *self, dt_drawlayer_worker_t **rt_out)
Stop and free an existing worker state object.
Definition worker.c:1332
dt_drawlayer_paint_stroke_t * dt_drawlayer_worker_stroke(dt_drawlayer_worker_t *worker)
Read-only access to preserved stroke runtime.
Definition worker.c:1970
void dt_drawlayer_worker_cleanup(dt_drawlayer_worker_t **worker)
Public worker cleanup entry point.
Definition worker.c:1844
void dt_drawlayer_worker_reset_backend_path(dt_drawlayer_worker_t *worker)
Reset worker-owned backend damage accumulator.
Definition worker.c:1937
static guint _rasterize_pending_dab_batch(drawlayer_paint_backend_ctx_t *ctx, gint64 budget_us)
Definition worker.c:996
static void _paint_emit_noop_cb(void *user_data, const dt_drawlayer_brush_dab_t *dab)
Definition worker.c:306
static gboolean _fullres_worker_started(const dt_drawlayer_worker_t *rt)
Definition worker.c:1149
static gboolean _rt_queue_push_locked(dt_drawlayer_worker_t *rt, const dt_drawlayer_paint_raw_input_t *event)
Push one event in ring queue (lock must be held).
Definition worker.c:1104
drawlayer_rt_worker_kind_t
Internal worker slot kinds (currently backend only).
Definition worker.c:33
@ DRAWLAYER_RT_WORKER_COUNT
Definition worker.c:35
@ DRAWLAYER_RT_WORKER_BACKEND
Definition worker.c:34
static gboolean _backend_pending_dabs_locked(const dt_drawlayer_worker_t *rt)
Definition worker.c:1144
gboolean dt_drawlayer_worker_ensure_running(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Ensure realtime/backend worker threads are started.
Definition worker.c:1861
static gboolean _live_publish_deadline_reached(const dt_drawlayer_worker_t *rt, const gint64 input_ts, const gint64 interval_us)
Definition worker.c:819
static gboolean _start_worker(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Start backend worker thread if not running.
Definition worker.c:1649
static gboolean _enqueue_event(dt_iop_module_t *self, dt_drawlayer_worker_t *rt, const dt_drawlayer_paint_raw_input_t *event)
Generic enqueue helper ensuring worker startup.
Definition worker.c:1760
static void _reset_backend_path(dt_drawlayer_worker_t *rt)
Definition worker.c:763
gboolean dt_drawlayer_worker_enqueue_stroke_end(dt_drawlayer_worker_t *worker, const dt_drawlayer_paint_raw_input_t *input)
Public FIFO enqueue for stroke-end event.
Definition worker.c:2001
static void _process_backend_input(dt_iop_module_t *self, const dt_drawlayer_paint_raw_input_t *input, dt_drawlayer_paint_stroke_t *stroke)
Definition worker.c:345
static void _cancel_async_commit(dt_drawlayer_worker_t *rt)
Cancel pending async commit idle callback if any.
Definition worker.c:1679
static gboolean _start_fullres_worker(dt_drawlayer_worker_t *rt)
Start deferred full-resolution replay worker if not running.
Definition worker.c:1467
static gboolean _fullres_worker_busy(const dt_drawlayer_worker_t *rt)
Definition worker.c:1154
static GPrivate _drawlayer_fullres_replay_scratch_key
Definition worker.c:402
static drawlayer_rt_worker_t * _backend_worker(dt_drawlayer_worker_t *rt)
Definition worker.c:776
static void _drain_queued_raw_inputs_locked(dt_drawlayer_worker_t *worker)
Definition worker.c:1069
static void * _drawlayer_fullres_worker_main(void *user_data)
Deferred full-resolution replay worker main loop.
Definition worker.c:1417
#define DRAWLAYER_OUTER_FULLRES_BATCH_MULTIPLIER
Definition worker.c:162
static gboolean _workers_any_active_locked(const dt_drawlayer_worker_t *rt)
Check whether any worker activity remains (backend or deferred replay).
Definition worker.c:1196
static void * _drawlayer_worker_main(void *user_data)
Worker main loop: FIFO dequeue, process, and idle scheduling.
Definition worker.c:1567
static void _rt_init_state(dt_iop_module_t *self, dt_drawlayer_worker_t **rt_out, gboolean *painting, gboolean *finish_commit_pending, guint *stroke_sample_count, uint32_t *current_stroke_batch, dt_drawlayer_worker_finished_stroke_cb finished_stroke_cb)
Allocate and initialize worker state object and buffers.
Definition worker.c:1356
static gboolean _async_commit_idle(gpointer user_data)
Idle callback committing pending stroke once workers are fully idle.
Definition worker.c:1233
static void _paint_stroke_seed_cb(void *user_data, uint64_t stroke_seed)
Definition worker.c:312
static void _rt_set_worker_state(dt_drawlayer_worker_t *rt, const dt_drawlayer_worker_state_t state)
Set worker state atomically under caller synchronization.
Definition worker.c:1160
void dt_drawlayer_worker_flush_pending(dt_drawlayer_worker_t *worker)
Flush pending backend stroke inputs synchronously.
Definition worker.c:1900
static gboolean _fullres_active_locked(const dt_drawlayer_worker_t *rt)
Check whether deferred full-resolution replay still has pending activity (lock must be held).
Definition worker.c:1189
static gboolean _rt_workers_any_active(dt_drawlayer_worker_t *rt)
Thread-safe wrapper for any worker activity, including deferred replay.
Definition worker.c:1222
static void _rt_cleanup_state(dt_drawlayer_worker_t **rt_out)
Destroy worker state object and all owned resources.
Definition worker.c:1389
void(* drawlayer_rt_sample_cb)(dt_iop_module_t *self, dt_drawlayer_worker_t *rt, const dt_drawlayer_paint_raw_input_t *input)
Callback signature for one raw-input event processing.
Definition worker.c:39
static void _reset_live_publish(dt_drawlayer_worker_t *rt)
Definition worker.c:768
static gboolean _enqueue_input(dt_iop_module_t *self, dt_drawlayer_worker_t *rt, const dt_drawlayer_paint_raw_input_t *input)
Enqueue raw input with saturation policy and stroke-abort fallback.
Definition worker.c:1774
static void _backend_worker_process_sample(dt_iop_module_t *self, dt_drawlayer_worker_t *rt, const dt_drawlayer_paint_raw_input_t *input)
Process one backend raw input event.
Definition worker.c:1276
static gboolean _worker_pause_requested(const drawlayer_rt_worker_t *worker)
Definition worker.c:1137
static gboolean _rt_workers_active(dt_drawlayer_worker_t *rt)
Thread-safe wrapper for active-workers status.
Definition worker.c:1211
gboolean dt_drawlayer_worker_active(const dt_drawlayer_worker_t *worker)
Public status query: TRUE when worker has pending activity.
Definition worker.c:1850
static void _set_current_thread_realtime_best_effort(void)
Try elevating current thread scheduling policy for lower-latency input.
Definition worker.c:1167
static void _stop_worker(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Stop worker thread and clear transient state.
Definition worker.c:1694
static gboolean _workers_ready_for_commit_locked(const dt_drawlayer_worker_t *rt)
Check if workers are idle and commit can be safely scheduled.
Definition worker.c:1202
void dt_drawlayer_worker_init(dt_iop_module_t *self, dt_drawlayer_worker_t **worker, gboolean *painting, gboolean *finish_commit_pending, guint *stroke_sample_count, uint32_t *current_stroke_batch, dt_drawlayer_worker_finished_stroke_cb finished_stroke_cb)
Public worker initialization entry point.
Definition worker.c:1834
static gboolean _enqueue_finished_stroke(dt_drawlayer_worker_t *rt)
Queue preserved finished stroke for deferred full-resolution replay (lock must be held).
Definition worker.c:1505
void dt_drawlayer_worker_publish_backend_stroke_damage(dt_iop_module_t *self)
Publish accumulated backend stroke damage into drawlayer process/runtime state.
Definition worker.c:376
static void _rt_queue_clear_locked(dt_drawlayer_worker_t *rt)
Clear queued events (lock must be held).
Definition worker.c:1080
void dt_drawlayer_worker_request_commit(dt_drawlayer_worker_t *worker)
Public commit request helper.
Definition worker.c:1889
gboolean dt_drawlayer_worker_any_active(const dt_drawlayer_worker_t *worker)
Public status query: TRUE when any worker still has pending activity.
Definition worker.c:1856
static drawlayer_fullres_replay_scratch_t * _get_fullres_replay_scratch(void)
Definition worker.c:404
gboolean dt_drawlayer_worker_enqueue_input(dt_drawlayer_worker_t *worker, const dt_drawlayer_paint_raw_input_t *input)
Public FIFO enqueue for one raw input event.
Definition worker.c:1994
void dt_drawlayer_worker_reset_live_publish(dt_drawlayer_worker_t *worker)
Reset worker-owned transient live-publish state.
Definition worker.c:1945
guint dt_drawlayer_worker_pending_dab_count(const dt_drawlayer_worker_t *worker)
Return the number of interpolated-but-not-yet-rasterized dabs in the current stroke batch.
Definition worker.c:1975
GArray * dt_drawlayer_worker_raw_inputs(dt_drawlayer_worker_t *worker)
Read-only access to preserved raw input history.
Definition worker.c:1964
static void _publish_backend_progress(drawlayer_paint_backend_ctx_t *ctx, gboolean flush_pending)
Definition worker.c:319
static gboolean _rt_queue_empty(const dt_drawlayer_worker_t *rt)
Test whether event queue is empty.
Definition worker.c:1090
static gboolean _paint_layer_to_widget_cb(void *user_data, float lx, float ly, float *wx, float *wy)
Definition worker.c:294
static gboolean _enqueue_stroke_end(dt_iop_module_t *self, dt_drawlayer_worker_t *rt, const dt_drawlayer_paint_raw_input_t *input)
Enqueue explicit stroke-end event (with optional raw release sample).
Definition worker.c:1817
static void _resume_worker(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Resume worker processing and wake sleeping thread.
Definition worker.c:1747
static gint64 _live_publish_interval_us(void)
Definition worker.c:786
void dt_drawlayer_worker_seal_for_commit(dt_drawlayer_worker_t *worker)
Seal current stroke for synchronous commit by folding queued raw inputs into preserved history.
Definition worker.c:1906
static void _process_backend_dab(dt_iop_module_t *self, const dt_drawlayer_brush_dab_t *dab, drawlayer_paint_backend_ctx_t *ctx)
Definition worker.c:631
static gboolean _paint_build_dab_cb(void *user_data, dt_drawlayer_paint_stroke_t *state, const dt_drawlayer_paint_raw_input_t *input, dt_drawlayer_brush_dab_t *out_dab)
Definition worker.c:284
static const drawlayer_rt_worker_t * _backend_worker_const(const dt_drawlayer_worker_t *rt)
Definition worker.c:781
static void _log_worker_batch_timing(const char *tag, guint processed_dabs, guint thread_count, double elapsed_ms, gboolean outer_loop)
Definition worker.c:811
static gboolean _worker_is_started(const drawlayer_rt_worker_t *worker)
Definition worker.c:1127
void dt_drawlayer_worker_reset_stroke(dt_drawlayer_worker_t *worker)
Clear preserved stroke runtime/history after commit completed.
Definition worker.c:1954
static void _wait_fullres_idle(dt_drawlayer_worker_t *rt)
Wait until deferred full-resolution replay queue is drained and idle.
Definition worker.c:1491
void(* drawlayer_rt_idle_cb)(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Callback signature for idle transitions inside worker loop.
Definition worker.c:44
static void _destroy_fullres_replay_scratch(gpointer data)
Definition worker.c:386
static gboolean _stroke_begin(dt_drawlayer_worker_t *rt)
Start new stroke runtime and reset history/path state.
Definition worker.c:730
gboolean dt_drawlayer_worker_replay_finished_stroke_to_base_patch(dt_iop_module_t *self, const GArray *raw_inputs)
Replay one finished stroke into the authoritative base patch from preserved raw inputs.
Definition worker.c:468
gboolean dt_drawlayer_build_worker_input_dab(dt_iop_module_t *self, dt_drawlayer_paint_stroke_t *state, const dt_drawlayer_paint_raw_input_t *input, dt_drawlayer_brush_dab_t *dab)
Definition worker.c:164
void dt_drawlayer_worker_flush_finished_strokes(dt_drawlayer_worker_t *worker)
Wait until deferred full-resolution replay queue becomes idle.
Definition worker.c:1932
static drawlayer_paint_backend_ctx_t _make_backend_ctx(dt_iop_module_t *self, dt_drawlayer_worker_t *worker, dt_drawlayer_paint_stroke_t *stroke)
Definition worker.c:825
static void _stroke_destroy(dt_drawlayer_worker_t *rt)
Deep-copy preserved stroke history into one deferred replay job.
Definition worker.c:688
static gboolean _wait_worker_idle(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Wait until worker queue is drained and not busy.
Definition worker.c:1395
static gboolean _rt_queue_pop_locked(dt_drawlayer_worker_t *rt, dt_drawlayer_paint_raw_input_t *event)
Pop one event from ring queue (lock must be held).
Definition worker.c:1116
static const drawlayer_rt_callbacks_t _rt_callbacks[DRAWLAYER_RT_WORKER_COUNT]
Definition worker.c:674
#define DRAWLAYER_OUTER_LIVE_BATCH_MULTIPLIER
Definition worker.c:161
static void _schedule_async_commit_if_ready_locked(dt_drawlayer_worker_t *rt)
Schedule async commit when lock-state indicates readiness.
Definition worker.c:1250
static void _stroke_clear(dt_drawlayer_worker_t *rt)
Clear current stroke state while preserving allocations.
Definition worker.c:750
dt_drawlayer_worker_state_t
Definition worker.h:31
@ DT_DRAWLAYER_WORKER_STATE_STOPPED
Definition worker.h:32
@ DT_DRAWLAYER_WORKER_STATE_IDLE
Definition worker.h:33
@ DT_DRAWLAYER_WORKER_STATE_BUSY
Definition worker.h:34
@ DT_DRAWLAYER_WORKER_STATE_PAUSED
Definition worker.h:36
@ DT_DRAWLAYER_WORKER_STATE_PAUSING
Definition worker.h:35
gboolean(* dt_drawlayer_worker_finished_stroke_cb)(dt_iop_module_t *self, const GArray *raw_inputs)
Callback processing one finished stroke on the deferred full-resolution worker.
Definition worker.h:47