summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeandro Ribeiro <leandro.ribeiro@collabora.com>2022-01-24 18:35:03 -0300
committerMarius Vlad <marius.vlad@collabora.com>2022-05-24 22:11:23 +0300
commitd2d5c666a3926d2e7924b597546942e364189c97 (patch)
treebd3221ab125596f50534d2d6fcf19d554ab73bb5
parentf573612d379503c85f106a2f19924bf8f21a11cf (diff)
downloadweston-d2d5c666a3926d2e7924b597546942e364189c97.tar.gz
clients/simple-dmabuf-feedback: do not use buffer before compositor's response
This fixes an issue when running simple-dmabuf-feedback: "wl_display@1: error 1: invalid arguments for wl_surface@3.attach". As we are not using create_immed request from zwp_linux_dmabuf_v1, we can't start to use a dma-buf buffer before we process compositor's event telling us that the creation succeeded. This was causing problems in the following scenario: 1. buffer is marked to be recreated (because of dma-buf feedback); 2. in buffer_release() event, we destroy the buffer and recreate it; 3. after we recreate it, roundtrip is not called, as we don't want to block during the drawing loop; 4. buffer status is not being properly tracked, so we are trying to use a buffer before receiving the event from the compositor telling us that the creation succeeded. To fix this, this patch improves buffer status tracking. Now we only pick a buffer in the drawing loop when it is available. Also, if we have no buffers available we perform a roundtrip and try again, as we may have recreated all of them but still didn't have the chance to process compositor's events telling us that creation succeeded. Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com> (cherry picked from commit 7724c5ea380da617883ce8f644276e75f7e5bb7f)
-rw-r--r--clients/simple-dmabuf-feedback.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/clients/simple-dmabuf-feedback.c b/clients/simple-dmabuf-feedback.c
index dd2e64a5..94d734b9 100644
--- a/clients/simple-dmabuf-feedback.c
+++ b/clients/simple-dmabuf-feedback.c
@@ -140,7 +140,11 @@ struct display {
struct buffer {
struct window *window;
struct wl_buffer *buffer;
- bool busy;
+ enum {
+ NOT_CREATED,
+ IN_USE,
+ AVAILABLE
+ } status;
bool recreate;
int dmabuf_fds[4];
struct gbm_bo *bo;
@@ -469,7 +473,7 @@ buffer_release(void *data, struct wl_buffer *buffer)
{
struct buffer *buf = data;
- buf->busy = false;
+ buf->status = AVAILABLE;
if (buf->recreate)
buffer_recreate(buf);
@@ -485,6 +489,7 @@ create_succeeded(void *data, struct zwp_linux_buffer_params_v1 *params,
{
struct buffer *buf = data;
+ buf->status = AVAILABLE;
buf->buffer = new_buffer;
wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
zwp_linux_buffer_params_v1_destroy(params);
@@ -516,6 +521,7 @@ create_dmabuf_buffer(struct window *window, struct buffer *buf, uint32_t width,
struct zwp_linux_buffer_params_v1 *params;
int i;
+ buf->status = NOT_CREATED;
buf->window = window;
buf->width = width;
buf->height = height;
@@ -573,8 +579,22 @@ window_next_buffer(struct window *window)
unsigned int i;
for (i = 0; i < NUM_BUFFERS; i++)
- if (!window->buffers[i].busy)
+ if (window->buffers[i].status == AVAILABLE)
return &window->buffers[i];
+
+ /* In this client, we sometimes have to recreate the buffers. As we are
+ * not using the create_immed request from zwp_linux_dmabuf_v1, we need
+ * to wait an event from the server (what leads to create_succeeded()
+ * being called in this client). So if all buffers are busy, it may be
+ * the case in which all the buffers were recreated but the server still
+ * didn't send the events. This is very unlikely to happen, but a
+ * roundtrip() guarantees that we receive and process the events. */
+ wl_display_roundtrip(window->display->display);
+
+ for (i = 0; i < NUM_BUFFERS; i++)
+ if (window->buffers[i].status == AVAILABLE)
+ return &window->buffers[i];
+
return NULL;
}
@@ -639,7 +659,7 @@ redraw(void *data, struct wl_callback *callback, uint32_t time)
window->callback = wl_surface_frame(window->surface);
wl_callback_add_listener(window->callback, &frame_listener, window);
wl_surface_commit(window->surface);
- buf->busy = true;
+ buf->status = IN_USE;
region = wl_compositor_create_region(window->display->compositor);
wl_region_add(region, 0, 0, window->display->output.width,