android: use cpufeatures to support SDL_HasNEON() (thanks, Sylvain!).
Fixes Bugzilla #4406.
1.1 --- a/Android.mk Sat Dec 01 12:17:34 2018 -0500
1.2 +++ b/Android.mk Sat Dec 01 12:19:11 2018 -0500
1.3 @@ -75,6 +75,8 @@
1.4 cmd-strip :=
1.5 endif
1.6
1.7 +LOCAL_STATIC_LIBRARIES := cpufeatures
1.8 +
1.9 include $(BUILD_SHARED_LIBRARY)
1.10
1.11 ###########################
1.12 @@ -124,3 +126,6 @@
1.13 LOCAL_LDLIBS := -llog
1.14
1.15 include $(BUILD_SHARED_LIBRARY)
1.16 +
1.17 +$(call import-module,android/cpufeatures)
1.18 +
2.1 --- a/src/cpuinfo/SDL_cpuinfo.c Sat Dec 01 12:17:34 2018 -0500
2.2 +++ b/src/cpuinfo/SDL_cpuinfo.c Sat Dec 01 12:19:11 2018 -0500
2.3 @@ -78,6 +78,12 @@
2.4 #endif
2.5 #endif
2.6
2.7 +#if defined(__ANDROID__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
2.8 +#if __ARM_ARCH < 8
2.9 +#include <cpu-features.h>
2.10 +#endif
2.11 +#endif
2.12 +
2.13 #define CPU_HAS_RDTSC (1 << 0)
2.14 #define CPU_HAS_ALTIVEC (1 << 1)
2.15 #define CPU_HAS_MMX (1 << 2)
2.16 @@ -320,7 +326,7 @@
2.17 return altivec;
2.18 }
2.19
2.20 -#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
2.21 +#if defined(__LINUX__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
2.22 static int
2.23 readProcAuxvForNeon(void)
2.24 {
2.25 @@ -359,8 +365,20 @@
2.26 return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON;
2.27 #elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL)
2.28 return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON);
2.29 -#elif (defined(__LINUX__) || defined(__ANDROID__))
2.30 - return readProcAuxvForNeon(); /* Android offers a static library for this, but it just parses /proc/self/auxv */
2.31 +#elif defined(__LINUX__)
2.32 + return readProcAuxvForNeon();
2.33 +#elif defined(__ANDROID__)
2.34 + /* Use NDK cpufeatures to read either /proc/self/auxv or /proc/cpuinfo */
2.35 + {
2.36 + AndroidCpuFamily cpu_family = android_getCpuFamily();
2.37 + if (cpu_family == ANDROID_CPU_FAMILY_ARM) {
2.38 + uint64_t cpu_features = android_getCpuFeatures();
2.39 + if ((cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
2.40 + return 1;
2.41 + }
2.42 + }
2.43 + return 0;
2.44 + }
2.45 #elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
2.46 /* All WinRT ARM devices are required to support NEON, but just in case. */
2.47 return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;