diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp index 7931709c9ff..44fa07fd38d 100644 --- a/core/safe_refcount.cpp +++ b/core/safe_refcount.cpp @@ -29,26 +29,259 @@ /*************************************************************************/ #include "safe_refcount.h" -#ifdef _MSC_VER +// Atomic functions, these are used for multithread safe reference counters! -// don't pollute my namespace! -#include -long atomic_conditional_increment(register long *pw) { +#ifdef NO_THREADS - /* try to increment until it actually works */ - // taken from boost +/* Bogus implementation unaware of multiprocessing */ + +template +static _ALWAYS_INLINE_ T _atomic_conditional_increment_impl(register T *pw) { + + if (*pw == 0) + return 0; + + (*pw)++; + + return *pw; +} + +template +static _ALWAYS_INLINE_ T _atomic_decrement_impl(register T *pw) { + + (*pw)--; + + return *pw; +} + +template +static _ALWAYS_INLINE_ T _atomic_increment_impl(register T *pw) { + + (*pw)++; + + return *pw; +} + +template +static _ALWAYS_INLINE_ T _atomic_sub_impl(register T *pw, register T val) { + + (*pw) -= val; + + return *pw; +} + +template +static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) { + + (*pw) += val; + + return *pw; +} + +template +static _ALWAYS_INLINE_ T _atomic_exchange_if_greater_impl(register T *pw, register T val) { + + if (val > *pw) + *pw = val; + + return *pw; +} + +#elif defined(__GNUC__) + +/* Implementation for GCC & Clang */ + +// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes. +// Clang states it supports GCC atomic builtins. + +template +static _ALWAYS_INLINE_ T _atomic_conditional_increment_impl(register T *pw) { while (true) { - long tmp = static_cast(*pw); + T tmp = static_cast(*pw); if (tmp == 0) return 0; // if zero, can't add to it anymore - if (InterlockedCompareExchange(pw, tmp + 1, tmp) == tmp) + if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp) return tmp + 1; } } -long atomic_decrement(register long *pw) { - return InterlockedDecrement(pw); +template +static _ALWAYS_INLINE_ T _atomic_decrement_impl(register T *pw) { + + return __sync_sub_and_fetch(pw, 1); } +template +static _ALWAYS_INLINE_ T _atomic_increment_impl(register T *pw) { + + return __sync_add_and_fetch(pw, 1); +} + +template +static _ALWAYS_INLINE_ T _atomic_sub_impl(register T *pw, register T val) { + + return __sync_sub_and_fetch(pw, val); +} + +template +static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) { + + return __sync_add_and_fetch(pw, val); +} + +template +static _ALWAYS_INLINE_ T _atomic_exchange_if_greater_impl(register T *pw, register T val) { + + while (true) { + T tmp = static_cast(*pw); + if (tmp >= val) + return tmp; // already greater, or equal + if (__sync_val_compare_and_swap(pw, tmp, val) == tmp) + return val; + } +} + +#elif defined(_MSC_VER) + +/* Implementation for MSVC-Windows */ + +// don't pollute my namespace! +#include + +#define ATOMIC_CONDITIONAL_INCREMENT_BODY(m_pw, m_win_type, m_win_cmpxchg, m_cpp_type) \ + /* try to increment until it actually works */ \ + /* taken from boost */ \ + while (true) { \ + m_cpp_type tmp = static_cast(*(m_pw)); \ + if (tmp == 0) \ + return 0; /* if zero, can't add to it anymore */ \ + if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) \ + return tmp + 1; \ + } + +#define ATOMIC_EXCHANGE_IF_GREATER_BODY(m_pw, m_val, m_win_type, m_win_cmpxchg, m_cpp_type) \ + while (true) { \ + m_cpp_type tmp = static_cast(*(m_pw)); \ + if (tmp >= m_val) \ + return tmp; /* already greater, or equal */ \ + if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) \ + return m_val; \ + } + +static _ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(register uint32_t *pw) { + + ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t) +} + +static _ALWAYS_INLINE_ uint32_t _atomic_decrement_impl(register uint32_t *pw) { + + return InterlockedDecrement((LONG volatile *)pw); +} + +static _ALWAYS_INLINE_ uint32_t _atomic_increment_impl(register uint32_t *pw) { + + return InterlockedIncrement((LONG volatile *)pw); +} + +static _ALWAYS_INLINE_ uint32_t _atomic_sub_impl(register uint32_t *pw, register uint32_t val) { + + return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val; +} + +static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register uint32_t val) { + + return InterlockedAdd((LONG volatile *)pw, val); +} + +static _ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(register uint32_t *pw, register uint32_t val) { + + ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t) +} + +static _ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(register uint64_t *pw) { + + ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t) +} + +static _ALWAYS_INLINE_ uint64_t _atomic_decrement_impl(register uint64_t *pw) { + + return InterlockedDecrement64((LONGLONG volatile *)pw); +} + +static _ALWAYS_INLINE_ uint64_t _atomic_increment_impl(register uint64_t *pw) { + + return InterlockedIncrement64((LONGLONG volatile *)pw); +} + +static _ALWAYS_INLINE_ uint64_t _atomic_sub_impl(register uint64_t *pw, register uint64_t val) { + + return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val; +} + +static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register uint64_t val) { + + return InterlockedAdd64((LONGLONG volatile *)pw, val); +} + +static _ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(register uint64_t *pw, register uint64_t val) { + + ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t) +} + +#else + +//no threads supported? +#error Must provide atomic functions for this platform or compiler! + #endif + +// The actual advertised functions; they'll call the right implementation + +uint32_t atomic_conditional_increment(register uint32_t *counter) { + return _atomic_conditional_increment_impl(counter); +} + +uint32_t atomic_decrement(register uint32_t *pw) { + return _atomic_decrement_impl(pw); +} + +uint32_t atomic_increment(register uint32_t *pw) { + return _atomic_increment_impl(pw); +} + +uint32_t atomic_sub(register uint32_t *pw, register uint32_t val) { + return _atomic_sub_impl(pw, val); +} + +uint32_t atomic_add(register uint32_t *pw, register uint32_t val) { + return _atomic_add_impl(pw, val); +} + +uint32_t atomic_exchange_if_greater(register uint32_t *pw, register uint32_t val) { + return _atomic_exchange_if_greater_impl(pw, val); +} + +uint64_t atomic_conditional_increment(register uint64_t *counter) { + return _atomic_conditional_increment_impl(counter); +} + +uint64_t atomic_decrement(register uint64_t *pw) { + return _atomic_decrement_impl(pw); +} + +uint64_t atomic_increment(register uint64_t *pw) { + return _atomic_increment_impl(pw); +} + +uint64_t atomic_sub(register uint64_t *pw, register uint64_t val) { + return _atomic_sub_impl(pw, val); +} + +uint64_t atomic_add(register uint64_t *pw, register uint64_t val) { + return _atomic_add_impl(pw, val); +} + +uint64_t atomic_exchange_if_greater(register uint64_t *pw, register uint64_t val) { + return _atomic_exchange_if_greater_impl(pw, val); +} diff --git a/core/safe_refcount.h b/core/safe_refcount.h index 1a0cb2e371e..62f16b7b80b 100644 --- a/core/safe_refcount.h +++ b/core/safe_refcount.h @@ -34,277 +34,25 @@ /* x86/x86_64 GCC */ #include "platform_config.h" +#include "typedefs.h" -#ifdef NO_THREADS +uint32_t atomic_conditional_increment(register uint32_t *counter); +uint32_t atomic_decrement(register uint32_t *pw); +uint32_t atomic_increment(register uint32_t *pw); +uint32_t atomic_sub(register uint32_t *pw, register uint32_t val); +uint32_t atomic_add(register uint32_t *pw, register uint32_t val); +uint32_t atomic_exchange_if_greater(register uint32_t *pw, register uint32_t val); + +uint64_t atomic_conditional_increment(register uint64_t *counter); +uint64_t atomic_decrement(register uint64_t *pw); +uint64_t atomic_increment(register uint64_t *pw); +uint64_t atomic_sub(register uint64_t *pw, register uint64_t val); +uint64_t atomic_add(register uint64_t *pw, register uint64_t val); +uint64_t atomic_exchange_if_greater(register uint64_t *pw, register uint64_t val); struct SafeRefCount { - int count; - -public: - // destroy() is called when weak_count_ drops to zero. - - bool ref() { //true on success - - if (count == 0) - return false; - count++; - - return true; - } - - int refval() { //true on success - - if (count == 0) - return 0; - count++; - return count; - } - - bool unref() { // true if must be disposed of - - if (count > 0) - count--; - - return count == 0; - } - - long get() const { // nothrow - - return static_cast(count); - } - - void init(int p_value = 1) { - - count = p_value; - }; -}; - -#else - -#if defined(PLATFORM_REFCOUNT) - -#include "platform_refcount.h" - -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - -#define REFCOUNT_T volatile int -#define REFCOUNT_GET_T int const volatile & - -static inline int atomic_conditional_increment(volatile int *pw) { - // int rv = *pw; - // if( rv != 0 ) ++*pw; - // return rv; - - int rv, tmp; - - __asm__( - "movl %0, %%eax\n\t" - "0:\n\t" - "test %%eax, %%eax\n\t" - "je 1f\n\t" - "movl %%eax, %2\n\t" - "incl %2\n\t" - "lock\n\t" - "cmpxchgl %2, %0\n\t" - "jne 0b\n\t" - "1:" - : "=m"(*pw), "=&a"(rv), "=&r"(tmp) - : // outputs (%0, %1, %2) - "m"(*pw) - : // input (%3) - "cc" // clobbers - ); - - return rv; -} - -static inline int atomic_decrement(volatile int *pw) { - - // return --(*pw); - - unsigned char rv; - - __asm__( - "lock\n\t" - "decl %0\n\t" - "setne %1" - : "=m"(*pw), "=qm"(rv) - : "m"(*pw) - : "memory"); - return static_cast(rv); -} - - /* PowerPC32/64 GCC */ - -#elif (defined(__GNUC__)) && (defined(__powerpc__) || defined(__ppc__)) - -#define REFCOUNT_T int -#define REFCOUNT_GET_T int const volatile & - -inline int atomic_conditional_increment(int *pw) { - // if( *pw != 0 ) ++*pw; - // return *pw; - - int rv; - - __asm__( - "0:\n\t" - "lwarx %1, 0, %2\n\t" - "cmpwi %1, 0\n\t" - "beq 1f\n\t" - "addi %1, %1, 1\n\t" - "1:\n\t" - "stwcx. %1, 0, %2\n\t" - "bne- 0b" - : - - "=m"(*pw), "=&b"(rv) - : "r"(pw), "m"(*pw) - : "cc"); - - return rv; -} - -inline int atomic_decrement(int *pw) { - // return --*pw; - - int rv; - - __asm__ __volatile__( - "sync\n\t" - "0:\n\t" - "lwarx %1, 0, %2\n\t" - "addi %1, %1, -1\n\t" - "stwcx. %1, 0, %2\n\t" - "bne- 0b\n\t" - "isync" - : - - "=m"(*pw), "=&b"(rv) - : "r"(pw), "m"(*pw) - : "memory", "cc"); - - return rv; -} - - /* CW ARM */ - -#elif defined(__GNUC__) && (defined(__arm__)) - -#define REFCOUNT_T int -#define REFCOUNT_GET_T int const volatile & - -inline int atomic_conditional_increment(volatile int *v) { - int t; - int tmp; - - __asm__ __volatile__( - "1: ldrex %0, [%2] \n" - " cmp %0, #0 \n" - " beq 2f \n" - " add %0, %0, #1 \n" - "2: \n" - " strex %1, %0, [%2] \n" - " cmp %1, #0 \n" - " bne 1b \n" - - : "=&r"(t), "=&r"(tmp) - : "r"(v) - : "cc", "memory"); - - return t; -} - -inline int atomic_decrement(volatile int *v) { - int t; - int tmp; - - __asm__ __volatile__( - "1: ldrex %0, [%2] \n" - " add %0, %0, #-1 \n" - " strex %1, %0, [%2] \n" - " cmp %1, #0 \n" - " bne 1b \n" - - : "=&r"(t), "=&r"(tmp) - : "r"(v) - : "cc", "memory"); - - return t; -} - - /* CW PPC */ - -#elif (defined(__MWERKS__)) && defined(__POWERPC__) - -inline long atomic_conditional_increment(register long *pw) { - register int a; - - asm { - loop: - - lwarx a, 0, pw - cmpwi a, 0 - beq store - - addi a, a, 1 - - store: - - stwcx. a, 0, pw - bne- loop - } - - return a; -} - -inline long atomic_decrement(register long *pw) { - register int a; - - asm { - - sync - - loop: - - lwarx a, 0, pw - addi a, a, -1 - stwcx. a, 0, pw - bne- loop - - isync - } - - return a; -} - - /* Any Windows (MSVC) */ - -#elif defined(_MSC_VER) - -// made functions to not pollute namespace.. - -#define REFCOUNT_T long -#define REFCOUNT_GET_T long const volatile & - -long atomic_conditional_increment(register long *pw); -long atomic_decrement(register long *pw); - -#if 0 -#elif defined(__GNUC__) && defined(ARMV6_ENABLED) - -#endif - -#else - -#error This platform cannot use safe refcount, compile with NO_THREADS or implement it. - -#endif - -struct SafeRefCount { - - REFCOUNT_T count; + uint32_t count; public: // destroy() is called when weak_count_ drops to zero. @@ -314,7 +62,7 @@ public: return atomic_conditional_increment(&count) != 0; } - int refval() { //true on success + uint32_t refval() { //true on success return atomic_conditional_increment(&count); } @@ -328,17 +76,15 @@ public: return false; } - long get() const { // nothrow + uint32_t get() const { // nothrow - return static_cast(count); + return count; } - void init(int p_value = 1) { + void init(uint32_t p_value = 1) { count = p_value; - }; + } }; -#endif // no thread safe - #endif diff --git a/platform/android/SCsub b/platform/android/SCsub index 3f3cddda6f1..54bb09c1c7b 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -150,6 +150,8 @@ if env['android_arch'] == 'armv6': lib_arch_dir = 'armeabi' elif env['android_arch'] == 'armv7': lib_arch_dir = 'armeabi-v7a' +elif env['android_arch'] == 'arm64v8': + lib_arch_dir = 'arm64-v8a' elif env['android_arch'] == 'x86': lib_arch_dir = 'x86' else: diff --git a/platform/android/detect.py b/platform/android/detect.py index 461cb776745..f9bc977a343 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -16,13 +16,17 @@ def can_build(): return ("ANDROID_NDK_ROOT" in os.environ) +def get_platform(platform): + return int(platform.split("-")[1]) + + def get_opts(): return [ ('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)), ('ndk_platform', 'compile for platform: (android- , example: android-14)', "android-14"), - ('android_arch', 'select compiler architecture: (armv7/armv6/x86)', "armv7"), + ('android_arch', 'select compiler architecture: (armv7/armv6/arm64v8/x86)', "armv7"), ('android_neon', 'enable neon (armv7 only)', "yes"), ('android_stl', 'enable STL support in android port (for modules)', "no") ] @@ -89,7 +93,7 @@ def configure(env): ndk_platform = env['ndk_platform'] - if env['android_arch'] not in ['armv7', 'armv6', 'x86']: + if env['android_arch'] not in ['armv7', 'armv6', 'arm64v8', 'x86']: env['android_arch'] = 'armv7' if env['android_arch'] == 'x86': @@ -107,16 +111,19 @@ def configure(env): env.Append(CPPPATH=['#platform/android']) if env['android_arch'] == 'x86': + env['ARCH'] = 'arch-x86' env.extra_suffix = ".x86" + env.extra_suffix target_subpath = "x86-4.9" abi_subpath = "i686-linux-android" arch_subpath = "x86" elif env['android_arch'] == 'armv6': + env['ARCH'] = 'arch-arm' env.extra_suffix = ".armv6" + env.extra_suffix target_subpath = "arm-linux-androideabi-4.9" abi_subpath = "arm-linux-androideabi" arch_subpath = "armeabi" elif env["android_arch"] == "armv7": + env['ARCH'] = 'arch-arm' target_subpath = "arm-linux-androideabi-4.9" abi_subpath = "arm-linux-androideabi" arch_subpath = "armeabi-v7a" @@ -124,6 +131,15 @@ def configure(env): env.extra_suffix = ".armv7.neon" + env.extra_suffix else: env.extra_suffix = ".armv7" + env.extra_suffix + elif env["android_arch"] == "arm64v8": + if get_platform(ndk_platform) < 21: + print("WARNING: android_arch=arm64v8 is not supported by ndk_platform lower than andorid-21; setting ndk_platform=android-21") + ndk_platform = "android-21" + env['ARCH'] = 'arch-arm64' + target_subpath = "aarch64-linux-android-4.9" + abi_subpath = "aarch64-linux-android" + arch_subpath = "arm64-v8a" + env.extra_suffix = ".armv8" + env.extra_suffix mt_link = True if (sys.platform.startswith("linux")): @@ -137,10 +153,11 @@ def configure(env): mt_link = False host_subpath = "windows" - compiler_path = env["ANDROID_NDK_ROOT"] + \ - "/toolchains/llvm/prebuilt/" + host_subpath + "/bin" - gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + \ - "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath + if env["android_arch"] == "arm64v8": + mt_link = False + + compiler_path = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" + host_subpath + "/bin" + gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath tools_path = gcc_toolchain_path + "/" + abi_subpath + "/bin" # For Clang to find NDK tools in preference of those system-wide @@ -159,11 +176,6 @@ def configure(env): env['RANLIB'] = tools_path + "/ranlib" env['AS'] = tools_path + "/as" - if env['android_arch'] == 'x86': - env['ARCH'] = 'arch-x86' - else: - env['ARCH'] = 'arch-arm' - common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path] lib_sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + ndk_platform + "/" + env['ARCH'] @@ -175,7 +187,7 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"]) env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath]) # For unified headers this define has to be set manually - env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(int(ndk_platform.split("-")[1]))]) + env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(get_platform(ndk_platform))]) else: print("Using NDK deprecated headers") env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"]) @@ -204,6 +216,12 @@ def configure(env): else: env.Append(CPPFLAGS=['-mfpu=vfpv3-d16']) + elif env["android_arch"] == "arm64v8": + can_vectorize = True + target_opts = ['-target', 'aarch64-none-linux-android'] + env.Append(CPPFLAGS=['-D__ARM_ARCH_8A__']) + env.Append(CPPFLAGS=['-mfix-cortex-a53-835769']) + env.Append(CPPFLAGS=target_opts) env.Append(CPPFLAGS=common_opts) @@ -215,18 +233,20 @@ def configure(env): env['SHLIBSUFFIX'] = '.so' env['LINKFLAGS'] = ['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'] - env.Append(LINKFLAGS='-Wl,--fix-cortex-a8'.split()) + if env["android_arch"] == "armv7": + env.Append(LINKFLAGS=string.split('-Wl,--fix-cortex-a8')) env.Append(LINKFLAGS='-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now'.split()) env.Append(LINKFLAGS='-Wl,-soname,libgodot_android.so -Wl,--gc-sections'.split()) + if mt_link: env.Append(LINKFLAGS=['-Wl,--threads']) env.Append(LINKFLAGS=target_opts) env.Append(LINKFLAGS=common_opts) - env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/' + + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/lib/gcc/' + abi_subpath + '/4.9.x']) env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + - '/toolchains/arm-linux-androideabi-4.9/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) if (env["target"].startswith("release")): env.Append(LINKFLAGS=['-O2']) diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index d87233d7e79..835a6654a01 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -217,6 +217,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { bool use_32_fb; bool immersive; bool export_arm; + bool export_arm64; bool export_x86; String apk_expansion_salt; String apk_expansion_pkey; @@ -314,6 +315,8 @@ bool EditorExportPlatformAndroid::_set(const StringName &p_name, const Variant & _signed = p_value; else if (n == "architecture/arm") export_arm = p_value; + else if (n == "architecture/arm64") + export_arm64 = p_value; else if (n == "architecture/x86") export_x86 = p_value; else if (n == "screen/use_32_bits_view") @@ -387,6 +390,8 @@ bool EditorExportPlatformAndroid::_get(const StringName &p_name, Variant &r_ret) r_ret = _signed; else if (n == "architecture/arm") r_ret = export_arm; + else if (n == "architecture/arm64") + r_ret = export_arm64; else if (n == "architecture/x86") r_ret = export_x86; else if (n == "screen/use_32_bits_view") @@ -443,6 +448,7 @@ void EditorExportPlatformAndroid::_get_property_list(List *p_list) p_list->push_back(PropertyInfo(Variant::STRING, "package/icon", PROPERTY_HINT_FILE, "png")); p_list->push_back(PropertyInfo(Variant::BOOL, "package/signed")); p_list->push_back(PropertyInfo(Variant::BOOL, "architecture/arm")); + p_list->push_back(PropertyInfo(Variant::BOOL, "architecture/arm64")); p_list->push_back(PropertyInfo(Variant::BOOL, "architecture/x86")); p_list->push_back(PropertyInfo(Variant::BOOL, "screen/use_32_bits_view")); p_list->push_back(PropertyInfo(Variant::BOOL, "screen/immersive_mode")); @@ -1122,6 +1128,10 @@ Error EditorExportPlatformAndroid::export_project(const String &p_path, bool p_d skip = true; } + if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) { + skip = true; + } + if (file.begins_with("META-INF") && _signed) { skip = true; } @@ -1772,6 +1782,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() { immersive = true; export_arm = true; + export_arm64 = false; export_x86 = false; device_thread = Thread::create(_device_poll_thread, this); diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index e24d956a58a..abe28f76241 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -190,7 +190,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, argv[i].i = *p_args[i]; } break; case ARG_TYPE_LONG: { - argv[i].j = *p_args[i]; + argv[i].j = (int64_t)*p_args[i]; } break; case ARG_TYPE_FLOAT: { argv[i].f = *p_args[i]; @@ -350,7 +350,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, Array arr = *p_args[i]; jlongArray a = env->NewLongArray(arr.size()); for (int j = 0; j < arr.size(); j++) { - jlong val = arr[j]; + jlong val = (int64_t)arr[j]; env->SetLongArrayRegion(a, j, 1, &val); } argv[i].l = a; @@ -460,9 +460,9 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, case ARG_TYPE_LONG: { if (method->_static) { - ret = env->CallStaticLongMethodA(_class, method->method, argv); + ret = (int64_t)env->CallStaticLongMethodA(_class, method->method, argv); } else { - ret = env->CallLongMethodA(p_instance->instance, method->method, argv); + ret = (int64_t)env->CallLongMethodA(p_instance->instance, method->method, argv); } } break; @@ -679,7 +679,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va } break; case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT: { - var = env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue); + var = (int64_t)env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue); return true; } break; @@ -801,7 +801,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va jlong val; env->GetLongArrayRegion((jlongArray)arr, 0, 1, &val); - ret.push_back(val); + ret.push_back((int64_t)val); } var = ret;