mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 21:30:23 +01:00
egl/gbm: Destroy excess BOs
Calculate the minimum available buffer age in addition to the maximum, and if they differ for 1000 frames in a row, destroy the BO for the highest-age unused buffer. Without this, Wayland compositors using dynamic triple buffering always get buffer age 3 once a third BO has been allocated. v2: * Rename function to destroy_oldest_unused_bo. (Marek Olšák) * Move function call into if block. * Use == instead of > as the condition for the function call. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37511>
This commit is contained in:
parent
15b8d3ca43
commit
dd7ae41091
2 changed files with 43 additions and 5 deletions
|
|
@ -338,6 +338,7 @@ struct dri2_egl_surface {
|
|||
|
||||
#ifdef HAVE_DRM_PLATFORM
|
||||
struct gbm_dri_surface *gbm_surf;
|
||||
unsigned excess_bo_frames;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
|
||||
|
|
|
|||
|
|
@ -216,22 +216,59 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
|
|||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_oldest_unused_bo(struct dri2_egl_surface *dri2_surf)
|
||||
{
|
||||
int max_age = 0;
|
||||
struct dri2_egl_buffer *oldest_buffer = NULL;
|
||||
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
|
||||
if (dri2_surf->color_buffers[i].locked ||
|
||||
dri2_surf->back == &dri2_surf->color_buffers[i])
|
||||
continue;
|
||||
|
||||
if (!max_age || dri2_surf->color_buffers[i].age > max_age) {
|
||||
oldest_buffer = &dri2_surf->color_buffers[i];
|
||||
max_age = dri2_surf->color_buffers[i].age;
|
||||
}
|
||||
}
|
||||
|
||||
gbm_bo_destroy(oldest_buffer->bo);
|
||||
oldest_buffer->bo = NULL;
|
||||
oldest_buffer->age = 0;
|
||||
|
||||
dri2_surf->excess_bo_frames = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
get_back_bo(struct dri2_egl_surface *dri2_surf)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy =
|
||||
dri2_egl_display(dri2_surf->base.Resource.Display);
|
||||
struct gbm_dri_surface *surf = dri2_surf->gbm_surf;
|
||||
int age = 0;
|
||||
int min_age = 0, max_age = 0;
|
||||
|
||||
if (dri2_surf->back == NULL) {
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
|
||||
if (!dri2_surf->color_buffers[i].locked &&
|
||||
dri2_surf->color_buffers[i].age >= age) {
|
||||
dri2_surf->back = &dri2_surf->color_buffers[i];
|
||||
age = dri2_surf->color_buffers[i].age;
|
||||
if (!dri2_surf->color_buffers[i].locked) {
|
||||
int age = dri2_surf->color_buffers[i].age;
|
||||
|
||||
if (!min_age || age < min_age)
|
||||
min_age = age;
|
||||
|
||||
if (!max_age || age > max_age) {
|
||||
dri2_surf->back = &dri2_surf->color_buffers[i];
|
||||
max_age = age;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (min_age && min_age < max_age) {
|
||||
if (++dri2_surf->excess_bo_frames == 1000)
|
||||
destroy_oldest_unused_bo(dri2_surf);
|
||||
} else {
|
||||
dri2_surf->excess_bo_frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (dri2_surf->back == NULL)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue