get_msc_cookie = xcb_dri2_get_msc_unchecked(c, pdraw->xDrawable);
get_msc_reply = xcb_dri2_get_msc_reply(c, get_msc_cookie, NULL);
+
+ if (!get_msc_reply)
+ return 0;
+
*ust = merge_counter(get_msc_reply->ust_hi, get_msc_reply->ust_lo);
*msc = merge_counter(get_msc_reply->msc_hi, get_msc_reply->msc_lo);
*sbc = merge_counter(get_msc_reply->sbc_hi, get_msc_reply->sbc_lo);
free(get_msc_reply);
- return 0;
+ return 1;
}
static int
divisor_hi, divisor_lo,
remainder_hi, remainder_lo);
wait_msc_reply = xcb_dri2_wait_msc_reply(c, wait_msc_cookie, NULL);
+
+ if (!wait_msc_reply)
+ return 0;
+
*ust = merge_counter(wait_msc_reply->ust_hi, wait_msc_reply->ust_lo);
*msc = merge_counter(wait_msc_reply->msc_hi, wait_msc_reply->msc_lo);
*sbc = merge_counter(wait_msc_reply->sbc_hi, wait_msc_reply->sbc_lo);
free(wait_msc_reply);
- return 0;
+ return 1;
}
static int
wait_sbc_cookie = xcb_dri2_wait_sbc_unchecked(c, pdraw->xDrawable,
target_sbc_hi, target_sbc_lo);
wait_sbc_reply = xcb_dri2_wait_sbc_reply(c, wait_sbc_cookie, NULL);
+
+ if (!wait_sbc_reply)
+ return 0;
+
*ust = merge_counter(wait_sbc_reply->ust_hi, wait_sbc_reply->ust_lo);
*msc = merge_counter(wait_sbc_reply->msc_hi, wait_sbc_reply->msc_lo);
*sbc = merge_counter(wait_sbc_reply->sbc_hi, wait_sbc_reply->sbc_lo);
free(wait_sbc_reply);
- return 0;
+ return 1;
}
/**
static void
__dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
int width, int height,
- enum __DRI2throttleReason reason)
+ enum __DRI2throttleReason reason, Bool flush)
{
struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
struct dri2_screen *psc = (struct dri2_screen *) pdraw->psc;
xrect.width = width;
xrect.height = height;
+ if (flush) {
+ glFlush();
+ }
+
if (psc->f)
(*psc->f->flush) (priv->driDrawable);
static void
dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y,
- int width, int height)
+ int width, int height, Bool flush)
{
__dri2CopySubBuffer(pdraw, x, y, width, height,
- __DRI2_THROTTLE_COPYSUBBUFFER);
+ __DRI2_THROTTLE_COPYSUBBUFFER, flush);
}
static int64_t
dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
- int64_t remainder)
+ int64_t remainder, Bool flush)
{
struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
struct glx_display *dpyPriv = __glXInitialize(priv->base.psc->dpy);
/* Old servers can't handle swapbuffers */
if (!pdp->swapAvailable) {
__dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height,
- __DRI2_THROTTLE_SWAPBUFFER);
+ __DRI2_THROTTLE_SWAPBUFFER, flush);
} else {
-#ifdef X_DRI2SwapBuffers
- if (psc->f) {
- struct glx_context *gc = __glXGetCurrentContext();
+ xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy);
+ xcb_dri2_swap_buffers_cookie_t swap_buffers_cookie;
+ xcb_dri2_swap_buffers_reply_t *swap_buffers_reply;
+ uint32_t target_msc_hi, target_msc_lo;
+ uint32_t divisor_hi, divisor_lo;
+ uint32_t remainder_hi, remainder_lo;
+
+ if (flush) {
+ glFlush();
+ }
+
+ if (psc->f) {
+ struct glx_context *gc = __glXGetCurrentContext();
- if (gc) {
- (*psc->f->flush)(priv->driDrawable);
+ if (gc) {
+ (*psc->f->flush)(priv->driDrawable);
+ }
}
- }
dri2Throttle(psc, priv, __DRI2_THROTTLE_SWAPBUFFER);
- DRI2SwapBuffers(psc->base.dpy, pdraw->xDrawable,
- target_msc, divisor, remainder, &ret);
-#endif
+ split_counter(target_msc, &target_msc_hi, &target_msc_lo);
+ split_counter(divisor, &divisor_hi, &divisor_lo);
+ split_counter(remainder, &remainder_hi, &remainder_lo);
+
+ swap_buffers_cookie =
+ xcb_dri2_swap_buffers_unchecked(c, pdraw->xDrawable,
+ target_msc_hi, target_msc_lo,
+ divisor_hi, divisor_lo,
+ remainder_hi, remainder_lo);
+ /* Immediately wait on the swapbuffers reply. If we didn't, we'd have
+ * to do so some time before reusing a (non-pageflipped) backbuffer.
+ * Otherwise, the new rendering could get ahead of the X Server's
+ * dispatch of the swapbuffer and you'd display garbage.
+ *
+ * We use XSync() first to reap the invalidate events through the event
+ * filter, to ensure that the next drawing doesn't use an invalidated
+ * buffer.
+ */
+ XSync(pdraw->psc->dpy, False);
+ swap_buffers_reply =
+ xcb_dri2_swap_buffers_reply(c, swap_buffers_cookie, NULL);
+ ret = merge_counter(swap_buffers_reply->swap_hi,
+ swap_buffers_reply->swap_lo);
+ free(swap_buffers_reply);
}
if (psc->show_fps) {
return pdraw->buffers;
}
-#ifdef X_DRI2SwapInterval
-
static int
dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
{
+ xcb_connection_t *c = XGetXCBConnection(pdraw->psc->dpy);
struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
GLint vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1;
struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
break;
}
- DRI2SwapInterval(priv->base.psc->dpy, priv->base.xDrawable, interval);
+ xcb_dri2_swap_interval(c, priv->base.xDrawable, interval);
priv->swap_interval = interval;
return 0;
return priv->swap_interval;
}
-#endif /* X_DRI2SwapInterval */
-
static const __DRIdri2LoaderExtension dri2LoaderExtension = {
{__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
dri2GetBuffers,
__glXEnableDirectExtension(&psc->base, "GLX_SGI_make_current_read");
/* FIXME: if DRI2 version supports it... */
- __glXEnableDirectExtension(&psc->base, "INTEL_swap_event");
+ __glXEnableDirectExtension(&psc->base, "GLX_INTEL_swap_event");
if (psc->dri2->base.version >= 3) {
const unsigned mask = psc->dri2->getAPIMask(psc->driScreen);
psp->getDrawableMSC = dri2DrawableGetMSC;
psp->waitForMSC = dri2WaitForMSC;
psp->waitForSBC = dri2WaitForSBC;
-#ifdef X_DRI2SwapInterval
psp->setSwapInterval = dri2SetSwapInterval;
psp->getSwapInterval = dri2GetSwapInterval;
-#endif
__glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
}