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".
This commit is contained in:
ManoloFLTK 2022-09-08 16:11:53 +02:00
parent 71069b8570
commit 0ff31668a1
3 changed files with 23 additions and 9 deletions

View File

@ -78,7 +78,8 @@ public:
virtual void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen osrc, int srcx, int srcy); 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 struct fl_wld_buffer *create_shm_buffer(int width, int height);
static void buffer_release(struct wld_window *window); 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); 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();
virtual void gc(void *gc); virtual void gc(void *gc);

View File

@ -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, 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_t *surf = cairo_get_target(window->buffer->cairo_);
cairo_surface_flush(surf); cairo_surface_flush(surf);
memcpy(window->buffer->data, window->buffer->draw_buffer, window->buffer->data_size); 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_attach(window->wl_surface, window->buffer->wl_buffer, 0, 0);
wl_surface_set_buffer_scale(window->wl_surface, window->scale); wl_surface_set_buffer_scale(window->wl_surface, window->scale);
struct wl_callback *cb = wl_surface_frame(window->wl_surface); window->buffer->cb = wl_surface_frame(window->wl_surface);
if (listener) { if (need_damage) wl_surface_damage_buffer(window->wl_surface, 0, 0, 1000000, 1000000);
window->buffer->cb = cb; wl_callback_add_listener(window->buffer->cb, listener, window);
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); wl_surface_commit(window->wl_surface);
window->buffer->draw_buffer_needs_commit = false; window->buffer->draw_buffer_needs_commit = false;
//fprintf(stderr,"buffer_commit %s\n", window->fl_win->parent()?"child":"top"); //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) void Fl_Wayland_Graphics_Driver::buffer_release(struct wld_window *window)
{ {
if (window->buffer) { if (window->buffer) {
if (window->buffer->cb) wl_callback_destroy(window->buffer->cb);
wl_buffer_destroy(window->buffer->wl_buffer); wl_buffer_destroy(window->buffer->wl_buffer);
delete[] window->buffer->draw_buffer; delete[] window->buffer->draw_buffer;
window->buffer->draw_buffer = NULL; window->buffer->draw_buffer = NULL;

View File

@ -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() { void Fl_Wayland_Window_Driver::flush() {
if (!pWindow->damage()) return; if (!pWindow->damage()) return;
if (pWindow->as_gl_window()) { if (pWindow->as_gl_window()) {
@ -420,7 +432,9 @@ void Fl_Wayland_Window_Driver::flush() {
Fl_Window_Driver::flush(); Fl_Window_Driver::flush();
Fl_Wayland_Window_Driver::in_flush = false; 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);
}
} }