[Pixman] [PATCH 1/2] allow runtime switching of pixman_implementation_t's for testing.

Chris Toshok toshok at gmail.com
Mon May 17 19:38:17 PDT 2010


define a new public entry point _pixman_debug_set_implementation.

_pixman_choose_implementation now takes a "char* imp_name" parameter,
with NULL being equivalent to "general".  unrecognized names also result
in the general implementation being chosen.

the thread local cache now includes a pixman_implementation_t* which is
used to clear the fastpath cache when a change in pixman_implementation_t
is noticed.
---
 pixman/pixman-cpu.c     |   23 +++++++++++++++--------
 pixman/pixman-private.h |    2 +-
 pixman/pixman.c         |   22 +++++++++++++++++++---
 pixman/pixman.h         |    3 +++
 4 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index e96b140..ebdeef8 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -546,30 +546,37 @@ pixman_have_sse2 (void)
 #endif

 pixman_implementation_t *
-_pixman_choose_implementation (void)
+_pixman_choose_implementation (const char *imp_name)
 {
 #ifdef USE_SSE2
-    if (pixman_have_sse2 ())
+    if (pixman_have_sse2 () && (!imp_name || !strcmp (imp_name, "sse2")))
        return _pixman_implementation_create_sse2 ();
 #endif
 #ifdef USE_MMX
-    if (pixman_have_mmx ())
+    if (pixman_have_mmx () && (!imp_name || !strcmp (imp_name, "mmx")))
        return _pixman_implementation_create_mmx ();
 #endif

 #ifdef USE_ARM_NEON
-    if (pixman_have_arm_neon ())
+    if (pixman_have_arm_neon () && (!imp_name || !strcmp (imp_name,
"arm-neon")))
        return _pixman_implementation_create_arm_neon ();
 #endif
 #ifdef USE_ARM_SIMD
-    if (pixman_have_arm_simd ())
+    if (pixman_have_arm_simd () && (!imp_name || !strcmp (imp_name,
"arm-simd")))
        return _pixman_implementation_create_arm_simd ();
 #endif
 #ifdef USE_VMX
-    if (pixman_have_vmx ())
+    if (pixman_have_vmx () && (!imp_name || !strcmp (imp_name, "vmx")))
        return _pixman_implementation_create_vmx ();
 #endif

-    return _pixman_implementation_create_fast_path ();
-}
+    if (!imp_name || !strcmp (imp_name, "fast"))
+        return _pixman_implementation_create_fast_path ();

+    if (imp_name && strcmp (imp_name, "general"))
+        fprintf (stderr,
+                "unsupported pixman implementation '%s', using general\n",
+                imp_name);
+
+    return _pixman_implementation_create_general ();
+}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d5767af..3a60100 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -544,7 +544,7 @@ _pixman_implementation_create_vmx (void);
 #endif

 pixman_implementation_t *
-_pixman_choose_implementation (void);
+_pixman_choose_implementation (const char *imp_name);



diff --git a/pixman/pixman.c b/pixman/pixman.c
index 56c9536..53bb766 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -554,6 +554,7 @@ compute_src_extents_flags (pixman_image_t *image,

 typedef struct
 {
+    pixman_implementation_t *imp;
     pixman_fast_path_t cache [N_CACHED_FAST_PATHS];
 } cache_t;

@@ -656,6 +657,12 @@ do_composite (pixman_implementation_t *imp,
     /* Check cache for fast paths */
     cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);

+    /* First check if we need to invalidate our cache due to
implementation change */
+    if (cache->imp != imp) {
+       cache->imp = imp;
+       memset (cache->cache, 0, sizeof (pixman_fast_path_t) *
N_CACHED_FAST_PATHS);
+    }
+
     for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
     {
        info = &(cache->cache[i]);
@@ -814,7 +821,7 @@ pixman_image_composite32 (pixman_op_t      op,
     _pixman_image_validate (dest);

     if (!imp)
-       imp = _pixman_choose_implementation ();
+       imp = _pixman_choose_implementation (NULL);

     do_composite (imp, op,
                  src, mask, dest,
@@ -839,7 +846,7 @@ pixman_blt (uint32_t *src_bits,
             int       height)
 {
     if (!imp)
-       imp = _pixman_choose_implementation ();
+       imp = _pixman_choose_implementation (NULL);

     return _pixman_implementation_blt (imp, src_bits, dst_bits,
src_stride, dst_stride,
                                        src_bpp, dst_bpp,
@@ -859,7 +866,7 @@ pixman_fill (uint32_t *bits,
              uint32_t xor)
 {
     if (!imp)
-       imp = _pixman_choose_implementation ();
+       imp = _pixman_choose_implementation (NULL);

     return _pixman_implementation_fill (imp, bits, stride, bpp, x, y,
width, height, xor);
 }
@@ -1219,3 +1226,12 @@ pixman_compute_composite_region
(pixman_region16_t * region,
     pixman_region32_fini (&r32);
     return retval;
 }
+
+PIXMAN_EXPORT void
+_pixman_debug_set_implementation (const char *imp_name)
+{
+    pixman_implementation_t* new_imp = _pixman_choose_implementation
(imp_name);
+    if (imp)
+       free (imp);
+    imp = new_imp;
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 8df5813..3b3805c 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -943,6 +943,9 @@ void           pixman_rasterize_trapezoid
(pixman_image_t            *image,
                                            int                        x_off,
                                            int                        y_off);

+void
+_pixman_debug_set_implementation (const char *implementation_name);
+
 PIXMAN_END_DECLS

 #endif /* PIXMAN_H__ */
-- 
1.6.4.2


More information about the Pixman mailing list