Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
pixelpipe_raster_masks.c
Go to the documentation of this file.
1
27 dt_dev_pixelpipe_iop_t *current_piece,
28 const dt_iop_module_t *target_module)
29{
30 gboolean success = TRUE;
31 gchar *clean_target_name = !IS_NULL_PTR(target_module)
32 ? delete_underscore(target_module->name())
33 : g_strdup(_("export"));
34 gchar *target_name = !IS_NULL_PTR(target_module)
35 ? g_strdup_printf("%s (%s)", clean_target_name, target_module->multi_name)
36 : g_strdup(clean_target_name);
37
38 if(IS_NULL_PTR(source_piece)
39 || (!IS_NULL_PTR(target_module) && IS_NULL_PTR(current_piece)))
40 {
41 dt_print(DT_DEBUG_MASKS,"[raster masks] ERROR: source: %s, current: %s\n",
42 (!IS_NULL_PTR(source_piece)) ? "is defined" : "is undefined",
43 (!IS_NULL_PTR(current_piece)) ? "is defined" : "is undefined");
44
45 gchar *hint = NULL;
46 if(IS_NULL_PTR(source_piece))
47 {
48 hint = g_strdup_printf(
49 _("- Check if the module providing the masks for the module %s has not been deleted.\n"),
50 target_name);
51 }
52 else if(IS_NULL_PTR(current_piece))
53 {
54 gchar *clean_source_name = delete_underscore(source_piece->module->name());
55 hint = g_strdup_printf(_("- Check if the module %s (%s) providing the masks has not been moved above %s.\n"),
56 clean_source_name,
57 source_piece->module->multi_name, clean_target_name);
58 dt_free(clean_source_name);
59 }
60
61 dt_control_log(_("The %s module is trying to reuse a mask from a module but it can't be found.\n"
62 "\n%s"),
63 target_name, hint ? hint : "");
64 dt_free(hint);
65
66 dt_print(DT_DEBUG_MASKS, "[raster masks] no source module for module %s could be found\n", target_name);
67 success = FALSE;
68 }
69
70 if(success && !source_piece->enabled)
71 {
72 gchar *clean_source_name = delete_underscore(source_piece->module->name());
73 gchar *source_name = g_strdup_printf("%s (%s)", clean_source_name, source_piece->module->multi_name);
74 dt_control_log(_("The `%s` module is trying to reuse a mask from disabled module `%s`.\n"
75 "Disabled modules cannot provide their masks to other modules.\n"
76 "\n- Please enable `%s` or change the raster mask in `%s`."),
77 target_name, source_name, source_name, target_name);
78
79 dt_print(DT_DEBUG_MASKS, "[raster masks] module %s trying to reuse a mask from disabled instance of %s\n",
80 target_name, source_name);
81
82 dt_free(clean_source_name);
83 dt_free(source_name);
84 success = FALSE;
85 }
86
87 dt_free(clean_target_name);
88 dt_free(target_name);
89 return success;
90}
91
92float *dt_dev_get_raster_mask(dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *raster_mask_source,
93 const int raster_mask_id, const dt_iop_module_t *target_module,
94 int *error)
95{
96 if(!IS_NULL_PTR(error)) *error = 0;
97
98 gchar *clean_target_name = !IS_NULL_PTR(target_module)
99 ? delete_underscore(target_module->name())
100 : g_strdup(_("export"));
101 gchar *target_name = !IS_NULL_PTR(target_module)
102 ? g_strdup_printf("%s (%s)", clean_target_name, target_module->multi_name)
103 : g_strdup(clean_target_name);
104
105 if(IS_NULL_PTR(raster_mask_source))
106 {
107 dt_print(DT_DEBUG_MASKS, "[raster masks] The source module of the mask for %s was not found\n", target_name);
108 dt_free(clean_target_name);
109 dt_free(target_name);
110 return NULL;
111 }
112
113 float *raster_mask = NULL;
114
115 dt_dev_pixelpipe_iop_t *source_piece = NULL;
116 dt_dev_pixelpipe_iop_t *current_piece = NULL;
117 GList *source_iter = NULL;
118 for(source_iter = g_list_last(pipe->nodes); source_iter; source_iter = g_list_previous(source_iter))
119 {
120 dt_dev_pixelpipe_iop_t *candidate = (dt_dev_pixelpipe_iop_t *)source_iter->data;
121 if(candidate->module == target_module)
122 current_piece = candidate;
123 else if(candidate->module == raster_mask_source)
124 {
125 source_piece = candidate;
126 break;
127 }
128 }
129
130 const int err_ret = !_dt_dev_raster_mask_check(source_piece, current_piece, target_module);
131 if(!IS_NULL_PTR(error)) *error = err_ret;
132
133 if(!err_ret)
134 {
135 const uint64_t provider_hash = source_piece->global_hash;
136 const uint64_t raster_hash
137 = dt_dev_pixelpipe_raster_mask_hash(source_piece, raster_mask_id);
138
139 gchar *clean_source_name = delete_underscore(source_piece->module->name());
140 gchar *source_name = g_strdup_printf("%s (%s)", clean_source_name, source_piece->module->multi_name);
141 dt_pixel_cache_entry_t *raster_entry = NULL;
142 void *cache_data = NULL;
143 const gboolean found = dt_dev_pixelpipe_cache_ref_entry_by_hash(
144 darktable.pixelpipe_cache, raster_hash, &cache_data, &raster_entry);
145
146 gchar *type = dt_pixelpipe_get_pipe_name(pipe->type);
147 if(found && !IS_NULL_PTR(cache_data) && !IS_NULL_PTR(raster_entry))
148 {
149 const size_t mask_size
150 = sizeof(float) * (size_t)source_piece->roi_out.width * source_piece->roi_out.height;
152 (size_t)source_piece->roi_out.width * source_piece->roi_out.height, pipe->type);
153 if(IS_NULL_PTR(raster_mask))
154 {
156 darktable.pixelpipe_cache, FALSE, raster_entry);
157 if(!IS_NULL_PTR(error)) *error = 1;
158 dt_free(clean_source_name);
159 dt_free(source_name);
160 dt_free(clean_target_name);
161 dt_free(target_name);
162 return NULL;
163 }
164
165 // The cache owns the canonical mask. Copy it under a read lock so the
166 // caller can freely distort and release its private working buffer.
168 darktable.pixelpipe_cache, TRUE, raster_entry);
169 memcpy(raster_mask, cache_data, mask_size);
171 darktable.pixelpipe_cache, FALSE, raster_entry);
173 darktable.pixelpipe_cache, FALSE, raster_entry);
174
176 "[raster masks] found cached mask id %i from %s for module %s"
177 " in pipe %s with hash %" PRIu64 "\n",
178 raster_mask_id, source_name, target_name, type, raster_hash);
179 dt_dev_pixelpipe_unset_reentry(pipe, provider_hash);
180 }
181 else
182 {
183 if(!IS_NULL_PTR(raster_entry))
185 darktable.pixelpipe_cache, FALSE, raster_entry);
186
188 "[raster masks] missing source=%s instance=%d target=%s instance=%d"
189 " requested_id=%d cache_hash=%" PRIu64 " source_enabled=%d pipe=%s\n",
190 source_piece->module->op, source_piece->module->multi_priority,
191 !IS_NULL_PTR(target_module) ? target_module->op : "export",
192 !IS_NULL_PTR(target_module) ? target_module->multi_priority : -1,
193 raster_mask_id, raster_hash, source_piece->enabled,
194 type);
195
197 "[raster masks] mask id %i from %s for module %s could not be found"
198 " in the global cache for pipe %s.\n",
199 raster_mask_id, source_name, target_name, type);
200
201 // A cache miss can still happen after LRU eviction. Cached provider
202 // pixels cannot reconstruct the side-band mask, so interactive pipes get
203 // one targeted provider retry; export callers pass no error pointer and
204 // simply report the missing mask.
205 if(!IS_NULL_PTR(error))
206 {
207 if(dt_dev_pixelpipe_set_reentry(pipe, provider_hash))
208 pipe->flush_cache = TRUE;
209 *error = 1;
210 }
211
212 dt_free(clean_source_name);
213 dt_free(source_name);
214 dt_free(clean_target_name);
215 dt_free(target_name);
216 return NULL;
217 }
218
219 for(GList *iter = g_list_next(source_iter); iter; iter = g_list_next(iter))
220 {
221 dt_dev_pixelpipe_iop_t *module = (dt_dev_pixelpipe_iop_t *)iter->data;
222
223 if(module->enabled
224 && !dt_dev_pixelpipe_activemodule_disables_currentmodule(module->module->dev, module->module))
225 {
226 if(module->module->distort_mask
227 && !(!strcmp(module->module->op, "finalscale")
228 && module->roi_in.width == 0
229 && module->roi_in.height == 0))
230 {
231 float *transformed_mask = dt_pixelpipe_cache_alloc_align_float_cache(
232 (size_t)module->roi_out.width * module->roi_out.height, 0);
233 if(IS_NULL_PTR(transformed_mask))
234 {
235 dt_print(DT_DEBUG_MASKS, "[raster masks] could not allocate memory for transformed mask\n");
236 if(!IS_NULL_PTR(error)) *error = 1;
238 dt_free(clean_source_name);
239 dt_free(source_name);
240 dt_free(clean_target_name);
241 dt_free(target_name);
242 return NULL;
243 }
244
245 module->module->distort_mask(module->module, pipe, module, raster_mask, transformed_mask,
246 &module->roi_in, &module->roi_out);
248 raster_mask = transformed_mask;
249 dt_print(DT_DEBUG_MASKS, "[raster masks] doing transform\n");
250 }
251 else if(!module->module->distort_mask
252 && (module->roi_in.width != module->roi_out.width
253 || module->roi_in.height != module->roi_out.height
254 || module->roi_in.x != module->roi_out.x
255 || module->roi_in.y != module->roi_out.y))
256 dt_print(DT_DEBUG_MASKS, "FIXME: module `%s' changed the roi from %d x %d @ %d / %d to %d x %d | %d / %d but doesn't have "
257 "distort_mask() implemented!\n", module->module->op, module->roi_in.width,
258 module->roi_in.height, module->roi_in.x, module->roi_in.y,
259 module->roi_out.width, module->roi_out.height, module->roi_out.x,
260 module->roi_out.y);
261 }
262
263 if(module->module == target_module)
264 {
265 gchar *clean_module_name = delete_underscore(module->module->name());
266 dt_print(DT_DEBUG_MASKS, "[raster masks] found mask id %i from %s for module %s (%s) in pipe %s\n",
267 raster_mask_id, source_name, clean_module_name,
268 module->module->multi_name, dt_pixelpipe_get_pipe_name(pipe->type));
269 dt_free(clean_module_name);
270 break;
271 }
272 }
273
274 dt_free(clean_source_name);
275 dt_free(source_name);
276 }
277
278 dt_free(clean_target_name);
279 dt_free(target_name);
280 return raster_mask;
281}
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
int type
void dt_control_log(const char *msg,...)
Definition control.c:761
darktable_t darktable
Definition darktable.c:181
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
@ DT_DEBUG_DEV
Definition darktable.h:717
@ DT_DEBUG_MASKS
Definition darktable.h:727
#define dt_pixelpipe_cache_alloc_align_float_cache(pixels, id)
Definition darktable.h:447
#define dt_free(ptr)
Definition darktable.h:456
static gchar * delete_underscore(const char *s)
Definition darktable.h:1083
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:453
#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
gboolean dt_dev_pixelpipe_activemodule_disables_currentmodule(struct dt_develop_t *dev, struct dt_iop_module_t *current_module)
uint64_t dt_dev_pixelpipe_raster_mask_hash(const dt_dev_pixelpipe_iop_t *piece, const int raster_mask_id)
Definition pixelpipe.c:53
void dt_dev_pixelpipe_cache_ref_count_entry(dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Increase/Decrease the reference count on the cache line as to prevent LRU item removal....
gboolean dt_dev_pixelpipe_cache_ref_entry_by_hash(dt_dev_pixelpipe_cache_t *cache, const uint64_t hash, void **data, dt_pixel_cache_entry_t **entry)
Resolve and retain an existing cache entry by hash.
void dt_dev_pixelpipe_cache_rdlock_entry(dt_dev_pixelpipe_cache_t *cache, gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the read lock on the entry.
char * dt_pixelpipe_get_pipe_name(dt_dev_pixelpipe_type_t pipe_type)
gboolean dt_dev_pixelpipe_unset_reentry(dt_dev_pixelpipe_t *pipe, uint64_t hash)
Remove the re-entry pipeline flag, only if the object identifier is the one that set it....
gboolean dt_dev_pixelpipe_set_reentry(dt_dev_pixelpipe_t *pipe, uint64_t hash)
Set the re-entry pipeline flag, only if no object is already capturing it.
static gboolean _dt_dev_raster_mask_check(dt_dev_pixelpipe_iop_t *source_piece, dt_dev_pixelpipe_iop_t *current_piece, const dt_iop_module_t *target_module)
Check that the raster-mask provider/consumer relation is still valid in the current pipe.
float * dt_dev_get_raster_mask(dt_dev_pixelpipe_t *pipe, const dt_iop_module_t *raster_mask_source, const int raster_mask_id, const dt_iop_module_t *target_module, int *error)
unsigned __int64 uint64_t
Definition strptime.c:75
struct dt_dev_pixelpipe_cache_t * pixelpipe_cache
Definition darktable.h:790
struct dt_iop_module_t *void * data
dt_dev_pixelpipe_type_t type
char multi_name[128]
Definition imageop.h:363
GModule *dt_dev_operation_t op
Definition imageop.h:256