clients/simple-dmabuf-feedback: Support multi-tranche feedbacks

Compositors may choose to send multiple scanout or non-scanout
tranches. So instead of assuming that the first respective tranche
contains the format/modifier we're looking for, check all tranches.

While on it, make sure that in case a compositor sends scanout
tranches on the initial feedback, `pick_format_from_scanout_tranche()`
does not unintentionally pick `INITIAL_BUFFER_FORMAT`.

Signed-off-by: Robert Mader <robert.mader@collabora.com>
dev
Robert Mader 2 years ago committed by Robert Mader
parent a55bd6798e
commit 46a6b5b448
  1. 47
      clients/simple-dmabuf-feedback.c

@ -1223,7 +1223,7 @@ dmabuf_feedback_tranche_done(void *data,
dmabuf_feedback_tranche_init(&feedback->pending_tranche); dmabuf_feedback_tranche_init(&feedback->pending_tranche);
} }
static void static bool
pick_initial_format_from_renderer_tranche(struct window *window, pick_initial_format_from_renderer_tranche(struct window *window,
struct dmabuf_feedback_tranche *tranche) struct dmabuf_feedback_tranche *tranche)
{ {
@ -1237,13 +1237,12 @@ pick_initial_format_from_renderer_tranche(struct window *window,
window->format.format = fmt->format; window->format.format = fmt->format;
wl_array_copy(&window->format.modifiers, &fmt->modifiers); wl_array_copy(&window->format.modifiers, &fmt->modifiers);
return; return true;
} }
return false;
assert(0 && "error: INITIAL_BUFFER_FORMAT not supported by the hardware");
} }
static void static bool
pick_format_from_scanout_tranche(struct window *window, pick_format_from_scanout_tranche(struct window *window,
struct dmabuf_feedback_tranche *tranche) struct dmabuf_feedback_tranche *tranche)
{ {
@ -1252,8 +1251,9 @@ pick_format_from_scanout_tranche(struct window *window,
wl_array_for_each(fmt, &tranche->formats.arr) { wl_array_for_each(fmt, &tranche->formats.arr) {
/* Ignore format that we're already using. */ /* Ignore the format that we want to pick from the render
if (fmt->format == window->format.format) * tranche. */
if (fmt->format == INITIAL_BUFFER_FORMAT)
continue; continue;
/* Format should be supported by the compositor. */ /* Format should be supported by the compositor. */
@ -1267,10 +1267,9 @@ pick_format_from_scanout_tranche(struct window *window,
window->format.format = fmt->format; window->format.format = fmt->format;
wl_array_copy(&window->format.modifiers, &fmt->modifiers); wl_array_copy(&window->format.modifiers, &fmt->modifiers);
return; return true;
} }
return false;
assert(0 && "error: no valid pair of format/modifier in the scanout tranche");
} }
static void static void
@ -1278,25 +1277,37 @@ dmabuf_feedback_done(void *data, struct zwp_linux_dmabuf_feedback_v1 *dmabuf_fee
{ {
struct window *window = data; struct window *window = data;
struct dmabuf_feedback_tranche *tranche; struct dmabuf_feedback_tranche *tranche;
bool got_scanout_tranche = false;
unsigned int i; unsigned int i;
fprintf(stderr, L_LAST " end of dma-buf feedback\n\n"); fprintf(stderr, L_LAST " end of dma-buf feedback\n\n");
/* The first time that we receive dma-buf feedback for a surface it /* The first time that we receive dma-buf feedback for a surface it
* contains only the renderer tranche. We pick the INITIAL_BUFFER_FORMAT * contains only the renderer tranches. We pick the INITIAL_BUFFER_FORMAT
* from there. Then the compositor should detect that the format is * from there. Then the compositor should detect that the format is
* unsupported by the underlying hardware (not actually, but you should * unsupported by the underlying hardware (not actually, but you should
* have faked this in the DRM-backend) and send the scanout tranche. We * have faked this in the DRM-backend) and send the scanout tranches. We
* use the formats/modifiers of the scanout tranche to reallocate our * use the formats/modifiers of the scanout tranches to reallocate our
* buffers. */ * buffers. */
wl_array_for_each(tranche, &window->pending_dmabuf_feedback.tranches) { wl_array_for_each(tranche, &window->pending_dmabuf_feedback.tranches) {
if (tranche->is_scanout_tranche) { if (tranche->is_scanout_tranche) {
pick_format_from_scanout_tranche(window, tranche); got_scanout_tranche = true;
for (i = 0; i < NUM_BUFFERS; i++) if (pick_format_from_scanout_tranche(window, tranche)) {
window->buffers[i].recreate = true; for (i = 0; i < NUM_BUFFERS; i++)
break; window->buffers[i].recreate = true;
break;
}
} }
pick_initial_format_from_renderer_tranche(window, tranche); if (pick_initial_format_from_renderer_tranche(window, tranche))
break;
}
if (got_scanout_tranche) {
assert(window->format.format != INITIAL_BUFFER_FORMAT &&
"error: no valid pair of format/modifier in the scanout tranches");
} else {
assert(window->format.format == INITIAL_BUFFER_FORMAT &&
"error: INITIAL_BUFFER_FORMAT not supported by the hardware");
} }
dmabuf_feedback_fini(&window->dmabuf_feedback); dmabuf_feedback_fini(&window->dmabuf_feedback);

Loading…
Cancel
Save