From 9e73df9095b1db9be9f915cbef2f7ab8d46de7c5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 15 Oct 2016 00:17:18 +0100 Subject: [PATCH] dri3 --- src/loader/loader_dri3_helper.c | 44 ++++++++++++++++++++++++++++++++++++++++- src/loader/loader_dri3_helper.h | 3 +++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index cb52bfa..f55f766 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -139,6 +139,11 @@ loader_dri3_drawable_fini(struct loader_dri3_drawable *draw) for (int i = 0; i < LOADER_DRI3_MAX_BACK; i++) dri3_free_render_buffer(draw, draw->back[i].buffer); + if (draw->sync_fence) { + xcb_sync_destroy_fence(draw->conn, draw->sync_fence); + xshmfence_unmap_shm(draw->shm_fence); + } + if (draw->special_event) { xcb_void_cookie_t cookie = xcb_present_select_input_checked(draw->conn, draw->eid, draw->drawable, @@ -587,7 +592,19 @@ loader_dri3_wait_x(struct loader_dri3_drawable *draw) { struct loader_dri3_buffer *front; - if (draw == NULL || !draw->have_fake_front) + if (draw == NULL) + return; + + if (draw->sync_fence) { + xshmfence_reset(draw->shm_fence); + + xcb_sync_trigger_fence(draw->conn, draw->sync_fence); + xcb_flush(draw->conn); + + xshmfence_await(draw->shm_fence); + } + + if (!draw->have_fake_front) return; front = dri3_fake_front_buffer(draw); @@ -976,6 +993,29 @@ no_shm_fence: return NULL; } +static void +dri3_attach_sync(struct loader_dri3_drawable *draw) +{ + int fence_fd; + + fence_fd = xshmfence_alloc_shm(); + if (fence_fd < 0) + return; + + draw->shm_fence = xshmfence_map_shm(fence_fd); + if (draw->shm_fence == NULL) { + close(fence_fd); + return; + } + + draw->sync_fence = xcb_generate_id(draw->conn); + xcb_dri3_fence_from_fd(draw->conn, + draw->drawable, + draw->sync_fence, + false, + fence_fd); +} + /** loader_dri3_update_drawable * * Called the first time we use the drawable and then @@ -1063,6 +1103,8 @@ dri3_update_drawable(__DRIdrawable *driDrawable, draw->is_pixmap = true; xcb_unregister_for_special_event(draw->conn, draw->special_event); draw->special_event = NULL; + + dri3_attach_sync(draw); } } dri3_flush_present_events(draw); diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 1dd0e33..af5600f 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -150,6 +150,9 @@ struct loader_dri3_drawable { xcb_gcontext_t gc; xcb_special_event_t *special_event; + xcb_sync_fence_t sync_fence; + struct xshmfence *shm_fence; + bool first_init; struct loader_dri3_extensions *ext; -- 2.7.4