Ejemplo n.º 1
0
static gboolean
gegl_post_parse_hook (GOptionContext *context,
                      GOptionGroup   *group,
                      gpointer        data,
                      GError        **error)
{
  GeglConfig *config;

  g_assert (global_time == 0);
  global_time = gegl_ticks ();

  if (g_getenv ("GEGL_DEBUG_TIME") != NULL)
    gegl_instrument_enable ();

  gegl_instrument ("gegl", "gegl_init", 0);

  config = gegl_config ();

  gegl_config_parse_env (config);

  babl_init ();

#ifdef GEGL_ENABLE_DEBUG
  {
    const char *env_string;
    env_string = g_getenv ("GEGL_DEBUG");
    if (env_string != NULL)
      {
        gegl_debug_flags =
          g_parse_debug_string (env_string,
                                gegl_debug_keys,
                                G_N_ELEMENTS (gegl_debug_keys));
        env_string = NULL;
      }
  }
#endif /* GEGL_ENABLE_DEBUG */

  if (cmd_gegl_swap)
    g_object_set (config, "swap", cmd_gegl_swap, NULL);
  if (cmd_gegl_quality)
    config->quality = atof (cmd_gegl_quality);
  if (cmd_gegl_cache_size)
    config->tile_cache_size = atoll (cmd_gegl_cache_size)*1024*1024;
  if (cmd_gegl_chunk_size)
    config->chunk_size = atoi (cmd_gegl_chunk_size);
  if (cmd_gegl_tile_size)
    {
      const gchar *str = cmd_gegl_tile_size;
      config->tile_width = atoi(str);
      str = strchr (str, 'x');
      if (str)
        config->tile_height = atoi(str+1);
    }
  if (cmd_gegl_threads)
    {
      _gegl_threads = atoi (cmd_gegl_threads);
      if (_gegl_threads > GEGL_MAX_THREADS)
        {
          g_warning ("Tried to use %i threads, max is %i",
                     _gegl_threads, GEGL_MAX_THREADS);
          _gegl_threads = GEGL_MAX_THREADS;
        }
    }
  if (cmd_gegl_disable_opencl)
    gegl_cl_hard_disable ();

  gegl_init_swap_dir ();

  GEGL_INSTRUMENT_START();

  gegl_operation_gtype_init ();

  if (!module_db)
    {
      GSList *paths = gegl_get_default_module_paths ();
      module_db = gegl_module_db_new (FALSE);
      g_slist_foreach(paths, (GFunc)load_module_path, module_db);
      g_slist_free_full (paths, g_free);
    }

  GEGL_INSTRUMENT_END ("gegl_init", "load modules");

  gegl_instrument ("gegl", "gegl_init", gegl_ticks () - global_time);

  swap_clean ();

  g_signal_connect (G_OBJECT (config),
                   "notify::use-opencl",
                   G_CALLBACK (gegl_config_use_opencl_notify),
                   NULL);
  g_object_set (config, "use-opencl", config->use_opencl, NULL);

  g_signal_connect (G_OBJECT (config),
                   "notify::application-license",
                   G_CALLBACK (gegl_config_application_license_notify),
                   NULL);
  gegl_operations_set_licenses_from_string (config->application_license);

  return TRUE;
}
Ejemplo n.º 2
0
/**
 * gegl_graph_process:
 * @path: The traversal path
 *
 * Process the prepared request. This will return the
 * resulting buffer from the final node, or NULL if
 * that node is a sink.
 *
 * If gegl_graph_prepare_request has not been called
 * the behavior of this function is undefined.
 *
 * Return value: (transfer full): The result of the graph, or NULL if
 * there is no output pad.
 */
GeglBuffer *
gegl_graph_process (GeglGraphTraversal *path,
                    gint                level)
{
  GList *list_iter = NULL;
  GeglBuffer *result = NULL;
  GeglOperationContext *context = NULL;
  GeglOperationContext *last_context = NULL;
  GeglBuffer *operation_result = NULL;

  for (list_iter = path->dfs_path; list_iter; list_iter = list_iter->next)
    {
      GeglNode *node = GEGL_NODE (list_iter->data);
      GeglOperation *operation = node->operation;
      g_return_val_if_fail (node, NULL);
      g_return_val_if_fail (operation, NULL);
      
      GEGL_INSTRUMENT_START();

      operation_result = NULL;

      if (last_context)
        gegl_operation_context_purge (last_context);
      
      context = g_hash_table_lookup (path->contexts, node);
      g_return_val_if_fail (context, NULL);

      GEGL_NOTE (GEGL_DEBUG_PROCESS,
                 "Will process %s result_rect = %d, %d %d×%d",
                 gegl_node_get_debug_name (node),
                 context->result_rect.x, context->result_rect.y, context->result_rect.width, context->result_rect.height);
      
      if (context->need_rect.width > 0 && context->need_rect.height > 0)
        {
          if (context->cached)
            {
              GEGL_NOTE (GEGL_DEBUG_PROCESS,
                         "Using cached result for %s",
                         gegl_node_get_debug_name (node));
              operation_result = GEGL_BUFFER (node->cache);
            }
          else
            {
              /* provide something on input pad, always - this makes having
                 behavior depending on it not being set.. not work, is
                 sacrifising that worth it?
               */
              if (gegl_node_has_pad (node, "input") &&
                  !gegl_operation_context_get_object (context, "input"))
                {
                  gegl_operation_context_set_object (context, "input", G_OBJECT (gegl_graph_get_shared_empty(path)));
                }

              context->level = level;

              /* note: this hard-coding of "output" makes some more custom
               * graph topologies harder than neccesary.
               */
              gegl_operation_process (operation, context, "output", &context->need_rect, context->level);
              operation_result = GEGL_BUFFER (gegl_operation_context_get_object (context, "output"));

              if (operation_result && operation_result == (GeglBuffer *)operation->node->cache)
                gegl_cache_computed (operation->node->cache, &context->need_rect, level);
            }
        }
      else
        {
          operation_result = NULL;
        }

      if (operation_result)
        {
          GeglPad *output_pad = gegl_node_get_pad (node, "output");
          GList   *targets = gegl_graph_get_connected_output_contexts (path, output_pad);
          GList   *targets_iter;

          GEGL_NOTE (GEGL_DEBUG_PROCESS,
                     "Will deliver the results of %s:%s to %d targets",
                     gegl_node_get_debug_name (node),
                     "output",
                     g_list_length (targets));

          if (g_list_length (targets) > 1)
            gegl_object_set_has_forked (G_OBJECT (operation_result));

          for (targets_iter = targets; targets_iter; targets_iter = g_list_next (targets_iter))
            {
              ContextConnection *target_con = targets_iter->data;
              gegl_operation_context_set_object (target_con->context, target_con->name, G_OBJECT (operation_result));
            }
          g_list_free_full (targets, free_context_connection);
        }
      last_context = context;

      GEGL_INSTRUMENT_END ("process", gegl_node_get_operation (node));
    }
  if (last_context)
    {
      if (operation_result)
        result = g_object_ref (operation_result);
      else if (gegl_node_has_pad (last_context->operation->node, "output"))
        result = g_object_ref (gegl_graph_get_shared_empty (path));
      gegl_operation_context_purge (last_context);
    }

  return result;
}
Ejemplo n.º 3
0
void
gegl_exit (void)
{
  if (!config)
    {
      g_warning("gegl_exit() called without matching call to gegl_init()");
      return;
    }

  GEGL_INSTRUMENT_START()

  gegl_tile_backend_swap_cleanup ();
  gegl_tile_cache_destroy ();
  gegl_operation_gtype_cleanup ();
  gegl_extension_handler_cleanup ();
  gegl_random_cleanup ();
  gegl_cl_cleanup ();

  gegl_temp_buffer_free ();

  if (module_db != NULL)
    {
      g_object_unref (module_db);
      module_db = NULL;
    }

  babl_exit ();

  GEGL_INSTRUMENT_END ("gegl", "gegl_exit")

  /* used when tracking buffer and tile leaks */
  if (g_getenv ("GEGL_DEBUG_BUFS") != NULL)
    {
      gegl_buffer_stats ();
      gegl_tile_backend_ram_stats ();
      gegl_tile_backend_file_stats ();
    }
  global_time = gegl_ticks () - global_time;
  gegl_instrument ("gegl", "gegl", global_time);

  if (gegl_instrument_enabled)
    {
      g_printf ("\n%s", gegl_instrument_utf8 ());
    }

  if (gegl_buffer_leaks ())
    {
      g_printf ("EEEEeEeek! %i GeglBuffers leaked\n", gegl_buffer_leaks ());
#ifdef GEGL_ENABLE_DEBUG
      if (!(gegl_debug_flags & GEGL_DEBUG_BUFFER_ALLOC))
        g_printerr ("To debug GeglBuffer leaks, set the environment "
                    "variable GEGL_DEBUG to \"buffer-alloc\"\n");
#endif
    }
  gegl_tile_cache_destroy ();

  if (gegl_swap_dir ())
    {
      /* remove all files matching <$GEGL_SWAP>/GEGL-<pid>-*.swap */

      guint         pid     = getpid ();
      GDir         *dir     = g_dir_open (gegl_swap_dir (), 0, NULL);

      gchar        *glob    = g_strdup_printf ("%i-*", pid);
      GPatternSpec *pattern = g_pattern_spec_new (glob);
      g_free (glob);

      if (dir != NULL)
        {
          const gchar *name;

          while ((name = g_dir_read_name (dir)) != NULL)
            {
              if (g_pattern_match_string (pattern, name))
                {
                  gchar *fname = g_build_filename (gegl_swap_dir (),
                                                   name,
                                                   NULL);
                  g_unlink (fname);
                  g_free (fname);
                }
            }

          g_dir_close (dir);
        }

      g_pattern_spec_free (pattern);
    }
  g_object_unref (config);
  config = NULL;
  global_time = 0;
}