[Pixman] [PATCH 05/13] Implementing memcpy through pointer
Nemanja Lukic
nemanja.lukic at rt-rk.com
Fri Jun 27 09:05:42 PDT 2014
pointer to function (memcpy) added to pixman_implementation_t
and it points to C version of memcpy (linked in
pixman-general.c). Function to call is pixman_memcpy and
every call of memcpy is replaced with pixman_memcpy.
If there is optimized version of memcpy it should
be linked with imp->memcpy.
---
pixman/pixman-combine32.c | 2 +-
pixman/pixman-fast-path.c | 2 +-
pixman/pixman-filter.c | 4 ++--
pixman/pixman-general.c | 2 ++
pixman/pixman-image.c | 8 ++++----
pixman/pixman-implementation.c | 20 ++++++++++++++++++++
pixman/pixman-private.h | 10 ++++++++++
pixman/pixman-region.c | 4 ++--
pixman/pixman-x86.c | 6 +++---
pixman/pixman.c | 9 +++++++++
pixman/pixman.h | 3 +++
test/lowlevel-blt-bench.c | 36 ++++++++++++++++++------------------
test/tolerance-test.c | 2 +-
test/utils-prng.c | 2 +-
14 files changed, 77 insertions(+), 33 deletions(-)
diff --git a/pixman/pixman-combine32.c b/pixman/pixman-combine32.c
index 4c484d3..68c4427 100644
--- a/pixman/pixman-combine32.c
+++ b/pixman/pixman-combine32.c
@@ -173,7 +173,7 @@ combine_src_u (pixman_implementation_t *imp,
if (!mask)
{
- memcpy (dest, src, width * sizeof (uint32_t));
+ pixman_memcpy (dest, src, width * sizeof (uint32_t));
}
else
{
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index c6e43de..9eb1ed8 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1175,7 +1175,7 @@ fast_composite_src_memcpy (pixman_implementation_t *imp,
while (height--)
{
- memcpy (dst, src, n_bytes);
+ pixman_memcpy (dst, src, n_bytes);
dst += dst_stride;
src += src_stride;
diff --git a/pixman/pixman-filter.c b/pixman/pixman-filter.c
index b2bf53f..52db5f3 100644
--- a/pixman/pixman-filter.c
+++ b/pixman/pixman-filter.c
@@ -337,9 +337,9 @@ pixman_filter_create_separable_convolution (int *n_values,
params[2] = pixman_int_to_fixed (subsample_bits_x);
params[3] = pixman_int_to_fixed (subsample_bits_y);
- memcpy (params + 4, horz,
+ pixman_memcpy (params + 4, horz,
width * subsample_x * sizeof (pixman_fixed_t));
- memcpy (params + 4 + width * subsample_x, vert,
+ pixman_memcpy (params + 4 + width * subsample_x, vert,
height * subsample_y * sizeof (pixman_fixed_t));
out:
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 7cdea29..8ecbe30 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -249,6 +249,8 @@ _pixman_implementation_create_general (void)
{
pixman_implementation_t *imp = _pixman_implementation_create (NULL, general_fast_path);
+ imp->memcpy = (void*)memcpy;
+
_pixman_setup_combiner_functions_32 (imp);
_pixman_setup_combiner_functions_float (imp);
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 1ff1a49..4896399 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -98,7 +98,7 @@ _pixman_init_gradient (gradient_t * gradient,
return FALSE;
gradient->stops += 1;
- memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
+ pixman_memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
gradient->n_stops = n_stops;
gradient->common.property_changed = gradient_property_changed;
@@ -652,7 +652,7 @@ pixman_image_set_transform (pixman_image_t * image,
goto out;
}
- memcpy (common->transform, transform, sizeof(pixman_transform_t));
+ pixman_memcpy (common->transform, transform, sizeof(pixman_transform_t));
result = TRUE;
@@ -706,8 +706,8 @@ pixman_image_set_filter (pixman_image_t * image,
if (!new_params)
return FALSE;
- memcpy (new_params,
- params, n_params * sizeof (pixman_fixed_t));
+ pixman_memcpy (new_params,
+ params, n_params * sizeof (pixman_fixed_t));
}
common->filter = filter;
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 5884054..d4ca0b2 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -285,6 +285,26 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
return FALSE;
}
+pixman_bool_t
+_pixman_implementation_memcpy (pixman_implementation_t *imp,
+ void *dest,
+ const void *src,
+ uint32_t n)
+{
+ while (imp)
+ {
+ if (imp->memcpy &&
+ ((*imp->memcpy) (dest, src, n)))
+ {
+ return TRUE;
+ }
+
+ imp = imp->fallback;
+ }
+
+ return FALSE;
+}
+
static uint32_t *
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
{
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index fdc966a..367f4cb 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -476,6 +476,9 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
int width,
int height,
uint32_t filler);
+typedef void* (*pixman_memcpy_func_t) (void * dest,
+ const void * src,
+ uint32_t n);
void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
void _pixman_setup_combiner_functions_float (pixman_implementation_t *imp);
@@ -501,6 +504,7 @@ struct pixman_implementation_t
pixman_blt_func_t blt;
pixman_fill_func_t fill;
+ pixman_memcpy_func_t memcpy;
pixman_combine_32_func_t combine_32[PIXMAN_N_OPERATORS];
pixman_combine_32_func_t combine_32_ca[PIXMAN_N_OPERATORS];
@@ -561,6 +565,12 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
int height,
uint32_t filler);
+pixman_bool_t
+_pixman_implementation_memcpy (pixman_implementation_t *imp,
+ void * dest,
+ const void * src,
+ uint32_t n);
+
void
_pixman_implementation_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 59bc9c7..8cfc5f6 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -1712,7 +1712,7 @@ validate (region_type_t * badreg)
rit = malloc (data_size);
if (!rit)
goto bail;
- memcpy (rit, ri, num_ri * sizeof (region_info_t));
+ pixman_memcpy (rit, ri, num_ri * sizeof (region_info_t));
}
else
{
@@ -2506,7 +2506,7 @@ PREFIX (_init_rects) (region_type_t *region,
rects = PIXREGION_RECTS (region);
/* Copy in the rects */
- memcpy (rects, boxes, sizeof(box_type_t) * count);
+ pixman_memcpy (rects, boxes, sizeof(box_type_t) * count);
region->data->numRects = count;
/* Eliminate empty and malformed rectangles */
diff --git a/pixman/pixman-x86.c b/pixman/pixman-x86.c
index 05297c4..9a278c7 100644
--- a/pixman/pixman-x86.c
+++ b/pixman/pixman-x86.c
@@ -182,9 +182,9 @@ detect_cpu_features (void)
memset (vendor, 0, sizeof vendor);
pixman_cpuid (0x00, &a, &b, &c, &d);
- memcpy (vendor + 0, &b, 4);
- memcpy (vendor + 4, &d, 4);
- memcpy (vendor + 8, &c, 4);
+ pixman_memcpy (vendor + 0, &b, 4);
+ pixman_memcpy (vendor + 4, &d, 4);
+ pixman_memcpy (vendor + 8, &c, 4);
if (strcmp (vendor, "AuthenticAMD") == 0 ||
strcmp (vendor, "Geode by NSC") == 0)
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 9555cea..280bc31 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -767,6 +767,15 @@ pixman_fill (uint32_t *bits,
get_implementation(), bits, stride, bpp, x, y, width, height, filler);
}
+PIXMAN_EXPORT pixman_bool_t
+pixman_memcpy (void *dest,
+ const void *src,
+ uint32_t n)
+{
+ return _pixman_implementation_memcpy (
+ get_implementation(), dest, src, n);
+}
+
static uint32_t
color_to_uint32 (const pixman_color_t *color)
{
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 509ba5e..6f2f6ad 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -609,6 +609,9 @@ pixman_bool_t pixman_fill (uint32_t *bits,
int width,
int height,
uint32_t _xor);
+pixman_bool_t pixman_memcpy (void *dest,
+ const void *src,
+ uint32_t n);
int pixman_version (void);
const char* pixman_version_string (void);
diff --git a/test/lowlevel-blt-bench.c b/test/lowlevel-blt-bench.c
index 9d7fc3f..ae1ab1f 100644
--- a/test/lowlevel-blt-bench.c
+++ b/test/lowlevel-blt-bench.c
@@ -67,8 +67,8 @@ bench_memcpy ()
t1 = gettime ();
while (1)
{
- memcpy (dst, src, BUFSIZE - 64);
- memcpy (src, dst, BUFSIZE - 64);
+ pixman_memcpy (dst, src, BUFSIZE - 64);
+ pixman_memcpy (src, dst, BUFSIZE - 64);
n += 4 * (BUFSIZE - 64);
t2 = gettime ();
if (t2 - t1 > 0.5)
@@ -80,8 +80,8 @@ bench_memcpy ()
{
if (++x >= 64)
x = 0;
- memcpy ((char *)dst + 1, (char *)src + x, BUFSIZE - 64);
- memcpy ((char *)src + 1, (char *)dst + x, BUFSIZE - 64);
+ pixman_memcpy ((char *)dst + 1, (char *)src + x, BUFSIZE - 64);
+ pixman_memcpy ((char *)src + 1, (char *)dst + x, BUFSIZE - 64);
n -= 4 * (BUFSIZE - 64);
}
t2 = gettime ();
@@ -465,8 +465,8 @@ bench_composite (char * testname,
printf ("%24s %c", testname, func != pixman_image_composite_wrapper ?
'-' : '=');
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
l1test_width = L1CACHE_SIZE / 8 - 64;
if (l1test_width < 1)
@@ -485,8 +485,8 @@ bench_composite (char * testname,
((t3 - t2) - (t2 - t1)) / 1000000.);
fflush (stdout);
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
nlines = (L2CACHE_SIZE / l1test_width) /
((PIXMAN_FORMAT_BPP(src_fmt) + PIXMAN_FORMAT_BPP(dst_fmt)) / 8);
@@ -504,8 +504,8 @@ bench_composite (char * testname,
((t3 - t2) - (t2 - t1)) / 1000000.);
fflush (stdout);
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
n = 1 + npix / (WIDTH * HEIGHT);
t1 = gettime ();
@@ -520,8 +520,8 @@ bench_composite (char * testname,
((double)n * (WIDTH - 64) * HEIGHT / ((t3 - t2) - (t2 - t1)) * bytes_per_pix) * (100.0 / bandwidth) );
fflush (stdout);
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
t1 = gettime ();
@@ -534,8 +534,8 @@ bench_composite (char * testname,
printf (" HT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
fflush (stdout);
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
t1 = gettime ();
@@ -548,8 +548,8 @@ bench_composite (char * testname,
printf (" VT:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
fflush (stdout);
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
n = 1 + npix / (8 * TILEWIDTH * TILEWIDTH);
t1 = gettime ();
@@ -562,8 +562,8 @@ bench_composite (char * testname,
printf (" R:%6.2f", (double)pix_cnt / ((t3 - t2) - (t2 - t1)) / 1000000.);
fflush (stdout);
- memcpy (dst, src, BUFSIZE);
- memcpy (src, dst, BUFSIZE);
+ pixman_memcpy (dst, src, BUFSIZE);
+ pixman_memcpy (src, dst, BUFSIZE);
n = 1 + npix / (16 * TINYWIDTH * TINYWIDTH);
t1 = gettime ();
diff --git a/test/tolerance-test.c b/test/tolerance-test.c
index 320bb7f..db4a949 100644
--- a/test/tolerance-test.c
+++ b/test/tolerance-test.c
@@ -108,7 +108,7 @@ create_image (pixman_image_t **clone)
{
uint32_t *bytes_dup = malloc (stride * height);
- memcpy (bytes_dup, bytes, stride * height);
+ pixman_memcpy (bytes_dup, bytes, stride * height);
*clone = pixman_image_create_bits (
format, width, height, bytes_dup, stride);
diff --git a/test/utils-prng.c b/test/utils-prng.c
index c27b5be..1b16eaa 100644
--- a/test/utils-prng.c
+++ b/test/utils-prng.c
@@ -92,7 +92,7 @@ store_rand_128_data (void *addr, prng_rand_128_data_t *d, int aligned)
#endif
/* we could try something better for unaligned writes (packed attribute),
* but GCC is not very reliable: http://gcc.gnu.org/PR55454 */
- memcpy (addr, d, 16);
+ pixman_memcpy (addr, d, 16);
}
/*
--
1.7.3
More information about the Pixman
mailing list