[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