From be07e5448f54fbd84c5299cbadfd097d1ce893db Mon Sep 17 00:00:00 2001 From: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> Date: Sun, 17 Sep 2023 13:05:50 +0200 Subject: Improve reuse of mmap'ed data by Wayland buffers --- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H | 1 + src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 19 ++++++++++++------- src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx | 10 ++++++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H index 9991bd99f..b1deee5cb 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H @@ -51,6 +51,7 @@ public: struct wl_list buffers; // to list of fl_wld_buffer's from this pool }; static const uint32_t wld_format; + static struct wl_shm_pool *pool; // the current pool void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy) FL_OVERRIDE; static struct wld_buffer *create_shm_buffer(int width, int height); static void buffer_release(struct wld_window *window); diff --git a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx index f738a88a5..774bc52aa 100644 --- a/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx @@ -28,8 +28,8 @@ extern "C" { # include "../../../libdecor/src/os-compatibility.h" // for os_create_anonymous_file() } -// used by create_shm_buffer and buffer_release -static struct wl_shm_pool *pool = NULL; // the current pool + +struct wl_shm_pool *Fl_Wayland_Graphics_Driver::pool = NULL; struct Fl_Wayland_Graphics_Driver::wld_buffer * @@ -43,12 +43,17 @@ struct Fl_Wayland_Graphics_Driver::wld_buffer * struct wld_shm_pool_data *pool_data = pool ? // data record attached to current pool (struct wld_shm_pool_data *)wl_shm_pool_get_user_data(pool) : NULL; int pool_size = pool ? pool_data->pool_size : default_pool_size; // current pool size - if (pool) { - // last wld_buffer created from current pool + if (pool_data && !wl_list_empty(&pool_data->buffers)) { struct wld_buffer *record = wl_container_of(pool_data->buffers.next, record, link); chunk_offset = ((char*)record->data - pool_data->pool_memory) + record->draw_buffer.data_size; } if (!pool || chunk_offset + size > pool_size) { // if true, a new pool is needed + if (pool_data && wl_list_empty(&pool_data->buffers)) { + wl_shm_pool_destroy(pool); + /*int err =*/ munmap(pool_data->pool_memory, pool_data->pool_size); + //printf("munmap(%p)->%d\n", pool_data->pool_memory, err); + free(pool_data); + } chunk_offset = 0; pool_size = default_pool_size; if (size > pool_size) pool_size = 2 * size; // a larger pool is needed @@ -63,10 +68,10 @@ struct Fl_Wayland_Graphics_Driver::wld_buffer * close(fd); Fl::fatal("mmap failed: %s\n", strerror(errno)); } +//printf("os_create_anonymous_file(%d): mmap(%p)\n", pool_size, pool_data->pool_memory); Fl_Wayland_Screen_Driver *scr_driver = (Fl_Wayland_Screen_Driver*)Fl::screen_driver(); pool = wl_shm_create_pool(scr_driver->wl_shm, fd, pool_size); close(fd); // does not prevent the mmap'ed memory from being used -//puts("wl_shm_create_pool"); pool_data->pool_size = pool_size; wl_list_init(&pool_data->buffers); wl_shm_pool_set_user_data(pool, pool_data); @@ -186,12 +191,12 @@ void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window) // remove wld_buffer from list of pool's buffers wl_list_remove(&window->buffer->link); //printf("last=%p\n", wl_list_empty(&pool_data->buffers) ? NULL : pool_data->buffers.next); - if (wl_list_empty(&pool_data->buffers)) { // all buffers from pool are gone + if (wl_list_empty(&pool_data->buffers) && my_pool != pool) { + // all buffers from my_pool are gone wl_shm_pool_destroy(my_pool); /*int err = */munmap(pool_data->pool_memory, pool_data->pool_size); //printf("munmap(%p)->%d\n", pool_data->pool_memory, err); free(pool_data); - if (my_pool == pool) pool = NULL; } delete[] window->buffer->draw_buffer.buffer; window->buffer->draw_buffer.buffer = NULL; diff --git a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx index 9ccebc669..969a4f0c1 100644 --- a/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx +++ b/src/drivers/Wayland/Fl_Wayland_Screen_Driver.cxx @@ -1252,6 +1252,16 @@ void Fl_Wayland_Screen_Driver::open_display_platform() { void Fl_Wayland_Screen_Driver::close_display() { + if (Fl_Wayland_Graphics_Driver::pool ) { + struct Fl_Wayland_Graphics_Driver::wld_shm_pool_data *pool_data = + (struct Fl_Wayland_Graphics_Driver::wld_shm_pool_data *) + wl_shm_pool_get_user_data(Fl_Wayland_Graphics_Driver::pool); + wl_shm_pool_destroy(Fl_Wayland_Graphics_Driver::pool); + /*int err = */munmap(pool_data->pool_memory, pool_data->pool_size); + //printf("munmap(%p)->%d\n", pool_data->pool_memory, err); + free(pool_data); + Fl_Wayland_Graphics_Driver::pool = NULL; + } if (text_input_base) { disable_im(); zwp_text_input_manager_v3_destroy(text_input_base); -- cgit v1.2.3