static int64_t dri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, int64_t msc, int64_t divisor, int64_t remainder) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); uint32_t msc_hi = msc >> 32; uint32_t msc_lo = msc & 0xffffffff; uint32_t divisor_hi = divisor >> 32; uint32_t divisor_lo = divisor & 0xffffffff; uint32_t remainder_hi = remainder >> 32; uint32_t remainder_lo = remainder & 0xffffffff; xcb_dri2_swap_buffers_cookie_t cookie; xcb_dri2_swap_buffers_reply_t *reply; int64_t swap_count = -1; /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) return 0; if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available) return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1; if (dri2_dpy->flush) (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable, msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo); reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL); if (reply) { swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo; free(reply); } /* Since we aren't watching for the server's invalidate events like we're * supposed to (due to XCB providing no mechanism for filtering the events * the way xlib does), and SwapBuffers is a common cause of invalidate * events, just shove one down to the driver, even though we haven't told * the driver that we're the kind of loader that provides reliable * invalidate events. This causes the driver to request buffers again at * its next draw, so that we get the correct buffers if a pageflip * happened. The driver should still be using the viewport hack to catch * window resizes. */ if (dri2_dpy->flush && dri2_dpy->flush->base.version >= 3 && dri2_dpy->flush->invalidate) (*dri2_dpy->flush->invalidate)(dri2_surf->dri_drawable); return swap_count; }
static void vl_dri2_screen_destroy(struct vl_screen *vscreen) { struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen; assert(vscreen); if (scrn->flushed) { free(xcb_dri2_swap_buffers_reply(scrn->conn, scrn->swap_cookie, NULL)); free(xcb_dri2_wait_sbc_reply(scrn->conn, scrn->wait_cookie, NULL)); free(xcb_dri2_get_buffers_reply(scrn->conn, scrn->buffers_cookie, NULL)); } vl_dri2_destroy_drawable(scrn); scrn->base.pscreen->destroy(scrn->base.pscreen); pipe_loader_release(&scrn->base.dev, 1); /* There is no user provided fd */ FREE(scrn); }
static int64_t dri2_swap_buffers_msc(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, int64_t msc, int64_t divisor, int64_t remainder) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw); uint32_t msc_hi = msc >> 32; uint32_t msc_lo = msc & 0xffffffff; uint32_t divisor_hi = divisor >> 32; uint32_t divisor_lo = divisor & 0xffffffff; uint32_t remainder_hi = remainder >> 32; uint32_t remainder_lo = remainder & 0xffffffff; xcb_dri2_swap_buffers_cookie_t cookie; xcb_dri2_swap_buffers_reply_t *reply; int64_t swap_count = -1; /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) return 0; if (draw->SwapBehavior == EGL_BUFFER_PRESERVED || !dri2_dpy->swap_available) return dri2_copy_region(drv, disp, draw, dri2_surf->region) ? 0 : -1; if (dri2_dpy->flush) (*dri2_dpy->flush->flush)(dri2_surf->dri_drawable); cookie = xcb_dri2_swap_buffers_unchecked(dri2_dpy->conn, dri2_surf->drawable, msc_hi, msc_lo, divisor_hi, divisor_lo, remainder_hi, remainder_lo); reply = xcb_dri2_swap_buffers_reply(dri2_dpy->conn, cookie, NULL); if (reply) { swap_count = (((int64_t)reply->swap_hi) << 32) | reply->swap_lo; free(reply); } return swap_count; }
static xcb_dri2_get_buffers_reply_t * vl_dri2_get_flush_reply(struct vl_dri_screen *scrn) { xcb_dri2_wait_sbc_reply_t *wait_sbc_reply; assert(scrn); if (!scrn->flushed) return NULL; scrn->flushed = false; free(xcb_dri2_swap_buffers_reply(scrn->conn, scrn->swap_cookie, NULL)); wait_sbc_reply = xcb_dri2_wait_sbc_reply(scrn->conn, scrn->wait_cookie, NULL); if (!wait_sbc_reply) return NULL; vl_dri2_handle_stamps(scrn, wait_sbc_reply->ust_hi, wait_sbc_reply->ust_lo, wait_sbc_reply->msc_hi, wait_sbc_reply->msc_lo); free(wait_sbc_reply); return xcb_dri2_get_buffers_reply(scrn->conn, scrn->buffers_cookie, NULL); }