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

Reply via email to