Kristian, what do you think of this one?
The current state of affairs is that clients have to choose between holding more than 2 buffers, or constantly syncing with the compositor until a release comes. Thanks, Tomeu On 31 October 2013 02:59, Jason Ekstrand <[email protected]> wrote: > 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
