summaryrefslogtreecommitdiff
path: root/src/loader
diff options
context:
space:
mode:
authorMichel Dänzer <mdaenzer@redhat.com>2021-08-19 15:53:06 +0200
committerMarge Bot <emma+marge@anholt.net>2022-12-16 10:30:47 +0000
commitc82c71a650eb37a4c7f09dd5aef085053f3f5ca4 (patch)
treef075755db8ac01b8ad331f56700a642974ce20f1 /src/loader
parentd58814516144646175026a138c2af309d4fa7d00 (diff)
downloadmesa-c82c71a650eb37a4c7f09dd5aef085053f3f5ca4.tar.gz
loader/dri3: Find idle buffer with minimum buffer age in dri3_find_back
This may allow applications making use of buffer age to save some effort in some cases. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18269>
Diffstat (limited to 'src/loader')
-rw-r--r--src/loader/loader_dri3_helper.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 0883a539c2d..dd521b11693 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -685,13 +685,26 @@ loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
static int
dri3_find_back(struct loader_dri3_drawable *draw, bool prefer_a_different)
{
+ struct loader_dri3_buffer *buffer;
int b;
int num_to_consider;
int max_num;
+ int best_id = -1;
+ uint64_t best_swap = 0;
mtx_lock(&draw->mtx);
- /* Increase the likelyhood of reusing current buffer */
- dri3_flush_present_events(draw);
+
+ if (!prefer_a_different) {
+ /* Increase the likelyhood of reusing current buffer */
+ dri3_flush_present_events(draw);
+
+ /* Reuse current back buffer if it's idle */
+ buffer = draw->buffers[draw->cur_back];
+ if (buffer && !buffer->busy) {
+ best_id = draw->cur_back;
+ goto unlock;
+ }
+ }
/* Check whether we need to reuse the current back buffer as new back.
* In that case, wait until it's not busy anymore.
@@ -716,25 +729,30 @@ dri3_find_back(struct loader_dri3_drawable *draw, bool prefer_a_different)
*/
int current_back_id = draw->cur_back;
for (;;) {
- /* Find idle buffer or unallocated slot */
+ /* Find idle buffer with lowest buffer age, or unallocated slot */
for (b = 0; b < num_to_consider; b++) {
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 &&
- (!prefer_a_different || id != current_back_id))) {
- draw->cur_back = id;
- mtx_unlock(&draw->mtx);
- return id;
+ buffer = draw->buffers[id];
+ if (buffer) {
+ if (!buffer->busy &&
+ (!prefer_a_different || id != current_back_id) &&
+ (best_id == -1 || buffer->last_swap > best_swap)) {
+ best_id = id;
+ best_swap = buffer->last_swap;
+ }
+ } else if (best_id == -1) {
+ best_id = id;
}
}
+ if (best_id != -1)
+ break;
+
/* No idle buffer, allocate another one if possible */
if (num_to_consider < max_num) {
- b = LOADER_DRI3_BACK_ID(draw->cur_num_back++);
- draw->cur_back = b;
- mtx_unlock(&draw->mtx);
- return b;
+ best_id = LOADER_DRI3_BACK_ID(draw->cur_num_back++);
+ break;
}
/* Prefer re-using the same buffer over blocking */
@@ -744,8 +762,12 @@ dri3_find_back(struct loader_dri3_drawable *draw, bool prefer_a_different)
break;
}
+ if (best_id != -1)
+ draw->cur_back = best_id;
+
+unlock:
mtx_unlock(&draw->mtx);
- return -1;
+ return best_id;
}
static xcb_gcontext_t