diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | include/stl/platform.h | 3 | ||||
| -rw-r--r-- | meson.build | 96 | ||||
| -rw-r--r-- | meson_options.txt | 2 | ||||
| -rw-r--r-- | src/egl_common.c | 4 | ||||
| -rw-r--r-- | src/gl_common.h | 4 | ||||
| -rw-r--r-- | src/platform.h | 6 | ||||
| -rw-r--r-- | src/window.h | 2 | ||||
| -rw-r--r-- | src/window_glfm.c | 162 | ||||
| -rw-r--r-- | src/window_glfm.h | 10 | ||||
| -rw-r--r-- | src/window_glfw.c | 14 | ||||
| -rw-r--r-- | src/window_glfw.h | 4 | ||||
| -rw-r--r-- | src/window_wayland.c | 19 | ||||
| -rw-r--r-- | src/window_x11.c | 3 | ||||
| -rw-r--r-- | subprojects/glfm.wrap | 5 |
15 files changed, 278 insertions, 57 deletions
@@ -3,6 +3,7 @@ build*/ compile_commands.json subprojects/c89atomic.wrap subprojects/glad/ +subprojects/glfm/ subprojects/libakiyo subprojects/libalabaster subprojects/libev.wrap diff --git a/include/stl/platform.h b/include/stl/platform.h new file mode 100644 index 0000000..cdd1d81 --- /dev/null +++ b/include/stl/platform.h @@ -0,0 +1,3 @@ +#pragma once + +#include "../../src/platform.h" diff --git a/meson.build b/meson.build index f157dc8..ec32412 100644 --- a/meson.build +++ b/meson.build @@ -10,6 +10,17 @@ is_minsize = get_option('buildtype') == 'minsize' is_linux = host_machine.system() == 'linux' is_windows = host_machine.system() == 'windows' is_macos = host_machine.system() == 'darwin' +is_android = host_machine.system() == 'android' + +if get_option('window') in ['x11', 'wayland'] + if not (is_linux and not is_android) + error('Wayland is only supported on linux desktop.') + endif +endif + +if get_option('window') == 'glfm' and not is_android + error('GLFM only supported on android.') +endif alabaster = subproject('libalabaster').get_variable('alabaster') akiyo = subproject('libakiyo', default_options: ['event-loop=disabled']).get_variable('akiyo') @@ -42,27 +53,30 @@ if get_option('api') == 'null' elif get_option('api') == 'opengl' use_glad = false use_gles = false - if use_glad - stela_deps += [subproject('glad', default_options: [ - use_gles ? 'use_gles=true' : 'use_gles=false' - ]).get_variable('glad')] - stela_args += ['-DSTELA_USE_GLAD'] - else - stela_deps += [dependency('gl')] + if get_option('window') not in ['glfm'] + if use_glad + stela_deps += [subproject('glad', default_options: [ + use_gles ? 'use_gles=true' : 'use_gles=false' + ]).get_variable('glad')] + stela_args += ['-DSTELA_USE_GLAD'] + else + stela_deps += [dependency('gl')] + endif + if get_option('window') in ['x11', 'wayland'] + egl = dependency('egl') + stela_src += ['src/egl_common.c'] + stela_deps += [egl] + # Raspberry Pi + #brcmEGL = compiler.find_library('brcmEGL') + #brcmGLESv2 = compiler.find_library('brcmGLESv2') + #stela_deps += [brcmEGL, brcmGLESv2] + endif endif if use_gles stela_args += ['-DSTELA_USE_GLES'] endif stela_src += ['src/gl_common.c'] stela_args += ['-DSTELA_API_OPENGL'] - if get_option('window') in ['x11', 'wayland'] - egl = dependency('egl') - #brcmEGL = compiler.find_library('brcmEGL') - #brcmGLESv2 = compiler.find_library('brcmGLESv2') - stela_src += ['src/egl_common.c'] - stela_deps += [egl] - #stela_deps += [brcmEGL, brcmGLESv2] - endif elif get_option('api') == 'vulkan' vulkan = dependency('vulkan') vulkan_headers = vulkan.partial_dependency(includes: true, compile_args: true, link_args: true) @@ -70,26 +84,7 @@ elif get_option('api') == 'vulkan' stela_args += ['-DSTELA_API_VULKAN'] endif -if get_option('window') == 'glfw' - glfw3 = dependency('glfw3', required: false, allow_fallback: false) - if not glfw3.found() - glfw_opts = cmake.subproject_options() - reltype = is_minsize ? 'MinSizeRel' : 'Release' - glfw_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) - glfw_opts.add_cmake_defines({ 'GLFW_INSTALL': false }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_EXAMPLES': false }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_TESTS': false }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_DOCS': false }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_WAYLAND': is_linux }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_X11': is_linux }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_WIN32': is_windows }) - glfw_opts.add_cmake_defines({ 'GLFW_BUILD_COCAO': is_macos }) - glfw3 = cmake.subproject('glfw3', options: glfw_opts).dependency('glfw') - endif - stela_src += ['src/window_glfw.c'] - stela_deps += [glfw3] - stela_args += ['-DSTELA_WINDOW_GLFW'] -elif get_option('window') == 'x11' +if get_option('window') == 'x11' x11 = dependency('X11') xext = dependency('xext') xrandr = dependency('xrandr') @@ -161,6 +156,37 @@ elif get_option('window') == 'wayland' stela_src += ['src/window_wayland.c'] stela_deps += [wl_egl, protocols] stela_args += ['-DSTELA_WINDOW_WAYLAND'] +elif get_option('window') == 'glfw' + glfw3 = dependency('glfw3', required: false, allow_fallback: false) + if not glfw3.found() + glfw_opts = cmake.subproject_options() + reltype = is_minsize ? 'MinSizeRel' : 'Release' + glfw_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) + glfw_opts.add_cmake_defines({ 'GLFW_INSTALL': false }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_EXAMPLES': false }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_TESTS': false }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_DOCS': false }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_WAYLAND': is_linux }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_X11': is_linux }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_WIN32': is_windows }) + glfw_opts.add_cmake_defines({ 'GLFW_BUILD_COCAO': is_macos }) + glfw3 = cmake.subproject('glfw3', options: glfw_opts).dependency('glfw') + endif + stela_src += ['src/window_glfw.c'] + stela_deps += [glfw3] + stela_args += ['-DSTELA_WINDOW_GLFW'] +elif get_option('window') == 'glfm' + glfm = dependency('glfm', required: false, allow_fallback: false) + if not glfm.found() + glfm_opts = cmake.subproject_options() + reltype = is_minsize ? 'MinSizeRel' : 'Release' + glfm_opts.add_cmake_defines({ 'CMAKE_BUILD_TYPE': is_debug ? 'Debug' : reltype }) + glfm_opts.add_cmake_defines({ 'CMAKE_POSITION_INDEPENDENT_CODE': true }) + glfm = cmake.subproject('glfm', options: glfm_opts).dependency('glfm') + endif + stela_src += ['src/window_glfm.c'] + stela_deps += [glfm] + stela_args += ['-DSTELA_WINDOW_GLFM'] endif stela = declare_dependency(include_directories: stela_inc, diff --git a/meson_options.txt b/meson_options.txt index 8f77cb3..17e6c3b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,5 +1,5 @@ option('api', type: 'combo', choices: ['null', 'opengl', 'vulkan', 'dx11'], value: 'null') -option('window', type: 'combo', choices: ['glfw', 'wayland', 'x11'], value: 'wayland') +option('window', type: 'combo', choices: ['wayland', 'x11', 'glfw', 'glfm'], value: 'wayland') option('poll', type: 'combo', choices: ['inline', 'fd'], value: 'inline') option('event-buffer', type: 'boolean', value: false) option('pause', type: 'boolean', value: true) diff --git a/src/egl_common.c b/src/egl_common.c index 1c086d0..7952894 100644 --- a/src/egl_common.c +++ b/src/egl_common.c @@ -1,5 +1,5 @@ -#include <al/lib.h> #include <al/log.h> +#include <al/macros.h> #include "egl_common.h" @@ -107,7 +107,7 @@ bool stl_init_egl_context(struct stl_egl *egl, struct stl_egl_global *global, EG egl->display = global->display; egl->context = EGL_NO_CONTEXT; - for (u32 i = 0; i < AL_ARRAY_SIZE(stl_gl_vers); i++) { + for (u32 i = 0; i < ARRAY_SIZE(stl_gl_vers); i++) { const EGLint context_attr_gles[] = { EGL_CONTEXT_CLIENT_VERSION, stl_gl_vers[i].major, EGL_NONE diff --git a/src/gl_common.h b/src/gl_common.h index bef0a75..1e2ed3f 100644 --- a/src/gl_common.h +++ b/src/gl_common.h @@ -1,5 +1,8 @@ #include <al/types.h> +#ifdef STELA_WINDOW_GLFM +#include <glfm.h> +#else #ifdef STELA_USE_GLAD #ifdef STELA_USE_GLES #include <glad/gles2.h> @@ -16,6 +19,7 @@ #include <GL/glcorearb.h> #endif #endif +#endif bool stl_gl_check_error(); bool stl_gl_loader_load(void (*(*get_proc_address)(const char *))(void)); diff --git a/src/platform.h b/src/platform.h new file mode 100644 index 0000000..f87f4b6 --- /dev/null +++ b/src/platform.h @@ -0,0 +1,6 @@ +#pragma once + +#ifdef STELA_WINDOW_GLFM +#include <glfm.h> +#include <android/log.h> +#endif diff --git a/src/window.h b/src/window.h index a72071a..a68a75f 100644 --- a/src/window.h +++ b/src/window.h @@ -136,7 +136,7 @@ s32 stl_global_get_poll_fd(); void stl_global_process_events(); void stl_global_close(void); -struct stl_window *stl_window_create(void); +struct stl_window *stl_window_create(void *context); void stl_window_send_pointer_pos_event(struct stl_window *window, f64 x, f64 y); void stl_window_send_scroll_event(struct stl_window *window, f64 y); void stl_window_send_mouse_button_event(struct stl_window *window, u8 state, u8 button); diff --git a/src/window_glfm.c b/src/window_glfm.c new file mode 100644 index 0000000..b9639dc --- /dev/null +++ b/src/window_glfm.c @@ -0,0 +1,162 @@ +#include <al/log.h> + +#include "window_glfm.h" + +void stl_set_output_discovered_callback(void (*output_discovered)(void *, struct stl_monitor *), void *userdata) +{ + (void)output_discovered; + (void)userdata; +} + +bool stl_global_init(bool skip_graphics) +{ + (void)skip_graphics; + return false; +} + +s32 stl_global_get_poll_fd() +{ + return -1; +} + +void stl_global_process_events() +{ +} + +void stl_global_close(void) +{ +} + +static bool window_glfm_create_window(struct stl_window *window, s32 width, s32 height, + const char *monitor, const char *name, s32 flags) +{ + struct stl_window_glfm *glfm = (struct stl_window_glfm *)window; + (void)monitor; + (void)name; + (void)flags; + glfmGetDisplaySize(glfm->display, &width, &height); + glfm->w.width = width; + glfm->w.height = height; + return true; +} + +static void window_glfm_resize_internal(struct stl_window *window, s32 width, s32 height) +{ + (void)window; + (void)width; + (void)height; +} + +static void window_glfm_resize(struct stl_window *window, s32 width, s32 height) +{ + (void)window; + (void)width; + (void)height; +} + +static void window_glfm_toggle_fullscreen(struct stl_window *window) +{ + (void)window; +} + +#ifdef STELA_POLL_INLINE +static bool window_glfm_poll(struct stl_window *window, bool block) +{ + (void)window; + (void)block; + return true; +} + +#ifdef STELA_PAUSE +static void window_glfm_wake(struct stl_window *window) +{ + (void)window; +} +#endif +#endif + +static void window_glfm_process_events(struct stl_window *window) +{ + (void)window; +} + +#ifdef STELA_PAUSE +static bool window_glfm_should_refresh(struct stl_window *window) +{ + (void)window; + return true; +} +#endif + +static void window_glfm_free(struct stl_window **window) +{ + (void)window; +} + +#if defined STELA_API_VULKAN +#elif defined STELA_API_OPENGL +static bool window_glfm_gl_loader_load(void *data) +{ + (void)data; + return true; +} + +static bool window_glfm_gl_make_current(void *data) +{ + (void)data; + return true; +} + +static void window_glfm_gl_release_current(void *data) +{ + (void)data; +} + +static void window_glfm_gl_swap_buffers(void *data) +{ + struct stl_window_glfm *glfm = (struct stl_window_glfm *)data; + glfmSwapBuffers(glfm->display); +} +#endif + +struct stl_window *stl_window_create(void *context) +{ + al_log_info("stela", "Wrapping GLFM window."); + struct stl_window_glfm *glfm = al_alloc_object(struct stl_window_glfm); + glfm->display = (GLFMDisplay *)context; +#ifdef STELA_EVENT_BUFFER + glfm->w.data = al_malloc(STELA_EVENTS_SIZE); + al_ring_buffer_init(&glfm->w.events, glfm->w.data, STELA_EVENTS_SIZE); +#endif +#ifdef STELA_PAUSE + glfm->w.pending_refresh = true; +#endif + glfm->w.fullscreen = false; + glfm->w.create_context = NULL; + glfm->w.create_window = window_glfm_create_window; + glfm->w.resize_internal = window_glfm_resize_internal; + glfm->w.resize = window_glfm_resize; + glfm->w.toggle_fullscreen = window_glfm_toggle_fullscreen; +#ifdef STELA_POLL_INLINE + glfm->w.poll = window_glfm_poll; +#ifdef STELA_PAUSE + glfm->w.wake = window_glfm_wake; +#endif +#endif + glfm->w.process_events = window_glfm_process_events; +#ifdef STELA_PAUSE + glfm->w.should_refresh = window_glfm_should_refresh; +#endif + glfm->w.free = window_glfm_free; +#if defined STELA_API_VULKAN +#elif defined STELA_API_OPENGL + glfm->w.get_gl_proc_address = glfmGetProcAddress; + glfm->w.gl_loader_load = window_glfm_gl_loader_load; + glfm->w.gl_make_current = window_glfm_gl_make_current; + glfm->w.gl_release_current = window_glfm_gl_release_current; + glfm->w.gl_swap_buffers = window_glfm_gl_swap_buffers; +#elif defined STELA_API_DX11 +#endif + return (struct stl_window *)glfm; + return NULL; +} diff --git a/src/window_glfm.h b/src/window_glfm.h new file mode 100644 index 0000000..9b4c223 --- /dev/null +++ b/src/window_glfm.h @@ -0,0 +1,10 @@ +#pragma once + +#include <glfm.h> + +#include "window.h" + +struct stl_window_glfm { + struct stl_window w; + GLFMDisplay *display; +}; diff --git a/src/window_glfw.c b/src/window_glfw.c index 0c6e5c7..24389a0 100644 --- a/src/window_glfw.c +++ b/src/window_glfw.c @@ -3,6 +3,9 @@ #include "window_glfw.h" #include "common.h" +#ifdef STELA_API_OPENGL +#include "gl_common.h" +#endif #ifdef STELA_API_OPENGL #define STELA_GL_API GLFW_OPENGL_API @@ -130,7 +133,7 @@ static bool window_glfw_create_window(struct stl_window *window, s32 width, s32 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); #elif defined STELA_API_OPENGL glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); - for (u32 i = 0; i < AL_ARRAY_SIZE(stl_gl_vers); i++) { + for (u32 i = 0; i < ARRAY_SIZE(stl_gl_vers); i++) { glfwWindowHint(GLFW_CLIENT_API, stl_gl_vers[i].api); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, stl_gl_vers[i].major); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, stl_gl_vers[i].minor); @@ -231,9 +234,9 @@ static GLFWmonitor *get_current_monitor(GLFWwindow *window) mw = mode->width; mh = mode->height; - s32 dx = AL_MIN(wx + ww, mx + mw) - AL_MAX(wx, mx); - s32 dy = AL_MIN(wy + wh, my + mh) - AL_MAX(wy, my); - overlap = AL_MAX(0, dx) * AL_MAX(0, dy); + s32 dx = MIN(wx + ww, mx + mw) - MAX(wx, mx); + s32 dy = MIN(wy + wh, my + mh) - MAX(wy, my); + overlap = MAX(0, dx) * MAX(0, dy); if (best_overlap < overlap) { best_overlap = overlap; @@ -353,8 +356,9 @@ static void window_glfw_gl_swap_buffers(void *data) } #endif -struct stl_window *stl_window_create(void) +struct stl_window *stl_window_create(void *context) { + (void)context; al_log_info("stela", "Creating GLFW3 window."); struct stl_window_glfw *glfw = al_alloc_object(struct stl_window_glfw); #ifdef STELA_EVENT_BUFFER diff --git a/src/window_glfw.h b/src/window_glfw.h index 2fa8f16..67cf63a 100644 --- a/src/window_glfw.h +++ b/src/window_glfw.h @@ -1,9 +1,7 @@ #pragma once -#if defined STELA_API_VULKAN +#ifdef STELA_API_VULKAN #define GLFW_INCLUDE_VULKAN -#elif defined STELA_API_OPENGL -#include "gl_common.h" #endif #include <GLFW/glfw3.h> #ifndef _WIN32 diff --git a/src/window_wayland.c b/src/window_wayland.c index d9ef0fb..f07d1ac 100644 --- a/src/window_wayland.c +++ b/src/window_wayland.c @@ -54,7 +54,7 @@ static void handle_output_done(void *data, struct wl_output *output) struct stl_monitor_wayland *monitor = (struct stl_monitor_wayland *)data; (void)output; al_log_info("window_wayland", "Output discovered: %s (%dx%d) (vertical: %s).", - monitor->m.name, monitor->m.width, monitor->m.height, AL_BOOLSTR(monitor->m.vertical)); + monitor->m.name, monitor->m.width, monitor->m.height, BOOLSTR(monitor->m.vertical)); if (global.output_discovered) { global.output_discovered(global.userdata, (struct stl_monitor *)monitor); } @@ -102,7 +102,7 @@ static void global_add(void *data, struct wl_registry *registry, u32 name, if (strcmp(interface, wl_output_interface.name) == 0) { struct stl_monitor_wayland *monitor = al_alloc_object(struct stl_monitor_wayland); al_array_push(global.monitors, (struct stl_monitor *)monitor); - monitor->output = wl_registry_bind(registry, name, &wl_output_interface, AL_MIN(4u, version)); + monitor->output = wl_registry_bind(registry, name, &wl_output_interface, MIN(4u, version)); wl_output_add_listener(monitor->output, &output_listener, monitor); } } @@ -480,19 +480,19 @@ static void context_global_add(void *data, struct wl_registry *registry, u32 nam { struct stl_window_wayland *wl = (struct stl_window_wayland *)data; if (strcmp(interface, wl_compositor_interface.name) == 0) { - wl->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, AL_MIN(5u, version)); + wl->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, MIN(5u, version)); } else if (strcmp(interface, wl_seat_interface.name) == 0) { - wl->seat = wl_registry_bind(registry, name, &wl_seat_interface, AL_MIN(8u, version)); + wl->seat = wl_registry_bind(registry, name, &wl_seat_interface, MIN(8u, version)); wl_seat_add_listener(wl->seat, &seat_listener, wl); } else if (strcmp(interface, xdg_wm_base_interface.name) == 0) { - wl->xdg_wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, AL_MIN(2u, version)); + wl->xdg_wm_base = wl_registry_bind(registry, name, &xdg_wm_base_interface, MIN(2u, version)); xdg_wm_base_add_listener(wl->xdg_wm_base, &xdg_wm_base_listener, wl); } else if (strcmp(interface, zxdg_decoration_manager_v1_interface.name) == 0) { - wl->zxdg_decoration_manager = wl_registry_bind(registry, name, &zxdg_decoration_manager_v1_interface, AL_MIN(1u, version)); + wl->zxdg_decoration_manager = wl_registry_bind(registry, name, &zxdg_decoration_manager_v1_interface, MIN(1u, version)); } else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) { - wl->cursor_shape = wl_registry_bind(registry, name, &wp_cursor_shape_manager_v1_interface, AL_MIN(1u, version)); + wl->cursor_shape = wl_registry_bind(registry, name, &wp_cursor_shape_manager_v1_interface, MIN(1u, version)); } else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) { - wl->layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, AL_MIN(4u, version)); + wl->layer_shell = wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, MIN(4u, version)); } } @@ -945,8 +945,9 @@ static void window_wayland_gl_swap_buffers(void *data) } #endif -struct stl_window *stl_window_create(void) +struct stl_window *stl_window_create(void *context) { + (void)context; al_log_info("stela", "Creating Wayland (EGL) window."); struct stl_window_wayland *wl = al_alloc_object(struct stl_window_wayland); #ifdef STELA_EVENT_BUFFER diff --git a/src/window_x11.c b/src/window_x11.c index 300b528..ed8d2ae 100644 --- a/src/window_x11.c +++ b/src/window_x11.c @@ -333,8 +333,9 @@ static void window_x11_gl_swap_buffers(void *data) } #endif -struct stl_window *stl_window_create(void) +struct stl_window *stl_window_create(void *context) { + (void)context; al_log_info("stela", "Creating X11 (EGL) window."); struct stl_window_x11 *xw = al_alloc_object(struct stl_window_x11); #ifdef STELA_EVENT_BUFFER diff --git a/subprojects/glfm.wrap b/subprojects/glfm.wrap new file mode 100644 index 0000000..fdb6598 --- /dev/null +++ b/subprojects/glfm.wrap @@ -0,0 +1,5 @@ +[wrap-git] +url = https://github.com/brackeen/glfm.git +revision = 38cc2c12ac1b0d59a269e72cc2d965f3f896ef52 +depth = 1 +method = cmake |