[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