pixman_region32_init(&overlap);
primary = &c->base.primary_plane;
wl_list_for_each_safe(es, next, &c->base.surface_list, link) {
+ /* test whether this buffer can ever go into a plane:
+ * non-shm, or small enough to be a cursor
+ */
+ if ((es->buffer_ref.buffer &&
+ !wl_buffer_is_shm(es->buffer_ref.buffer)) ||
+ (es->geometry.width <= 64 && es->geometry.height <= 64))
+ es->keep_buffer = 1;
+ else
+ es->keep_buffer = 0;
+
pixman_region32_init(&surface_overlap);
pixman_region32_intersect(&surface_overlap, &overlap,
&es->transform.boundingbox);
pixman_region32_init(&overlap);
wl_list_for_each(surface, &compositor->base.surface_list, link) {
+ /* always, since all buffers are shm on rpi */
+ surface->keep_buffer = 1;
+
pixman_region32_init(&surface_overlap);
pixman_region32_intersect(&surface_overlap, &overlap,
&surface->transform.boundingbox);
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);
struct weston_buffer_reference buffer_ref;
uint32_t buffer_transform;
+ int keep_buffer; /* bool for backends to prevent early release */
/* All the pending state, that wl_surface.commit will apply. */
struct {