192 && a->width == b->width
193 && a->height == b->height
194 && fabs(a->scale - b->scale) < 1e-6;
258 if(engine->
job == job)
289 if(job_active)
return;
304 if(engine->
job == job) engine->
job = NULL;
318 "snapshot-preview",
TRUE))
332 cairo_translate(cr, tx, ty);
333 cairo_scale(cr, preview_scale, preview_scale);
334 cairo_rectangle(cr, 0, 0, preview_wd, preview_ht);
342 GList *history_override, GList *iop_order_override,
343 int32_t history_end_override)
359 dt_print(
DT_DEBUG_DEV,
"[dev_snapshot] capture failed: dt_dev_load_image failed for imgid=%d\n", imgid);
368 frozen->
history = history_override;
369 history_override = NULL;
372 iop_order_override = NULL;
374 for(GList *history = g_list_first(frozen->
history); history; history = g_list_next(history))
386 "[dev_snapshot] capture failed: unresolved module op=%s multi=%s priority=%d for imgid=%d\n",
406 for(GList *history = g_list_first(frozen->
history); history && hist_pos < history_end_override;
407 history = g_list_next(history), hist_pos++)
422 dt_print(
DT_DEBUG_DEV,
"[dev_snapshot] capture failed: mipmap full unavailable for imgid=%d\n", imgid);
461 if(!pipe_inited || !preview_inited)
463 dt_print(
DT_DEBUG_DEV,
"[dev_snapshot] capture failed: pixelpipe init failed for imgid=%d\n", imgid);
485 live_preview = live_dev ? live_dev->
preview_pipe : NULL;
487 for(
int i = 0;
i < 2;
i++)
525 if(iop_order_override) g_list_free_full(iop_order_override,
dt_free_gpointer);
531 double clip_x,
double clip_y,
double clip_w,
double clip_h)
534 if(clip_w <= 0.0 || clip_h <= 0.0)
return;
543 const gboolean roi_valid = engine->
roi_valid;
547 const gboolean main_ready = want_ok && roi_valid &&
_roi_equal(&last_roi, &want_roi);
556 cairo_rectangle(cri, clip_x, clip_y, clip_w, clip_h);
567 cairo_set_source_rgb(cri, bg_color[0], bg_color[1], bg_color[2]);
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
int dt_atomic_sub_int(dt_atomic_int *var, int decr)
int dt_atomic_add_int(dt_atomic_int *var, int incr)
void dt_control_queue_redraw_center()
Request a redraw of the centre view.
struct dt_control_t * dt_control_get_global(void)
struct dt_develop_t * dt_dev_get_global(void)
struct dt_gui_gtk_t * dt_gui_get_global(void)
gboolean dt_dev_lock_pipe_surface(dt_develop_t *dev, dt_dev_pixelpipe_t *pipe, dt_dev_locked_surface_t *locked, dt_dev_pixelpipe_cache_wait_t *wait, const char *wait_owner_tag, gboolean keep_previous_on_fail)
gboolean dt_dev_render_locked_surface(cairo_t *cr, const dt_develop_t *dev, dt_dev_locked_surface_t *locked, const int width, const int height, const int border, const dt_aligned_pixel_t bg_color)
void dt_dev_get_background_color(const dt_develop_t *dev, dt_aligned_pixel_t bg_color)
void dt_dev_release_locked_surface(dt_dev_locked_surface_t *locked)
dt_iop_module_t * dt_dev_get_module_instance(dt_develop_t *dev, const char *op, const char *multi_name, const int multi_priority)
Find a module instance by op name and instance metadata.
dt_iop_module_t * dt_dev_create_module_instance(dt_develop_t *dev, const char *op, const char *multi_name, const int multi_priority, gboolean use_next_priority)
Create a new module instance from an existing base .so.
void dt_dev_history_free_history(dt_develop_t *dev) REQUIRES(dev -> history_mutex)
Free the whole history list attached to dev->history.
uint64_t dt_dev_history_compute_hash(dt_develop_t *dev) REQUIRES_SHARED(dev -> history_mutex)
Get the integrity checksum of the whole history stack. This should be done ONLY when history is chang...
void dt_dev_set_history_end_ext(struct dt_develop_t *dev, const uint32_t index)
Set the history end index (GUI perspective).
void dt_dev_pixelpipe_propagate_formats(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_get_roi_out(dt_dev_pixelpipe_t *pipe, const int width_in, const int height_in, int *width, int *height)
void dt_dev_pixelpipe_change(dt_dev_pixelpipe_t *pipe)
float dt_dev_roi_request_natural_scale(const dt_develop_t *dev)
gboolean dt_dev_roi_request_valid(const dt_develop_t *dev)
static void _engine_unref(dt_dev_snapshot_engine_t *engine)
static void _draw_preview_fallback(dt_dev_snapshot_engine_t *engine, dt_develop_t *dev, cairo_t *cr, int width, int height)
void dt_dev_snapshot_draw(dt_dev_snapshot_t *snap, cairo_t *cri, struct dt_develop_t *dev, int32_t width, int32_t height, double clip_x, double clip_y, double clip_w, double clip_h)
static gboolean _compute_main_roi(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, dt_iop_roi_t *roi)
static void _engine_free(dt_dev_snapshot_engine_t *engine)
static int32_t _recompute_job_run(dt_job_t *job)
void dt_dev_snapshot_clear(dt_dev_snapshot_t *snap)
static void _schedule_main_recompute(dt_dev_snapshot_engine_t *engine, const dt_iop_roi_t *roi)
static void _recompute_job_cleanup(void *params)
gboolean dt_dev_snapshot_is_valid(const dt_dev_snapshot_t *snap)
static gboolean _compute_preview_roi(const dt_develop_t *dev, const dt_dev_pixelpipe_t *pipe, dt_iop_roi_t *roi)
static void _sync_preview_now(dt_dev_snapshot_engine_t *engine, dt_develop_t *dev)
static gboolean _sync_main_now(dt_dev_snapshot_engine_t *engine, const dt_iop_roi_t *roi)
gboolean dt_dev_snapshot_capture(dt_dev_snapshot_t *snap, dt_develop_t *dev, int32_t imgid, GList *history_override, GList *iop_order_override, int32_t history_end_override)
static gboolean _roi_equal(const dt_iop_roi_t *a, const dt_iop_roi_t *b)
static gboolean _process_at_roi(dt_dev_snapshot_engine_t *engine, dt_dev_pixelpipe_t *pipe, const dt_iop_roi_t *roi)
float dt_dev_viewport_center_y(const dt_develop_t *dev)
float dt_dev_viewport_center_x(const dt_develop_t *dev)
int32_t dt_dev_viewport_border_size(const dt_develop_t *dev)
int32_t dt_dev_viewport_box_height(const dt_develop_t *dev)
float dt_dev_viewport_scaling(const dt_develop_t *dev)
int32_t dt_dev_viewport_box_width(const dt_develop_t *dev)
void dt_dev_cleanup(dt_develop_t *dev)
dt_dev_image_storage_t dt_dev_load_image(dt_develop_t *dev, const int32_t imgid)
void dt_dev_init(dt_develop_t *dev, int32_t gui_attached)
static void dt_dev_set_history_hash(dt_develop_t *dev, const uint64_t history_hash)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
dt_iop_module_t * dt_iop_get_module_by_op_priority(GList *modules, const char *operation, const int multi_priority)
dt_job_state_t dt_control_job_get_state(_dt_job_t *job)
void dt_control_job_cancel(_dt_job_t *job)
dt_job_t * dt_control_job_create(dt_job_execute_callback execute, const char *msg,...)
int dt_control_add_job(dt_control_t *control, dt_job_queue_t queue_id, _dt_job_t *job)
void * dt_control_job_get_params(const _dt_job_t *job)
void dt_control_job_set_params(_dt_job_t *job, void *params, dt_job_destroy_callback callback)
void dt_control_job_dispose(_dt_job_t *job)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
void dt_masks_replace_current_forms(dt_develop_t *dev, GList *forms)
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
#define dt_mipmap_cache_get(B, C, D, E, F)
#define dt_mipmap_cache_release(B)
void dt_dev_pixelpipe_cache_rdlock_entry(gboolean lock, dt_pixel_cache_entry_t *cache_entry)
Lock or release the read lock on the entry.
void dt_dev_pixelpipe_set_input(dt_dev_pixelpipe_t *pipe, int32_t imgid, int width, int height, float iscale, dt_mipmap_size_t size)
int dt_dev_pixelpipe_init(dt_dev_pixelpipe_t *pipe, dt_develop_t *dev)
void dt_dev_pixelpipe_set_icc(dt_dev_pixelpipe_t *pipe, dt_colorspaces_color_profile_type_t icc_type, const gchar *icc_filename, dt_iop_color_intent_t icc_intent)
void dt_dev_pixelpipe_create_nodes(dt_dev_pixelpipe_t *pipe)
void dt_dev_pixelpipe_cleanup(dt_dev_pixelpipe_t *pipe)
int dt_dev_pixelpipe_process(dt_dev_pixelpipe_t *pipe, dt_iop_roi_t roi)
static void dt_dev_pixelpipe_or_changed(dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_change_t flags)
#define dt_dev_pixelpipe_synch_all(pipe)
DT_ALIGNED_PIXEL float dt_aligned_pixel_t[4]
struct dt_pixel_cache_entry_t * entry
cairo_surface_t * surface
dt_colorspaces_color_profile_type_t icc_type
dt_iop_color_intent_t icc_intent
dt_dev_pixelpipe_t * preview_pipe
dt_iop_roi_t preview_last_roi
gboolean preview_roi_valid
dt_dev_pixelpipe_t * pipe
dt_dev_locked_surface_t preview_locked
dt_dev_pixelpipe_cache_wait_t wait
dt_dev_pixelpipe_cache_wait_t preview_wait
dt_dev_locked_surface_t locked
struct dt_dev_snapshot_engine_t * engine
struct dt_dev_pixelpipe_t * preview_pipe
Region of interest passed through the pixelpipe.
One consumer's outstanding request, owned by that consumer, not by the queue.