33 if(errors->len > 0) g_string_append(errors,
"; ");
34 g_string_append(errors, message);
67 const int listed_count = count;
68 for(
int i = 0;
i < count;
i++)
70 const char *page_name = names[
i] ? names[
i] :
"";
72 if(params->layer_order ==
i || (params->layer_name[0] && !g_strcmp0(page_name, params->layer_name)))
92 g->stroke.stroke_sample_count = 0;
93 g->stroke.stroke_event_index = 0;
94 g->stroke.last_dab_valid =
FALSE;
107 if(
g->process.cache_imgid !=
key->imgid ||
g->process.base_patch.width !=
key->layer_width
108 ||
g->process.base_patch.height !=
key->layer_height)
118 const char *target_name =
key->layer_name ?
key->layer_name :
"";
119 if(target_name[0] !=
'\0' ||
g->process.cache_layer_name[0] !=
'\0')
return !g_strcmp0(
g->process.cache_layer_name, target_name);
121 if(
key->layer_order >= 0 &&
g->process.cache_layer_order >= 0)
122 return g->process.cache_layer_order ==
key->layer_order;
138 int layer_height = 0;
140 GMainContext *
const ui_ctx = g_main_context_default();
141 const gboolean ui_thread = ui_ctx && g_main_context_is_owner(ui_ctx);
142 if(!_resolve_layer_geometry(self, NULL, NULL, &layer_width, &layer_height, NULL, NULL))
147 if(imgid <= 0 || layer_width <= 0 || layer_height <= 0)
return FALSE;
152 g->process.cache_valid =
FALSE;
153 g->process.cache_dirty =
FALSE;
155 g->process.cache_imgid = -1;
156 g->process.cache_layer_name[0] =
'\0';
157 g->process.cache_layer_order = -1;
164 .layer_width = layer_width,
165 .layer_height = layer_height,
166 .layer_name = params->layer_name,
167 .layer_order = params->layer_order,
170 GString *errors = g_string_new(NULL);
174 current_profile,
sizeof(current_profile));
175 if(!have_current_profile)
177 else if(params->work_profile[0] ==
'\0')
178 g_strlcpy(params->work_profile, current_profile,
sizeof(params->work_profile));
179 else if(g_strcmp0(params->work_profile, current_profile))
185 g_string_free(errors,
TRUE);
193 g_string_free(errors,
TRUE);
202 _drawlayer_params_cache_hash(imgid, params, layer_width, layer_height),
203 (
size_t)layer_width * layer_height, layer_width, layer_height,
204 "drawlayer sidecar cache", &created))
208 g->process.cache_valid =
FALSE;
210 g_string_free(errors,
TRUE);
214 "drawlayer stroke mask"))
218 g->process.cache_valid =
FALSE;
221 g_string_free(errors,
TRUE);
232 gboolean cache_loaded =
FALSE;
233 gboolean file_exists =
FALSE;
244 g->process.cache_valid =
FALSE;
247 g_string_free(errors,
TRUE);
251 if(created) file_exists = g_file_test(path, G_FILE_TEST_EXISTS);
253 if(created && !file_exists)
256 params->layer_order = -1;
257 params->sidecar_timestamp = 0;
261 const gboolean pending_new_layer = (params->layer_order < 0 && params->sidecar_timestamp == 0);
266 if(pending_new_layer)
272 g_snprintf(
g->session.missing_layer_error,
sizeof(
g->session.missing_layer_error),
273 _(
"The drawing layer \"%s\" was not found in the sidecar TIFF."),
275 params->layer_name[0] =
'\0';
276 params->layer_order = -1;
277 params->sidecar_timestamp = 0;
278 memset(params->work_profile, 0,
sizeof(params->work_profile));
281 g->process.cache_valid =
FALSE;
282 g->process.cache_dirty =
FALSE;
284 g->process.cache_imgid = -1;
285 g->process.cache_layer_name[0] =
'\0';
286 g->process.cache_layer_order = -1;
300 if(
g)
g->session.missing_layer_error[0] =
'\0';
301 params->layer_order = info.
index;
302 if(info.
work_profile[0] !=
'\0' && params->work_profile[0] ==
'\0')
303 g_strlcpy(params->work_profile, info.
work_profile,
sizeof(params->work_profile));
310 .
x =
g->process.base_patch.x,
311 .y =
g->process.base_patch.y,
312 .width =
g->process.base_patch.width,
313 .height =
g->process.base_patch.height,
314 .pixels =
g->process.base_patch.pixels,
316 const gboolean loaded
334 g->process.cache_valid =
TRUE;
335 g->process.cache_dirty =
FALSE;
337 g->process.cache_imgid = imgid;
338 g_strlcpy(
g->process.cache_layer_name, params->layer_name,
sizeof(
g->process.cache_layer_name));
339 g->process.cache_layer_order = params->layer_order;
347 g->process.cache_valid =
FALSE;
348 g->process.cache_dirty =
FALSE;
354 g_string_free(errors,
TRUE);
355 return ok || !cache_loaded;
368 const int32_t flush_imgid = (
g->process.cache_imgid > 0) ?
g->process.cache_imgid : self->
dev->
image_storage.
id;
369 if(flush_imgid <= 0)
return TRUE;
372 int final_order =
g->process.cache_layer_order;
373 const char *work_profile = params ? params->work_profile :
"";
376 .
x =
g->process.base_patch.x,
377 .y =
g->process.base_patch.y,
378 .width =
g->process.base_patch.width,
379 .height =
g->process.base_patch.height,
380 .pixels =
g->process.base_patch.pixels,
384 g->process.base_patch.
width,
g->process.base_patch.height,
FALSE, &final_order);
386 if(!ok)
return FALSE;
388 g->process.cache_layer_order = final_order;
389 g->process.cache_dirty =
FALSE;
395 if(!g_strcmp0(mutable_params->
layer_name,
g->process.cache_layer_name)) mutable_params->
layer_order = final_order;
411 float wx0 = 0.0f, wy0 = 0.0f, wx1 = 0.0f, wy1 = 0.0f;
413 view.layer_y1, &wx0, &wy0, &wx1, &wy1))
418 .nw = { (int)floorf(
view.layer_x0), (int)floorf(
view.layer_y0) },
419 .se = { (int)ceilf(
view.layer_x1), (int)ceilf(
view.layer_y1) },
423 .nw = { (int)floorf(wx0), (int)floorf(wy0) },
424 .se = { (int)ceilf(wx1), (int)ceilf(wy1) },
427 const gboolean same_view = (memcmp(&
g->session.live_patch, &
view.patch,
sizeof(
view.patch)) == 0
428 && memcmp(&
g->session.live_view_rect, &live_view_rect,
sizeof(live_view_rect)) == 0
429 && memcmp(&
g->session.preview_rect, &preview_rect,
sizeof(preview_rect)) == 0);
433 g->session.last_view_x = self->
dev->
roi.
x;
434 g->session.last_view_y = self->
dev->
roi.
y;
439 g->session.live_patch =
view.patch;
440 g->session.live_view_rect = live_view_rect;
441 g->session.preview_rect = preview_rect;
444 g->session.last_view_x = self->
dev->
roi.
x;
445 g->session.last_view_y = self->
dev->
roi.
y;
455 if(was_realtime !=
state)
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_bauhaus_combobox_length(GtkWidget *widget)
Definition bauhaus.c:1645
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
Definition bauhaus.c:1782
void dt_bauhaus_combobox_remove_at(GtkWidget *widget, int pos)
Definition bauhaus.c:1615
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
Definition bauhaus.c:1556
const float i
Definition colorspaces_inline_conversions.h:440
const float g
Definition colorspaces_inline_conversions.h:674
void dt_control_log(const char *msg,...)
Definition control.c:530
gboolean dt_drawlayer_compute_view_patch(dt_iop_module_t *self, const float padding, drawlayer_view_patch_info_t *view)
Definition coordinates.c:163
gboolean dt_drawlayer_layer_bounds_to_widget_bounds(dt_iop_module_t *self, const float x0, const float y0, const float x1, const float y1, float *left, float *top, float *right, float *bottom)
Definition coordinates.c:106
uint32_t view(const dt_view_t *self)
Definition darkroom.c:191
darktable_t darktable
Definition darktable.c:173
#define PATH_MAX
Definition darktable.h:1061
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
#define dt_dev_pixelpipe_resync_history_main(dev)
Definition dev_pixelpipe.h:68
static gboolean _rekey_shared_base_patch(drawlayer_patch_t *patch, const int32_t imgid, const dt_iop_drawlayer_params_t *params)
Definition drawlayer.c:421
static void _retain_base_patch_loaded_ref(dt_iop_drawlayer_gui_data_t *g)
Definition drawlayer.c:469
#define _flush_layer_cache
Definition drawlayer.c:118
#define _current_live_padding
Definition drawlayer.c:125
#define _release_all_base_patch_extra_refs
Definition drawlayer.c:122
static int64_t _sidecar_timestamp_from_path(const char *path)
Definition drawlayer.c:1014
static gboolean _get_current_work_profile_key(dt_iop_module_t *self, GList *iop_list, dt_dev_pixelpipe_t *pipe, char *key, const size_t key_size)
Definition drawlayer.c:302
static gboolean _layer_name_non_empty(const char *name)
Definition drawlayer.c:293
static void _sanitize_params(dt_iop_module_t *self, dt_iop_drawlayer_params_t *params)
Definition drawlayer.c:1395
static void _refresh_layer_widgets(dt_iop_module_t *self)
Definition drawlayer.c:1558
gboolean dt_drawlayer_io_find_layer(const char *path, const char *target_name, const int target_order, dt_drawlayer_io_layer_info_t *info)
Find target layer metadata in sidecar TIFF.
Definition io.c:684
gboolean dt_drawlayer_io_sidecar_path(const int32_t imgid, char *path, const size_t path_size)
Build absolute sidecar path from image id.
Definition io.c:673
gboolean dt_drawlayer_io_list_layer_names(const char *path, char ***names, int *count)
List all TIFF layer page names.
Definition io.c:1008
gboolean dt_drawlayer_io_load_layer(const char *path, const char *target_name, const int target_order, const int layer_width, const int layer_height, dt_drawlayer_io_patch_t *patch)
Load one sidecar layer patch into float RGBA destination patch.
Definition io.c:698
gboolean dt_drawlayer_io_store_layer(const char *path, const char *target_name, const int target_order, const char *work_profile, const dt_drawlayer_io_patch_t *patch, const int layer_width, const int layer_height, const gboolean delete_target, int *final_order)
Store/update/delete one layer entry in sidecar TIFF.
Definition io.c:904
void dt_drawlayer_io_free_layer_names(char ***names, int *count)
Free array returned by dt_drawlayer_io_list_layer_names.
Definition io.c:1046
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:802
gboolean dt_drawlayer_flush_layer_cache(dt_iop_module_t *self)
Definition layers.c:358
gboolean dt_drawlayer_sync_widget_cache(dt_iop_module_t *self)
Definition layers.c:464
static gboolean _layer_cache_matches(const dt_iop_drawlayer_gui_data_t *g, const drawlayer_layer_cache_key_t *key)
Definition layers.c:100
static void _layerio_log_errors(GString *errors)
Definition layers.c:37
void dt_drawlayer_set_pipeline_realtime_mode(dt_iop_module_t *self, const gboolean state)
Definition layers.c:450
static void _reset_stroke_session(dt_iop_drawlayer_gui_data_t *g)
Definition layers.c:89
static gboolean _ensure_widget_cache(dt_iop_module_t *self)
Definition layers.c:403
static void _populate_layer_list(dt_iop_module_t *self)
Definition layers.c:43
static void _layerio_append_error(GString *errors, const char *message)
Definition layers.c:30
gboolean dt_drawlayer_ensure_layer_cache(dt_iop_module_t *self)
Definition layers.c:126
gboolean dt_dev_pixelpipe_get_realtime(const dt_dev_pixelpipe_t *pipe)
Definition pixelpipe_hb.c:461
void dt_dev_pixelpipe_set_realtime(dt_dev_pixelpipe_t *pipe, gboolean state)
Definition pixelpipe_hb.c:455
void dt_drawlayer_process_state_reset_stroke(dt_drawlayer_process_state_t *state)
Definition runtime.c:938
void dt_drawlayer_process_state_invalidate(dt_drawlayer_process_state_t *state)
Definition runtime.c:945
const float uint32_t state[4]
Definition src/develop/noise_generator.h:72
void dt_drawlayer_cache_patch_wrunlock(const dt_drawlayer_cache_patch_t *patch)
Release write lock on shared patch cache entry.
Definition src/iop/drawlayer/cache.c:180
void dt_drawlayer_cache_patch_wrlock(const dt_drawlayer_cache_patch_t *patch)
Acquire write lock on shared patch cache entry.
Definition src/iop/drawlayer/cache.c:173
void dt_drawlayer_cache_patch_clear(dt_drawlayer_cache_patch_t *patch, const char *external_alloc_name)
Release patch storage and reset patch metadata.
Definition src/iop/drawlayer/cache.c:65
gboolean dt_drawlayer_cache_ensure_mask_buffer(dt_drawlayer_cache_patch_t *mask, const int width, const int height, const char *name)
Ensure a float stroke-mask buffer exists and matches the requested size.
Definition src/iop/drawlayer/cache.c:123
gboolean dt_drawlayer_cache_patch_alloc_shared(dt_drawlayer_cache_patch_t *patch, const uint64_t hash, const size_t pixel_count, const int width, const int height, const char *name, int *created_out)
Allocate patch storage from shared pixel cache entry.
Definition src/iop/drawlayer/cache.c:87
void dt_drawlayer_cache_patch_rdlock(const dt_drawlayer_cache_patch_t *patch)
Acquire read lock on shared patch cache entry.
Definition src/iop/drawlayer/cache.c:159
void dt_drawlayer_cache_patch_rdunlock(const dt_drawlayer_cache_patch_t *patch)
Release read lock on shared patch cache entry.
Definition src/iop/drawlayer/cache.c:166
void dt_drawlayer_cache_clear_transparent_float(float *pixels, const size_t pixel_count)
Fill float RGBA buffer with transparent black.
Definition src/iop/drawlayer/cache.c:58
#define DRAWLAYER_NAME_SIZE
Definition src/iop/drawlayer/common.h:10
#define DRAWLAYER_PROFILE_SIZE
Definition src/iop/drawlayer/common.h:11
struct dt_gui_gtk_t * gui
Definition darktable.h:774
char work_profile[DRAWLAYER_PROFILE_SIZE]
Definition layers.c:18
int count
Definition layers.c:14
char name[DRAWLAYER_NAME_SIZE]
Definition layers.c:17
uint32_t height
Definition layers.c:16
int index
Definition layers.c:13
gboolean found
Definition layers.c:12
uint32_t width
Definition layers.c:15
int layer_height
Definition layers.c:25
int layer_width
Definition layers.c:24
const char * layer_name
Definition layers.c:26
int layer_order
Definition layers.c:27
int32_t imgid
Definition layers.c:23
Definition coordinates.h:19
dt_atomic_int shutdown
Definition pixelpipe_hb.h:276
gboolean pause
Definition pixelpipe_hb.h:365
dt_image_t image_storage
Definition develop.h:248
float x
Definition develop.h:186
GList * iop
Definition develop.h:268
int32_t raw_height
Definition develop.h:217
float y
Definition develop.h:186
struct dt_dev_pixelpipe_t * preview_pipe
Definition develop.h:236
int32_t raw_width
Definition develop.h:217
float scaling
Definition develop.h:182
struct dt_dev_pixelpipe_t * pipe
Definition develop.h:236
struct dt_develop_t::@18 roi
Integer axis-aligned rectangle in buffer coordinates.
Definition iop/drawlayer/paint.h:87
gboolean valid
Definition iop/drawlayer/paint.h:88
Metadata returned when probing one layer directory in sidecar TIFF.
Definition io.h:45
uint32_t height
Definition io.h:50
char work_profile[256]
Definition io.h:52
uint32_t width
Definition io.h:49
char name[64]
Definition io.h:51
int count
Definition io.h:48
int index
Definition io.h:47
gboolean found
Definition io.h:46
Float RGBA patch used by drawlayer I/O routines.
Definition io.h:35
int width
Definition io.h:38
int32_t reset
Definition gtk.h:143
int32_t id
Definition image.h:285
Definition src/iop/drawlayer/common.h:14
char layer_name[64]
Definition src/iop/drawlayer/common.h:16
int layer_order
Definition src/iop/drawlayer/common.h:19
int64_t sidecar_timestamp
Definition src/iop/drawlayer/common.h:18
struct dt_develop_t * dev
Definition imageop.h:297
dt_iop_gui_data_t * gui_data
Definition imageop.h:312
dt_iop_params_t * params
Definition imageop.h:308
static void _pause_worker(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Pause worker processing after current callback returns.
Definition worker.c:1429
void dt_drawlayer_worker_reset_backend_path(dt_drawlayer_worker_t *worker)
Reset worker-owned backend damage accumulator.
Definition worker.c:1603
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:1551
void dt_drawlayer_worker_reset_live_publish(dt_drawlayer_worker_t *worker)
Reset worker-owned transient live-publish state.
Definition worker.c:1611
static void _resume_worker(dt_iop_module_t *self, dt_drawlayer_worker_t *rt)
Resume worker processing and wake sleeping thread.
Definition worker.c:1444
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:1260