Module: Mesa Branch: staging/20.2 Commit: 2785b7baeb0eae1836ad562453d8be4918017e8e URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2785b7baeb0eae1836ad562453d8be4918017e8e
Author: Michel Dänzer <[email protected]> Date: Fri Oct 2 15:20:17 2020 +0200 loader/dri3: Only allocate additional buffers if needed Previously, we would always allocate 3 buffers for page flipping. But 2 buffers can suffice for clients which always wait for buffer swaps to complete before starting a new frame. Therefore, keep track of the maximum number of buffers separately from the current number, and only bump the latter if both current buffers are busy. Cc: mesa-stable Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Adam Jackson <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7033> (cherry picked from commit 60585fc4e34858aa277286209f3cf61e83770181) --- .pick_status.json | 2 +- src/loader/loader_dri3_helper.c | 40 +++++++++++++++++++++++++++++----------- src/loader/loader_dri3_helper.h | 3 ++- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index a9e3bb90321..b67d4d7032b 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -1219,7 +1219,7 @@ "description": "loader/dri3: Only allocate additional buffers if needed", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index cba3dfe2695..488c038ae5d 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -272,12 +272,23 @@ dri3_fence_await(xcb_connection_t *c, struct loader_dri3_drawable *draw, } static void -dri3_update_num_back(struct loader_dri3_drawable *draw) +dri3_update_max_num_back(struct loader_dri3_drawable *draw) { - if (draw->last_present_mode == XCB_PRESENT_COMPLETE_MODE_FLIP) - draw->num_back = 3; - else - draw->num_back = 2; + switch (draw->last_present_mode) { + case XCB_PRESENT_COMPLETE_MODE_FLIP: + /* Leave cur_num_back unchanged, it'll grow as needed */ + draw->max_num_back = 3; + break; + + default: + /* On transition from flips to copies, start with a single buffer again, + * a second one will be allocated if needed + */ + if (draw->max_num_back != 2) + draw->cur_num_back = 1; + + draw->max_num_back = 2; + } } void @@ -395,7 +406,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, } draw->swap_interval = swap_interval; - dri3_update_num_back(draw); + dri3_update_max_num_back(draw); /* Create a new drawable */ draw->dri_drawable = @@ -643,6 +654,7 @@ dri3_find_back(struct loader_dri3_drawable *draw) { int b; int num_to_consider; + int max_num; mtx_lock(&draw->mtx); /* Increase the likelyhood of reusing current buffer */ @@ -651,15 +663,18 @@ dri3_find_back(struct loader_dri3_drawable *draw) /* Check whether we need to reuse the current back buffer as new back. * In that case, wait until it's not busy anymore. */ - num_to_consider = draw->num_back; if (!loader_dri3_have_image_blit(draw) && draw->cur_blit_source != -1) { num_to_consider = 1; + max_num = 1; draw->cur_blit_source = -1; + } else { + num_to_consider = draw->cur_num_back; + max_num = draw->max_num_back; } for (;;) { for (b = 0; b < num_to_consider; b++) { - int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->num_back); + int id = LOADER_DRI3_BACK_ID((b + draw->cur_back) % draw->cur_num_back); struct loader_dri3_buffer *buffer = draw->buffers[id]; if (!buffer || !buffer->busy) { @@ -668,7 +683,10 @@ dri3_find_back(struct loader_dri3_drawable *draw) return id; } } - if (!dri3_wait_for_event_locked(draw, NULL)) { + + if (num_to_consider < max_num) { + num_to_consider = ++draw->cur_num_back; + } else if (!dri3_wait_for_event_locked(draw, NULL)) { mtx_unlock(&draw->mtx); return -1; } @@ -2006,10 +2024,10 @@ loader_dri3_get_buffers(__DRIdrawable *driDrawable, if (!dri3_update_drawable(draw)) return false; - dri3_update_num_back(draw); + dri3_update_max_num_back(draw); /* Free no longer needed back buffers */ - for (buf_id = draw->num_back; buf_id < LOADER_DRI3_MAX_BACK; buf_id++) { + for (buf_id = draw->cur_num_back; buf_id < LOADER_DRI3_MAX_BACK; buf_id++) { if (draw->cur_blit_source != buf_id && draw->buffers[buf_id]) { dri3_free_render_buffer(draw, draw->buffers[buf_id]); draw->buffers[buf_id] = NULL; diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index af5fdbc4193..3d50852ba86 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -146,7 +146,8 @@ struct loader_dri3_drawable { struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS]; int cur_back; - int num_back; + int cur_num_back; + int max_num_back; int cur_blit_source; uint32_t *stamp; _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
