fix crash caused by swappy on android

* fix native android crash

Co-authored-by: Zeqiang Li <zeqiang-li@outlook.com.com>
This commit is contained in:
Zeqiang Li 2022-03-24 14:38:07 +08:00 committed by GitHub
parent 660df56732
commit 5c20ccbf71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 68 deletions

View File

@ -34,7 +34,6 @@
// to your game/engine's own Java component, you do not need to add the binary // to your game/engine's own Java component, you do not need to add the binary
// resource and can instead define ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE which // resource and can instead define ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE which
// will avoid the linker requiring these symbols. // will avoid the linker requiring these symbols.
#define ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE
#ifndef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE #ifndef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE
extern const char _binary_classes_dex_start; extern const char _binary_classes_dex_start;
extern const char _binary_classes_dex_end; extern const char _binary_classes_dex_end;
@ -63,8 +62,8 @@ static bool deleteFile(std::string fileName) {
static bool createTempFile(JNIEnv* env, jobject activity, const char* ext, static bool createTempFile(JNIEnv* env, jobject activity, const char* ext,
std::string& tempFileName) { std::string& tempFileName) {
bool result = false; bool result = false;
jclass activityClass = env->GetObjectClass(activity); jclass activityClass = env->GetObjectClass(activity);
jmethodID getCacheDir = jmethodID getCacheDir =
env->GetMethodID(activityClass, "getCacheDir", "()Ljava/io/File;"); env->GetMethodID(activityClass, "getCacheDir", "()Ljava/io/File;");
jobject cacheDir = env->CallObjectMethod(activity, getCacheDir); jobject cacheDir = env->CallObjectMethod(activity, getCacheDir);
@ -72,13 +71,13 @@ static bool createTempFile(JNIEnv* env, jobject activity, const char* ext,
env->ExceptionDescribe(); env->ExceptionDescribe();
env->ExceptionClear(); env->ExceptionClear();
} else { } else {
jclass fileClass = env->FindClass("java/io/File"); jclass fileClass = env->FindClass("java/io/File");
jmethodID createTempFile = jmethodID createTempFile =
env->GetStaticMethodID(fileClass, "createTempFile", env->GetStaticMethodID(fileClass, "createTempFile",
"(Ljava/lang/String;Ljava/lang/String;Ljava/" "(Ljava/lang/String;Ljava/lang/String;Ljava/"
"io/File;)Ljava/io/File;"); "io/File;)Ljava/io/File;");
jstring prefix = env->NewStringUTF("ags"); jstring prefix = env->NewStringUTF("ags");
jstring suffix = env->NewStringUTF(ext); jstring suffix = env->NewStringUTF(ext);
jobject tempFile = env->CallStaticObjectMethod( jobject tempFile = env->CallStaticObjectMethod(
fileClass, createTempFile, prefix, suffix, cacheDir); fileClass, createTempFile, prefix, suffix, cacheDir);
if (env->ExceptionCheck()) { if (env->ExceptionCheck()) {
@ -105,11 +104,11 @@ static bool createTempFile(JNIEnv* env, jobject activity, const char* ext,
return result; return result;
} }
#endif // #ifndef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE #endif // #ifndef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE
static jclass loadClass(JNIEnv* env, jobject activity, const char* name, static jclass loadClass(JNIEnv* env, jobject activity, const char* name,
JNINativeMethod* nativeMethods, JNINativeMethod* nativeMethods,
size_t nativeMethodsSize) { size_t nativeMethodsSize) {
/* /*
* 1. Get a classloader from actvity * 1. Get a classloader from actvity
* 2. Try to create the requested class from the activty classloader * 2. Try to create the requested class from the activty classloader
@ -120,15 +119,15 @@ static jclass loadClass(JNIEnv* env, jobject activity, const char* name,
if (!env || !activity || !name) { if (!env || !activity || !name) {
return nullptr; return nullptr;
} }
jclass activityClass = env->GetObjectClass(activity); jclass activityClass = env->GetObjectClass(activity);
jclass classLoaderClass = env->FindClass("java/lang/ClassLoader"); jclass classLoaderClass = env->FindClass("java/lang/ClassLoader");
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader",
"()Ljava/lang/ClassLoader;"); "()Ljava/lang/ClassLoader;");
jobject classLoaderObj = env->CallObjectMethod(activity, getClassLoader); jobject classLoaderObj = env->CallObjectMethod(activity, getClassLoader);
jmethodID loadClass = env->GetMethodID( jmethodID loadClass = env->GetMethodID(
classLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); classLoaderClass, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;");
jstring className = env->NewStringUTF(name); jstring className = env->NewStringUTF(name);
jclass targetClass = static_cast<jclass>( jclass targetClass = static_cast<jclass>(
env->CallObjectMethod(classLoaderObj, loadClass, className)); env->CallObjectMethod(classLoaderObj, loadClass, className));
if (env->ExceptionCheck()) { if (env->ExceptionCheck()) {
env->ExceptionClear(); env->ExceptionClear();
@ -230,10 +229,10 @@ static jclass loadClass(JNIEnv* env, jobject activity, const char* name,
if (imclassloaderClass) { if (imclassloaderClass) {
env->DeleteLocalRef(imclassloaderClass); env->DeleteLocalRef(imclassloaderClass);
} }
#endif // #ifdef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE #endif // #ifdef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE
} }
env->DeleteLocalRef(className); env->DeleteLocalRef(className);
return targetClass; return targetClass;
} }
} // namespace gamesdk } // namespace gamesdk

View File

@ -16,6 +16,9 @@ set(IgnoreOldToolchainWarning "${ANDROID_UNIFIED_HEADERS}")
# set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-s" ) # set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-s" )
# set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-style=both" ) # set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-style=both" )
#no statistics log
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNDEBUG" )
set ( SOURCE_LOCATION ${CMAKE_CURRENT_LIST_DIR}) set ( SOURCE_LOCATION ${CMAKE_CURRENT_LIST_DIR})
set ( SOURCE_LOCATION_COMMON "${SOURCE_LOCATION}/common" ) set ( SOURCE_LOCATION_COMMON "${SOURCE_LOCATION}/common" )
set ( SOURCE_LOCATION_OPENGL "${SOURCE_LOCATION}/opengl" ) set ( SOURCE_LOCATION_OPENGL "${SOURCE_LOCATION}/opengl" )
@ -38,93 +41,92 @@ message( STATUS "Building swappy_static to ${CMAKE_CURRENT_BINARY_DIR}/build" )
# Dex linking requires an extra option for later versions of clang lld # Dex linking requires an extra option for later versions of clang lld
if (ANDROID_NDK_MAJOR GREATER 22) if (ANDROID_NDK_MAJOR GREATER 22)
if ( ANDROID_NDK_ABI_NAME MATCHES "armeabi-v7a") if ( ANDROID_NDK_ABI_NAME MATCHES "armeabi-v7a")
set (LINKER_TARGET_EMULATION_OPTION "-m" "armelf_linux_eabi") set (LINKER_TARGET_EMULATION_OPTION "-m" "armelf_linux_eabi")
elseif(ANDROID_NDK_ABI_NAME MATCHES "arm64-v8a") elseif(ANDROID_NDK_ABI_NAME MATCHES "arm64-v8a")
set (LINKER_TARGET_EMULATION_OPTION "-m" "aarch64linux") set (LINKER_TARGET_EMULATION_OPTION "-m" "aarch64linux")
elseif(ANDROID_NDK_ABI_NAME MATCHES "x86_64") elseif(ANDROID_NDK_ABI_NAME MATCHES "x86_64")
set (LINKER_TARGET_EMULATION_OPTION "-m" "elf_x86_64") set (LINKER_TARGET_EMULATION_OPTION "-m" "elf_x86_64")
elseif(ANDROID_NDK_ABI_NAME MATCHES "x86") elseif(ANDROID_NDK_ABI_NAME MATCHES "x86")
set (LINKER_TARGET_EMULATION_OPTION "-m" "elf_i386") set (LINKER_TARGET_EMULATION_OPTION "-m" "elf_i386")
endif() endif()
endif() endif()
add_custom_command(OUTPUT classes_dex.o add_custom_command(OUTPUT classes_dex.o
COMMAND cd ../intermediates/dex/release/mergeDexRelease/out && ${CMAKE_LINKER} ${LINKER_TARGET_EMULATION_OPTION} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/classes_dex.o classes.dex COMMAND cd ${CMAKE_CURRENT_LIST_DIR}/ && ${CMAKE_LINKER} ${LINKER_TARGET_EMULATION_OPTION} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/classes_dex.o classes.dex
WORKING_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY} WORKING_DIRECTORY ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}
) )
set_source_files_properties( set_source_files_properties(SwappyDisplayManager
classes_dex.o classes_dex.o
PROPERTIES PROPERTIES
EXTERNAL_OBJECT true EXTERNAL_OBJECT true
GENERATED true GENERATED true
) )
set(SRC_FILE set(SRC_FILE
${SOURCE_LOCATION_COMMON}/ChoreographerFilter.cpp ${SOURCE_LOCATION_COMMON}/ChoreographerFilter.cpp
${SOURCE_LOCATION_COMMON}/ChoreographerThread.cpp ${SOURCE_LOCATION_COMMON}/ChoreographerThread.cpp
${SOURCE_LOCATION_COMMON}/CpuInfo.cpp ${SOURCE_LOCATION_COMMON}/CpuInfo.cpp
${SOURCE_LOCATION_COMMON}/Settings.cpp ${SOURCE_LOCATION_COMMON}/Settings.cpp
${SOURCE_LOCATION_COMMON}/Thread.cpp ${SOURCE_LOCATION_COMMON}/Thread.cpp
${SOURCE_LOCATION_COMMON}/SwappyCommon.cpp ${SOURCE_LOCATION_COMMON}/SwappyCommon.cpp
${SOURCE_LOCATION_COMMON}/swappy_c.cpp ${SOURCE_LOCATION_COMMON}/swappy_c.cpp
${SOURCE_LOCATION_COMMON}/SwappyDisplayManager.cpp ${SOURCE_LOCATION_COMMON}/SwappyDisplayManager.cpp
${SOURCE_LOCATION_COMMON}/CPUTracer.cpp ${SOURCE_LOCATION_COMMON}/CPUTracer.cpp
${SOURCE_LOCATION}/../common/system_utils.cpp) ${SOURCE_LOCATION}/../common/system_utils.cpp)
set(SWAPPY_C_SRC) set(SWAPPY_C_SRC)
if(CC_USE_GLES3 OR CC_USE_GLES2) if(CC_USE_GLES3 OR CC_USE_GLES2)
list(APPEND SRC_FILE list(APPEND SRC_FILE
${SOURCE_LOCATION_OPENGL}/EGL.cpp ${SOURCE_LOCATION_OPENGL}/EGL.cpp
${SOURCE_LOCATION_OPENGL}/swappyGL_c.cpp ${SOURCE_LOCATION_OPENGL}/swappyGL_c.cpp
${SOURCE_LOCATION_OPENGL}/SwappyGL.cpp ${SOURCE_LOCATION_OPENGL}/SwappyGL.cpp
${SOURCE_LOCATION_OPENGL}/FrameStatisticsGL.cpp) ${SOURCE_LOCATION_OPENGL}/FrameStatisticsGL.cpp)
list(APPEND SWAPPY_C_SRC list(APPEND SWAPPY_C_SRC
${SOURCE_LOCATION_OPENGL}/swappyGL_c.cpp) ${SOURCE_LOCATION_OPENGL}/swappyGL_c.cpp)
endif() endif()
if(CC_USE_VULKAN) if(CC_USE_VULKAN)
list(APPEND SRC_FILE list(APPEND SRC_FILE
${SOURCE_LOCATION_VULKAN}/swappyVk_c.cpp ${SOURCE_LOCATION_VULKAN}/swappyVk_c.cpp
${SOURCE_LOCATION_VULKAN}/SwappyVk.cpp ${SOURCE_LOCATION_VULKAN}/SwappyVk.cpp
${SOURCE_LOCATION_VULKAN}/SwappyVkBase.cpp ${SOURCE_LOCATION_VULKAN}/SwappyVkBase.cpp
${SOURCE_LOCATION_VULKAN}/SwappyVkFallback.cpp ${SOURCE_LOCATION_VULKAN}/SwappyVkFallback.cpp
${SOURCE_LOCATION_VULKAN}/SwappyVkGoogleDisplayTiming.cpp) ${SOURCE_LOCATION_VULKAN}/SwappyVkGoogleDisplayTiming.cpp)
list(APPEND SWAPPY_C_SRC list(APPEND SWAPPY_C_SRC
${SOURCE_LOCATION_VULKAN}/swappyVk_c.cpp) ${SOURCE_LOCATION_VULKAN}/swappyVk_c.cpp)
endif() endif()
add_library( swappy_static add_library( swappy_static
STATIC STATIC
${SRC_FILE} ${SRC_FILE}
# ${CMAKE_CURRENT_BINARY_DIR}/classes_dex.o ${CMAKE_CURRENT_BINARY_DIR}/classes_dex.o
# Add new source files here # Add new source files here
) )
set_target_properties( swappy_static PROPERTIES set_target_properties( swappy_static PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build ) LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build )
add_library( swappy add_library( swappy
SHARED SHARED
${SWAPPY_C_SRC}) ${SWAPPY_C_SRC})
set(SWAPPY_ENABLED TRUE) set(SWAPPY_ENABLED TRUE)
add_definitions(-DSWAPPY_ENABLED) add_definitions(-DSWAPPY_ENABLED)
set(LIBS set(LIBS
swappy_static swappy_static
android android
log log
atomic) atomic)
if(CC_USE_GLES3 OR CC_USE_GLES2) if(CC_USE_GLES3 OR CC_USE_GLES2)
list(APPEND LIBS GLESv2) list(APPEND LIBS GLESv2)

Binary file not shown.