Mesa (staging/20.2): loader/dri3: Only allocate additional buffers if needed
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Oct 30 19:36:50 UTC 2020
Module: Mesa
Branch: staging/20.2
Commit: 2785b7baeb0eae1836ad562453d8be4918017e8e
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2785b7baeb0eae1836ad562453d8be4918017e8e
Author: Michel Dänzer <mdaenzer at redhat.com>
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 <eric at anholt.net>
Reviewed-by: Adam Jackson <ajax at redhat.com>
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;
More information about the mesa-commit
mailing list