diff --git a/CMake/modules/FindVulkan.cmake b/CMake/modules/FindVulkan.cmake index 5bdb55605..731de2f31 100644 --- a/CMake/modules/FindVulkan.cmake +++ b/CMake/modules/FindVulkan.cmake @@ -34,6 +34,9 @@ elseif (APPLE) find_library(VULKAN_STATIC_LIBRARY MoltenVK) find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS "${VULKAN_LIBRARY}/Headers") +elseif (ANDROID) + find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h NO_CMAKE_FIND_ROOT_PATH) + find_library(VULKAN_LIBRARY NAMES vulkan NO_CMAKE_FIND_ROOT_PATH) else() find_path(VULKAN_INCLUDE_DIR NAMES vulkan/vulkan.h HINTS "$ENV{VULKAN_SDK}/include") diff --git a/CMakeLists.txt b/CMakeLists.txt index a50c6e3e9..ede49b00e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,9 @@ elseif (WIN32) elseif (APPLE) set(_GLFW_COCOA 1) message(STATUS "Using Cocoa for window creation") +elseif (ANDROID) + set(_GLFW_ANDROID 1) + message(STATUS "Using Android for window creation") elseif (UNIX) set(_GLFW_X11 1) message(STATUS "Using X11 for window creation") @@ -330,6 +333,13 @@ if (_GLFW_COCOA) set(glfw_PKG_LIBS "-framework Cocoa -framework IOKit -framework CoreFoundation -framework CoreVideo") endif() +#-------------------------------------------------------------------- +# Use Android APIs for window creation +#-------------------------------------------------------------------- +if (_GLFW_ANDROID) + list(APPEND glfw_INCLUDE_DIRS "${ANDROID_NDK}/sources/android/native_app_glue/") +endif() + #-------------------------------------------------------------------- # Export GLFW library dependencies #-------------------------------------------------------------------- diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 217b2c5dd..50cf92828 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -5519,4 +5519,3 @@ GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window #endif #endif /* _glfw3_h_ */ - diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 4372cb766..07ab74222 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -123,6 +123,9 @@ extern "C" { #include #endif +#if defined(GLFW_EXPOSE_NATIVE_ANDROID) + #include +#endif /************************************************************************* * Functions @@ -564,6 +567,10 @@ GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window); #endif +#if defined(GLFW_EXPOSE_NATIVE_ANDROID) +GLFWAPI struct android_app * glfwGetAndroidApp(GLFWwindow* window); +#endif + #ifdef __cplusplus } #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f886ff217..197df7cd9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,6 +71,11 @@ elseif (_GLFW_OSMESA) posix_time.h posix_thread.h osmesa_context.h) set(glfw_SOURCES ${common_SOURCES} null_init.c null_monitor.c null_window.c null_joystick.c posix_time.c posix_thread.c osmesa_context.c) +elseif (_GLFW_ANDROID) + set(glfw_HEADERS ${common_HEADERS} android_platform.h android_joystick.h + posix_time.h posix_thread.h) + set(glfw_SOURCES ${common_SOURCES} android_init.c android_monitor.c android_window.c + android_joystick.c posix_time.c posix_thread.c egl_context.c osmesa_context.c "${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c") endif() if (APPLE) diff --git a/src/android_init.c b/src/android_init.c new file mode 100644 index 000000000..b0cc1b84b --- /dev/null +++ b/src/android_init.c @@ -0,0 +1,78 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2017 Curi0 +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include +#include "internal.h" + +struct android_app* _globalApp; + +extern int main(); +void handle_cmd(struct android_app* _app, int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: { + break; + } + case APP_CMD_LOST_FOCUS: { + break; + } + case APP_CMD_GAINED_FOCUS: { + break; + } + case APP_CMD_TERM_WINDOW: { + glfwDestroyWindow((GLFWwindow *) _glfw.windowListHead); + } +} +} + +// Android Entry Point +void android_main(struct android_app *app) { + app->onAppCmd = handle_cmd; + // hmmm...global....eek + _globalApp = app; + main(); +} +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformInit(void) +{ + _glfw.gstate.app = _globalApp; + _glfwInitTimerPOSIX(); + return GLFW_TRUE; +} + +void _glfwPlatformTerminate(void) +{ + _glfwTerminateOSMesa(); +} + +const char* _glfwPlatformGetVersionString(void) +{ + return _GLFW_VERSION_NUMBER " Android EGL"; +} + diff --git a/src/android_joystick.c b/src/android_joystick.c new file mode 100644 index 000000000..7f2849b7d --- /dev/null +++ b/src/android_joystick.c @@ -0,0 +1,43 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2017 Curi0 +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) +{ + return GLFW_FALSE; +} + +void _glfwPlatformUpdateGamepadGUID(char* guid) +{ +} + diff --git a/src/android_joystick.h b/src/android_joystick.h new file mode 100644 index 000000000..db724ad70 --- /dev/null +++ b/src/android_joystick.h @@ -0,0 +1,31 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#define _GLFW_PLATFORM_JOYSTICK_STATE int nulljs +#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int nulljs + +#define _GLFW_PLATFORM_MAPPING_NAME "Android" + diff --git a/src/android_monitor.c b/src/android_monitor.c new file mode 100644 index 000000000..e9e211e5b --- /dev/null +++ b/src/android_monitor.c @@ -0,0 +1,56 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2017 Curi0 +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + + +#include "internal.h" + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos) +{ +} + +GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found) +{ + return NULL; +} + +void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode) +{ +} + +void _glfwPlatformGetGammaRamp(_GLFWmonitor* monitor, GLFWgammaramp* ramp) +{ +} + +void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp) +{ +} + diff --git a/src/android_platform.h b/src/android_platform.h new file mode 100644 index 000000000..6dcf631f5 --- /dev/null +++ b/src/android_platform.h @@ -0,0 +1,69 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2017 Curi0 +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include + +#include "egl_context.h" +#include "osmesa_context.h" +#include "posix_time.h" +#include "posix_thread.h" +#include "android_joystick.h" +#include +#include + +#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL) +#define _glfw_dlclose(handle) dlclose(handle) +#define _glfw_dlsym(handle, name) dlsym(handle, name) + +#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->android->window) +#define _GLFW_PLATFORM_WINDOW_STATE struct android_app* android; +#define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE android_gstate gstate; +#define _GLFW_PLATFORM_MONITOR_STATE +#define _GLFW_PLATFORM_CURSOR_STATE + +#define _GLFW_PLATFORM_CONTEXT_STATE +#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE +#define _GLFW_EGL_NATIVE_DISPLAY EGL_DEFAULT_DISPLAY + +float x,y; + +typedef struct android_gstate { + struct android_app* app; + struct android_poll_source* source; +} android_gstate; + +typedef VkFlags VkAndroidSurfaceCreateFlagsKHR; + +typedef struct VkAndroidSurfaceCreateInfoKHR { + VkStructureType sType; + const void* pNext; + VkAndroidSurfaceCreateFlagsKHR flags; + ANativeWindow* window; +} VkAndroidSurfaceCreateInfoKHR; + +typedef VkResult (APIENTRY *PFN_vkCreateAndroidSurfaceKHR)(VkInstance,const VkAndroidSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*); + diff --git a/src/android_window.c b/src/android_window.c new file mode 100644 index 000000000..0ebcdac76 --- /dev/null +++ b/src/android_window.c @@ -0,0 +1,367 @@ +//======================================================================== +// GLFW 3.3 - www.glfw.org +//------------------------------------------------------------------------ +// Copyright (c) 2017 Curi0 +// Copyright (c) 2006-2016 Camilla Löwy +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would +// be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not +// be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source +// distribution. +// +//======================================================================== + +#include "internal.h" + +static int32_t handle_input(struct android_app* app, AInputEvent* event) +{ + if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) + for (size_t i = 0; i < AMotionEvent_getPointerCount(event); ++i) + { + x = AMotionEvent_getX(event, i); + y = AMotionEvent_getY(event, i); + } + if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) + _glfwInputKey(_glfw.windowListHead, 0 , AKeyEvent_getKeyCode(event), GLFW_PRESS,0); + + return 0; +} + +static void handleEvents(int timeout) { + ALooper_pollOnce(0, NULL, NULL,(void**)&_glfw.gstate.source); + + if (_glfw.gstate.source != NULL) { + _glfw.gstate.source->process(_glfw.gstate.app, _glfw.gstate.source); + } + _glfwInputCursorPos(_glfw.windowListHead, x, y); +} + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +int _glfwPlatformCreateWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + // wait for window to become ready + while (_glfw.gstate.app->window == NULL) { + handleEvents(-1); + } + // hmmm maybe should be ANative_Window only? + window->android = _glfw.gstate.app; + window->android->onInputEvent = handle_input; + + //ANativeWindow_setBuffersGeometry(window->android->window, wndconfig->width, wndconfig->height, 0); + + if (ctxconfig->client != GLFW_NO_API) + { + if ((ctxconfig->source == GLFW_NATIVE_CONTEXT_API) | + (ctxconfig->source == GLFW_EGL_CONTEXT_API)) + { + if (!_glfwInitEGL()) + return GLFW_FALSE; + if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + else if (ctxconfig->source == GLFW_OSMESA_CONTEXT_API) + { + if (!_glfwInitOSMesa()) + return GLFW_FALSE; + if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig)) + return GLFW_FALSE; + } + + } + return GLFW_TRUE; +} + + +void _glfwPlatformDestroyWindow(_GLFWwindow* window) +{ + if (window->context.destroy) + window->context.destroy(window); + ANativeActivity_finish(window->android->activity); +} + +void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) +{ +} + +void _glfwPlatformSetWindowIcon(_GLFWwindow* window, int count, + const GLFWimage* images) +{ +} + +void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, + _GLFWmonitor* monitor, + int xpos, int ypos, + int width, int height, + int refreshRate) +{ +} + +void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) +{ + +} + +void _glfwPlatformSetWindowPos(_GLFWwindow* window, int xpos, int ypos) +{ +} + +void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) +{ + if (height) + *height = ANativeWindow_getHeight(window->android->window); + if (width) + *width = ANativeWindow_getWidth(window->android->window); +} + +void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) +{ +} + +void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, + int minwidth, int minheight, + int maxwidth, int maxheight) +{ + +} + +void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int n, int d) +{ +} + +void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) +{ + // the underlying buffergeometry is currently being initialized from the + // window width and height...so high resolution displays are currently + // not supported...so it is safe to just call GetWindowSize() for now + _glfwPlatformGetWindowSize(window, width, height); +} + +void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, + int* left, int* top, + int* right, int* bottom) +{ +} + +void _glfwPlatformIconifyWindow(_GLFWwindow* window) +{ +} + +void _glfwPlatformRestoreWindow(_GLFWwindow* window) +{ +} + +void _glfwPlatformMaximizeWindow(_GLFWwindow* window) +{ +} + +int _glfwPlatformWindowMaximized(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + +void _glfwPlatformSetWindowResizable(_GLFWwindow* window, GLFWbool enabled) +{ +} + +void _glfwPlatformSetWindowDecorated(_GLFWwindow* window, GLFWbool enabled) +{ +} + +void _glfwPlatformSetWindowFloating(_GLFWwindow* window, GLFWbool enabled) +{ +} + +void _glfwPlatformShowWindow(_GLFWwindow* window) +{ +} + + +void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) +{ +} + +void _glfwPlatformUnhideWindow(_GLFWwindow* window) +{ +} + +void _glfwPlatformHideWindow(_GLFWwindow* window) +{ +} + +void _glfwPlatformFocusWindow(_GLFWwindow* window) +{ +} + +int _glfwPlatformWindowFocused(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + +int _glfwPlatformWindowIconified(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + +int _glfwPlatformWindowVisible(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + +void _glfwPlatformPollEvents(void) +{ + handleEvents(0); +} + +void _glfwPlatformWaitEvents(void) +{ + handleEvents(-1); +} + +void _glfwPlatformWaitEventsTimeout(double timeout) +{ + handleEvents(timeout * 1e3); +} + +void _glfwPlatformPostEmptyEvent(void) +{ +} + +void _glfwPlatformGetCursorPos(_GLFWwindow* window, double* xpos, double* ypos) +{ + if (xpos) + *xpos = x; + if (ypos) + *ypos = y; +} + +void _glfwPlatformSetCursorPos(_GLFWwindow* window, double x, double y) +{ +} + +void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode) +{ +} + +int _glfwPlatformCreateCursor(_GLFWcursor* cursor, + const GLFWimage* image, + int xhot, int yhot) +{ + return GLFW_TRUE; +} + +int _glfwPlatformCreateStandardCursor(_GLFWcursor* cursor, int shape) +{ + return GLFW_TRUE; +} + +void _glfwPlatformDestroyCursor(_GLFWcursor* cursor) +{ +} + +void _glfwPlatformSetCursor(_GLFWwindow* window, _GLFWcursor* cursor) +{ +} + +void _glfwPlatformSetClipboardString(_GLFWwindow* window, const char* string) +{ +} + +const char* _glfwPlatformGetClipboardString(_GLFWwindow* window) +{ + return NULL; +} + +const char* _glfwPlatformGetScancodeName(int scancode) +{ + return ""; +} + +int _glfwPlatformGetKeyScancode(int key) +{ + return -1; +} + +void _glfwPlatformGetRequiredInstanceExtensions(char** extensions) +{ + if (!_glfw.vk.KHR_surface || !_glfw.vk.KHR_android_surface) + return; + + extensions[0] = "VK_KHR_surface"; + extensions[1] = "VK_KHR_android_surface"; +} + +int _glfwPlatformGetPhysicalDevicePresentationSupport(VkInstance instance, + VkPhysicalDevice device, + uint32_t queuefamily) +{ + return GLFW_TRUE; +} + +int _glfwPlatformFramebufferTransparent(_GLFWwindow* window) +{ + return GLFW_FALSE; +} + +VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, + _GLFWwindow* window, + const VkAllocationCallbacks* allocator, + VkSurfaceKHR* surface) +{ + VkResult err; + VkAndroidSurfaceCreateInfoKHR sci; + PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR; + + vkCreateAndroidSurfaceKHR = (PFN_vkCreateAndroidSurfaceKHR) + vkGetInstanceProcAddr(instance, "vkCreateAndroidSurfaceKHR"); + if (!vkCreateAndroidSurfaceKHR) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "Android: Vulkan instance missing VK_KHR_android_surface extension"); + return VK_ERROR_EXTENSION_NOT_PRESENT; + } + + memset(&sci, 0, sizeof(sci)); + sci.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + sci.window = window->android->window; + + err = vkCreateAndroidSurfaceKHR(instance, &sci, allocator, surface); + if (err) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "Android: Failed to create Vulkan surface: %s", + _glfwGetVulkanResultString(err)); + } + + return err; +} + +////////////////////////////////////////////////////////////////////////// +////// GLFW native API ////// +////////////////////////////////////////////////////////////////////////// + +GLFWAPI struct android_app * glfwGetAndroidApp(GLFWwindow* handle) +{ + _GLFWwindow *window = (_GLFWwindow*)handle; + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + return window->android; +} diff --git a/src/egl_context.c b/src/egl_context.c index b2d11a471..742e7f4ac 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -311,6 +311,8 @@ GLFWbool _glfwInitEGL(void) "libEGL.dylib", #elif defined(__CYGWIN__) "libEGL-1.so", +#elif defined(_GLFW_ANDROID) + "libEGL.so", #else "libEGL.so.1", #endif @@ -393,6 +395,7 @@ GLFWbool _glfwInitEGL(void) } _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); + if (_glfw.egl.display == EGL_NO_DISPLAY) { _glfwInputError(GLFW_API_UNAVAILABLE, @@ -461,7 +464,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, EGLConfig config; EGLContext share = NULL; int index = 0; - if (!_glfw.egl.display) { _glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available"); @@ -626,6 +628,9 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, "libGLES_CM.dll", #elif defined(_GLFW_COCOA) "libGLESv1_CM.dylib", +#elif defined(_GLFW_ANDROID) + "libGLESv1_CM.so", + "libGLES_CM.so", #else "libGLESv1_CM.so.1", "libGLES_CM.so.1", @@ -643,6 +648,8 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, "libGLESv2.dylib", #elif defined(__CYGWIN__) "libGLESv2-2.so", +#elif defined(_GLFW_ANDROID) + "libGLESv2.so", #else "libGLESv2.so.2", #endif diff --git a/src/egl_context.h b/src/egl_context.h index aa339baac..2c4a3b6a8 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -27,28 +27,32 @@ #if defined(_GLFW_USE_EGLPLATFORM_H) #include +#elif defined(_GLFW_ANDROID) + #define EGLAPIENTRY + typedef void* EGLNativeDisplayType; + typedef struct ANativeWindow* EGLNativeWindowType; #elif defined(_GLFW_WIN32) #define EGLAPIENTRY __stdcall -typedef HDC EGLNativeDisplayType; -typedef HWND EGLNativeWindowType; + typedef HDC EGLNativeDisplayType; + typedef HWND EGLNativeWindowType; #elif defined(_GLFW_COCOA) #define EGLAPIENTRY -typedef void* EGLNativeDisplayType; -typedef id EGLNativeWindowType; + typedef void* EGLNativeDisplayType; + typedef id EGLNativeWindowType; #elif defined(_GLFW_X11) #define EGLAPIENTRY -typedef Display* EGLNativeDisplayType; -typedef Window EGLNativeWindowType; + typedef Display* EGLNativeDisplayType; + typedef Window EGLNativeWindowType; #elif defined(_GLFW_WAYLAND) #define EGLAPIENTRY -typedef struct wl_display* EGLNativeDisplayType; -typedef struct wl_egl_window* EGLNativeWindowType; + typedef struct wl_display* EGLNativeDisplayType; + typedef struct wl_egl_window* EGLNativeWindowType; #elif defined(_GLFW_MIR) #define EGLAPIENTRY -typedef MirEGLNativeDisplayType EGLNativeDisplayType; -typedef MirEGLNativeWindowType EGLNativeWindowType; + typedef MirEGLNativeDisplayType EGLNativeDisplayType; + typedef MirEGLNativeWindowType EGLNativeWindowType; #else - #error "No supported EGL platform selected" +#error "No supported EGL platform selected" #endif #define EGL_SUCCESS 0x3000 diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index 0b47945c0..575aaa65d 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -46,6 +46,9 @@ #cmakedefine _GLFW_MIR // Define this to 1 if building GLFW for OSMesa #cmakedefine _GLFW_OSMESA +// Define this to 1 if building GLFW for Android +#cmakedefine _GLFW_ANDROID + // Define this to 1 if building as a shared library / dynamic library / DLL #cmakedefine _GLFW_BUILD_DLL diff --git a/src/internal.h b/src/internal.h index fb0cbc8e4..13d91feec 100644 --- a/src/internal.h +++ b/src/internal.h @@ -129,6 +129,7 @@ typedef enum VkStructureType VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR = 1000007000, VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000053000, + VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000, VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF } VkStructureType; @@ -192,6 +193,8 @@ typedef void (APIENTRY * PFN_vkVoidFunction)(void); #include "mir_platform.h" #elif defined(_GLFW_OSMESA) #include "null_platform.h" +#elif defined(_GLFW_ANDROID) + #include "android_platform.h" #else #error "No supported window creation API selected" #endif @@ -562,6 +565,8 @@ struct _GLFWlibrary GLFWbool KHR_wayland_surface; #elif defined(_GLFW_MIR) GLFWbool KHR_mir_surface; +#elif defined(_GLFW_ANDROID) + GLFWbool KHR_android_surface; #endif } vk; diff --git a/src/vulkan.c b/src/vulkan.c index ab45c9b3e..a567223e4 100644 --- a/src/vulkan.c +++ b/src/vulkan.c @@ -55,6 +55,8 @@ GLFWbool _glfwInitVulkan(int mode) _glfw.vk.handle = _glfw_dlopen("vulkan-1.dll"); #elif defined(_GLFW_COCOA) _glfw.vk.handle = _glfw_dlopen("libMoltenVK.dylib"); +#elif defined(_GLFW_ANDROID) + _glfw.vk.handle = _glfw_dlopen("libvulkan.so"); #else _glfw.vk.handle = _glfw_dlopen("libvulkan.so.1"); #endif @@ -139,6 +141,9 @@ GLFWbool _glfwInitVulkan(int mode) #elif defined(_GLFW_MIR) else if (strcmp(ep[i].extensionName, "VK_KHR_mir_surface") == 0) _glfw.vk.KHR_mir_surface = GLFW_TRUE; +#elif defined(_GLFW_ANDROID) + else if (strcmp(ep[i].extensionName, "VK_KHR_android_surface") == 0) + _glfw.vk.KHR_android_surface = GLFW_TRUE; #endif }