egl/dri/wayland: Refactor buffer wait out of get_back_bo()
This is a potentially slow process, so let's break it out into its own function so we can have more meaningful profiling data from perfetto later. Signed-off-by: Derek Foreman <derek.foreman@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32757>
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user