summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Spitzak <spitzak@gmail.com>2016-08-30 22:03:09 -0700
committerSøren Sandmann Pedersen <soren.sandmann@gmail.com>2016-09-02 00:40:12 -0400
commit6acaf2bcb1246529143c112dbce6dd9d6f7cb51e (patch)
tree9492d476710db2cb2e0d5d1f6e9caf4173504f78
parentd0e6c9f4f65e429058b97d2f947b048b445c17c4 (diff)
pixman-filter: reduce amount of malloc/free/memcpy to generate filter
Rearranged so that the entire block of memory for the filter pair is allocated first, and then filled in. Previous version allocated and freed two temporary buffers for each filter and did an extra memcpy. v8: small refactor to remove the filter_width function v10: Restored filter_width function but with arguments changed to match later patches v11: Removed unused arg and pointer from filter_width function Whitespace fixes. Signed-off-by: Bill Spitzak <spitzak@gmail.com> Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com> Acked-by: Søren Sandmann <soren.sandmann@gmail.com>
-rw-r--r--pixman/pixman-filter.c56
1 files changed, 23 insertions, 33 deletions
diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index aa7bb80..c018a67 100644
--- a/pixman/pixman-filter.c
+++ b/pixman/pixman-filter.c
@@ -217,25 +217,17 @@ integral (pixman_kernel_t kernel1, double x1,
}
}
-static pixman_fixed_t *
-create_1d_filter (int *width,
+static void
+create_1d_filter (int width,
pixman_kernel_t reconstruct,
pixman_kernel_t sample,
double scale,
- int n_phases)
+ int n_phases,
+ pixman_fixed_t *p)
{
- pixman_fixed_t *params, *p;
double step;
- double size;
int i;
- size = scale * filters[sample].width + filters[reconstruct].width;
- *width = ceil (size);
-
- p = params = malloc (*width * n_phases * sizeof (pixman_fixed_t));
- if (!params)
- return NULL;
-
step = 1.0 / n_phases;
for (i = 0; i < n_phases; ++i)
@@ -250,8 +242,8 @@ create_1d_filter (int *width,
* and sample positions.
*/
- x1 = ceil (frac - *width / 2.0 - 0.5);
- x2 = x1 + *width;
+ x1 = ceil (frac - width / 2.0 - 0.5);
+ x2 = x1 + width;
total = 0;
for (x = x1; x < x2; ++x)
@@ -279,7 +271,7 @@ create_1d_filter (int *width,
}
/* Normalize */
- p -= *width;
+ p -= width;
total = 1 / total;
new_total = 0;
for (x = x1; x < x2; ++x)
@@ -291,10 +283,15 @@ create_1d_filter (int *width,
}
if (new_total != pixman_fixed_1)
- *(p - *width / 2) += (pixman_fixed_1 - new_total);
+ *(p - width / 2) += (pixman_fixed_1 - new_total);
}
+}
- return params;
+
+static int
+filter_width (pixman_kernel_t reconstruct, pixman_kernel_t sample, double size)
+{
+ return ceil (filters[reconstruct].width + size * filters[sample].width);
}
#ifdef PIXMAN_GNUPLOT
@@ -426,38 +423,31 @@ pixman_filter_create_separable_convolution (int *n_values,
{
double sx = fabs (pixman_fixed_to_double (scale_x));
double sy = fabs (pixman_fixed_to_double (scale_y));
- pixman_fixed_t *horz = NULL, *vert = NULL, *params = NULL;
+ pixman_fixed_t *params;
int subsample_x, subsample_y;
int width, height;
+ width = filter_width (reconstruct_x, sample_x, sx);
subsample_x = (1 << subsample_bits_x);
- subsample_y = (1 << subsample_bits_y);
- horz = create_1d_filter (&width, reconstruct_x, sample_x, sx, subsample_x);
- vert = create_1d_filter (&height, reconstruct_y, sample_y, sy, subsample_y);
+ height = filter_width (reconstruct_y, sample_y, sy);
+ subsample_y = (1 << subsample_bits_y);
- if (!horz || !vert)
- goto out;
-
*n_values = 4 + width * subsample_x + height * subsample_y;
params = malloc (*n_values * sizeof (pixman_fixed_t));
if (!params)
- goto out;
+ return NULL;
params[0] = pixman_int_to_fixed (width);
params[1] = pixman_int_to_fixed (height);
params[2] = pixman_int_to_fixed (subsample_bits_x);
params[3] = pixman_int_to_fixed (subsample_bits_y);
- memcpy (params + 4, horz,
- width * subsample_x * sizeof (pixman_fixed_t));
- memcpy (params + 4 + width * subsample_x, vert,
- height * subsample_y * sizeof (pixman_fixed_t));
-
-out:
- free (horz);
- free (vert);
+ create_1d_filter (width, reconstruct_x, sample_x, sx, subsample_x,
+ params + 4);
+ create_1d_filter (height, reconstruct_y, sample_y, sy, subsample_y,
+ params + 4 + width * subsample_x);
#ifdef PIXMAN_GNUPLOT
gnuplot_filter(width, subsample_x, params + 4);