From 7e9424d91b06aca12d258959f68f7f7c7a2f12a8 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 23 Jun 2021 11:05:44 -0400 Subject: [PATCH] loader/dri3: Don't churn through xfixes regions in SwapBuffers Regions are not expensive objects on the server side, it's very slightly cheaper to update an existing one than to create a new one, and we can garbage collect them when the drawable is destroyed. Worse, XID reuse bugs exist, so the more we can do to not churn through XIDs the better. Reviewed-By: Mike Blumenkrantz Part-of: --- src/loader/loader_dri3_helper.c | 16 +++++++++++----- src/loader/loader_dri3_helper.h | 1 + 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index cd648545e47..608eff5e11d 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -360,6 +360,9 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw) xcb_unregister_for_special_event(draw->conn, draw->special_event); } + if (draw->region) + xcb_xfixes_destroy_region(draw->conn, draw->region); + cnd_destroy(&draw->event_cnd); mtx_destroy(&draw->mtx); } @@ -385,6 +388,7 @@ loader_dri3_drawable_init(xcb_connection_t *conn, draw->ext = ext; draw->vtable = vtable; draw->drawable = drawable; + draw->region = 0; draw->dri_screen = dri_screen; draw->is_different_gpu = is_different_gpu; draw->multiplanes_available = multiplanes_available; @@ -1058,6 +1062,11 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw, back->busy = 1; back->last_swap = draw->send_sbc; + if (!draw->region) { + draw->region = xcb_generate_id(draw->conn); + xcb_xfixes_create_region(draw->conn, draw->region, 0, NULL); + } + xcb_xfixes_region_t region = 0; xcb_rectangle_t xcb_rects[64]; @@ -1070,8 +1079,8 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw, xcb_rects[i].height = rect[3]; } - region = xcb_generate_id(draw->conn); - xcb_xfixes_create_region(draw->conn, region, n_rects, xcb_rects); + region = draw->region; + xcb_xfixes_set_region(draw->conn, region, n_rects, xcb_rects); } xcb_present_pixmap(draw->conn, @@ -1091,9 +1100,6 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw, remainder, 0, NULL); ret = (int64_t) draw->send_sbc; - if (region) - xcb_xfixes_destroy_region(draw->conn, region); - /* Schedule a server-side back-preserving blit if necessary. * This happens iff all conditions below are satisfied: * a) We have a fake front, diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index c70f1145caa..028e25dc070 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -122,6 +122,7 @@ struct loader_dri3_drawable { __DRIdrawable *dri_drawable; xcb_drawable_t drawable; xcb_window_t window; + xcb_xfixes_region_t region; int width; int height; int depth;