libweston: don't return buffers early with multiple backends

Releasing the buffer reference here works because the backend has seen the
surface and has updated keep_buffer if necessary. With multiple backends
the assumption breaks. The same surface may be visible (now or later) on an
output from another backend. This backend has not seen the buffer yet so it
cannot update keep_buffer.
As a result, the reference is released to early. A surface that is rendered
on a secondary backend first can no longer be placed on a plane on a DRM
backend.

To avoid this, always keep the buffer reference until it is replaced when
multiple backends are involved.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
Michael Olbrich 2022-07-25 17:21:57 +02:00 committed by Derek Foreman
parent 0b00090fdc
commit 44f36b9b55

View file

@ -3084,8 +3084,12 @@ output_accumulate_damage(struct weston_output *output)
* later, keep_buffer is true. Otherwise, drop the core
* reference now, and allow early buffer release. This enables
* clients to use single-buffering.
* The assumption that the backend has seen the surface only
* holds for one backend, so skip this optimization when
* multiple backends are involved.
*/
if (!pnode->surface->keep_buffer) {
if (!output->compositor->multi_backend &&
!pnode->surface->keep_buffer) {
weston_buffer_reference(&pnode->surface->buffer_ref,
pnode->surface->buffer_ref.buffer,
BUFFER_WILL_NOT_BE_ACCESSED);