This allows the caller to specify whether the wl_buffer.release event (if one is generated) should be sent immediately or queued for later. This only makes a difference if this weston_buffer_reference call will release the buffer. If there are other references to the buffer remaining, the argument is simply ignored. --- src/compositor-drm.c | 9 ++++++--- src/compositor.c | 28 +++++++++++++++++++--------- src/compositor.h | 8 +++++++- src/gl-renderer.c | 12 ++++++++---- src/pixman-renderer.c | 13 +++++++++---- src/rpi-renderer.c | 21 ++++++++++++++------- 6 files changed, 63 insertions(+), 28 deletions(-)
diff --git a/src/compositor-drm.c b/src/compositor-drm.c index b929728..ad57415 100644 --- a/src/compositor-drm.c +++ b/src/compositor-drm.c @@ -237,7 +237,8 @@ drm_fb_destroy_callback(struct gbm_bo *bo, void *data) if (fb->fb_id) drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id); - weston_buffer_reference(&fb->buffer_ref, NULL); + weston_buffer_reference(&fb->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); free(data); } @@ -310,7 +311,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb) if (fb->fb_id) drmModeRmFB(fb->fd, fb->fb_id); - weston_buffer_reference(&fb->buffer_ref, NULL); + weston_buffer_reference(&fb->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); munmap(fb->map, fb->size); @@ -395,7 +397,8 @@ drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer) fb->is_client_buffer = 1; - weston_buffer_reference(&fb->buffer_ref, buffer); + weston_buffer_reference(&fb->buffer_ref, buffer, + WESTON_BUFFER_RELEASE_DELAYED); } static void diff --git a/src/compositor.c b/src/compositor.c index 563bade..f67bc49 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -1240,7 +1240,8 @@ weston_surface_destroy(struct weston_surface *surface) if (surface->pending.buffer) wl_list_remove(&surface->pending.buffer_destroy_listener.link); - weston_buffer_reference(&surface->buffer_ref, NULL); + weston_buffer_reference(&surface->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); pixman_region32_fini(&surface->damage); pixman_region32_fini(&surface->opaque); @@ -1310,14 +1311,18 @@ weston_buffer_reference_handle_destroy(struct wl_listener *listener, WL_EXPORT void weston_buffer_reference(struct weston_buffer_reference *ref, - struct weston_buffer *buffer) + struct weston_buffer *buffer, + enum weston_buffer_release_type release_type) { if (ref->buffer && buffer != ref->buffer) { ref->buffer->busy_count--; if (ref->buffer->busy_count == 0) { assert(wl_resource_get_client(ref->buffer->resource)); - wl_resource_queue_event(ref->buffer->resource, - WL_BUFFER_RELEASE); + if (release_type == WESTON_BUFFER_RELEASE_DELAYED) + wl_resource_queue_event(ref->buffer->resource, + WL_BUFFER_RELEASE); + else + wl_buffer_send_release(ref->buffer->resource); } wl_list_remove(&ref->destroy_listener.link); } @@ -1336,7 +1341,8 @@ static void weston_surface_attach(struct weston_surface *surface, struct weston_buffer *buffer) { - weston_buffer_reference(&surface->buffer_ref, buffer); + weston_buffer_reference(&surface->buffer_ref, buffer, + WESTON_BUFFER_RELEASE_DELAYED); if (!buffer) { if (weston_surface_is_mapped(surface)) @@ -1464,7 +1470,8 @@ compositor_accumulate_damage(struct weston_compositor *ec) * clients to use single-buffering. */ if (!ev->surface->keep_buffer) - weston_buffer_reference(&ev->surface->buffer_ref, NULL); + weston_buffer_reference(&ev->surface->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_IMMEDIATE); } } @@ -2107,7 +2114,8 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub) /* wl_surface.attach */ if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached) weston_surface_attach(surface, sub->cached.buffer_ref.buffer); - weston_buffer_reference(&sub->cached.buffer_ref, NULL); + weston_buffer_reference(&sub->cached.buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); surface->width = 0; surface->height = 0; @@ -2187,7 +2195,8 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub) if (surface->pending.newly_attached) { sub->cached.newly_attached = 1; weston_buffer_reference(&sub->cached.buffer_ref, - surface->pending.buffer); + surface->pending.buffer, + WESTON_BUFFER_RELEASE_DELAYED); } sub->cached.sx += surface->pending.sx; sub->cached.sy += surface->pending.sy; @@ -2487,7 +2496,8 @@ weston_subsurface_cache_fini(struct weston_subsurface *sub) wl_list_for_each_safe(cb, tmp, &sub->cached.frame_callback_list, link) wl_resource_destroy(cb->resource); - weston_buffer_reference(&sub->cached.buffer_ref, NULL); + weston_buffer_reference(&sub->cached.buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); pixman_region32_fini(&sub->cached.damage); pixman_region32_fini(&sub->cached.opaque); pixman_region32_fini(&sub->cached.input); diff --git a/src/compositor.h b/src/compositor.h index e60a512..689c542 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -624,6 +624,11 @@ struct weston_buffer { int y_inverted; }; +enum weston_buffer_release_type { + WESTON_BUFFER_RELEASE_IMMEDIATE = 0, + WESTON_BUFFER_RELEASE_DELAYED = 1 +}; + struct weston_buffer_reference { struct weston_buffer *buffer; struct wl_listener destroy_listener; @@ -1136,7 +1141,8 @@ weston_buffer_from_resource(struct wl_resource *resource); void weston_buffer_reference(struct weston_buffer_reference *ref, - struct weston_buffer *buffer); + struct weston_buffer *buffer, + enum weston_buffer_release_type release_type); uint32_t weston_compositor_get_time(void); diff --git a/src/gl-renderer.c b/src/gl-renderer.c index d181c07..72ca2ce 100644 --- a/src/gl-renderer.c +++ b/src/gl-renderer.c @@ -942,7 +942,8 @@ done: pixman_region32_init(&gs->texture_damage); gs->needs_full_upload = 0; - weston_buffer_reference(&gs->buffer_ref, NULL); + weston_buffer_reference(&gs->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); } static void @@ -1106,7 +1107,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) EGLint format; int i; - weston_buffer_reference(&gs->buffer_ref, buffer); + weston_buffer_reference(&gs->buffer_ref, buffer, + WESTON_BUFFER_RELEASE_DELAYED); if (!buffer) { for (i = 0; i < gs->num_images; i++) { @@ -1130,7 +1132,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) gl_renderer_attach_egl(es, buffer, format); else { weston_log("unhandled buffer type!\n"); - weston_buffer_reference(&gs->buffer_ref, NULL); + weston_buffer_reference(&gs->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); gs->buffer_type = BUFFER_TYPE_NULL; gs->y_inverted = 1; } @@ -1166,7 +1169,8 @@ surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr) for (i = 0; i < gs->num_images; i++) gr->destroy_image(gr->egl_display, gs->images[i]); - weston_buffer_reference(&gs->buffer_ref, NULL); + weston_buffer_reference(&gs->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); pixman_region32_fini(&gs->texture_damage); free(gs); } diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c index 79c1d5b..f16c049 100644 --- a/src/pixman-renderer.c +++ b/src/pixman-renderer.c @@ -550,7 +550,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) struct wl_shm_buffer *shm_buffer; pixman_format_code_t pixman_format; - weston_buffer_reference(&ps->buffer_ref, buffer); + weston_buffer_reference(&ps->buffer_ref, buffer, + WESTON_BUFFER_RELEASE_DELAYED); if (ps->image) { pixman_image_unref(ps->image); @@ -564,7 +565,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) if (! shm_buffer) { weston_log("Pixman renderer supports only SHM buffers\n"); - weston_buffer_reference(&ps->buffer_ref, NULL); + weston_buffer_reference(&ps->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); return; } @@ -580,7 +582,9 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer) break; default: weston_log("Unsupported SHM buffer format\n"); - weston_buffer_reference(&ps->buffer_ref, NULL); + weston_buffer_reference(&ps->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); + return; break; } @@ -608,7 +612,8 @@ pixman_renderer_surface_state_destroy(struct pixman_surface_state *ps) pixman_image_unref(ps->image); ps->image = NULL; } - weston_buffer_reference(&ps->buffer_ref, NULL); + weston_buffer_reference(&ps->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); free(ps); } diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c index b7e9487..b41bcf8 100644 --- a/src/rpi-renderer.c +++ b/src/rpi-renderer.c @@ -386,7 +386,8 @@ rpir_egl_buffer_destroy(struct rpir_egl_buffer *egl_buffer) vc_dispmanx_resource_delete(egl_buffer->resource_handle); } else { vc_dispmanx_set_wl_buffer_in_use(buffer->resource, 0); - weston_buffer_reference(&egl_buffer->buffer_ref, NULL); + weston_buffer_reference(&egl_buffer->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_IMMEDIATE); } free(egl_buffer); @@ -1345,7 +1346,8 @@ rpi_renderer_flush_damage(struct weston_surface *base) weston_log("%s error: updating Dispmanx resource failed.\n", __func__); - weston_buffer_reference(&surface->buffer_ref, NULL); + weston_buffer_reference(&surface->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); } static void @@ -1367,7 +1369,8 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer) /* XXX: cannot do this, if middle of an update */ rpi_resource_release(surface->front); - weston_buffer_reference(&surface->buffer_ref, NULL); + weston_buffer_reference(&surface->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); } /* If buffer is NULL, Weston core unmaps the surface, the surface @@ -1384,7 +1387,8 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer) buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer); buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer); - weston_buffer_reference(&surface->buffer_ref, buffer); + weston_buffer_reference(&surface->buffer_ref, buffer, + WESTON_BUFFER_RELEASE_DELAYED); } else { #if ENABLE_EGL struct rpi_renderer *renderer = to_rpi_renderer(base->compositor); @@ -1395,7 +1399,8 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer) wl_resource, EGL_WIDTH, &buffer->width)) { weston_log("unhandled buffer type!\n"); - weston_buffer_reference(&surface->buffer_ref, NULL); + weston_buffer_reference(&surface->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); surface->buffer_type = BUFFER_TYPE_NULL; } @@ -1408,12 +1413,14 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer) if(surface->egl_back == NULL) surface->egl_back = calloc(1, sizeof *surface->egl_back); - weston_buffer_reference(&surface->egl_back->buffer_ref, buffer); + weston_buffer_reference(&surface->egl_back->buffer_ref, buffer, + WESTON_BUFFER_RELEASE_DELAYED); surface->egl_back->resource_handle = vc_dispmanx_get_handle_from_wl_buffer(wl_resource); #else weston_log("unhandled buffer type!\n"); - weston_buffer_reference(&surface->buffer_ref, NULL); + weston_buffer_reference(&surface->buffer_ref, NULL, + WESTON_BUFFER_RELEASE_DELAYED); surface->buffer_type = BUFFER_TYPE_NULL; #endif } -- 1.8.3.1 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel