Пример #1
0
// moved out of control.c to be able to make some helper functions static
void dt_control_jobs_init(dt_control_t *control)
{
  // start threads
  control->num_threads = CLAMP(dt_conf_get_int("worker_threads"), 1, 8);
  control->thread = (pthread_t *)calloc(control->num_threads, sizeof(pthread_t));
  control->job = (dt_job_t **)calloc(control->num_threads, sizeof(dt_job_t *));
  dt_pthread_mutex_lock(&control->run_mutex);
  control->running = 1;
  dt_pthread_mutex_unlock(&control->run_mutex);
  for(int k = 0; k < control->num_threads; k++)
  {
    worker_thread_parameters_t *params
        = (worker_thread_parameters_t *)calloc(1, sizeof(worker_thread_parameters_t));
    params->self = control;
    params->threadid = k;
    pthread_create(&control->thread[k], NULL, dt_control_work, params);
  }

  /* create queue kicker thread */
  pthread_create(&control->kick_on_workers_thread, NULL, dt_control_worker_kicker, control);

  for(int k = 0; k < DT_CTL_WORKER_RESERVED; k++)
  {
    control->job_res[k] = NULL;
    control->new_res[k] = 0;
    worker_thread_parameters_t *params
        = (worker_thread_parameters_t *)calloc(1, sizeof(worker_thread_parameters_t));
    params->self = control;
    params->threadid = k;
    pthread_create(&control->thread_res[k], NULL, dt_control_work_res, params);
  }
}
Пример #2
0
void gui_update(dt_iop_module_t *self)
{
  dt_iop_levels_gui_data_t *g = (dt_iop_levels_gui_data_t *)self->gui_data;
  dt_iop_levels_params_t *p = (dt_iop_levels_params_t *)self->params;

  dt_bauhaus_combobox_set(g->mode, g_list_index(g->modes, GUINT_TO_POINTER(p->mode)));
  dt_bauhaus_slider_set(g->percentile_black, p->percentiles[0]);
  dt_bauhaus_slider_set(g->percentile_grey, p->percentiles[1]);
  dt_bauhaus_slider_set(g->percentile_white, p->percentiles[2]);

  switch(p->mode)
  {
    case LEVELS_MODE_AUTOMATIC:
      gtk_stack_set_visible_child_name(GTK_STACK(g->mode_stack), "automatic");
      break;
    case LEVELS_MODE_MANUAL:
    default:
      gtk_stack_set_visible_child_name(GTK_STACK(g->mode_stack), "manual");
      break;
  }

  dt_pthread_mutex_lock(&g->lock);
  g->auto_levels[0] = NAN;
  g->auto_levels[1] = NAN;
  g->auto_levels[2] = NAN;
  g->hash = 0;
  dt_pthread_mutex_unlock(&g->lock);

  gtk_widget_queue_draw(self->widget);
}
Пример #3
0
dt_dev_zoom_t dt_control_get_dev_zoom()
{
  dt_pthread_mutex_lock(&(darktable.control->global_mutex));
  dt_dev_zoom_t result = darktable.control->dev_zoom;
  dt_pthread_mutex_unlock(&(darktable.control->global_mutex));
  return result;
}
Пример #4
0
static void *dt_control_work_res(void *ptr)
{
#ifdef _OPENMP // need to do this in every thread
  omp_set_num_threads(darktable.num_openmp_threads);
#endif
  worker_thread_parameters_t *params = (worker_thread_parameters_t *)ptr;
  dt_control_t *s = params->self;
  threadid = params->threadid;
  free(params);
  int32_t threadid_res = dt_control_get_threadid_res();
  while(dt_control_running())
  {
    // dt_print(DT_DEBUG_CONTROL, "[control_work] %d\n", threadid_res);
    if(dt_control_run_job_res(s, threadid_res) < 0)
    {
      // wait for a new job.
      int old;
      pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old);
      dt_pthread_mutex_lock(&s->cond_mutex);
      dt_pthread_cond_wait(&s->cond, &s->cond_mutex);
      dt_pthread_mutex_unlock(&s->cond_mutex);
      int tmp;
      pthread_setcancelstate(old, &tmp);
    }
  }
  return NULL;
}
Пример #5
0
int dt_control_get_dev_closeup()
{
  dt_pthread_mutex_lock(&(darktable.control->global_mutex));
  int result = darktable.control->dev_closeup;
  dt_pthread_mutex_unlock(&(darktable.control->global_mutex));
  return result;
}
Пример #6
0
int32_t dt_control_get_mouse_over_id()
{
  dt_pthread_mutex_lock(&(darktable.control->global_mutex));
  int32_t result = darktable.control->mouse_over_id;
  dt_pthread_mutex_unlock(&(darktable.control->global_mutex));
  return result;
}
Пример #7
0
static void dt_control_log_ack_all()
{
  dt_pthread_mutex_lock(&darktable.control->log_mutex);
  darktable.control->log_pos = darktable.control->log_ack;
  dt_pthread_mutex_unlock(&darktable.control->log_mutex);
  dt_control_queue_redraw_center();
}
Пример #8
0
static int lua_job_progress(lua_State *L)
{
  dt_progress_t *progress;
  luaA_to(L, dt_lua_backgroundjob_t, &progress, 1);
  dt_pthread_mutex_lock(&darktable.control->progress_system.mutex);
  GList *iter = g_list_find(darktable.control->progress_system.list, progress);
  dt_pthread_mutex_unlock(&darktable.control->progress_system.mutex);
  if(!iter) luaL_error(L, "Accessing an invalid job");
  if(lua_isnone(L, 3))
  {
    double result = dt_control_progress_get_progress(progress);
    if(!dt_control_progress_has_progress_bar(progress))
      lua_pushnil(L);
    else
      lua_pushnumber(L, result);
    return 1;
  }
  else
  {
    double value;
    luaA_to(L, progress_double, &value, 3);
    dt_control_progress_set_progress(darktable.control, progress, value);
    return 0;
  }
}
Пример #9
0
static int lua_job_valid(lua_State *L)
{
  dt_progress_t *progress;
  luaA_to(L, dt_lua_backgroundjob_t, &progress, 1);
  if(lua_isnone(L, 3))
  {
    dt_pthread_mutex_lock(&darktable.control->progress_system.mutex);
    GList *iter = g_list_find(darktable.control->progress_system.list, progress);
    dt_pthread_mutex_unlock(&darktable.control->progress_system.mutex);

    if(iter)
      lua_pushboolean(L, true);
    else
      lua_pushboolean(L, false);

    return 1;
  }
  else
  {
    int validity = lua_toboolean(L, 3);
    if(validity) return luaL_argerror(L, 3, "a job can not be made valid");
    dt_control_progress_destroy(darktable.control, progress);
    return 0;
  }
}
Пример #10
0
void dt_lua_unlock_internal(const char *function, int line)
{
#ifdef _DEBUG
  dt_print(DT_DEBUG_LUA,"LUA DEBUG : %s called from %s %d\n",__FUNCTION__,function,line);
#endif
  dt_pthread_mutex_unlock(&darktable.lua_state.mutex);
}
Пример #11
0
void dt_opencl_unlock_device(const int dev)
{
  dt_opencl_t *cl = darktable.opencl;
  if(!cl->inited) return;
  if(dev < 0 || dev >= cl->num_devs) return;
  dt_pthread_mutex_unlock(&cl->dev[dev].lock);
}
Пример #12
0
/** gui callbacks, these are needed. */
void gui_update(dt_iop_module_t *self)
{
  // let gui slider match current parameters:
  dt_iop_bilat_gui_data_t *g = (dt_iop_bilat_gui_data_t *)self->gui_data;
  dt_iop_bilat_params_t *p = (dt_iop_bilat_params_t *)self->params;
  dt_bauhaus_slider_set(g->detail, 100.0f*p->detail+100.0f);
  dt_bauhaus_combobox_set(g->mode, p->mode);
  if(p->mode == s_mode_local_laplacian)
  {
    dt_bauhaus_slider_set(g->shadows, p->sigma_s*100.0f);
    dt_bauhaus_slider_set(g->highlights, p->sigma_r*100.0f);
    dt_bauhaus_slider_set(g->midtone, p->midtone);
    gtk_widget_set_visible(g->range, FALSE);
    gtk_widget_set_visible(g->spatial, FALSE);
    gtk_widget_set_visible(g->highlights, TRUE);
    gtk_widget_set_visible(g->shadows, TRUE);
    gtk_widget_set_visible(g->midtone, TRUE);
    dt_pthread_mutex_lock(&g->lock);
    g->hash = 0;
    dt_pthread_mutex_unlock(&g->lock);
  }
  else
  {
    dt_bauhaus_slider_set(g->spatial, p->sigma_s);
    dt_bauhaus_slider_set(g->range, p->sigma_r);
    gtk_widget_set_visible(g->range, TRUE);
    gtk_widget_set_visible(g->spatial, TRUE);
    gtk_widget_set_visible(g->highlights, FALSE);
    gtk_widget_set_visible(g->shadows, FALSE);
    gtk_widget_set_visible(g->midtone, FALSE);
  }
}
Пример #13
0
dt_job_state_t dt_control_job_get_state(_dt_job_t *job)
{
  if(!job) return DT_JOB_STATE_DISPOSED;
  dt_pthread_mutex_lock(&job->state_mutex);
  dt_job_state_t state = job->state;
  dt_pthread_mutex_unlock(&job->state_mutex);
  return state;
}
Пример #14
0
void dt_capabilities_remove(char *capability)
{
  dt_pthread_mutex_lock(&darktable.capabilities_threadsafe);

  darktable.capabilities = g_list_remove(darktable.capabilities, capability);

  dt_pthread_mutex_unlock(&darktable.capabilities_threadsafe);
}
Пример #15
0
void dt_control_log_busy_leave()
{
  dt_pthread_mutex_lock(&darktable.control->log_mutex);
  darktable.control->log_busy--;
  dt_pthread_mutex_unlock(&darktable.control->log_mutex);
  /* lets redraw */
  dt_control_queue_redraw_center();
}
Пример #16
0
void dt_lua_unlock(gboolean relock_gdk)
{
  dt_pthread_mutex_unlock(&darktable.lua_state.mutex);
  if(relock_gdk)
  {
    dt_control_gdk_lock();
  }
}
Пример #17
0
// return read locked bucket, or NULL if it's not already there.
// never attempt to allocate a new slot.
dt_cache_entry_t *dt_cache_testget(dt_cache_t *cache, const uint32_t key, char mode)
{
  gpointer orig_key, value;
  gboolean res;
  int result;
  double start = dt_get_wtime();
  dt_pthread_mutex_lock(&cache->lock);
  res = g_hash_table_lookup_extended(
      cache->hashtable, GINT_TO_POINTER(key), &orig_key, &value);
  if(res)
  {
    dt_cache_entry_t *entry = (dt_cache_entry_t *)value;
    // lock the cache entry
    if(mode == 'w') result = dt_pthread_rwlock_trywrlock(&entry->lock);
    else            result = dt_pthread_rwlock_tryrdlock(&entry->lock);
    if(result)
    { // need to give up mutex so other threads have a chance to get in between and
      // free the lock we're trying to acquire:
      dt_pthread_mutex_unlock(&cache->lock);
      return 0;
    }
    // bubble up in lru list:
    cache->lru = g_list_remove_link(cache->lru, entry->link);
    cache->lru = g_list_concat(cache->lru, entry->link);
    dt_pthread_mutex_unlock(&cache->lock);
    double end = dt_get_wtime();
    if(end - start > 0.1)
      fprintf(stderr, "try+ wait time %.06fs mode %c \n", end - start, mode);

    if(mode == 'w')
    {
      assert(entry->data_size);
      ASAN_POISON_MEMORY_REGION(entry->data, entry->data_size);
    }

    // WARNING: do *NOT* unpoison here. it must be done by the caller!

    return entry;
  }
  dt_pthread_mutex_unlock(&cache->lock);
  double end = dt_get_wtime();
  if(end - start > 0.1)
    fprintf(stderr, "try- wait time %.06fs\n", end - start);
  return 0;
}
Пример #18
0
void dt_capabilities_add(char *capability)
{
  dt_pthread_mutex_lock(&darktable.capabilities_threadsafe);

  if(!dt_capabilities_check(capability))
    darktable.capabilities = g_list_append(darktable.capabilities, capability);

  dt_pthread_mutex_unlock(&darktable.capabilities_threadsafe);
}
Пример #19
0
void dt_camctl_unregister_listener( const dt_camctl_t *c, dt_camctl_listener_t *listener)
{
  dt_camctl_t *camctl=(dt_camctl_t *)c;
  // Just locking mutex and prevent signalling CAMERA_CONTROL_BUSY
  dt_pthread_mutex_lock(&camctl->lock);
  dt_print(DT_DEBUG_CAMCTL,"[camera_control] unregistering listener %lx\n",(unsigned long int)listener);
  camctl->listeners = g_list_remove( camctl->listeners, listener );
  dt_pthread_mutex_unlock(&camctl->lock);
}
Пример #20
0
void dt_control_progress_set_progress(dt_control_t *control, dt_progress_t *progress, double value)
{
  // set the value
  dt_pthread_mutex_lock(&progress->mutex);
  progress->progress = value;
  dt_pthread_mutex_unlock(&progress->mutex);

  // tell the gui
  dt_pthread_mutex_lock(&control->progress_system.mutex);
  if(control->progress_system.proxy.module != NULL)
    control->progress_system.proxy.updated(control->progress_system.proxy.module, progress->gui_data, value);
  dt_pthread_mutex_unlock(&control->progress_system.mutex);

#ifdef HAVE_UNITY
  if(progress->has_progress_bar)
    unity_launcher_entry_set_progress(progress->darktable_launcher, CLAMP(value, 0, 1.0));
#endif
}
Пример #21
0
void dt_control_quit()
{
#ifdef HAVE_MAP
  // since map mode doesn't like to quit we just switch to lighttable mode. hacky, but it works :(
  if(dt_conf_get_int("ui_last/view") == DT_MAP) // we are in map mode where no expose is running
    dt_ctl_switch_mode_to(DT_LIBRARY);
#endif

  dt_gui_gtk_quit();
  // thread safe quit, 1st pass:
  dt_pthread_mutex_lock(&darktable.control->cond_mutex);
  dt_pthread_mutex_lock(&darktable.control->run_mutex);
  darktable.control->running = 0;
  dt_pthread_mutex_unlock(&darktable.control->run_mutex);
  dt_pthread_mutex_unlock(&darktable.control->cond_mutex);
  // let gui pick up the running = 0 state and die
  gtk_widget_queue_draw(dt_ui_center(darktable.gui->ui));
}
Пример #22
0
void _camctl_unlock(const dt_camctl_t *c)
{
  dt_camctl_t *camctl=(dt_camctl_t *)c;
  const dt_camera_t *cam=camctl->active_camera;
  camctl->active_camera=NULL;
  dt_pthread_mutex_unlock(&camctl->lock);
  dt_print(DT_DEBUG_CAMCTL,"[camera_control] camera control un-locked for camera %lx\n",(unsigned long int)cam);
  _dispatch_control_status(c,CAMERA_CONTROL_AVAILABLE);
}
Пример #23
0
int dt_control_running()
{
  // FIXME: when shutdown, run_mutex is not inited anymore!
  dt_control_t *s = darktable.control;
  dt_pthread_mutex_lock(&s->run_mutex);
  int running = s->running;
  dt_pthread_mutex_unlock(&s->run_mutex);
  return running;
}
Пример #24
0
static void dt_control_job_set_state(_dt_job_t *job, dt_job_state_t state)
{
  if(!job) return;
  dt_pthread_mutex_lock(&job->state_mutex);
  job->state = state;
  /* pass state change to callback */
  if(job->state_changed_cb) job->state_changed_cb(job, state);
  dt_pthread_mutex_unlock(&job->state_mutex);
}
Пример #25
0
void dt_control_init(dt_control_t *s)
{
  memset(s->vimkey, 0, sizeof(s->vimkey));
  s->vimkey_cnt = 0;

  // same thread as init
  s->gui_thread = pthread_self();

  // initialize static mutex
  dt_pthread_mutex_init(&_control_gdk_lock_threads_mutex, NULL);

  // s->last_expose_time = dt_get_wtime();
  s->key_accelerators_on = 1;
  s->log_pos = s->log_ack = 0;
  s->log_busy = 0;
  s->log_message_timeout_id = 0;
  dt_pthread_mutex_init(&(s->log_mutex), NULL);
  s->progress = 200.0f;

  dt_conf_set_int("ui_last/view", DT_MODE_NONE);

  pthread_cond_init(&s->cond, NULL);
  dt_pthread_mutex_init(&s->cond_mutex, NULL);
  dt_pthread_mutex_init(&s->queue_mutex, NULL);
  dt_pthread_mutex_init(&s->run_mutex, NULL);
  pthread_rwlock_init(&s->xprofile_lock, NULL);
  dt_pthread_mutex_init(&(s->global_mutex), NULL);
  dt_pthread_mutex_init(&(s->image_mutex), NULL);

  // start threads
  s->num_threads = CLAMP(dt_conf_get_int ("worker_threads"), 1, 8);
  s->thread = (pthread_t *)malloc(sizeof(pthread_t)*s->num_threads);
  dt_pthread_mutex_lock(&s->run_mutex);
  s->running = 1;
  dt_pthread_mutex_unlock(&s->run_mutex);
  for(int k=0; k<s->num_threads; k++)
    pthread_create(&s->thread[k], NULL, dt_control_work, s);

  /* create queue kicker thread */
  pthread_create(&s->kick_on_workers_thread, NULL, _control_worker_kicker, s);

  for(int k=0; k<DT_CTL_WORKER_RESERVED; k++)
  {
    s->new_res[k] = 0;
    pthread_create(&s->thread_res[k], NULL, dt_control_work_res, s);
    dt_pthread_mutex_init(&s->job_res[k].state_mutex, NULL);
    dt_pthread_mutex_init(&s->job_res[k].wait_mutex, NULL);
  }
  s->button_down = 0;
  s->button_down_which = 0;
  s->mouse_over_id = -1;
  s->dev_closeup = 0;
  s->dev_zoom_x = 0;
  s->dev_zoom_y = 0;
  s->dev_zoom = DT_ZOOM_FIT;
}
Пример #26
0
void dt_film_import1_init(dt_job_t *job, dt_film_t *film)
{
  dt_control_job_init(job, "cache load raw images for preview");
  job->execute = &dt_film_import1_run;
  dt_film_import1_t *t = (dt_film_import1_t *)job->param;
  t->film = film;
  dt_pthread_mutex_lock(&film->images_mutex);
  film->ref++;
  dt_pthread_mutex_unlock(&film->images_mutex);
}
Пример #27
0
static gboolean _dt_ctl_log_message_timeout_callback(gpointer data)
{
  dt_pthread_mutex_lock(&darktable.control->log_mutex);
  if(darktable.control->log_ack != darktable.control->log_pos)
    darktable.control->log_ack = (darktable.control->log_ack + 1) % DT_CTL_LOG_SIZE;
  darktable.control->log_message_timeout_id = 0;
  dt_pthread_mutex_unlock(&darktable.control->log_mutex);
  dt_control_queue_redraw_center();
  return FALSE;
}
Пример #28
0
void _control_job_set_state(dt_job_t *j,int state)
{
  dt_pthread_mutex_lock (&j->state_mutex);
  j->state = state;
  /* pass state change to callback */
  if (j->state_changed_cb)
    j->state_changed_cb (j,state);
  dt_pthread_mutex_unlock (&j->state_mutex);

}
Пример #29
0
void dt_dev_module_remove(dt_develop_t *dev, dt_iop_module_t *module)
{
  //if(darktable.gui->reset) return;
  dt_pthread_mutex_lock(&dev->history_mutex);
  int del = 0;
  if(dev->gui_attached)
  {
    int nb = g_list_length(dev->history);
    int pos = 0;
    for (int i=0; i<nb; i++)
    {
      GList *elem = g_list_nth(dev->history,pos);

      dt_dev_history_item_t *hist = (dt_dev_history_item_t *)(elem->data);

      if (module->instance == hist->module->instance && module->multi_priority == hist->module->multi_priority)
      {
        free(hist->params);
        free(hist->blend_params);
        free(hist);
        dev->history = g_list_delete_link(dev->history, elem);
        dev->history_end--;
        del = 1;
      }
      else
      {
        pos++;
      }
    }
  }

  dt_pthread_mutex_unlock(&dev->history_mutex);

  //and we remove it from the list
  GList *modules = g_list_first(dev->iop);
  while(modules)
  {
    dt_iop_module_t *mod = (dt_iop_module_t *)modules->data;
    if(mod == module)
    {
      dev->iop = g_list_remove_link(dev->iop,modules);
      break;
    }
    modules = g_list_next(modules);
  }

  if(dev->gui_attached && del)
  {
    /* signal that history has changed */
    dt_control_signal_raise(darktable.signals, DT_SIGNAL_DEVELOP_HISTORY_CHANGE);
    /* redraw */
    dt_control_queue_redraw_center();
  }

}
Пример #30
0
void gui_update(struct dt_iop_module_t *self)
{
  dt_iop_exposure_gui_data_t *g = (dt_iop_exposure_gui_data_t *)self->gui_data;
  dt_iop_exposure_params_t *p = (dt_iop_exposure_params_t *)self->params;

  if(!dt_image_is_raw(&self->dev->image_storage))
  {
    gtk_widget_hide(GTK_WIDGET(g->mode));
    p->mode = EXPOSURE_MODE_MANUAL;
    dt_dev_add_history_item(darktable.develop, self, TRUE);
  }
  else
  {
    gtk_widget_show(GTK_WIDGET(g->mode));
  }

  dt_bauhaus_combobox_set(g->mode, g_list_index(g->modes, GUINT_TO_POINTER(p->mode)));

  dt_bauhaus_slider_set_soft(g->black, p->black);
  dt_bauhaus_slider_set_soft(g->exposure, p->exposure);

  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(g->autoexp), FALSE);
  dt_bauhaus_slider_set(g->autoexpp, 0.01);
  gtk_widget_set_sensitive(GTK_WIDGET(g->autoexpp), FALSE);

  dt_bauhaus_slider_set(g->deflicker_percentile, p->deflicker_percentile);
  dt_bauhaus_slider_set(g->deflicker_target_level, p->deflicker_target_level);
  dt_bauhaus_combobox_set(
      g->deflicker_histogram_source,
      g_list_index(g->deflicker_histogram_sources, GUINT_TO_POINTER(p->deflicker_histogram_source)));

  self->request_color_pick = DT_REQUEST_COLORPICK_OFF;

  free(g->deflicker_histogram);
  g->deflicker_histogram = NULL;

  gtk_label_set_text(g->deflicker_used_EC, "");
  dt_pthread_mutex_lock(&g->lock);
  g->deflicker_computed_exposure = NAN;
  dt_pthread_mutex_unlock(&g->lock);

  switch(p->mode)
  {
    case EXPOSURE_MODE_DEFLICKER:
      autoexp_disable(self);
      gtk_stack_set_visible_child_name(GTK_STACK(g->mode_stack), "deflicker");
      if(p->deflicker_histogram_source == DEFLICKER_HISTOGRAM_SOURCE_SOURCEFILE)
        deflicker_prepare_histogram(self, &g->deflicker_histogram, &g->deflicker_histogram_stats);
      break;
    case EXPOSURE_MODE_MANUAL:
    default:
      gtk_stack_set_visible_child_name(GTK_STACK(g->mode_stack), "manual");
      break;
  }
}