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>
This commit is contained in:
committed by
Robert Mader
parent
a55bd6798e
commit
46a6b5b448
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user