From cca2fb967c6ab342bd938bfdd47de8fbd1b08a19 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 26 Oct 2018 08:49:17 +0530 Subject: [PATCH] Avoid malloc for frame callbacks --- glfw/wl_platform.h | 7 +++++++ glfw/wl_window.c | 24 ++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 9f5ad0a35..276ecb2e7 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -177,6 +177,13 @@ typedef struct _GLFWwindowWayland int focus; } decorations; + struct { + unsigned long long id; + void(*callback)(unsigned long long id); + struct wl_callback *current_wl_callback; + } frameCallbackData; + + } _GLFWwindowWayland; typedef struct _GLFWWaylandDataOffer diff --git a/glfw/wl_window.c b/glfw/wl_window.c index 22140275a..096befb27 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -973,6 +973,8 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) free(window->wl.title); free(window->wl.monitors); + if (window->wl.frameCallbackData.current_wl_callback) + wl_callback_destroy(window->wl.frameCallbackData.current_wl_callback); } void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) @@ -1929,16 +1931,13 @@ _glfwPlatformUpdateIMEState(_GLFWwindow *w, int which, int a, int b, int c, int glfw_xkb_update_ime_state(w, &_glfw.wl.xkb, which, a, b, c, d); } -struct frame_callback_data { - unsigned long long id; - void(*callback)(unsigned long long id); -}; - static void frame_handle_redraw(void *data, struct wl_callback *callback, uint32_t time) { - struct frame_callback_data *cbdata = (struct frame_callback_data*)data; - cbdata->callback(cbdata->id); - free(cbdata); + _GLFWwindow* window = (_GLFWwindow*) data; + if (callback == window->wl.frameCallbackData.current_wl_callback) { + window->wl.frameCallbackData.callback(window->wl.frameCallbackData.id); + window->wl.frameCallbackData.current_wl_callback = NULL; + } wl_callback_destroy(callback); } @@ -1965,9 +1964,10 @@ GLFWAPI int glfwGetXKBScancode(const char* keyName, GLFWbool caseSensitive) { GLFWAPI void glfwRequestWaylandFrameEvent(GLFWwindow *handle, unsigned long long id, void(*callback)(unsigned long long id)) { _GLFWwindow* window = (_GLFWwindow*) handle; - struct frame_callback_data *cbdata = malloc(sizeof(struct frame_callback_data)); - cbdata->callback = callback; cbdata->id = id; static const struct wl_callback_listener frame_listener = { .done = frame_handle_redraw }; - struct wl_callback *wlcallback = wl_surface_frame(window->wl.surface); - wl_callback_add_listener(wlcallback, &frame_listener, cbdata); + if (window->wl.frameCallbackData.current_wl_callback) wl_callback_destroy(window->wl.frameCallbackData.current_wl_callback); + window->wl.frameCallbackData.id = id; + window->wl.frameCallbackData.callback = callback; + window->wl.frameCallbackData.current_wl_callback = wl_surface_frame(window->wl.surface); + if (window->wl.frameCallbackData.current_wl_callback) wl_callback_add_listener(window->wl.frameCallbackData.current_wl_callback, &frame_listener, window); }