From cb5efd9224d7e2a2648629276499b7e740f11a7c Mon Sep 17 00:00:00 2001 From: IoIxD Date: Mon, 21 Sep 2026 15:49:01 -0700 Subject: [PATCH] wayland: got resizing looking good enough --- include/Mw/LowLevel/Wayland.h | 7 ++++ src/backend/wayland/buffer.c | 65 +++++++++++++++++++++++++++++++---- src/backend/wayland/wayland.c | 10 ++---- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 83cd299..9123458 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -271,6 +271,7 @@ struct _MwLLWaylandShmBuffer { MwU8* buf; MwU8* buf_back; MwU64 buf_size; + MwU64 buf_capacity; int fd; int fd_back; MwBool setup; @@ -466,6 +467,12 @@ void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* handle); void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height); void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer); void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer); +/* Resize an already set-up shm buffer pair in place, growing the backing pool with + * wl_shm_pool_resize instead of tearing it down and recreating it from scratch. */ +void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height); + +void MwLLWaylandFramebufferResize(struct _MwLLWayland* wayland); +void MwLLWaylandBackbufferResize(struct _MwLLWayland* wayland); void MwLLWaylandRegionSetup(MwLL handle); void MwLLWaylandRegionInvalidate(MwLL handle); diff --git a/src/backend/wayland/buffer.c b/src/backend/wayland/buffer.c index 79ce72c..3b61716 100644 --- a/src/backend/wayland/buffer.c +++ b/src/backend/wayland/buffer.c @@ -7,7 +7,7 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) { MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh); - memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); + memset(wayland->framebuffer.buf_back, 255, wayland->framebuffer.buf_size); if(wayland->configured) wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); if(wayland->framebuffer.fifo) @@ -38,7 +38,7 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland) { MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h); - memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); + memset(wayland->backbuffer.buf_back, 0, wayland->backbuffer.buf_size); if(wayland->configured) wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); // if(wayland->framebuffer.fifo) @@ -90,6 +90,8 @@ void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, M buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0); buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0); + buffer->buf_capacity = buffer->buf_size; + fsync(buffer->fd); fsync(buffer->fd_back); @@ -108,8 +110,8 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) { if(!buffer->setup) { return; } - if(buffer->buf) munmap(buffer->buf, buffer->buf_size); - if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_size); + if(buffer->buf) munmap(buffer->buf, buffer->buf_capacity); + if(buffer->buf_back) munmap(buffer->buf_back, buffer->buf_capacity); if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer); if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back); if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool); @@ -119,14 +121,63 @@ void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer) { buffer->setup = MwFALSE; } +void MwLLWaylandBufferResize(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { + MwLLWaylandBufferDestroy(buffer); + MwLLWaylandBufferSetup(buffer, width, height); + memset(buffer->buf_back, 0, buffer->buf_size); + memset(buffer->buf, 0, buffer->buf_size); +} + +void MwLLWaylandFramebufferResize(struct _MwLLWayland* wayland) { + MwLLWaylandBufferResize(&wayland->framebuffer, wayland->ww, wayland->wh); + + MwLLCairoFrontDestroy(&wayland->cairo); + MwLLCairoFrontSetup(&wayland->cairo, wayland->framebuffer.buf_back, wayland->ww, wayland->wh); + + 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); + MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer); +} + +void MwLLWaylandBackbufferResize(struct _MwLLWayland* wayland) { + MwU32 w = wayland->ww; + MwU32 h = wayland->wh; + + if(wayland->type != MwLL_WAYLAND_TOPLEVEL) { + return; + } + + if(!wayland->has_decorations && wayland->do_csd) { + w += (CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT); + h += (CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM); + } + + MwLLWaylandBufferResize(&wayland->backbuffer, w, h); + + MwLLCairoBackDestroy(&wayland->cairo); + MwLLCairoBackSetup(&wayland->cairo, wayland->backbuffer.buf_back, w, h); + + if(wayland->configured) + wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); + wl_surface_commit(wayland->backbuffer.surface); + MwLLWaylandHangUntilConfigured((MwLL)wayland); + MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->backbuffer); +} + 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); - } + // if(self->wayland.configured) { + // wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); + // } if(buffer->fifo) wp_fifo_v1_wait_barrier(buffer->fifo); wl_surface_commit(buffer->surface); diff --git a/src/backend/wayland/wayland.c b/src/backend/wayland/wayland.c index a0645e7..650e949 100644 --- a/src/backend/wayland/wayland.c +++ b/src/backend/wayland/wayland.c @@ -173,10 +173,7 @@ static void xdg_toplevel_configure(void* data, if(self->wayland.resizing == 0) { xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh); - MwLLWaylandBackbufferDestroy(&self->wayland); - MwLLWaylandBackbufferSetup(&self->wayland); - MwLLWaylandFramebufferDestroy(&self->wayland); - MwLLWaylandFramebufferSetup(&self->wayland); + MwLLWaylandFramebufferResize(&self->wayland); MwLLWaylandRegionSetup(self); MwLLDispatch(self, resize, NULL); @@ -1112,10 +1109,7 @@ static void actually_set_wh(MwLL handle) { MwLLWaylandRegionSetup(handle); if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL) recursive_render(handle); - MwLLWaylandFramebufferDestroy(&handle->wayland); - MwLLWaylandFramebufferSetup(&handle->wayland); - MwLLWaylandBackbufferDestroy(&handle->wayland); - MwLLWaylandBackbufferSetup(&handle->wayland); + MwLLWaylandFramebufferResize(&handle->wayland); MwLLDispatch(handle, draw, NULL); }