From 4b393e78ef92aef9f1c97b9bbee0cd95d95f9590 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Wed, 16 Sep 2026 12:35:47 -0700 Subject: [PATCH] test --- CMakeLists.txt | 1 + include/Mw/LowLevel/Cairo.h | 3 ++ include/Mw/LowLevel/Wayland.h | 11 ++---- pl/rules.pl | 1 + src/backend/cairo.c | 27 +++++++++------ src/backend/wayland/buffer.c | 24 +++++++++++++ src/backend/wayland/interfaces.c | 17 +++++++++ src/backend/wayland/wayland.c | 59 ++++++++------------------------ 8 files changed, 79 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 534614f..abc882d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -261,6 +261,7 @@ if(MW_USE_WAYLAND) scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1") scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1") scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1") + scan_wayland_protocol("staging" "fifo" "-v1") scan_wayland_protocol_from_file("wlr-layer-shell" "wlr-layer-shell-unstable-v1.xml") target_sources( diff --git a/include/Mw/LowLevel/Cairo.h b/include/Mw/LowLevel/Cairo.h index 680c651..92304fa 100644 --- a/include/Mw/LowLevel/Cairo.h +++ b/include/Mw/LowLevel/Cairo.h @@ -196,6 +196,9 @@ struct _MwLLCairo { /* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */ cairo_t* selected_cairo; + cairo_surface_t* frontbuffer_cs; + cairo_t* frontbuffer_cairo; + int x; int y; int width; diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 7a2c25c..4f09d0b 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -207,6 +207,7 @@ MwInline int wayland_load_funcs() { #include "Wayland/relative-pointer-client-protocol.h" #include "Wayland/xdg-toplevel-icon-client-protocol.h" #include "Wayland/wlr-layer-shell-client-protocol.h" +#include "Wayland/fifo-client-protocol.h" #endif typedef struct wayland_protocol { @@ -265,6 +266,7 @@ struct _MwLLWaylandShmBuffer { struct wl_buffer* shm_buffer_back; struct wl_surface* surface; struct wl_output* output; + struct wp_fifo_v1* fifo; MwU8* buf; MwU8* buf_back; @@ -440,14 +442,7 @@ struct _MwLLWayland { MwLLPixmap icon_pixmap; - pthread_mutex_t eventsMutex; - - int cancelEvent; - int numCallbacksRunning; - - uint32_t last_time; - - MwBool moving; + MwU64 time_test; MwI64 keyboard_rate; MwI32 keyboard_delay; diff --git a/pl/rules.pl b/pl/rules.pl index 551d391..f12c092 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -66,6 +66,7 @@ if (grep(/^wayland$/, @backends)) { scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1"); scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1"); scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1"); + scan_wayland_protocol("staging", "fifo", "-v1"); scan_wayland_protocol_from_file("wlr-layer-shell", "wlr-layer-shell-unstable-v1.xml"); diff --git a/src/backend/cairo.c b/src/backend/cairo.c index 3683ca8..9dab1c1 100644 --- a/src/backend/cairo.c +++ b/src/backend/cairo.c @@ -113,13 +113,16 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { if(data) { - cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); + cairo->front_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); + cairo->frontbuffer_cs = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, width * 4); } else { - cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo->frontbuffer_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); } - cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); - cairo->front_cairo_back = cairo_create(cairo->front_cs_back); - cairo->front_cairo = cairo_create(cairo->front_cs); + cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + cairo->front_cairo_back = cairo_create(cairo->front_cs_back); + cairo->front_cairo = cairo_create(cairo->front_cs); + cairo->frontbuffer_cairo = cairo_create(cairo->frontbuffer_cs); } void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) { @@ -135,6 +138,8 @@ void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) { cairo_destroy(cairo->front_cairo); cairo_destroy(cairo->front_cairo_back); cairo_surface_destroy(cairo->front_cs); + cairo_surface_destroy(cairo->frontbuffer_cs); + cairo_destroy(cairo->frontbuffer_cairo); }; void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) { cairo_destroy(cairo->back_cairo); @@ -214,8 +219,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {} static MwBool lmao = MwFALSE; static int MwLLPendingImpl(MwLL handle) { - lmao = !lmao; - return lmao; + lmao = !lmao; + return lmao; } static void MwLLNextEventImpl(MwLL handle) { MwLLDispatch(handle, draw, NULL); @@ -259,10 +264,10 @@ static void MwLLRaiseImpl(MwLL handle) {} static void MwLLClipImpl(MwLL handle, MwRect* rect) {} static void MwLLSetupDragAndDropImpl(MwLL handle) {} static int MwLLCairoCallInitImpl(void) { - if(cairo_load_funcs() != 0) { - return 1; - } - return 0; + if(cairo_load_funcs() != 0) { + return 1; + } + return 0; } #include "call.c" CALL(Cairo); diff --git a/src/backend/wayland/buffer.c b/src/backend/wayland/buffer.c index cb1eca5..9ee4f45 100644 --- a/src/backend/wayland/buffer.c +++ b/src/backend/wayland/buffer.c @@ -10,6 +10,9 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) { memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); if(wayland->configured) wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); + // if(wayland->framebuffer.fifo) + // wp_fifo_v1_set_barrier(wayland->framebuffer.fifo); + wl_surface_commit(wayland->framebuffer.surface); MwLLWaylandHangUntilConfigured((MwLL)wayland); @@ -38,6 +41,8 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) { memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); if(wayland->configured) wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); + // if(wayland->framebuffer.fifo) + // wp_fifo_v1_set_barrier(wayland->framebuffer.fifo); wl_surface_commit(wayland->backbuffer.surface); MwLLWaylandHangUntilConfigured((MwLL)wayland); MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer); @@ -113,3 +118,22 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) { close(buffer->fd_back); buffer->setup = MwFALSE; } + +void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { + if(self->wayland.configured) { + memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); + if(buffer->surface) { + if(self->wayland.framebuffer.fifo) { + // wp_fifo_v1_wait_barrier(self->wayland.framebuffer.fifo); + } + // Yes this is needed every time, it's how we fix weston. + if(self->wayland.configured) { + wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); + // if(buffer->fifo) + // wp_fifo_v1_set_barrier(buffer->fifo); + } + + wl_surface_commit(buffer->surface); + } + } +} diff --git a/src/backend/wayland/interfaces.c b/src/backend/wayland/interfaces.c index dd58f9a..3378d0d 100644 --- a/src/backend/wayland/interfaces.c +++ b/src/backend/wayland/interfaces.c @@ -749,6 +749,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time if(self->wayland.backbuffer.surface) { wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0); } + WAYLAND_EVENT_OP_END(self); }; @@ -1511,6 +1512,21 @@ static void zwlr_layer_shell_v1_interface_destroy(struct _MwLLWayland* wayland, free(data); } +static wayland_protocol_t* wp_fifo_manager_v1_setup(MwU32 name, struct _MwLLWayland* wayland, MwU32 version) { + wayland_protocol_t* proto = malloc(sizeof(wayland_protocol_t)); + + proto->context = wl_registry_bind(wayland->registry, name, &wp_fifo_manager_v1_interface, version); + proto->listener = NULL; + + return proto; +} + +static void wp_fifo_manager_v1_interface_destroy(struct _MwLLWayland* wayland, wayland_protocol_t* data) { + (void)wayland; + + free(data); +} + /* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) { /* Convience macro for adding the interface functions to the setup map */ @@ -1553,6 +1569,7 @@ void MwLLWaylandSetupCallbacks(struct _MwLLWayland* wayland) { WL_INTERFACE(xdg_toplevel_icon_manager_v1); WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_seat); + WL_INTERFACE(wp_fifo_manager_v1); } else if(wayland->type == MwLL_WAYLAND_POPUP) { WL_INTERFACE(wl_seat); } else if(wayland->type == MwLL_WAYLAND_LAYER_SURFACE) { diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c index bd17f84..5b59795 100644 --- a/src/backend/wayland/wayland.c +++ b/src/backend/wayland/wayland.c @@ -218,19 +218,6 @@ static void xdg_surface_configure( self->wayland.configured = MwTRUE; } -void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { - if(self->wayland.configured) { - memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); - if(buffer->surface) { - // Yes this is needed every time, it's how we fix weston. - if(self->wayland.configured) - wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); - - wl_surface_commit(buffer->surface); - } - } -} - /* Toplevel setup function */ static void setup_toplevel(MwLL r, int x, int y) { char* mw_force_csd = getenv("MW_FORCE_CSD"); @@ -278,6 +265,10 @@ static void setup_toplevel(MwLL r, int x, int y) { r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface); wl_subsurface_set_desync(r->wayland.toplevel->ssurface); + if(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1) != NULL) { + r->wayland.framebuffer.fifo = wp_fifo_manager_v1_get_fifo(WAYLAND_GET_INTERFACE(r->wayland, wp_fifo_manager_v1)->context, r->wayland.framebuffer.surface); + } + r->wayland.toplevel->xdg_surface = xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface); r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface); @@ -921,13 +912,6 @@ static void draw_child(MwLL handle, MwLL child) { cairo_t* c; cairo_surface_t* cs; cairo_t* selected_cairo; - MwLL topmost_parent = handle; - - if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP) { - while(topmost_parent->wayland.parent) { - topmost_parent = topmost_parent->wayland.parent; - } - } wl_surface_commit(child->wayland.framebuffer.surface); @@ -941,8 +925,6 @@ static void draw_child(MwLL handle, MwLL child) { cairo_paint(c); - // printf("%d %d\n", child->wayland.x, child->wayland.y); - cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y); cairo_paint(handle->wayland.cairo.front_cairo_back); @@ -962,11 +944,8 @@ static void draw_children(MwLL handle) { } static void frontbuffer_draw(MwLL handle) { - cairo_t* c; - cairo_surface_t* cs; - - cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh); - c = cairo_create(cs); + cairo_t* c = handle->wayland.cairo.frontbuffer_cairo; + cairo_surface_t* cs = handle->wayland.cairo.frontbuffer_cs; cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0); cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); @@ -977,16 +956,13 @@ static void frontbuffer_draw(MwLL handle) { cairo_set_source_surface(handle->wayland.cairo.front_cairo, cs, 0, 0); cairo_paint(handle->wayland.cairo.front_cairo); - - cairo_destroy(c); - cairo_surface_destroy(cs); } static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { MwLL r; r = malloc(sizeof(*r)); memset(r, 0, sizeof(*r)); - pthread_mutex_init(&r->wayland.eventsMutex, NULL); + // pthread_mutex_init(&r->wayland.eventsMutex, NULL); MwLLCreateCommon(r); r->wayland.is_toplevel = parent == NULL; @@ -1015,8 +991,6 @@ static void MwLLDestroyImpl(MwLL handle) { MwLLWaylandFlush(handle); - handle->wayland.cancelEvent = MwTRUE; - MwLLDestroyCommon(handle); tv.tv_sec = 0; @@ -1050,7 +1024,7 @@ static void MwLLDestroyImpl(MwLL handle) { printf("widget invalid\n"); } - pthread_mutex_destroy(&handle->wayland.eventsMutex); + // pthread_mutex_destroy(&handle->wayland.eventsMutex); free(handle); } @@ -1320,11 +1294,8 @@ static void MwLLEndDrawImpl(MwLL handle) { if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer); } - MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); - if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) { - handle->wayland.do_cascading_draw = 1; - } + MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer); } } @@ -1382,16 +1353,16 @@ static int MwLLPendingImpl(MwLL handle) { handle->wayland.resizing = 0; + if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) { + draw_children(handle); + frontbuffer_draw(handle); + } + if(handle->wayland.setting_wh) { actually_set_wh(handle); handle->wayland.setting_wh = 0; } - if(handle->wayland.do_cascading_draw) { - draw_children(handle); - frontbuffer_draw(handle); - } - handle->wayland.end_time = MwTimeGetTick(); if(handle->wayland.holding_key) { @@ -1449,7 +1420,6 @@ static int MwLLPendingImpl(MwLL handle) { } static void MwLLNextEventImpl(MwLL handle) { - if(!MwWaylandVulkan) { if(handle->wayland.did_event_loop_early) { handle->wayland.did_event_loop_early = MwFALSE; @@ -1469,7 +1439,6 @@ static void MwLLNextEventImpl(MwLL handle) { } static void MwLLSetTitleImpl(MwLL handle, const char* title) { - if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) { xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title); }