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