diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index 9cf4a491..9780d798 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -1232,7 +1232,7 @@ err: if (output->dumb[i]) drm_fb_unref(output->dumb[i]); if (output->renderbuffer[i]) - pixman->renderbuffer_destroy(output->renderbuffer[i]); + weston_renderbuffer_unref(output->renderbuffer[i]); output->dumb[i] = NULL; output->renderbuffer[i] = NULL; @@ -1258,7 +1258,7 @@ drm_output_fini_pixman(struct drm_output *output) } for (i = 0; i < ARRAY_LENGTH(output->dumb); i++) { - renderer->pixman->renderbuffer_destroy(output->renderbuffer[i]); + weston_renderbuffer_unref(output->renderbuffer[i]); drm_fb_unref(output->dumb[i]); output->dumb[i] = NULL; output->renderbuffer[i] = NULL; diff --git a/libweston/backend-headless/headless.c b/libweston/backend-headless/headless.c index 236aa468..e6689bf8 100644 --- a/libweston/backend-headless/headless.c +++ b/libweston/backend-headless/headless.c @@ -192,7 +192,8 @@ headless_output_disable_pixman(struct headless_output *output) { struct weston_renderer *renderer = output->base.compositor->renderer; - renderer->pixman->renderbuffer_destroy(output->renderbuffer); + weston_renderbuffer_unref(output->renderbuffer); + output->renderbuffer = NULL; renderer->pixman->output_destroy(&output->base); } diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 9886d0b8..b68e4fd5 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -423,7 +423,7 @@ rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode) pixman_image_composite32(PIXMAN_OP_SRC, old_image, 0, new_image, 0, 0, 0, 0, 0, 0, mode->width, mode->height); - pixman->renderbuffer_destroy(rdpOutput->renderbuffer); + weston_renderbuffer_unref(rdpOutput->renderbuffer); rdpOutput->renderbuffer = new_renderbuffer; } @@ -522,7 +522,8 @@ rdp_output_disable(struct weston_output *base) if (!output->base.enabled) return 0; - renderer->pixman->renderbuffer_destroy(output->renderbuffer); + weston_renderbuffer_unref(output->renderbuffer); + output->renderbuffer = NULL; renderer->pixman->output_destroy(&output->base); wl_event_source_remove(output->finish_frame_timer); diff --git a/libweston/backend-vnc/vnc.c b/libweston/backend-vnc/vnc.c index 69f33e38..ace6119d 100644 --- a/libweston/backend-vnc/vnc.c +++ b/libweston/backend-vnc/vnc.c @@ -449,11 +449,10 @@ static void fb_side_data_destroy(void *userdata) { struct fb_side_data *fb_side_data = userdata; - struct weston_renderer *renderer = fb_side_data->renderer; wl_list_remove(&fb_side_data->link); pixman_region32_fini(&fb_side_data->damage); - renderer->pixman->renderbuffer_destroy(fb_side_data->renderbuffer); + weston_renderbuffer_unref(fb_side_data->renderbuffer); free(fb_side_data); } diff --git a/libweston/backend-wayland/wayland.c b/libweston/backend-wayland/wayland.c index a4caf94e..9f11b347 100644 --- a/libweston/backend-wayland/wayland.c +++ b/libweston/backend-wayland/wayland.c @@ -257,12 +257,8 @@ static void wayland_shm_buffer_destroy(struct wayland_shm_buffer *buffer) { cairo_surface_destroy(buffer->c_surface); - if (buffer->output) { - const struct pixman_renderer_interface *pixman; - - pixman = buffer->output->base.compositor->renderer->pixman; - pixman->renderbuffer_destroy(buffer->renderbuffer); - } + if (buffer->output) + weston_renderbuffer_unref(buffer->renderbuffer); wl_buffer_destroy(buffer->buffer); munmap(buffer->data, buffer->size); diff --git a/libweston/backend-x11/x11.c b/libweston/backend-x11/x11.c index d286dd0a..edb2abb0 100644 --- a/libweston/backend-x11/x11.c +++ b/libweston/backend-x11/x11.c @@ -554,12 +554,11 @@ finish_frame_handler(void *data) static void x11_output_deinit_shm(struct x11_backend *b, struct x11_output *output) { - const struct weston_renderer *renderer = b->compositor->renderer; xcb_void_cookie_t cookie; xcb_generic_error_t *err; xcb_free_gc(b->conn, output->gc); - renderer->pixman->renderbuffer_destroy(output->renderbuffer); + weston_renderbuffer_unref(output->renderbuffer); output->renderbuffer = NULL; cookie = xcb_shm_detach_checked(b->conn, output->segment); err = xcb_request_check(b->conn, cookie); diff --git a/libweston/compositor.c b/libweston/compositor.c index cf1f351d..fbb8eeeb 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -8899,6 +8899,25 @@ weston_output_disable_planes_decr(struct weston_output *output) } +WL_EXPORT struct weston_renderbuffer * +weston_renderbuffer_ref(struct weston_renderbuffer *renderbuffer) +{ + renderbuffer->refcount++; + + return renderbuffer; +} + +WL_EXPORT void +weston_renderbuffer_unref(struct weston_renderbuffer *renderbuffer) +{ + assert(renderbuffer->refcount > 0); + + if (--renderbuffer->refcount > 0) + return; + + renderbuffer->destroy(renderbuffer); +} + /** Tell the renderer that the target framebuffer size has changed * * \param output The output that was resized. diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h index 87354067..54d71032 100644 --- a/libweston/libweston-internal.h +++ b/libweston/libweston-internal.h @@ -48,8 +48,17 @@ struct weston_renderbuffer { pixman_region32_t damage; + int refcount; + + void (*destroy)(struct weston_renderbuffer *renderbuffer); }; +struct weston_renderbuffer * +weston_renderbuffer_ref(struct weston_renderbuffer *renderbuffer); + +void +weston_renderbuffer_unref(struct weston_renderbuffer *renderbuffer); + struct weston_renderer_options { }; diff --git a/libweston/pixman-renderer.c b/libweston/pixman-renderer.c index 4ecdf432..643f7945 100644 --- a/libweston/pixman-renderer.c +++ b/libweston/pixman-renderer.c @@ -1133,6 +1133,9 @@ pixman_renderer_output_destroy(struct weston_output *output) free(po); } +static void +pixman_renderer_renderbuffer_destroy(struct weston_renderbuffer *renderbuffer); + static struct weston_renderbuffer * pixman_renderer_create_image_from_ptr(struct weston_output *output, pixman_format_code_t format, int width, @@ -1153,6 +1156,8 @@ pixman_renderer_create_image_from_ptr(struct weston_output *output, } pixman_region32_init(&renderbuffer->base.damage); + renderbuffer->base.refcount = 1; + renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy; wl_list_insert(&po->renderbuffer_list, &renderbuffer->link); return &renderbuffer->base; @@ -1178,6 +1183,8 @@ pixman_renderer_create_image(struct weston_output *output, } pixman_region32_init(&renderbuffer->base.damage); + renderbuffer->base.refcount = 1; + renderbuffer->base.destroy = pixman_renderer_renderbuffer_destroy; wl_list_insert(&po->renderbuffer_list, &renderbuffer->link); return &renderbuffer->base; @@ -1200,6 +1207,5 @@ static struct pixman_renderer_interface pixman_renderer_interface = { .output_destroy = pixman_renderer_output_destroy, .create_image_from_ptr = pixman_renderer_create_image_from_ptr, .create_image = pixman_renderer_create_image, - .renderbuffer_destroy = pixman_renderer_renderbuffer_destroy, .renderbuffer_get_image = pixman_renderer_renderbuffer_get_image, }; diff --git a/libweston/pixman-renderer.h b/libweston/pixman-renderer.h index f7143520..e67501ad 100644 --- a/libweston/pixman-renderer.h +++ b/libweston/pixman-renderer.h @@ -56,6 +56,5 @@ struct pixman_renderer_interface { struct weston_renderbuffer *(*create_image)(struct weston_output *output, pixman_format_code_t format, int width, int height); - void (*renderbuffer_destroy)(struct weston_renderbuffer *renderbuffer); pixman_image_t *(*renderbuffer_get_image)(struct weston_renderbuffer *renderbuffer); };