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; }
/** * 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; }
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; }