Use one global XSync fence
And only sync once per frame. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
40
src/x.c
40
src/x.c
@ -454,46 +454,36 @@ bool x_atom_is_background_prop(session_t *ps, xcb_atom_t atom) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a XSync fence.
|
||||
*/
|
||||
static inline void
|
||||
x_free_fence(session_t *ps, xcb_sync_fence_t *pfence) {
|
||||
if (*pfence) {
|
||||
xcb_sync_destroy_fence(ps->c, *pfence);
|
||||
}
|
||||
*pfence = XCB_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronizes a X Render drawable to ensure all pending painting requests
|
||||
* are completed.
|
||||
*/
|
||||
void x_fence_sync(session_t *ps, xcb_drawable_t d) {
|
||||
x_sync(ps->c);
|
||||
bool x_fence_sync(session_t *ps, xcb_sync_fence_t f) {
|
||||
if (ps->xsync_exists) {
|
||||
// TODO(richardgv): If everybody just follows the rules stated in X Sync
|
||||
// prototype, we need only one fence per screen, but let's stay a bit
|
||||
// cautious right now
|
||||
xcb_sync_fence_t tmp_fence = xcb_generate_id(ps->c);
|
||||
xcb_generic_error_t *e =
|
||||
xcb_request_check(ps->c,
|
||||
xcb_sync_create_fence(ps->c, d, tmp_fence, 0));
|
||||
|
||||
auto e = xcb_request_check(ps->c, xcb_sync_trigger_fence_checked(ps->c, f));
|
||||
if (e) {
|
||||
log_error("Failed to create a XSync fence for %#010x", d);
|
||||
log_error("Failed to trigger the fence.");
|
||||
free(e);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
e = xcb_request_check(ps->c, xcb_sync_trigger_fence(ps->c, tmp_fence));
|
||||
e = xcb_request_check(ps->c, xcb_sync_await_fence_checked(ps->c, 1, &f));
|
||||
if (e) {
|
||||
log_error("Failed to trigger the fence");
|
||||
log_error("Failed to await on a fence.");
|
||||
free(e);
|
||||
x_free_fence(ps, &tmp_fence);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
xcb_sync_await_fence(ps->c, 1, &tmp_fence);
|
||||
x_free_fence(ps, &tmp_fence);
|
||||
e = xcb_request_check(ps->c, xcb_sync_reset_fence_checked(ps->c, f));
|
||||
if (e) {
|
||||
log_error("Failed to reset the fence.");
|
||||
free(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user