mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-06 09:08:33 +02:00
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 7724c5ea38)
This commit is contained in:
parent
f573612d37
commit
d2d5c666a3
1 changed files with 24 additions and 4 deletions
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue