[babl] babl: refactor code to get rid of more branches in babl_process
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] babl: refactor code to get rid of more branches in babl_process
- Date: Sun, 14 Jan 2018 22:31:03 +0000 (UTC)
commit 9debb9d7f68afb5b9028343e3b33cbf4aa7edc6c
Author: Øyvind Kolås <pippin gimp org>
Date: Sun Jan 14 22:49:40 2018 +0100
babl: refactor code to get rid of more branches in babl_process
In the best case scenario now, babl_process increments instrumentation
counters and directly calls the relevant registered fast path function,
with no additional call stack frames in-between.
babl/babl-fish-path.c | 119 +++++++++++++++++++++++---------------------
babl/babl-fish-reference.c | 7 ++-
babl/babl-fish-simple.c | 3 +-
babl/babl-fish.c | 1 +
babl/babl-fish.h | 2 +-
babl/babl-internal.h | 5 ++-
6 files changed, 75 insertions(+), 62 deletions(-)
---
diff --git a/babl/babl-fish-path.c b/babl/babl-fish-path.c
index dbfa4de..301dd5c 100644
--- a/babl/babl-fish-path.c
+++ b/babl/babl-fish-path.c
@@ -596,12 +596,8 @@ babl_fish_path2 (const Babl *source,
return NULL;
}
- if (babl_list_size (babl->fish_path.conversion_list) == 1)
- {
- babl->class_type = BABL_FISH_SIMPLE;
- babl->fish_simple.conversion = (void*)babl_list_get_first (babl->fish_path.conversion_list);
- }
-
+ babl_fish_prepare_bpp (babl);
+ _babl_fish_rig_dispatch (babl);
/* Since there is not an already registered instance by the required
* name, inserting newly created class into database.
*/
@@ -610,7 +606,6 @@ babl_fish_path2 (const Babl *source,
babl_db_insert (babl_fish_db (), babl);
}
babl_mutex_unlock (babl_format_mutex);
- babl_fish_prepare_bpp (babl);
return babl;
}
@@ -648,9 +643,10 @@ babl_fish_path (const Babl *source,
static inline void
babl_fish_path_process (const Babl *babl,
- const void *source,
- void *destination,
- long n)
+ const char *source,
+ char *destination,
+ long n,
+ void *data)
{
process_conversion_path (babl->fish_path.conversion_list,
source,
@@ -660,34 +656,40 @@ babl_fish_path_process (const Babl *babl,
n);
}
-static long
-_babl_process (Babl *babl,
- const void *source,
- void *destination,
- long n)
+static inline void
+babl_fish_memcpy_process (const Babl *babl,
+ const char *source,
+ char *destination,
+ long n,
+ void *data)
+{
+ memcpy (destination, source, n * babl->fish.source->format.bytes_per_pixel);
+}
+
+void
+_babl_fish_rig_dispatch (Babl *babl)
{
switch (babl->class_type)
{
case BABL_FISH_REFERENCE:
- babl->fish.processings++;
- babl->fish.pixels += n;
if (babl->fish.source == babl->fish.destination)
- { /* XXX: we're assuming linear buffers */
- memcpy (destination, source, n * babl->fish.source->format.bytes_per_pixel);
+ {
+ babl->fish.dispatch = babl_fish_memcpy_process;
}
else
{
- babl_fish_reference_process (babl, source, destination, n);
+ babl->fish.dispatch = babl_fish_reference_process;
}
break;
case BABL_FISH_SIMPLE:
- babl->fish.processings++;
- babl->fish.pixels += n;
if (BABL (babl->fish_simple.conversion)->class_type == BABL_CONVERSION_LINEAR)
{
- babl_conversion_process (BABL (babl->fish_simple.conversion),
- source, destination, n);
+ /* lift out conversion from single step conversion and make it be the dispatch function
+ * itself
+ */
+ babl->fish.data = babl->fish_simple.conversion->data;
+ babl->fish.dispatch = babl->fish_simple.conversion->dispatch;
}
else
{
@@ -696,9 +698,19 @@ _babl_process (Babl *babl,
break;
case BABL_FISH_PATH:
- babl->fish.processings++;
- babl->fish.pixels += n;
- babl_fish_path_process (babl, source, destination, n);
+ if (babl_list_size(babl->fish_path.conversion_list) == 1)
+ {
+ BablConversion *conversion = (void*)babl_list_get_first(babl->fish_path.conversion_list);
+
+ /* do same short-circuit optimization as for simple fishes */
+
+ babl->fish.dispatch = conversion->dispatch;
+ babl->fish.data = conversion->data;
+ }
+ else
+ {
+ babl->fish.dispatch = babl_fish_path_process;
+ }
break;
case BABL_CONVERSION:
@@ -706,14 +718,24 @@ _babl_process (Babl *babl,
case BABL_CONVERSION_PLANE:
case BABL_CONVERSION_PLANAR:
babl_assert (0);
- babl_conversion_process (babl, source, destination, n);
break;
default:
babl_log ("NYI");
- return -1;
break;
}
+}
+
+static long
+_babl_process (const Babl *cbabl,
+ const void *source,
+ void *destination,
+ long n)
+{
+ Babl *babl = (void*)cbabl;
+ babl->fish.processings++;
+ babl->fish.pixels += n;
+ babl->fish.dispatch (babl, source, destination, n, babl->fish.data);
return n;
}
@@ -745,33 +767,16 @@ babl_process_rows (const Babl *fish,
if (n <= 0)
return 0;
- /* first check if it is a fish since that is our fast path */
- if (babl->class_type >= BABL_FISH &&
- babl->class_type <= BABL_FISH_PATH)
+ babl->fish.processings++;
+ babl->fish.pixels += n * rows;
+ for (row = 0; row < rows; row++)
{
- babl->fish.processings++;
- babl->fish.pixels += n * rows;
- for (row = 0; row < rows; row++)
- {
- _babl_process ((void*)babl, src, dst, n);
- src += source_stride;
- dst += dest_stride;
- }
- return n * rows;
- }
+ babl->fish.dispatch (babl, (void*)src, (void*)dst, n, babl->fish.data);
- /* matches all conversion classes */
- if (babl->class_type >= BABL_CONVERSION &&
- babl->class_type <= BABL_CONVERSION_PLANAR)
- {
- for (row = 0; row < rows; row++)
- {
- babl_conversion_process (babl, (void*)src, (void*)dst, n);
src += source_stride;
dst += dest_stride;
}
- return n * rows;
- }
+ return n * rows;
babl_fatal ("eek");
return -1;
@@ -894,8 +899,8 @@ init_path_instrumentation (FishPathInstrumentation *fpi,
fpi->fmt_rgba_double->format.bytes_per_pixel);
/* create sourcebuffer from testbuffer in the correct format */
- babl_process (fpi->fish_rgba_to_source,
- test_pixels, fpi->source, fpi->num_test_pixels);
+ _babl_process (fpi->fish_rgba_to_source,
+ test_pixels, fpi->source, fpi->num_test_pixels);
/* calculate the reference buffer of how it should be */
ticks_start = babl_ticks ();
@@ -905,8 +910,8 @@ init_path_instrumentation (FishPathInstrumentation *fpi,
fpi->reference_cost = ticks_end - ticks_start;
/* transform the reference destination buffer to RGBA */
- babl_process (fpi->fish_destination_to_rgba,
- fpi->ref_destination, fpi->ref_destination_rgba_double, fpi->num_test_pixels);
+ _babl_process (fpi->fish_destination_to_rgba,
+ fpi->ref_destination, fpi->ref_destination_rgba_double, fpi->num_test_pixels);
}
static void
@@ -983,8 +988,8 @@ get_path_instrumentation (FishPathInstrumentation *fpi,
/* transform the reference and the actual destination buffers to RGBA
* for comparison with each other
*/
- babl_process (fpi->fish_destination_to_rgba,
- fpi->destination, fpi->destination_rgba_double, fpi->num_test_pixels);
+ _babl_process (fpi->fish_destination_to_rgba,
+ fpi->destination, fpi->destination_rgba_double, fpi->num_test_pixels);
*path_error = babl_rel_avg_error (fpi->destination_rgba_double,
fpi->ref_destination_rgba_double,
diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c
index 072c10f..695c3ca 100644
--- a/babl/babl-fish-reference.c
+++ b/babl/babl-fish-reference.c
@@ -115,6 +115,7 @@ babl_fish_reference (const Babl *source,
#ifndef HAVE_TLS
free (name);
#endif
+ _babl_fish_rig_dispatch (babl);
return babl;
}
@@ -124,7 +125,7 @@ babl_fish_reference (const Babl *source,
babl_assert (source->class_type == BABL_FORMAT);
babl_assert (destination->class_type == BABL_FORMAT);
- babl = babl_malloc (sizeof (BablFishReference) +
+ babl = babl_calloc (1, sizeof (BablFishReference) +
strlen (name) + 1);
babl->class_type = BABL_FISH_REFERENCE;
babl->instance.id = babl_fish_get_id (source, destination);
@@ -138,6 +139,7 @@ babl_fish_reference (const Babl *source,
babl->fish.error = 0.0; /* assuming the provided reference conversions for types
and models are as exact as possible
*/
+ _babl_fish_rig_dispatch (babl);
/* Since there is not an already registered instance by the required
* name, inserting newly created class into database.
@@ -443,7 +445,8 @@ void
babl_fish_reference_process (const Babl *babl,
const char *source,
char *destination,
- long n)
+ long n,
+ void *data)
{
void *source_double_buf;
void *rgba_double_buf;
diff --git a/babl/babl-fish-simple.c b/babl/babl-fish-simple.c
index eeaed51..1fa3384 100644
--- a/babl/babl-fish-simple.c
+++ b/babl/babl-fish-simple.c
@@ -42,7 +42,7 @@ babl_fish_simple (BablConversion *conversion)
return babl;
}
- babl = babl_malloc (sizeof (BablFishSimple) +
+ babl = babl_calloc (1, sizeof (BablFishSimple) +
strlen (name) + 1);
babl->class_type = BABL_FISH_SIMPLE;
babl->instance.id = babl_fish_get_id (conversion->source, conversion->destination);
@@ -58,6 +58,7 @@ babl_fish_simple (BablConversion *conversion)
reference, and babl fish reference only requests clean
conversions */
+ _babl_fish_rig_dispatch (babl);
/* Since there is not an already registered instance by the required
* name, inserting newly created class into database.
*/
diff --git a/babl/babl-fish.c b/babl/babl-fish.c
index 749b075..8c73a2b 100644
--- a/babl/babl-fish.c
+++ b/babl/babl-fish.c
@@ -257,6 +257,7 @@ babl_fish (const void *source,
if (ffish.fish_path)
{
/* we have found suitable fish path in the database */
+ _babl_fish_rig_dispatch (ffish.fish_path);
return ffish.fish_path;
}
diff --git a/babl/babl-fish.h b/babl/babl-fish.h
index 9f0cdd6..36ef098 100644
--- a/babl/babl-fish.h
+++ b/babl/babl-fish.h
@@ -31,7 +31,7 @@ typedef struct
BablInstance instance;
const Babl *source;
const Babl *destination;
- void (*dispatch) (const Babl *babl, const char *src, char *dst, long n);
+ void (*dispatch) (const Babl *babl, const char *src, char *dst, long n, void *data);
void *data; /* user data */
double error; /* the amount of noise introduced by the fish */
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 337541b..9d29b47 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -78,7 +78,8 @@ void babl_extension_deinit (void);
void babl_fish_reference_process (const Babl *babl,
const char *source,
char *destination,
- long n);
+ long n,
+ void *data); // data is ignored
Babl * babl_fish_reference (const Babl *source,
const Babl *destination);
@@ -495,4 +496,6 @@ babl_conversion_process (const Babl *babl,
conversion->dispatch (babl, source, destination, n, conversion->data);
}
+void _babl_fish_rig_dispatch (Babl *babl);
+
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]