diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2017-12-16 05:23:06 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2017-12-16 05:23:06 +0000 |
| commit | 035dd284b70429c7a59237c1e6debc1663bd7e15 (patch) | |
| tree | b2d50e6c0141bfb8c403010831036799ac657411 | |
| parent | Updated CMakeLists (diff) | |
| download | DiligentCore-035dd284b70429c7a59237c1e6debc1663bd7e15.tar.gz DiligentCore-035dd284b70429c7a59237c1e6debc1663bd7e15.zip | |
CMake: enabling Android build
24 files changed, 1034 insertions, 55 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4baa1385..64fa8b18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.6) set(PLATFORM_WIN32 FALSE CACHE INTERNAL "") set(PLATFORM_UNIVERSAL_WINDOWS FALSE CACHE INTERNAL "") @@ -8,6 +8,8 @@ set(D3D12_SUPPORTED FALSE CACHE INTERNAL "D3D12 is not spported") set(GL_SUPPORTED FALSE CACHE INTERNAL "GL is not spported") set(GLES_SUPPORTED FALSE CACHE INTERNAL "GLES is not spported") +set(CMAKE_OBJECT_PATH_MAX 4096) + if(WIN32) if(${CMAKE_SYSTEM_NAME} STREQUAL "WindowsStore") set(PLATFORM_UNIVERSAL_WINDOWS TRUE CACHE INTERNAL "Target platform: Windows Store") @@ -15,7 +17,9 @@ if(WIN32) set(PLATFORM_WIN32 TRUE CACHE INTERNAL "Target platform: Win32") #WIN32 is a variable, so we cannot use string "WIN32" endif() else() - message(FATAL_ERROR "Unknown platform") + if(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + set(PLATFORM_ANDROID TRUE CACHE INTERNAL "Target platform: Android") + endif() endif(WIN32) add_library(BuildSettings INTERFACE) @@ -71,12 +75,28 @@ else() set(ARCH 32 CACHE INTERNAL "32-bit architecture") endif() -# https://cmake.org/cmake/help/v3.8/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES -target_compile_features(BuildSettings INTERFACE cxx_std_11) +if(PLATFORM_WIN32 OR PLATFORM_UNIVERSAL_WINDOWS) + # https://cmake.org/cmake/help/v3.8/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES + target_compile_features(BuildSettings INTERFACE cxx_std_11) # Generates an error in gradle build on Android +elseif(PLATFORM_ANDROID) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + target_compile_options(BuildSettings INTERFACE -std=c++11) + elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + target_compile_options(BuildSettings INTERFACE -std=gnu++11) # Generates an error in gradle build on Android + else() + message(WARNING "Unknown compiler") + endif() + + # LOCAL_CPP_FEATURES := exceptions rtti + +endif() include(BuildUtils.cmake) -add_subdirectory(Utilities) +if(PLATFORM_WIN32 OR PLATFORM_UNIVERSAL_WINDOWS) + add_subdirectory(Utilities) +endif() + add_subdirectory(Platforms) add_subdirectory(External) add_subdirectory(Common) diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index 070a2793..6179dc43 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.6) project(Common CXX) diff --git a/Common/include/InterfaceID.h b/Common/include/InterfaceID.h index d24f0b75..ff60d168 100644 --- a/Common/include/InterfaceID.h +++ b/Common/include/InterfaceID.h @@ -23,6 +23,7 @@ #pragma once +#include <cstring> #include "BasicTypes.h" /// Unique identification structures @@ -41,7 +42,7 @@ namespace Diligent return Data1 == rhs.Data1 && Data2 == rhs.Data2 && Data3 == rhs.Data3 && - memcmp(Data4, rhs.Data4, sizeof(Data4)) == 0; + std::memcmp(Data4, rhs.Data4, sizeof(Data4)) == 0; } }; diff --git a/External/Android/CMakeLists.txt b/External/Android/CMakeLists.txt new file mode 100644 index 00000000..9d921c33 --- /dev/null +++ b/External/Android/CMakeLists.txt @@ -0,0 +1,4 @@ +cmake_minimum_required (VERSION 3.6) + +add_subdirectory(native_app_glue) +add_subdirectory(ndk_helper) diff --git a/External/Android/native_app_glue/CMakeLists.txt b/External/Android/native_app_glue/CMakeLists.txt new file mode 100644 index 00000000..7229afd3 --- /dev/null +++ b/External/Android/native_app_glue/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required (VERSION 3.6) + +project(NativeAppGlue CXX) + +# build native_app_glue as a static lib +#get_filename_component(ANDROID_NATIVE_APP_GLUE_C +# ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c +# ABSOLUTE +# ) + +#configure_file( +# ${ANDROID_NATIVE_APP_GLUE_C} +# ${CMAKE_CURRENT_SOURCE_DIR}/android_native_app_glue.c +# COPYONLY +#) + +# No matter what I do, the build fails when I try to reference android_native_app_glue.c +# directly in the ndk the same way as in this example: +# https://github.com/googlesamples/android-ndk/blob/master/teapots/classic-teapot/src/main/cpp/CMakeLists.txt +# Copying file locally also fails +add_library(NativeAppGlue STATIC + # ${ANDROID_NATIVE_APP_GLUE_C} + # ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c + android_native_app_glue.c +) + +# The linker will strip this as "unused" since this is a static library, but we +# need to keep it around since it's the interface for JNI. +# Refer to: https://github.com/android-ndk/ndk/issues/381. +#set_target_properties(NativeAppGlue PROPERTIES +# STATIC_LIBRARY_FLAGS "-u ANativeActivity_onCreate" +#) + +target_include_directories(NativeAppGlue +INTERFACE + ${ANDROID_NDK}/sources/android/native_app_glue +) + +set_target_properties(NativeAppGlue PROPERTIES + FOLDER Core/External +) diff --git a/External/Android/native_app_glue/android_native_app_glue.c b/External/Android/native_app_glue/android_native_app_glue.c new file mode 100644 index 00000000..7eada086 --- /dev/null +++ b/External/Android/native_app_glue/android_native_app_glue.c @@ -0,0 +1,442 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <jni.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/resource.h> + +#include "android_native_app_glue.h" +#include <android/log.h> + +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__)) + +/* For debug builds, always enable the debug traces in this library */ +#ifndef NDEBUG +# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__)) +#else +# define LOGV(...) ((void)0) +#endif + +static void free_saved_state(struct android_app* android_app) { + pthread_mutex_lock(&android_app->mutex); + if (android_app->savedState != NULL) { + free(android_app->savedState); + android_app->savedState = NULL; + android_app->savedStateSize = 0; + } + pthread_mutex_unlock(&android_app->mutex); +} + +int8_t android_app_read_cmd(struct android_app* android_app) { + int8_t cmd; + if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { + switch (cmd) { + case APP_CMD_SAVE_STATE: + free_saved_state(android_app); + break; + } + return cmd; + } else { + LOGE("No data on command pipe!"); + } + return -1; +} + +static void print_cur_config(struct android_app* android_app) { + char lang[2], country[2]; + AConfiguration_getLanguage(android_app->config, lang); + AConfiguration_getCountry(android_app->config, country); + + LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d " + "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d " + "modetype=%d modenight=%d", + AConfiguration_getMcc(android_app->config), + AConfiguration_getMnc(android_app->config), + lang[0], lang[1], country[0], country[1], + AConfiguration_getOrientation(android_app->config), + AConfiguration_getTouchscreen(android_app->config), + AConfiguration_getDensity(android_app->config), + AConfiguration_getKeyboard(android_app->config), + AConfiguration_getNavigation(android_app->config), + AConfiguration_getKeysHidden(android_app->config), + AConfiguration_getNavHidden(android_app->config), + AConfiguration_getSdkVersion(android_app->config), + AConfiguration_getScreenSize(android_app->config), + AConfiguration_getScreenLong(android_app->config), + AConfiguration_getUiModeType(android_app->config), + AConfiguration_getUiModeNight(android_app->config)); +} + +void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) { + switch (cmd) { + case APP_CMD_INPUT_CHANGED: + LOGV("APP_CMD_INPUT_CHANGED\n"); + pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) { + AInputQueue_detachLooper(android_app->inputQueue); + } + android_app->inputQueue = android_app->pendingInputQueue; + if (android_app->inputQueue != NULL) { + LOGV("Attaching input queue to looper"); + AInputQueue_attachLooper(android_app->inputQueue, + android_app->looper, LOOPER_ID_INPUT, NULL, + &android_app->inputPollSource); + } + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_INIT_WINDOW: + LOGV("APP_CMD_INIT_WINDOW\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->window = android_app->pendingWindow; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_TERM_WINDOW: + LOGV("APP_CMD_TERM_WINDOW\n"); + pthread_cond_broadcast(&android_app->cond); + break; + + case APP_CMD_RESUME: + case APP_CMD_START: + case APP_CMD_PAUSE: + case APP_CMD_STOP: + LOGV("activityState=%d\n", cmd); + pthread_mutex_lock(&android_app->mutex); + android_app->activityState = cmd; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_CONFIG_CHANGED: + LOGV("APP_CMD_CONFIG_CHANGED\n"); + AConfiguration_fromAssetManager(android_app->config, + android_app->activity->assetManager); + print_cur_config(android_app); + break; + + case APP_CMD_DESTROY: + LOGV("APP_CMD_DESTROY\n"); + android_app->destroyRequested = 1; + break; + } +} + +void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) { + switch (cmd) { + case APP_CMD_TERM_WINDOW: + LOGV("APP_CMD_TERM_WINDOW\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->window = NULL; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_SAVE_STATE: + LOGV("APP_CMD_SAVE_STATE\n"); + pthread_mutex_lock(&android_app->mutex); + android_app->stateSaved = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + break; + + case APP_CMD_RESUME: + free_saved_state(android_app); + break; + } +} + +void app_dummy() { + +} + +static void android_app_destroy(struct android_app* android_app) { + LOGV("android_app_destroy!"); + free_saved_state(android_app); + pthread_mutex_lock(&android_app->mutex); + if (android_app->inputQueue != NULL) { + AInputQueue_detachLooper(android_app->inputQueue); + } + AConfiguration_delete(android_app->config); + android_app->destroyed = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + // Can't touch android_app object after this. +} + +static void process_input(struct android_app* app, struct android_poll_source* source) { + AInputEvent* event = NULL; + while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { + LOGV("New input event: type=%d\n", AInputEvent_getType(event)); + if (AInputQueue_preDispatchEvent(app->inputQueue, event)) { + continue; + } + int32_t handled = 0; + if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event); + AInputQueue_finishEvent(app->inputQueue, event, handled); + } +} + +static void process_cmd(struct android_app* app, struct android_poll_source* source) { + int8_t cmd = android_app_read_cmd(app); + android_app_pre_exec_cmd(app, cmd); + if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); + android_app_post_exec_cmd(app, cmd); +} + +static void* android_app_entry(void* param) { + struct android_app* android_app = (struct android_app*)param; + + android_app->config = AConfiguration_new(); + AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager); + + print_cur_config(android_app); + + android_app->cmdPollSource.id = LOOPER_ID_MAIN; + android_app->cmdPollSource.app = android_app; + android_app->cmdPollSource.process = process_cmd; + android_app->inputPollSource.id = LOOPER_ID_INPUT; + android_app->inputPollSource.app = android_app; + android_app->inputPollSource.process = process_input; + + ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); + ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL, + &android_app->cmdPollSource); + android_app->looper = looper; + + pthread_mutex_lock(&android_app->mutex); + android_app->running = 1; + pthread_cond_broadcast(&android_app->cond); + pthread_mutex_unlock(&android_app->mutex); + + android_main(android_app); + + android_app_destroy(android_app); + return NULL; +} + +// -------------------------------------------------------------------- +// Native activity interaction (called from main thread) +// -------------------------------------------------------------------- + +static struct android_app* android_app_create(ANativeActivity* activity, + void* savedState, size_t savedStateSize) { + struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); + memset(android_app, 0, sizeof(struct android_app)); + android_app->activity = activity; + + pthread_mutex_init(&android_app->mutex, NULL); + pthread_cond_init(&android_app->cond, NULL); + + if (savedState != NULL) { + android_app->savedState = malloc(savedStateSize); + android_app->savedStateSize = savedStateSize; + memcpy(android_app->savedState, savedState, savedStateSize); + } + + int msgpipe[2]; + if (pipe(msgpipe)) { + LOGE("could not create pipe: %s", strerror(errno)); + return NULL; + } + android_app->msgread = msgpipe[0]; + android_app->msgwrite = msgpipe[1]; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&android_app->thread, &attr, android_app_entry, android_app); + + // Wait for thread to start. + pthread_mutex_lock(&android_app->mutex); + while (!android_app->running) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); + + return android_app; +} + +static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { + if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { + LOGE("Failure writing android_app cmd: %s\n", strerror(errno)); + } +} + +static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { + pthread_mutex_lock(&android_app->mutex); + android_app->pendingInputQueue = inputQueue; + android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); + while (android_app->inputQueue != android_app->pendingInputQueue) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { + pthread_mutex_lock(&android_app->mutex); + if (android_app->pendingWindow != NULL) { + android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW); + } + android_app->pendingWindow = window; + if (window != NULL) { + android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW); + } + while (android_app->window != android_app->pendingWindow) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { + pthread_mutex_lock(&android_app->mutex); + android_app_write_cmd(android_app, cmd); + while (android_app->activityState != cmd) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); +} + +static void android_app_free(struct android_app* android_app) { + pthread_mutex_lock(&android_app->mutex); + android_app_write_cmd(android_app, APP_CMD_DESTROY); + while (!android_app->destroyed) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + pthread_mutex_unlock(&android_app->mutex); + + close(android_app->msgread); + close(android_app->msgwrite); + pthread_cond_destroy(&android_app->cond); + pthread_mutex_destroy(&android_app->mutex); + free(android_app); +} + +static void onDestroy(ANativeActivity* activity) { + LOGV("Destroy: %p\n", activity); + android_app_free((struct android_app*)activity->instance); +} + +static void onStart(ANativeActivity* activity) { + LOGV("Start: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); +} + +static void onResume(ANativeActivity* activity) { + LOGV("Resume: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); +} + +static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { + struct android_app* android_app = (struct android_app*)activity->instance; + void* savedState = NULL; + + LOGV("SaveInstanceState: %p\n", activity); + pthread_mutex_lock(&android_app->mutex); + android_app->stateSaved = 0; + android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); + while (!android_app->stateSaved) { + pthread_cond_wait(&android_app->cond, &android_app->mutex); + } + + if (android_app->savedState != NULL) { + savedState = android_app->savedState; + *outLen = android_app->savedStateSize; + android_app->savedState = NULL; + android_app->savedStateSize = 0; + } + + pthread_mutex_unlock(&android_app->mutex); + + return savedState; +} + +static void onPause(ANativeActivity* activity) { + LOGV("Pause: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); +} + +static void onStop(ANativeActivity* activity) { + LOGV("Stop: %p\n", activity); + android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); +} + +static void onConfigurationChanged(ANativeActivity* activity) { + struct android_app* android_app = (struct android_app*)activity->instance; + LOGV("ConfigurationChanged: %p\n", activity); + android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); +} + +static void onLowMemory(ANativeActivity* activity) { + struct android_app* android_app = (struct android_app*)activity->instance; + LOGV("LowMemory: %p\n", activity); + android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); +} + +static void onWindowFocusChanged(ANativeActivity* activity, int focused) { + LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); + android_app_write_cmd((struct android_app*)activity->instance, + focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); +} + +static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { + LOGV("NativeWindowCreated: %p -- %p\n", activity, window); + android_app_set_window((struct android_app*)activity->instance, window); +} + +static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { + LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); + android_app_set_window((struct android_app*)activity->instance, NULL); +} + +static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { + LOGV("InputQueueCreated: %p -- %p\n", activity, queue); + android_app_set_input((struct android_app*)activity->instance, queue); +} + +static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { + LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); + android_app_set_input((struct android_app*)activity->instance, NULL); +} + +JNIEXPORT +void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, + size_t savedStateSize) { + LOGV("Creating: %p\n", activity); + activity->callbacks->onDestroy = onDestroy; + activity->callbacks->onStart = onStart; + activity->callbacks->onResume = onResume; + activity->callbacks->onSaveInstanceState = onSaveInstanceState; + activity->callbacks->onPause = onPause; + activity->callbacks->onStop = onStop; + activity->callbacks->onConfigurationChanged = onConfigurationChanged; + activity->callbacks->onLowMemory = onLowMemory; + activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; + activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; + activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; + activity->callbacks->onInputQueueCreated = onInputQueueCreated; + activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; + + activity->instance = android_app_create(activity, savedState, savedStateSize); +} diff --git a/External/Android/native_app_glue/android_native_app_glue.h b/External/Android/native_app_glue/android_native_app_glue.h new file mode 100644 index 00000000..c99d6e12 --- /dev/null +++ b/External/Android/native_app_glue/android_native_app_glue.h @@ -0,0 +1,354 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _ANDROID_NATIVE_APP_GLUE_H +#define _ANDROID_NATIVE_APP_GLUE_H + +#include <poll.h> +#include <pthread.h> +#include <sched.h> + +#include <android/configuration.h> +#include <android/looper.h> +#include <android/native_activity.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * The native activity interface provided by <android/native_activity.h> + * is based on a set of application-provided callbacks that will be called + * by the Activity's main thread when certain events occur. + * + * This means that each one of this callbacks _should_ _not_ block, or they + * risk having the system force-close the application. This programming + * model is direct, lightweight, but constraining. + * + * The 'android_native_app_glue' static library is used to provide a different + * execution model where the application can implement its own main event + * loop in a different thread instead. Here's how it works: + * + * 1/ The application must provide a function named "android_main()" that + * will be called when the activity is created, in a new thread that is + * distinct from the activity's main thread. + * + * 2/ android_main() receives a pointer to a valid "android_app" structure + * that contains references to other important objects, e.g. the + * ANativeActivity obejct instance the application is running in. + * + * 3/ the "android_app" object holds an ALooper instance that already + * listens to two important things: + * + * - activity lifecycle events (e.g. "pause", "resume"). See APP_CMD_XXX + * declarations below. + * + * - input events coming from the AInputQueue attached to the activity. + * + * Each of these correspond to an ALooper identifier returned by + * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT, + * respectively. + * + * Your application can use the same ALooper to listen to additional + * file-descriptors. They can either be callback based, or with return + * identifiers starting with LOOPER_ID_USER. + * + * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event, + * the returned data will point to an android_poll_source structure. You + * can call the process() function on it, and fill in android_app->onAppCmd + * and android_app->onInputEvent to be called for your own processing + * of the event. + * + * Alternatively, you can call the low-level functions to read and process + * the data directly... look at the process_cmd() and process_input() + * implementations in the glue to see how to do this. + * + * See the sample named "native-activity" that comes with the NDK with a + * full usage example. Also look at the JavaDoc of NativeActivity. + */ + +struct android_app; + +/** + * Data associated with an ALooper fd that will be returned as the "outData" + * when that source has data ready. + */ +struct android_poll_source { + // The identifier of this source. May be LOOPER_ID_MAIN or + // LOOPER_ID_INPUT. + int32_t id; + + // The android_app this ident is associated with. + struct android_app* app; + + // Function to call to perform the standard processing of data from + // this source. + void (*process)(struct android_app* app, struct android_poll_source* source); +}; + +/** + * This is the interface for the standard glue code of a threaded + * application. In this model, the application's code is running + * in its own thread separate from the main thread of the process. + * It is not required that this thread be associated with the Java + * VM, although it will need to be in order to make JNI calls any + * Java objects. + */ +struct android_app { + // The application can place a pointer to its own state object + // here if it likes. + void* userData; + + // Fill this in with the function to process main app commands (APP_CMD_*) + void (*onAppCmd)(struct android_app* app, int32_t cmd); + + // Fill this in with the function to process input events. At this point + // the event has already been pre-dispatched, and it will be finished upon + // return. Return 1 if you have handled the event, 0 for any default + // dispatching. + int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event); + + // The ANativeActivity object instance that this app is running in. + ANativeActivity* activity; + + // The current configuration the app is running in. + AConfiguration* config; + + // This is the last instance's saved state, as provided at creation time. + // It is NULL if there was no state. You can use this as you need; the + // memory will remain around until you call android_app_exec_cmd() for + // APP_CMD_RESUME, at which point it will be freed and savedState set to NULL. + // These variables should only be changed when processing a APP_CMD_SAVE_STATE, + // at which point they will be initialized to NULL and you can malloc your + // state and place the information here. In that case the memory will be + // freed for you later. + void* savedState; + size_t savedStateSize; + + // The ALooper associated with the app's thread. + ALooper* looper; + + // When non-NULL, this is the input queue from which the app will + // receive user input events. + AInputQueue* inputQueue; + + // When non-NULL, this is the window surface that the app can draw in. + ANativeWindow* window; + + // Current content rectangle of the window; this is the area where the + // window's content should be placed to be seen by the user. + ARect contentRect; + + // Current state of the app's activity. May be either APP_CMD_START, + // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. + int activityState; + + // This is non-zero when the application's NativeActivity is being + // destroyed and waiting for the app thread to complete. + int destroyRequested; + + // ------------------------------------------------- + // Below are "private" implementation of the glue code. + + pthread_mutex_t mutex; + pthread_cond_t cond; + + int msgread; + int msgwrite; + + pthread_t thread; + + struct android_poll_source cmdPollSource; + struct android_poll_source inputPollSource; + + int running; + int stateSaved; + int destroyed; + int redrawNeeded; + AInputQueue* pendingInputQueue; + ANativeWindow* pendingWindow; + ARect pendingContentRect; +}; + +enum { + /** + * Looper data ID of commands coming from the app's main thread, which + * is returned as an identifier from ALooper_pollOnce(). The data for this + * identifier is a pointer to an android_poll_source structure. + * These can be retrieved and processed with android_app_read_cmd() + * and android_app_exec_cmd(). + */ + LOOPER_ID_MAIN = 1, + + /** + * Looper data ID of events coming from the AInputQueue of the + * application's window, which is returned as an identifier from + * ALooper_pollOnce(). The data for this identifier is a pointer to an + * android_poll_source structure. These can be read via the inputQueue + * object of android_app. + */ + LOOPER_ID_INPUT = 2, + + /** + * Start of user-defined ALooper identifiers. + */ + LOOPER_ID_USER = 3, +}; + +enum { + /** + * Command from main thread: the AInputQueue has changed. Upon processing + * this command, android_app->inputQueue will be updated to the new queue + * (or NULL). + */ + APP_CMD_INPUT_CHANGED, + + /** + * Command from main thread: a new ANativeWindow is ready for use. Upon + * receiving this command, android_app->window will contain the new window + * surface. + */ + APP_CMD_INIT_WINDOW, + + /** + * Command from main thread: the existing ANativeWindow needs to be + * terminated. Upon receiving this command, android_app->window still + * contains the existing window; after calling android_app_exec_cmd + * it will be set to NULL. + */ + APP_CMD_TERM_WINDOW, + + /** + * Command from main thread: the current ANativeWindow has been resized. + * Please redraw with its new size. + */ + APP_CMD_WINDOW_RESIZED, + + /** + * Command from main thread: the system needs that the current ANativeWindow + * be redrawn. You should redraw the window before handing this to + * android_app_exec_cmd() in order to avoid transient drawing glitches. + */ + APP_CMD_WINDOW_REDRAW_NEEDED, + + /** + * Command from main thread: the content area of the window has changed, + * such as from the soft input window being shown or hidden. You can + * find the new content rect in android_app::contentRect. + */ + APP_CMD_CONTENT_RECT_CHANGED, + + /** + * Command from main thread: the app's activity window has gained + * input focus. + */ + APP_CMD_GAINED_FOCUS, + + /** + * Command from main thread: the app's activity window has lost + * input focus. + */ + APP_CMD_LOST_FOCUS, + + /** + * Command from main thread: the current device configuration has changed. + */ + APP_CMD_CONFIG_CHANGED, + + /** + * Command from main thread: the system is running low on memory. + * Try to reduce your memory use. + */ + APP_CMD_LOW_MEMORY, + + /** + * Command from main thread: the app's activity has been started. + */ + APP_CMD_START, + + /** + * Command from main thread: the app's activity has been resumed. + */ + APP_CMD_RESUME, + + /** + * Command from main thread: the app should generate a new saved state + * for itself, to restore from later if needed. If you have saved state, + * allocate it with malloc and place it in android_app.savedState with + * the size in android_app.savedStateSize. The will be freed for you + * later. + */ + APP_CMD_SAVE_STATE, + + /** + * Command from main thread: the app's activity has been paused. + */ + APP_CMD_PAUSE, + + /** + * Command from main thread: the app's activity has been stopped. + */ + APP_CMD_STOP, + + /** + * Command from main thread: the app's activity is being destroyed, + * and waiting for the app thread to clean up and exit before proceeding. + */ + APP_CMD_DESTROY, +}; + +/** + * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next + * app command message. + */ +int8_t android_app_read_cmd(struct android_app* android_app); + +/** + * Call with the command returned by android_app_read_cmd() to do the + * initial pre-processing of the given command. You can perform your own + * actions for the command after calling this function. + */ +void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd); + +/** + * Call with the command returned by android_app_read_cmd() to do the + * final post-processing of the given command. You must have done your own + * actions for the command before calling this function. + */ +void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd); + +/** + * Dummy function that used to be used to prevent the linker from stripping app + * glue code. No longer necessary, since __attribute__((visibility("default"))) + * does this for us. + */ +__attribute__(( + deprecated("Calls to app_dummy are no longer necessary. See " + "https://github.com/android-ndk/ndk/issues/381."))) void +app_dummy(); + +/** + * This is the function that application code must implement, representing + * the main entry to the app. + */ +extern void android_main(struct android_app* app); + +#ifdef __cplusplus +} +#endif + +#endif /* _ANDROID_NATIVE_APP_GLUE_H */ diff --git a/External/Android/ndk_helper/CMakeLists.txt b/External/Android/ndk_helper/CMakeLists.txt new file mode 100644 index 00000000..f0d1c6b2 --- /dev/null +++ b/External/Android/ndk_helper/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required (VERSION 3.6) + +project(NdkHelper CXX) + +set(SOURCE + src/gestureDetector.cpp + src/JNIHelper.cpp + src/perfMonitor.cpp + src/sensorManager.cpp + src/tapCamera.cpp + src/vecmath.cpp +) + +set(INCLUDE + include/gestureDetector.h + include/JNIHelper.h + include/perfMonitor.h + include/sensorManager.h + include/tapCamera.h +) + +add_library(NdkHelper STATIC ${SOURCE} ${INCLUDE}) +set_common_target_properties(NdkHelper) + +target_include_directories(NdkHelper +PUBLIC + include +) + +target_link_libraries(NdkHelper +PRIVATE + BuildSettings +PUBLIC + NativeAppGlue +) + +source_group("src" FILES ${SOURCE}) +source_group("include" FILES ${INCLUDE}) + +set_target_properties(NdkHelper PROPERTIES + FOLDER Core/External +) diff --git a/External/CMakeLists.txt b/External/CMakeLists.txt index ce1f3500..14890b34 100644 --- a/External/CMakeLists.txt +++ b/External/CMakeLists.txt @@ -1,5 +1,9 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 3.6) if(PLATFORM_WIN32) add_subdirectory(glew) endif() + +if(PLATFORM_ANDROID) + add_subdirectory(Android) +endif() diff --git a/Graphics/CMakeLists.txt b/Graphics/CMakeLists.txt index 9eea09a3..3ae9b9f3 100644 --- a/Graphics/CMakeLists.txt +++ b/Graphics/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 3.6) set(DLL_REL_SUFFIX _${ARCH}r) set(DLL_DBG_SUFFIX _${ARCH}d) diff --git a/Graphics/GraphicsEngine/CMakeLists.txt b/Graphics/GraphicsEngine/CMakeLists.txt index 377a625d..e0949b26 100644 --- a/Graphics/GraphicsEngine/CMakeLists.txt +++ b/Graphics/GraphicsEngine/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.6) project(GraphicsEngine CXX) diff --git a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt index 1ffe9558..decd024a 100644 --- a/Graphics/GraphicsEngineD3DBase/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3DBase/CMakeLists.txt @@ -37,9 +37,8 @@ SOURCES ) if(PLATFORM_UNIVERSAL_WINDOWS) - # On Universal Windows Platform, we cannot run File2String utility and will use prebuilt Win32 version - get_target_property(FILE2STRING_SOURCE_DIR File2String SOURCE_DIR) - set(FILE2STRING_PATH "${FILE2STRING_SOURCE_DIR}/bin/Win32/File2String.exe") + # On Universal Windows Platform, we cannot build File2String utility and will use prebuilt Win32 version + set(FILE2STRING_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../Utilities/File2Include/bin/Win32/File2String.exe") else() add_dependencies(ProcessHLSLDefinitions File2String) set(FILE2STRING_PATH $<TARGET_FILE:File2String>) diff --git a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt index bf046937..bb257613 100644 --- a/Graphics/GraphicsEngineOpenGL/CMakeLists.txt +++ b/Graphics/GraphicsEngineOpenGL/CMakeLists.txt @@ -84,7 +84,7 @@ if(PLATFORM_WIN32) list(APPEND SOURCE src/RenderDeviceGLImpl.cpp) set(APPEND INCLUDE include/GLContextWindows.h) -elseif(PLATFORM_ANRDOID) +elseif(PLATFORM_ANDROID) list(APPEND SOURCE src/GLContextAndroid.cpp) list(APPEND SOURCE src/RenderDeviceGLESImpl.cpp) list(APPEND SOURCE src/GLStubs.cpp) @@ -132,13 +132,10 @@ PRIVATE ../HLSL2GLSLConverterLib/include ) - set(PRIVATE_DEPENDENCIES BuildSettings - glew-static Common GraphicsTools - opengl32.lib TargetPlatform ) @@ -147,6 +144,17 @@ set(PUBLIC_DEPENDENCIES HLSL2GLSLConverterLib ) +if(PLATFORM_WIN32) + set(PRIVATE_DEPENDENCIES ${PRIVATE_DEPENDENCIES} glew-static opengl32.lib) +elseif(PLATFORM_ANDROID) + set(PRIVATE_DEPENDENCIES ${PRIVATE_DEPENDENCIES} GLESv3 EGL android) + target_compile_definitions(GraphicsEngineOpenGL-static PRIVATE BUILDING_DLL USE_GL3_STUB=0) + target_compile_definitions(GraphicsEngineOpenGL-shared PRIVATE BUILDING_DLL USE_GL3_STUB=0) + # LOCAL_CFLAGS := -fvisibility=hidden +else() + message(FATAL_ERROR "Unknown platform") +endif() + target_link_libraries(GraphicsEngineOpenGL-static PRIVATE ${PRIVATE_DEPENDENCIES} PUBLIC ${PUBLIC_DEPENDENCIES}) target_link_libraries(GraphicsEngineOpenGL-shared PRIVATE ${PRIVATE_DEPENDENCIES} PUBLIC ${PUBLIC_DEPENDENCIES}) target_compile_definitions(GraphicsEngineOpenGL-shared PUBLIC ENGINE_DLL) diff --git a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h index ac469f16..cd2995c8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/VAOCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/VAOCache.h @@ -23,6 +23,7 @@ #pragma once +#include <cstring> #include "GraphicsTypes.h" #include "Buffer.h" #include "InputLayout.h" @@ -91,7 +92,7 @@ private: return pPSO == Key.pPSO && pIndexBuffer == Key.pIndexBuffer && NumUsedSlots == Key.NumUsedSlots && - memcmp(Streams, Key.Streams, sizeof(StreamAttribs) * NumUsedSlots) == 0; + std::memcmp(Streams, Key.Streams, sizeof(StreamAttribs) * NumUsedSlots) == 0; } }; diff --git a/Graphics/GraphicsTools/CMakeLists.txt b/Graphics/GraphicsTools/CMakeLists.txt index 17919956..32b1e919 100644 --- a/Graphics/GraphicsTools/CMakeLists.txt +++ b/Graphics/GraphicsTools/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.6) project(GraphicsTools CXX) @@ -11,9 +11,6 @@ set(INCLUDE include/RingBuffer.h include/TextureUploader.h include/TextureUploaderBase.h - include/TextureUploaderD3D11.h - include/TextureUploaderD3D12.h - include/TextureUploaderGL.h include/VariableSizeAllocationsManager.h include/VariableSizeGPUAllocationsManager.h ) @@ -23,11 +20,22 @@ set(SOURCE src/GraphicsUtilities.cpp src/pch.cpp src/TextureUploader.cpp - src/TextureUploaderD3D11.cpp - src/TextureUploaderD3D12.cpp - src/TextureUploaderGL.cpp ) +if(D3D11_SUPPORTED) + list(APPEND SOURCE src/TextureUploaderD3D11.cpp) + list(APPEND INCLUDE include/TextureUploaderD3D11.h) +endif() + +if(D3D12_SUPPORTED) + list(APPEND SOURCE src/TextureUploaderD3D12.cpp) + list(APPEND INCLUDE include/TextureUploaderD3D12.h) +endif() + +if(GL_SUPPORTED OR GLES_SUPPORTED) + list(APPEND SOURCE src/TextureUploaderGL.cpp) + list(APPEND INCLUDE include/TextureUploaderGL.h) +endif() add_library(GraphicsTools STATIC ${SOURCE} ${INCLUDE}) diff --git a/Graphics/GraphicsTools/include/TextureUploaderBase.h b/Graphics/GraphicsTools/include/TextureUploaderBase.h index 0bd43bcd..4cb6f2ef 100644 --- a/Graphics/GraphicsTools/include/TextureUploaderBase.h +++ b/Graphics/GraphicsTools/include/TextureUploaderBase.h @@ -51,7 +51,6 @@ namespace Diligent { } - virtual void WaitForCopyScheduled() = 0; virtual void* GetDataPtr() override final { return m_pData; } virtual size_t GetRowStride() const override final{ return m_RowStride; } virtual size_t GetDepthStride()const override final{ return m_DepthStride; } diff --git a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp index 23089571..0cae06ac 100644 --- a/Graphics/GraphicsTools/src/GraphicsUtilities.cpp +++ b/Graphics/GraphicsTools/src/GraphicsUtilities.cpp @@ -814,10 +814,10 @@ void GenerateCheckerBoardPatternInternal(Uint32 Width, Uint32 Height, TEXTURE_FO static float LinearToSRGB(float x) { // This is exactly the sRGB curve - //return x < 0.0031308 ? 12.92 * x : 1.055 * pow(abs(x), 1.0 / 2.4) - 0.055; + //return x < 0.0031308 ? 12.92 * x : 1.055 * pow(std::abs(x), 1.0 / 2.4) - 0.055; // This is cheaper but nearly equivalent - return x < 0.0031308f ? 12.92f * x : 1.13005f * sqrtf(abs(x - 0.00228f)) - 0.13448f * x + 0.005719f; + return x < 0.0031308f ? 12.92f * x : 1.13005f * sqrtf(std::abs(x - 0.00228f)) - 0.13448f * x + 0.005719f; } diff --git a/Graphics/GraphicsTools/src/TextureUploader.cpp b/Graphics/GraphicsTools/src/TextureUploader.cpp index f056f162..ddc930ef 100644 --- a/Graphics/GraphicsTools/src/TextureUploader.cpp +++ b/Graphics/GraphicsTools/src/TextureUploader.cpp @@ -45,6 +45,9 @@ namespace Diligent case DeviceType::OpenGL: *ppUploader = MakeNewRCObj<TextureUploaderGL>()( pDevice, Desc ); break; + + default: + UNEXPECTED("Unexpected device type") } if (*ppUploader != nullptr) (*ppUploader)->AddRef(); diff --git a/Graphics/HLSL2GLSLConverterLib/CMakeLists.txt b/Graphics/HLSL2GLSLConverterLib/CMakeLists.txt index a2146be9..b3194592 100644 --- a/Graphics/HLSL2GLSLConverterLib/CMakeLists.txt +++ b/Graphics/HLSL2GLSLConverterLib/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.3) +cmake_minimum_required (VERSION 3.6) project(HLSL2GLSLConverterLib CXX) @@ -42,25 +42,36 @@ PRIVATE GraphicsTools ) -# Create custom target to convert GLSLDefinitions.h to GLSLDefinitions_inc.h -add_custom_target(ProcessGLSLDefinitions -SOURCES - include/GLSLDefinitions.h -) -add_dependencies(ProcessGLSLDefinitions File2String) +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + # Create custom target to convert GLSLDefinitions.h to GLSLDefinitions_inc.h + add_custom_target(ProcessGLSLDefinitions + SOURCES + include/GLSLDefinitions.h + ) -add_custom_command(TARGET ProcessGLSLDefinitions - # Unfortunately it is not possible to set TARGET directly to GraphicsEngineD3DBase - # because PRE_BUILD is only supported on Visual Studio 8 or later. For all other generators - # PRE_BUILD is treated as PRE_LINK. - COMMAND COMMAND $<TARGET_FILE:File2String> include/GLSLDefinitions.h include/GLSLDefinitions_inc.h - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMENT "Processing GLSLDefinitions.h" - VERBATIM -) + if(PLATFORM_WIN32) + set(FILE2STRING_PATH $<TARGET_FILE:File2String>) + add_dependencies(ProcessGLSLDefinitions File2String) + else() + # We cannot run File2String utility and will use prebuilt Win32 version + set(FILE2STRING_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../Utilities/File2Include/bin/Win32/File2String.exe") + endif() -add_dependencies(HLSL2GLSLConverterLib ProcessGLSLDefinitions) + add_custom_command(TARGET ProcessGLSLDefinitions + # Unfortunately it is not possible to set TARGET directly to GraphicsEngineD3DBase + # because PRE_BUILD is only supported on Visual Studio 8 or later. For all other generators + # PRE_BUILD is treated as PRE_LINK. + COMMAND COMMAND ${FILE2STRING_PATH} include/GLSLDefinitions.h include/GLSLDefinitions_inc.h + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Processing GLSLDefinitions.h" + VERBATIM + ) + add_dependencies(HLSL2GLSLConverterLib ProcessGLSLDefinitions) + set_target_properties(ProcessGLSLDefinitions PROPERTIES + FOLDER Core/Graphics/Helper + ) +endif() source_group("src" FILES ${SOURCE}) source_group("include" FILES ${INCLUDE}) @@ -70,6 +81,3 @@ source_group("generated" FILES include/GLSLDefinitions_inc.h) set_target_properties(HLSL2GLSLConverterLib PROPERTIES FOLDER Core/Graphics ) -set_target_properties(ProcessGLSLDefinitions PROPERTIES - FOLDER Core/Graphics/Helper -)
\ No newline at end of file diff --git a/Platforms/Android/CMakeLists.txt b/Platforms/Android/CMakeLists.txt new file mode 100644 index 00000000..0dcfc55b --- /dev/null +++ b/Platforms/Android/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required (VERSION 3.6) + +project(AndroidPlatform CXX) + +set(INCLUDE + include/AndroidDebug.h + include/AndroidFileSystem.h + include/AndroidPlatformDefinitions.h + include/AndroidPlatformMisc.h +) + +set(SOURCE + src/AndroidDebug.cpp + src/AndroidFileSystem.cpp +) + +add_library(AndroidPlatform ${SOURCE} ${INCLUDE}) +set_common_target_properties(AndroidPlatform) + +target_include_directories(AndroidPlatform +PUBLIC + include +) + +target_link_libraries(AndroidPlatform +PRIVATE + BuildSettings + Common + NdkHelper + log +PUBLIC + PlatformInterface + BasicPlatform +) + +source_group("src" FILES ${SOURCE}) +source_group("include" FILES ${INCLUDE}) + +set_target_properties(AndroidPlatform PROPERTIES + FOLDER Core/Platforms +) diff --git a/Platforms/Basic/CMakeLists.txt b/Platforms/Basic/CMakeLists.txt index 657b4932..1a08f952 100644 --- a/Platforms/Basic/CMakeLists.txt +++ b/Platforms/Basic/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.10) +cmake_minimum_required (VERSION 3.6) project(BasicPlatform CXX) diff --git a/Platforms/CMakeLists.txt b/Platforms/CMakeLists.txt index 465e37de..77fa5ce6 100644 --- a/Platforms/CMakeLists.txt +++ b/Platforms/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required (VERSION 3.6) add_library(PlatformInterface INTERFACE) diff --git a/Platforms/interface/PlatformDefinitions.h b/Platforms/interface/PlatformDefinitions.h index 6289a655..69fe10c1 100644 --- a/Platforms/interface/PlatformDefinitions.h +++ b/Platforms/interface/PlatformDefinitions.h @@ -24,10 +24,12 @@ #pragma once #if defined(ANDROID) - #if defined (PLATFORM_UNIVERSAL_WINDOWS) || defined (PLATFORM_WIN32) - #error Conflicting platform macros - #endif - #define PLATFORM_ANDROID +# if defined (PLATFORM_UNIVERSAL_WINDOWS) || defined (PLATFORM_WIN32) +# error Conflicting platform macros +# endif +# ifndef PLATFORM_ANDROID +# define PLATFORM_ANDROID +# endif #elif !defined (PLATFORM_UNIVERSAL_WINDOWS) && !defined (PLATFORM_WIN32) #error Platform is not defined #endif diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index 8d20e25d..e3d0e140 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -1,3 +1,5 @@ cmake_minimum_required (VERSION 3.3) -add_subdirectory(File2Include) +if(PLATFORM_WIN32) + add_subdirectory(File2Include) +endif() |
