summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby Salazar <bobby8934@gmail.com>2011-12-13 07:03:16 (GMT)
committerSøren Sandmann Pedersen <ssp@redhat.com>2012-01-18 20:35:41 (GMT)
commitb14fd2ad606baa4074b8cba8c58f6847d5840205 (patch)
treec7a547df6ded5b64d724ecb448b0600ab11331c9
parent3c87d862d9bdfd4500927f9502c87815175e48c9 (diff)
downloadpixman-b14fd2ad606baa4074b8cba8c58f6847d5840205.tar.gz
pixman-b14fd2ad606baa4074b8cba8c58f6847d5840205.tar.xz
Android Runtime Detection Support For ARM NEON
This patch adds runtime detection support for the ARM NEON fast paths for code compiled with the Android NDK. This is the only code change needed to enable the ARM NEON pixman fast paths for the ever growing Android platform (200 million+ smartphones, tablets, etc.). Just make sure to #define USE_ARM_NEON in your makefile.
-rw-r--r--pixman/pixman-cpu.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
index dff27d1..4172e52 100644
--- a/pixman/pixman-cpu.c
+++ b/pixman/pixman-cpu.c
@@ -244,6 +244,43 @@ pixman_have_arm_neon (void)
#endif /* USE_ARM_NEON */
+#elif defined (__linux__) || defined(__ANDROID__) || defined(ANDROID) /* linux ELF or ANDROID */
+
+static pixman_bool_t arm_has_v7 = FALSE;
+static pixman_bool_t arm_has_v6 = FALSE;
+static pixman_bool_t arm_has_vfp = FALSE;
+static pixman_bool_t arm_has_neon = FALSE;
+static pixman_bool_t arm_has_iwmmxt = FALSE;
+static pixman_bool_t arm_tests_initialized = FALSE;
+
+#if defined(__ANDROID__) || defined(ANDROID) /* Android device support */
+
+#include <cpu-features.h>
+
+static void
+pixman_arm_read_auxv_or_cpu_features ()
+{
+ AndroidCpuFamily cpu_family;
+ uint64_t cpu_features;
+
+ cpu_family = android_getCpuFamily();
+ cpu_features = android_getCpuFeatures();
+
+ if (cpu_family == ANDROID_CPU_FAMILY_ARM)
+ {
+ if (cpu_features & ANDROID_CPU_ARM_FEATURE_ARMv7)
+ arm_has_v7 = TRUE;
+
+ if (cpu_features & ANDROID_CPU_ARM_FEATURE_VFPv3)
+ arm_has_vfp = TRUE;
+
+ if (cpu_features & ANDROID_CPU_ARM_FEATURE_NEON)
+ arm_has_neon = TRUE;
+ }
+
+ arm_tests_initialized = TRUE;
+}
+
#elif defined (__linux__) /* linux ELF */
#include <stdlib.h>
@@ -255,15 +292,8 @@ pixman_have_arm_neon (void)
#include <string.h>
#include <elf.h>
-static pixman_bool_t arm_has_v7 = FALSE;
-static pixman_bool_t arm_has_v6 = FALSE;
-static pixman_bool_t arm_has_vfp = FALSE;
-static pixman_bool_t arm_has_neon = FALSE;
-static pixman_bool_t arm_has_iwmmxt = FALSE;
-static pixman_bool_t arm_tests_initialized = FALSE;
-
static void
-pixman_arm_read_auxv ()
+pixman_arm_read_auxv_or_cpu_features ()
{
int fd;
Elf32_auxv_t aux;
@@ -304,12 +334,14 @@ pixman_arm_read_auxv ()
arm_tests_initialized = TRUE;
}
+#endif /* Linux elf */
+
#if defined(USE_ARM_SIMD)
pixman_bool_t
pixman_have_arm_simd (void)
{
if (!arm_tests_initialized)
- pixman_arm_read_auxv ();
+ pixman_arm_read_auxv_or_cpu_features ();
return arm_has_v6;
}
@@ -321,7 +353,7 @@ pixman_bool_t
pixman_have_arm_neon (void)
{
if (!arm_tests_initialized)
- pixman_arm_read_auxv ();
+ pixman_arm_read_auxv_or_cpu_features ();
return arm_has_neon;
}
@@ -333,14 +365,14 @@ pixman_bool_t
pixman_have_arm_iwmmxt (void)
{
if (!arm_tests_initialized)
- pixman_arm_read_auxv ();
+ pixman_arm_read_auxv_or_cpu_features ();
return arm_has_iwmmxt;
}
#endif /* USE_ARM_IWMMXT */
-#else /* linux ELF */
+#else /* !_MSC_VER && !Linux elf && !Android */
#define pixman_have_arm_simd() FALSE
#define pixman_have_arm_neon() FALSE