summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <mdaenzer@redhat.com>2020-10-02 15:55:05 +0200
committerDylan Baker <dylan.c.baker@intel.com>2020-11-02 07:48:26 -0800
commitcacca2aaa1ceb4690d3800d3f0f918a5696e6e8b (patch)
tree3c2edf6cb9472589c03991c1da8360ed8531c782
parentfa73f34f79cc1a8b6deca0d7760b0a615eb97713 (diff)
loader/dri3: Allocate up to 4 back buffers for page flips
With swap interval 0, i.e. sync-to-vblank disabled. This can be necessary for unthrottled drawing with Xwayland: 1) One buffer can be scanned out 2) One buffer can be pending in the kernel for a page flip 3) One buffer can be pending in the Wayland compositor Therefore, with 3 buffers, the frame-rate could be capped much lower than the throughput the GPU is capable of, in the worst case at the Wayland compositor refresh rate. (The native Wayland EGL backend always uses up to 4 buffers) Leave the maximum number of buffers at 3 for swap interval != 0, it's sufficient in that case to always be able to queue one frame ahead of time. https://gitlab.gnome.org/GNOME/mutter/-/issues/1455 https://gitlab.gnome.org/GNOME/mutter/-/issues/1462 Cc: mesa-stable Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7033> (cherry picked from commit 31e9de9c8ac72399427cb0fc15f19205dd8182c9)
-rw-r--r--.pick_status.json2
-rw-r--r--src/loader/loader_dri3_helper.c25
2 files changed, 23 insertions, 4 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 10de6697160..dbf617eb5d7 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -1201,7 +1201,7 @@
"description": "loader/dri3: Allocate up to 4 back buffers for page flips",
"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 14af1eb0661..78cf14b9ff7 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -275,10 +275,29 @@ static void
dri3_update_max_num_back(struct loader_dri3_drawable *draw)
{
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;
+ case XCB_PRESENT_COMPLETE_MODE_FLIP: {
+ int new_max;
+
+ if (draw->swap_interval == 0)
+ new_max = 4;
+ else
+ new_max = 3;
+
+ assert(new_max <= LOADER_DRI3_MAX_BACK);
+
+ if (new_max != draw->max_num_back) {
+ /* On transition from swap interval == 0 to != 0, start with two
+ * buffers again. Otherwise keep the current number of buffers. Either
+ * way, more will be allocated if needed.
+ */
+ if (new_max < draw->max_num_back)
+ draw->cur_num_back = 2;
+
+ draw->max_num_back = new_max;
+ }
+
break;
+ }
case XCB_PRESENT_COMPLETE_MODE_SKIP:
break;