|
commit 0ff31668a1117cf784e41331105d5c76f9bc441f
Author: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Thu Sep 8 16:11:53 2022 +0200
Commit: ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Thu Sep 8 16:11:53 2022 +0200
Wayland: remove memory leak from missing wl_callback_destroy() call.
This hopefully corresponds to the memory leak mentioned in fltk.general
named "FLTK and Wayland".
src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H | 3 ++-
src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx | 13 ++++++-------
src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx | 16 +++++++++++++++-
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
index 9b2edba..855bce1 100644
--- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
+++ src/drivers/Wayland/Fl_Wayland_Graphics_Driver.H
@@ -78,7 +78,8 @@ public:
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy);
static struct fl_wld_buffer *create_shm_buffer(int width, int height);
static void buffer_release(struct wld_window *window);
- static void buffer_commit(struct wld_window *window, const struct wl_callback_listener*);
+ static void buffer_commit(struct wld_window *window, const struct wl_callback_listener*,
+ bool need_damage = true);
static void cairo_init(struct fl_wld_buffer *buffer, int width, int height, int stride, cairo_format_t format);
virtual void *gc();
virtual void gc(void *gc);
diff --git src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
index 031c44e..e4632b4 100644
--- src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
+++ src/drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
@@ -76,18 +76,16 @@ struct fl_wld_buffer *Fl_Wayland_Graphics_Driver::create_shm_buffer(int width, i
void Fl_Wayland_Graphics_Driver::buffer_commit(struct wld_window *window,
- const struct wl_callback_listener *listener) {
+ const struct wl_callback_listener *listener,
+ bool need_damage) {
cairo_surface_t *surf = cairo_get_target(window->buffer->cairo_);
cairo_surface_flush(surf);
memcpy(window->buffer->data, window->buffer->draw_buffer, window->buffer->data_size);
wl_surface_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0);
wl_surface_set_buffer_scale(window->wl_surface, window->scale);
- struct wl_callback *cb = wl_surface_frame(window->wl_surface);
- if (listener) {
- window->buffer->cb = cb;
- wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000);
- wl_callback_add_listener(window->buffer->cb, listener, window);
- }
+ window->buffer->cb = wl_surface_frame(window->wl_surface);
+ if (need_damage) wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000);
+ wl_callback_add_listener(window->buffer->cb, listener, window);
wl_surface_commit(window->wl_surface);
window->buffer->draw_buffer_needs_commit = false;
//fprintf(stderr,"buffer_commit %s\n", window->fl_win->parent()?"child":"top");
@@ -117,6 +115,7 @@ void Fl_Wayland_Graphics_Driver::cairo_init(struct fl_wld_buffer *buffer, int wi
void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
{
if (window->buffer) {
+ if (window->buffer->cb) wl_callback_destroy(window->buffer->cb);
wl_buffer_destroy(window->buffer->wl_buffer);
delete[] window->buffer->draw_buffer;
window->buffer->draw_buffer = NULL;
diff --git src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
index 2692e8a..72430c8 100644
--- src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
+++ src/drivers/Wayland/Fl_Wayland_Window_Driver.cxx
@@ -382,6 +382,18 @@ void Fl_Wayland_Window_Driver::make_current() {
}
+// used to support regular drawing
+static void surface_frame_one_shot(void *data, struct wl_callback *cb, uint32_t time) {
+ wl_callback_destroy(cb);
+ struct wld_window *window = (struct wld_window *)data;
+ window->buffer->cb = NULL;
+}
+
+static const struct wl_callback_listener surface_frame_listener_one_shot = {
+ .done = surface_frame_one_shot,
+};
+
+
void Fl_Wayland_Window_Driver::flush() {
if (!pWindow->damage()) return;
if (pWindow->as_gl_window()) {
@@ -420,7 +432,9 @@ void Fl_Wayland_Window_Driver::flush() {
Fl_Window_Driver::flush();
Fl_Wayland_Window_Driver::in_flush = false;
- Fl_Wayland_Graphics_Driver::buffer_commit(window, NULL);
+ if (!window->buffer->cb) {
+ Fl_Wayland_Graphics_Driver::buffer_commit(window, &surface_frame_listener_one_shot, false);
+ }
}
[ Direct Link to Message ] | |