Hi, attached is a path that introduces logic to disallow creation of a fish path that is actually slower than appropriate reference fish. Suggested Changelog entry: * babl/babl-fish-path.c (get_conversion_path), (babl_fish_path), (test_create), (init_path_instrumentation), (destroy_path_instrumentation), (get_path_instrumentation): Improved fish path instrumentation during the search for a new one to optimize for speed. Added logic to disallow creation of a fish path that is actually slower than appropriate reference fish. * babl/babl-util.[ch] (babl_process_cost): New function for unified timing formula for babl processings. * babl/babl-conversion.c (babl_conversion_error): Make use of the new babl_process_cost function. * extensions/gimp-8bit.c: Added a function declaration to prevent compiler warning. Regards, Jan
Index: extensions/gimp-8bit.c =================================================================== --- extensions/gimp-8bit.c (revision 304) +++ extensions/gimp-8bit.c (working copy) @@ -296,6 +296,7 @@ conv_g8_gamma_2_2_rgbaF_linear (unsigned return samples; } +int init (void); int init (void) Index: babl/babl-fish-path.c =================================================================== --- babl/babl-fish-path.c (revision 304) +++ babl/babl-fish-path.c (working copy) @@ -23,7 +23,17 @@ #define BABL_MAX_COST_VALUE 2000000 static double -get_conversion_path_error (BablList *path); +init_path_instrumentation (Babl *fmt_source, + Babl *fmt_destination); + +static void +destroy_path_instrumentation (void); + +static void +get_path_instrumentation (BablList *path, + double *path_cost, + double *ref_cost, + double *path_error); static long process_conversion_path (BablList *path, @@ -118,28 +128,32 @@ get_conversion_path (Babl *current_forma { /* We have found a candidate path, let's * see about it's properties */ - double temp_cost = 0.0; - double temp_error = 1.0; + double path_cost = 0.0; + double ref_cost = 0.0; + double path_error = 1.0; int i; for (i = 0; i < babl_list_size (current_path); i++) { - temp_error *= (1.0 + babl_conversion_error ((BablConversion *) current_path->items[i])); - temp_cost += babl_conversion_cost ((BablConversion *) current_path->items[i]); + path_error *= (1.0 + babl_conversion_error ((BablConversion *) current_path->items[i])); } - if (temp_cost < fish_path->fish_path.cost && - temp_error - 1.0 <= legal_error () && /* check this before the next; - which does a more accurate - measurement of the error */ - (temp_error = get_conversion_path_error (current_path)) <= legal_error () - ) + if (path_error - 1.0 <= legal_error ()) /* check this before the next; + which does a more accurate + measurement of the error */ { - /* We have found the best path so far, - * let's copy it into our new fish */ - fish_path->fish_path.cost = temp_cost; - fish_path->fish.error = temp_error; - babl_list_copy (current_path, fish_path->fish_path.conversion_list); + get_path_instrumentation (current_path, &path_cost, &ref_cost, &path_error); + + if ((path_cost < ref_cost) && /* do not use paths that took longer to compute than reference */ + (path_cost < fish_path->fish_path.cost) && + (path_error <= legal_error ())) + { + /* We have found the best path so far, + * let's copy it into our new fish */ + fish_path->fish_path.cost = path_cost; + fish_path->fish.error = path_error; + babl_list_copy (current_path, fish_path->fish_path.conversion_list); + } } } else @@ -163,11 +177,10 @@ get_conversion_path (Babl *current_forma if (!next_format->format.visited) { /* next_format is not in the current path, we can pay a visit */ - babl_list_insert_last (current_path, next_conversion); - get_conversion_path (next_format, current_length + 1, max_length); - babl_list_remove_last (current_path); - } - + babl_list_insert_last (current_path, next_conversion); + get_conversion_path (next_format, current_length + 1, max_length); + babl_list_remove_last (current_path); + } } /* Remove the current format from current path */ @@ -228,6 +241,7 @@ babl_fish_path (const Babl *source, to_format = (Babl *) destination; get_conversion_path ((Babl *) source, 0, max_path_length ()); + destroy_path_instrumentation (); babl_list_destroy (current_path); @@ -328,25 +342,21 @@ process_conversion_path (BablList *path, return n; } -#define NUM_TEST_PIXELS (128 + 16 + 16) +#define NUM_TEST_PIXELS (256 + 16 + 16) static double * test_create (void) { static double test[sizeof (double) * NUM_TEST_PIXELS * 4]; - static int flag = 0; int i, j; /* There is no need to generate the test * more times ... */ - if (flag) - return test; - flag = 1; srandom (20050728); /* add 128 pixels in the valid range between 0.0 and 1.0 */ - for (i = 0; i < 128 * 4; i++) + for (i = 0; i < 256 * 4; i++) test [i] = (double) random () / RAND_MAX; /* add 16 pixels between -1.0 and 0.0 */ @@ -360,38 +370,49 @@ test_create (void) return test; } +// FishPath instrumentation + +static Babl *fmt_rgba_double = NULL; +static double *test = NULL; +static void *source; +static void *destination; +static void *ref_destination; +static double *destination_rgba_double; +static double *ref_destination_rgba_double; +static Babl *fish_rgba_to_source; +static Babl *fish_reference; +static Babl *fish_destination_to_rgba; +static double reference_cost; +static int init_instrumentation_done = 0; + static double -get_conversion_path_error (BablList *path) +init_path_instrumentation (Babl *fmt_source, + Babl *fmt_destination) { - Babl *fmt_rgba_double = babl_format_new ( - babl_model ("RGBA"), - babl_type ("double"), - babl_component ("R"), - babl_component ("G"), - babl_component ("B"), - babl_component ("A"), - NULL); - - double error = 0.0; - - Babl *fmt_source = (Babl *) BABL (babl_list_get_first (path))->conversion.source; - Babl *fmt_destination = (Babl *) BABL (babl_list_get_last (path))->conversion.destination; - - double *test; - void *source; - void *destination; - double *destination_rgba_double; - void *ref_destination; - double *ref_destination_rgba_double; - - Babl *fish_rgba_to_source = babl_fish_reference (fmt_rgba_double, - fmt_source); - Babl *fish_reference = babl_fish_reference (fmt_source, - fmt_destination); - Babl *fish_destination_to_rgba = babl_fish_reference (fmt_destination, - fmt_rgba_double); + long ticks_start = 0; + long ticks_end = 0; + + if (!fmt_rgba_double) + { + fmt_rgba_double = babl_format_new ( + babl_model ("RGBA"), + babl_type ("double"), + babl_component ("R"), + babl_component ("G"), + babl_component ("B"), + babl_component ("A"), + NULL); + } - test = test_create (); + if (!test) + test = test_create (); + + fish_rgba_to_source = babl_fish_reference (fmt_rgba_double, + fmt_source); + fish_reference = babl_fish_reference (fmt_source, + fmt_destination); + fish_destination_to_rgba = babl_fish_reference (fmt_destination, + fmt_rgba_double); source = babl_calloc (NUM_TEST_PIXELS, fmt_source->format.bytes_per_pixel); @@ -409,23 +430,68 @@ get_conversion_path_error (BablList *pat test, source, NUM_TEST_PIXELS); /* calculate the reference buffer of how it should be */ + ticks_start = babl_ticks (); babl_process (fish_reference, source, ref_destination, NUM_TEST_PIXELS); + ticks_end = babl_ticks (); + reference_cost = babl_process_cost (ticks_start, ticks_end); + + /* transform the reference destination buffer to RGBA */ + babl_process (fish_destination_to_rgba, + ref_destination, ref_destination_rgba_double, NUM_TEST_PIXELS); +} + +static void +destroy_path_instrumentation (void) +{ + if (init_instrumentation_done) + { + babl_free (source); + babl_free (destination); + babl_free (destination_rgba_double); + babl_free (ref_destination); + babl_free (ref_destination_rgba_double); + + /* nulify the flag for potential new search */ + init_instrumentation_done = 0; + } +} + +static void +get_path_instrumentation (BablList *path, + double *path_cost, + double *ref_cost, + double *path_error) +{ + long ticks_start = 0; + long ticks_end = 0; + + if (!init_instrumentation_done) + { + /* this initialization can be done only once since the + * source and destination formats do not change during + * the search */ + Babl *fmt_source = (Babl *) BABL (babl_list_get_first (path))->conversion.source; + Babl *fmt_destination = (Babl *) BABL (babl_list_get_last (path))->conversion.destination; + init_path_instrumentation (fmt_source, fmt_destination); + init_instrumentation_done = 1; + } /* calculate this path's view of what the result should be */ + ticks_start = babl_ticks (); process_conversion_path (path, source, destination, NUM_TEST_PIXELS); + ticks_end = babl_ticks (); + *path_cost = babl_process_cost (ticks_start, ticks_end); /* transform the reference and the actual destination buffers to RGBA * for comparison with each other */ babl_process (fish_destination_to_rgba, - ref_destination, ref_destination_rgba_double, NUM_TEST_PIXELS); - babl_process (fish_destination_to_rgba, destination, destination_rgba_double, NUM_TEST_PIXELS); - error = babl_rel_avg_error (destination_rgba_double, - ref_destination_rgba_double, - NUM_TEST_PIXELS * 4); + *path_error = babl_rel_avg_error (destination_rgba_double, + ref_destination_rgba_double, + NUM_TEST_PIXELS * 4); fish_rgba_to_source->fish.processings--; fish_reference->fish.processings--; @@ -435,11 +501,5 @@ get_conversion_path_error (BablList *pat fish_reference->fish.pixels -= NUM_TEST_PIXELS; fish_destination_to_rgba->fish.pixels -= 2 * NUM_TEST_PIXELS; - babl_free (source); - babl_free (destination); - babl_free (destination_rgba_double); - babl_free (ref_destination); - babl_free (ref_destination_rgba_double); - - return error; + *ref_cost = reference_cost; } Index: babl/babl-util.c =================================================================== --- babl/babl-util.c (revision 304) +++ babl/babl-util.c (working copy) @@ -46,6 +46,13 @@ babl_ticks (void) return usecs (measure_time) - usecs (start_time); } +long +babl_process_cost (long ticks_start, + long ticks_end) +{ + return (ticks_end - ticks_start) * 10 + 1; +} + double babl_rel_avg_error (double *imgA, double *imgB, Index: babl/babl-util.h =================================================================== --- babl/babl-util.h (revision 304) +++ babl/babl-util.h (working copy) @@ -22,6 +22,10 @@ long babl_ticks (void); +long +babl_process_cost (long ticks_start, + long ticks_end); + double babl_rel_avg_error (double *imgA, double *imgB, Index: babl/babl-conversion.c =================================================================== --- babl/babl-conversion.c (revision 304) +++ babl/babl-conversion.c (working copy) @@ -550,7 +550,7 @@ babl_conversion_error (BablConversion *c babl_free (test); conversion->error = error; - conversion->cost = (ticks_end - ticks_start) * 10 + 1; + conversion->cost = babl_process_cost (ticks_start, ticks_end); return error; }
_______________________________________________ Gegl-developer mailing list Gegl-developer@xxxxxxxxxxxxxxxxxxxxxx https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer