android: use cpufeatures to support SDL_HasNEON() (thanks, Sylvain!). Fixes Bugzilla #4406.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
diff --git a/Android.mk b/Android.mk
index 043576c..2aee636 100644
--- a/Android.mk
+++ b/Android.mk
@@ -75,6 +75,8 @@ ifeq ($(NDK_DEBUG),1)
cmd-strip :=
endif
+LOCAL_STATIC_LIBRARIES := cpufeatures
+
include $(BUILD_SHARED_LIBRARY)
###########################
@@ -124,3 +126,6 @@ LOCAL_MODULE := libhidapi
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
+
+$(call import-module,android/cpufeatures)
+
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index 4410358..7abf408 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -78,6 +78,12 @@
#endif
#endif
+#if defined(__ANDROID__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
+#if __ARM_ARCH < 8
+#include <cpu-features.h>
+#endif
+#endif
+
#define CPU_HAS_RDTSC (1 << 0)
#define CPU_HAS_ALTIVEC (1 << 1)
#define CPU_HAS_MMX (1 << 2)
@@ -320,7 +326,7 @@ CPU_haveAltiVec(void)
return altivec;
}
-#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
+#if defined(__LINUX__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
static int
readProcAuxvForNeon(void)
{
@@ -359,8 +365,20 @@ CPU_haveNEON(void)
return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON;
#elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL)
return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON);
-#elif (defined(__LINUX__) || defined(__ANDROID__))
- return readProcAuxvForNeon(); /* Android offers a static library for this, but it just parses /proc/self/auxv */
+#elif defined(__LINUX__)
+ return readProcAuxvForNeon();
+#elif defined(__ANDROID__)
+ /* Use NDK cpufeatures to read either /proc/self/auxv or /proc/cpuinfo */
+ {
+ AndroidCpuFamily cpu_family = android_getCpuFamily();
+ if (cpu_family == ANDROID_CPU_FAMILY_ARM) {
+ uint64_t cpu_features = android_getCpuFeatures();
+ if ((cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
+ return 1;
+ }
+ }
+ return 0;
+ }
#elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
/* All WinRT ARM devices are required to support NEON, but just in case. */
return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;