diff options
Diffstat (limited to 'src/loader')
-rw-r--r-- | src/loader/loader_dri3_helper.c | 48 | ||||
-rw-r--r-- | src/loader/loader_dri3_helper.h | 2 |
2 files changed, 49 insertions, 1 deletions
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 7cd6b1e8ab6..5c48da93e6a 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -101,6 +101,32 @@ get_xcb_visualtype_for_depth(struct loader_dri3_drawable *draw, int depth) return NULL; } +/* Sets the adaptive sync window property state. */ +static void +set_adaptive_sync_property(xcb_connection_t *conn, xcb_drawable_t drawable, + uint32_t state) +{ + static char const name[] = "_VARIABLE_REFRESH"; + xcb_intern_atom_cookie_t cookie; + xcb_intern_atom_reply_t* reply; + xcb_void_cookie_t check; + + cookie = xcb_intern_atom(conn, 0, sizeof(name), name); + reply = xcb_intern_atom_reply(conn, cookie, NULL); + if (reply == NULL) + return; + + if (state) + check = xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE, + drawable, reply->atom, + XCB_ATOM_CARDINAL, 32, 1, &state); + else + check = xcb_delete_property_checked(conn, drawable, reply->atom); + + xcb_discard_reply(conn, check.sequence); + free(reply); +} + /* Get red channel mask for given drawable at given depth. */ static unsigned int dri3_get_red_mask_for_depth(struct loader_dri3_drawable *draw, int depth) @@ -331,16 +357,30 @@ loader_dri3_drawable_init(xcb_connection_t *conn, draw->have_back = 0; draw->have_fake_front = 0; draw->first_init = true; + draw->adaptive_sync = false; + draw->adaptive_sync_active = false; draw->cur_blit_source = -1; draw->back_format = __DRI_IMAGE_FORMAT_NONE; mtx_init(&draw->mtx, mtx_plain); cnd_init(&draw->event_cnd); - if (draw->ext->config) + if (draw->ext->config) { + unsigned char adaptive_sync; + draw->ext->config->configQueryi(draw->dri_screen, "vblank_mode", &vblank_mode); + draw->ext->config->configQueryb(draw->dri_screen, + "adaptive_sync", + &adaptive_sync); + + draw->adaptive_sync = adaptive_sync; + } + + if (!draw->adaptive_sync) + set_adaptive_sync_property(conn, draw->drawable, false); + switch (vblank_mode) { case DRI_CONF_VBLANK_NEVER: case DRI_CONF_VBLANK_DEF_INTERVAL_0: @@ -879,6 +919,12 @@ loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw, back = dri3_find_back_alloc(draw); mtx_lock(&draw->mtx); + + if (draw->adaptive_sync && !draw->adaptive_sync_active) { + set_adaptive_sync_property(draw->conn, draw->drawable, true); + draw->adaptive_sync_active = true; + } + if (draw->is_different_gpu && back) { /* Update the linear buffer before presenting the pixmap */ (void) loader_dri3_blit_image(draw, diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 0d181813126..663ce3c0e2f 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -156,6 +156,8 @@ struct loader_dri3_drawable { xcb_special_event_t *special_event; bool first_init; + bool adaptive_sync; + bool adaptive_sync_active; int swap_interval; struct loader_dri3_extensions *ext; |