compositor: add early wl_buffer.release

A client can reliably avoid allocating a second buffer per surface, if
the compositor sends the wl_buffer.release event before the frame
callback. To enable clients' single-buffering, release the wl_buffer
early if possible. Otherwise clients will double-buffer.

Releasing early is not possible, if the backend needs the buffer for
migrating a surface to or from a non-primary weston_plane. In that case,
a new buffer must arrive, before the old can be released. Backends will
indicate this by setting weston_surface:keep_buffer to 1 in
assign_planes().

A proper buffer reference in the backends would be better than the
keep_buffer flag, but that would require a per-surface backend private.

The rpi and DRM backends are updated to set keep_buffer, other backends
do not support planes, so do not have to set it.

Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
diff --git a/src/compositor.c b/src/compositor.c
index 869fffa..38bc6bc 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1084,9 +1084,21 @@
 	pixman_region32_fini(&ec->primary_plane.opaque);
 	pixman_region32_init(&ec->primary_plane.opaque);
 
-	wl_list_for_each(es, &ec->surface_list, link)
+	wl_list_for_each(es, &ec->surface_list, link) {
 		surface_accumulate_damage(es, &opaque);
 
+		/* Both the renderer and the backend have seen the buffer
+		 * by now. If renderer needs the buffer, it has its own
+		 * reference set. If the backend wants to keep the buffer
+		 * around for migrating the surface into a non-primary plane
+		 * later, keep_buffer is true. Otherwise, drop the core
+		 * reference now, and allow early buffer release. This enables
+		 * clients to use single-buffering.
+		 */
+		if (!es->keep_buffer)
+			weston_buffer_reference(&es->buffer_ref, NULL);
+	}
+
 	pixman_region32_fini(&opaque);
 
 	pixman_region32_init(&output_damage);