diff options
| -rw-r--r-- | meson.build | 2 | ||||
| -rw-r--r-- | src/egl_common.c | 17 | ||||
| -rw-r--r-- | src/window.h | 4 | ||||
| -rw-r--r-- | src/window_glfw.c | 46 | ||||
| -rw-r--r-- | src/window_glfw.h | 14 | ||||
| -rw-r--r-- | src/window_wayland.c | 6 | ||||
| -rw-r--r-- | subprojects/libnaunet.wrap | 2 |
7 files changed, 75 insertions, 16 deletions
diff --git a/meson.build b/meson.build index 90d7b93..e86cd82 100644 --- a/meson.build +++ b/meson.build @@ -86,6 +86,8 @@ elif get_option('api') == 'vulkan' vulkan_headers = vulkan.partial_dependency(includes: true, compile_args: true, link_args: true) stela_deps += [vulkan_headers] stela_args += ['-DSTELA_API_VULKAN'] +elif get_option('api') == 'dx11' + stela_args += ['-DSTELA_API_DX11'] endif if get_option('window') == 'x11' diff --git a/src/egl_common.c b/src/egl_common.c index 7bbcba9..b2f0688 100644 --- a/src/egl_common.c +++ b/src/egl_common.c @@ -168,6 +168,7 @@ bool stl_init_egl_context(struct stl_egl *egl, struct stl_egl_global *global, EG void stl_egl_make_current(struct stl_egl *egl) { if (egl->context != egl->current) { + al_assert(egl->current == EGL_NO_CONTEXT); // 1 context limit (for now). eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context); egl->current = egl->context; } @@ -176,8 +177,20 @@ void stl_egl_make_current(struct stl_egl *egl) void stl_egl_release_current(struct stl_egl *egl) { al_assert(egl->context == egl->current); - eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - egl->current = EGL_NO_CONTEXT; + // https://gitlab.freedesktop.org/mesa/mesa/-/issues/6547 + // libplacebo calls release_current() after swapping buffers. That locks in the + // current backbuffer size. So, if all that happens for the next frame is: + // 1. wl_egl_window_resize() + // 2. resize libplacebo swapchain + // 3. start frame + // 4. submit frame + // 5. swap buffers + // The frame that is presented will still have the dimensions of the previous backbuffer. + // We only support 1 context at a time, so this shouldn't be an issue. +#if 0 + eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + egl->current = EGL_NO_CONTEXT; +#endif } void stl_egl_swap_interval(struct stl_egl *egl, EGLint interval) diff --git a/src/window.h b/src/window.h index 11ba00f..7c71056 100644 --- a/src/window.h +++ b/src/window.h @@ -20,6 +20,8 @@ #if defined STELA_API_VULKAN #include <vulkan/vulkan.h> +#elif defined STELA_API_DX11 +#include <nnwt/windows.h> #elif defined STELA_API_OPENGL && defined STELA_USE_EGL #include "egl_common.h" #endif @@ -82,6 +84,8 @@ struct stl_window { VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *); VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *); const char *const *(*vk_get_extensions)(u32 *); +#elif defined STELA_API_DX11 + HWND win32_window; #elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL EGLDisplay egl_display; diff --git a/src/window_glfw.c b/src/window_glfw.c index fc7b020..836e7c8 100644 --- a/src/window_glfw.c +++ b/src/window_glfw.c @@ -45,7 +45,6 @@ bool stl_global_init(bool skip_graphics) return false; } global.master_window = NULL; - al_log_info("glfw", "Successfully initialized GLFW."); return true; } @@ -85,12 +84,28 @@ static void mouse_button_callback(GLFWwindow *window, s32 button, s32 action, s3 { struct stl_window_glfw *glfw = glfwGetWindowUserPointer(window); (void)mods; - if (button == GLFW_MOUSE_BUTTON_1) { + switch (button) { + case GLFW_MOUSE_BUTTON_1: if (action == GLFW_PRESS) { stl_window_send_mouse_button_event(&glfw->w, STELA_BUTTON_PRESSED, STELA_MOUSE1); } else if (action == GLFW_RELEASE) { stl_window_send_mouse_button_event(&glfw->w, STELA_BUTTON_RELEASED, STELA_MOUSE1); } + break; + case GLFW_MOUSE_BUTTON_2: + if (action == GLFW_PRESS) { + stl_window_send_mouse_button_event(&glfw->w, STELA_BUTTON_PRESSED, STELA_MOUSE2); + } else if (action == GLFW_RELEASE) { + stl_window_send_mouse_button_event(&glfw->w, STELA_BUTTON_RELEASED, STELA_MOUSE2); + } + break; + case GLFW_MOUSE_BUTTON_3: + if (action == GLFW_PRESS) { + stl_window_send_mouse_button_event(&glfw->w, STELA_BUTTON_PRESSED, STELA_MOUSE3); + } else if (action == GLFW_RELEASE) { + stl_window_send_mouse_button_event(&glfw->w, STELA_BUTTON_RELEASED, STELA_MOUSE3); + } + break; } } @@ -104,7 +119,10 @@ static void scroll_callback(GLFWwindow *window, f64 xoffset, f64 yoffset) static void resize_callback(GLFWwindow *window, s32 event_width, s32 event_height) { struct stl_window_glfw *glfw = glfwGetWindowUserPointer(window); - al_assert(event_width > 0 && event_height > 0); + if (event_width <= 0 || event_height <= 0) { + // This happens on Windows when minimizing. + return; + } u32 width = (u32)event_width; u32 height = (u32)event_height; @@ -138,10 +156,18 @@ static bool window_glfw_create_window(struct stl_window *window, u32 width, u32 struct stl_window_glfw *glfw = (struct stl_window_glfw *)window; (void)monitor; +#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4) glfwWindowHintString(GLFW_WAYLAND_APP_ID, name); +#endif glfwWindowHintString(GLFW_X11_CLASS_NAME, name); -#if defined STELA_API_VULKAN || defined STELA_API_DX11 +#if defined STELA_API_VULKAN + if (!glfwVulkanSupported()) { + al_log_error("window_glfw", "Vulkan not supported."); + return false; + } + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); +#elif defined STELA_API_DX11 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); #elif defined STELA_API_OPENGL glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_NATIVE_CONTEXT_API); @@ -180,7 +206,12 @@ static bool window_glfw_create_window(struct stl_window *window, u32 width, u32 global.master_window = glfw->window; } -#ifdef STELA_API_OPENGL +#if defined STELA_API_VULKAN + (void)flags; +#elif defined STELA_API_DX11 + (void)flags; + glfw->w.win32_window = glfwGetWin32Window(glfw->window); +#elif defined STELA_API_OPENGL #ifdef STELA_USE_EGL glfw->w.egl_display = glfwGetEGLDisplay(); glfw->w.egl_context = glfwGetEGLContext(glfw->window); @@ -189,7 +220,6 @@ static bool window_glfw_create_window(struct stl_window *window, u32 width, u32 glfwSwapInterval((flags & STELA_WINDOW_VSYNC) ? 1 : 0); glfwMakeContextCurrent(NULL); #else - (void)flags; #endif s32 buffer_width, buffer_height; @@ -237,11 +267,13 @@ static void window_glfw_resize(struct stl_window *window, u32 width, u32 height) // https://stackoverflow.com/a/31526753 static GLFWmonitor *get_current_monitor(GLFWwindow *window, s32 wx, s32 wy) { +#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4) if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) { // Calculating the current monitor doesn't work on Wayland // because we can't know the position of the window. return glfwGetPrimaryMonitor(); } +#endif s32 monitor_count; GLFWmonitor **monitors = glfwGetMonitors(&monitor_count); @@ -283,9 +315,11 @@ static void window_glfw_toggle_fullscreen(struct stl_window *window) { struct stl_window_glfw *glfw = (struct stl_window_glfw *)window; if (!glfw->w.fullscreen) { +#if GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4) if (glfwGetPlatform() != GLFW_PLATFORM_WAYLAND) { glfwGetWindowPos(glfw->window, &glfw->prev.x, &glfw->prev.y); } +#endif GLFWmonitor *monitor = get_current_monitor(glfw->window, glfw->prev.x, glfw->prev.y); if (!monitor) return; const GLFWvidmode *mode = glfwGetVideoMode(monitor); diff --git a/src/window_glfw.h b/src/window_glfw.h index f834f29..2cde53c 100644 --- a/src/window_glfw.h +++ b/src/window_glfw.h @@ -6,15 +6,19 @@ #define GLFW_INCLUDE_NONE #endif #include <GLFW/glfw3.h> -#ifdef STELA_USE_EGL -#define GLFW_EXPOSE_NATIVE_EGL + +#include "window.h" + +#if defined STELA_API_DX11 #define GLFW_NATIVE_INCLUDE_NONE -#include "egl_common.h" +#define GLFW_EXPOSE_NATIVE_WIN32 +#include <GLFW/glfw3native.h> +#elif defined STELA_USE_EGL +#define GLFW_NATIVE_INCLUDE_NONE +#define GLFW_EXPOSE_NATIVE_EGL #include <GLFW/glfw3native.h> #endif -#include "window.h" - struct stl_glfw_global { GLFWwindow *master_window; }; diff --git a/src/window_wayland.c b/src/window_wayland.c index 31d1e13..6935f0e 100644 --- a/src/window_wayland.c +++ b/src/window_wayland.c @@ -738,6 +738,7 @@ static bool create_toplevel(struct stl_window_wayland *wl, s32 scale, const char { wl->w.scale = scale; wl_surface_set_buffer_scale(wl->surface, scale); + u32 geom_width = wl->w.width, geom_height = wl->w.height; wl->w.width *= scale; wl->w.height *= scale; wl->pending = true; @@ -757,7 +758,7 @@ static bool create_toplevel(struct stl_window_wayland *wl, s32 scale, const char xdg_toplevel_set_title(wl->xdg_toplevel, name); xdg_toplevel_set_app_id(wl->xdg_toplevel, name); xdg_toplevel_set_min_size(wl->xdg_toplevel, STELA_MIN_WIDTH, STELA_MIN_HEIGHT); - //xdg_surface_set_window_geometry(wl->xdg_surface, 0, 0, wl->w.width, wl->w.height); + xdg_surface_set_window_geometry(wl->xdg_surface, 0, 0, geom_width, geom_height); u32 decor = ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE; wl->zxdg_toplevel_decoration = zxdg_decoration_manager_v1_get_toplevel_decoration( @@ -853,7 +854,8 @@ static void window_wayland_resize_internal(struct stl_window *window, u32 width, { struct stl_window_wayland *wl = (struct stl_window_wayland *)window; #ifdef STELA_API_OPENGL - //xdg_surface_set_window_geometry(wl->xdg_surface, 0, 0, width, height); + u32 scale = wl->w.scale; + xdg_surface_set_window_geometry(wl->xdg_surface, 0, 0, width / scale, height / scale); if (stl_egl_is_ready(&wl->egl)) { wl_egl_window_resize(wl->egl_window, width, height, 0, 0); } diff --git a/subprojects/libnaunet.wrap b/subprojects/libnaunet.wrap index b87715d..0fb98e4 100644 --- a/subprojects/libnaunet.wrap +++ b/subprojects/libnaunet.wrap @@ -1,4 +1,4 @@ [wrap-git] url = https://git.akon.city/libnaunet -revision = 0e4440d9235da485a75e52466bbffe9511ba6d97 +revision = c4023623b89d7518c92f675f44355f5ae1196264 depth = 1 |