diff --git a/examples/Demo/Source/Demos/SystemInfoDemo.cpp b/examples/Demo/Source/Demos/SystemInfoDemo.cpp index 4d9731bf22..c310943913 100644 --- a/examples/Demo/Source/Demos/SystemInfoDemo.cpp +++ b/examples/Demo/Source/Demos/SystemInfoDemo.cpp @@ -140,6 +140,7 @@ static String getAllSystemInfo() << "CPU has 3DNOW: " << (SystemStats::has3DNow() ? "yes" : "no") << newLine << "CPU has AVX: " << (SystemStats::hasAVX() ? "yes" : "no") << newLine << "CPU has AVX2: " << (SystemStats::hasAVX2() ? "yes" : "no") << newLine + << "CPU has Neon: " << (SystemStats::hasNeon() ? "yes" : "no") << newLine << newLine; systemInfo diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h index 13ca799646..1015513ea8 100644 --- a/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h +++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExport_Android.h @@ -349,13 +349,23 @@ private: if (! isLibrary()) mo << "SET(BINARY_NAME \"juce_jni\")" << newLine << newLine; + mo << "add_library(\"cpufeatures\" STATIC \"${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c\")" << newLine << newLine; + { StringArray projectDefines (getEscapedPreprocessorDefs (getProjectPreprocessorDefs())); if (projectDefines.size() > 0) mo << "add_definitions(" << projectDefines.joinIntoString (" ") << ")" << newLine << newLine; } - writeCmakePathLines (mo, "", "include_directories( AFTER", extraSearchPaths); + { + mo << "include_directories( AFTER" << newLine; + + for (auto& path : extraSearchPaths) + mo << " \"" << escapeDirectoryForCmake (path) << "\"" << newLine; + + mo << " \"${ANDROID_NDK}/sources/android/cpufeatures\"" << newLine; + mo << ")" << newLine << newLine; + } const String& cfgExtraLinkerFlags = getExtraLinkerFlagsString(); if (cfgExtraLinkerFlags.isNotEmpty()) @@ -460,6 +470,8 @@ private: for (auto& lib : libraries) mo << " ${" << lib.toLowerCase().replaceCharacter (L' ', L'_') << "}" << newLine; + + mo << " \"cpufeatures\"" << newLine; } mo << ")" << newLine; diff --git a/modules/juce_core/native/juce_BasicNativeHeaders.h b/modules/juce_core/native/juce_BasicNativeHeaders.h index 0ed4035a6a..088832b4ec 100644 --- a/modules/juce_core/native/juce_BasicNativeHeaders.h +++ b/modules/juce_core/native/juce_BasicNativeHeaders.h @@ -253,6 +253,10 @@ #include #include #include + + // If you are getting include errors here, then you to re-build the Projucer + // and re-save your .jucer file. + #include #endif // Need to clear various moronic redefinitions made by system headers.. diff --git a/modules/juce_core/native/juce_android_SystemStats.cpp b/modules/juce_core/native/juce_android_SystemStats.cpp index cb526fe394..073e1a2eaa 100644 --- a/modules/juce_core/native/juce_android_SystemStats.cpp +++ b/modules/juce_core/native/juce_android_SystemStats.cpp @@ -343,7 +343,36 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU //============================================================================== void CPUInformation::initialise() noexcept { - numPhysicalCPUs = numLogicalCPUs = jmax ((int) 1, (int) sysconf (_SC_NPROCESSORS_ONLN)); + numPhysicalCPUs = numLogicalCPUs = jmax ((int) 1, (int) android_getCpuCount()); + + auto cpuFamily = android_getCpuFamily(); + auto cpuFeatures = android_getCpuFeatures(); + + if (cpuFamily == ANDROID_CPU_FAMILY_X86 || cpuFamily == ANDROID_CPU_FAMILY_X86_64) + { + hasMMX = hasSSE = hasSSE2 = (cpuFamily == ANDROID_CPU_FAMILY_X86_64); + + hasSSSE3 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_SSSE3) != 0); + hasSSE41 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_SSE4_1) != 0); + hasSSE42 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_SSE4_2) != 0); + hasAVX = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_AVX) != 0); + hasAVX2 = ((cpuFeatures & ANDROID_CPU_X86_FEATURE_AVX2) != 0); + + // Google does not distinguish between MMX, SSE, SSE2, SSE3 and SSSE3. So + // I assume (and quick Google searches seem to confirm this) that there are + // only devices out there that either support all of this or none of this. + if (hasSSSE3) + hasMMX = hasSSE = hasSSE2 = hasSSE3 = true; + } + else if (cpuFamily == ANDROID_CPU_FAMILY_ARM) + { + hasNeon = ((cpuFeatures & ANDROID_CPU_ARM_FEATURE_NEON) != 0); + } + else if (cpuFamily == ANDROID_CPU_FAMILY_ARM64) + { + // all arm 64-bit cpus have neon + hasNeon = true; + } } //============================================================================== diff --git a/modules/juce_core/system/juce_SystemStats.cpp b/modules/juce_core/system/juce_SystemStats.cpp index 430f76e1b4..7e05277429 100644 --- a/modules/juce_core/system/juce_SystemStats.cpp +++ b/modules/juce_core/system/juce_SystemStats.cpp @@ -91,7 +91,7 @@ struct CPUInformation bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false, has3DNow = false, hasSSSE3 = false, hasSSE41 = false, - hasSSE42 = false, hasAVX = false, hasAVX2 = false; + hasSSE42 = false, hasAVX = false, hasAVX2 = false, hasNeon = false; }; static const CPUInformation& getCPUInformation() noexcept @@ -112,6 +112,7 @@ bool SystemStats::hasSSE41() noexcept { return getCPUInformation().has bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; } bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; } bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; } +bool SystemStats::hasNeon() noexcept { return getCPUInformation().hasNeon; } //============================================================================== diff --git a/modules/juce_core/system/juce_SystemStats.h b/modules/juce_core/system/juce_SystemStats.h index 0513c91acc..4bf4e0e13e 100644 --- a/modules/juce_core/system/juce_SystemStats.h +++ b/modules/juce_core/system/juce_SystemStats.h @@ -171,6 +171,7 @@ public: static bool hasSSE42() noexcept; /**< Returns true if Intel SSE4.2 instructions are available. */ static bool hasAVX() noexcept; /**< Returns true if Intel AVX instructions are available. */ static bool hasAVX2() noexcept; /**< Returns true if Intel AVX2 instructions are available. */ + static bool hasNeon() noexcept; /**< Returns true if ARM NEON instructions are available. */ //============================================================================== /** Finds out how much RAM is in the machine.