diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index a34dcf53410..aa2f61ab122 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -1146,6 +1146,41 @@ create_dri_image_from_formats(struct dri2_egl_surface *dri2_surf, surf_modifiers_count, &dri2_dpy->formats); } +static void +wait_for_free_buffer(struct dri2_egl_display *dri2_dpy, + struct dri2_egl_surface *dri2_surf) +{ + /* There might be a buffer release already queued that wasn't processed */ + wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue); + + while (dri2_surf->back == NULL) { + for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + /* Get an unlocked buffer, preferably one with a dri_buffer + * already allocated and with minimum age. + */ + if (dri2_surf->color_buffers[i].locked) + continue; + + if (!dri2_surf->back || !dri2_surf->back->dri_image || + (dri2_surf->color_buffers[i].age > 0 && + dri2_surf->color_buffers[i].age < dri2_surf->back->age)) + dri2_surf->back = &dri2_surf->color_buffers[i]; + } + + if (dri2_surf->back) + break; + + /* If we don't have a buffer, then block on the server to release one for + * us, and try again. wl_display_dispatch_queue will process any pending + * events, however not all servers flush on issuing a buffer release + * event. So, we spam the server with roundtrips as they always cause a + * client flush. + */ + if (wl_display_roundtrip_queue(dri2_dpy->wl_dpy, dri2_surf->wl_queue) < 0) + return; + } +} + static int get_back_bo(struct dri2_egl_surface *dri2_surf) { @@ -1174,36 +1209,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) dri2_dpy->formats.formats_bitmap, dri2_wl_visual_idx_from_pipe_format(linear_pipe_format))); - /* There might be a buffer release already queued that wasn't processed */ - wl_display_dispatch_queue_pending(dri2_dpy->wl_dpy, dri2_surf->wl_queue); - - while (dri2_surf->back == NULL) { - for (int i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { - /* Get an unlocked buffer, preferably one with a dri_buffer - * already allocated and with minimum age. - */ - if (dri2_surf->color_buffers[i].locked) - continue; - - if (!dri2_surf->back || !dri2_surf->back->dri_image || - (dri2_surf->color_buffers[i].age > 0 && - dri2_surf->color_buffers[i].age < dri2_surf->back->age)) - dri2_surf->back = &dri2_surf->color_buffers[i]; - } - - if (dri2_surf->back) - break; - - /* If we don't have a buffer, then block on the server to release one for - * us, and try again. wl_display_dispatch_queue will process any pending - * events, however not all servers flush on issuing a buffer release - * event. So, we spam the server with roundtrips as they always cause a - * client flush. - */ - if (wl_display_roundtrip_queue(dri2_dpy->wl_dpy, dri2_surf->wl_queue) < 0) - return -1; - } - + wait_for_free_buffer(dri2_dpy, dri2_surf); if (dri2_surf->back == NULL) return -1;