summaryrefslogtreecommitdiff
path: root/glx/glxdri2.c
diff options
context:
space:
mode:
Diffstat (limited to 'glx/glxdri2.c')
-rw-r--r--glx/glxdri2.c61
1 files changed, 50 insertions, 11 deletions
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index ed7dc80ba..58e4684fe 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -70,6 +70,7 @@ struct __GLXDRIscreen {
const __DRIcoreExtension *core;
const __DRIdri2Extension *dri2;
+ const __DRI2flushExtension *flush;
const __DRIcopySubBufferExtension *copySubBuffer;
const __DRIswapControlExtension *swapControl;
const __DRItexBufferExtension *texBuffer;
@@ -132,17 +133,6 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
}
-static GLboolean
-__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable)
-{
- __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
-
- __glXDRIdrawableCopySubBuffer(drawable, 0, 0,
- private->width, private->height);
-
- return TRUE;
-}
-
static void
__glXDRIdrawableWaitX(__GLXdrawable *drawable)
{
@@ -177,9 +167,37 @@ __glXDRIdrawableWaitGL(__GLXdrawable *drawable)
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
}
+/*
+ * Copy or flip back to front, honoring the swap interval if possible.
+ *
+ * If the kernel supports it, we request an event for the frame when the
+ * swap should happen, then perform the copy when we receive it.
+ */
+static GLboolean
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable;
+ __GLXDRIscreen *screen = priv->screen;
+ CARD64 unused;
+
+ if (screen->flush)
+ (*screen->flush->flushInvalidate)(priv->driDrawable);
+
+ if (DRI2SwapBuffers(client, drawable->pDraw, 0, 0, 0, &unused,
+ NULL, drawable->pDraw) != Success)
+ return FALSE;
+
+ return TRUE;
+}
+
static int
__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval)
{
+ if (interval <= 0) /* || interval > BIGNUM? */
+ return GLX_BAD_VALUE;
+
+ DRI2SwapInterval(drawable->pDraw, interval);
+
return 0;
}
@@ -241,6 +259,18 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext)
read->driDrawable);
}
+static Bool
+__glXDRIcontextWait(__GLXcontext *baseContext,
+ __GLXclientState *cl, int *error)
+{
+ if (DRI2WaitSwap(cl->client, baseContext->drawPriv->pDraw)) {
+ *error = cl->client->noClientException;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
#ifdef __DRI_TEX_BUFFER
static int
@@ -346,6 +376,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen,
context->base.copy = __glXDRIcontextCopy;
context->base.forceCurrent = __glXDRIcontextForceCurrent;
context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+ context->base.wait = __glXDRIcontextWait;
context->driContext =
(*screen->dri2->createNewContext)(screen->driScreen,
@@ -581,6 +612,14 @@ initializeExtensions(__GLXDRIscreen *screen)
LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n");
}
#endif
+
+#ifdef __DRI2_FLUSH
+ if (strcmp(extensions[i]->name, __DRI2_FLUSH) == 0 &&
+ extensions[i]->version >= __DRI2_FLUSH_VERSION) {
+ screen->flush = (__DRI2flushExtension *) extensions[i];
+ }
+#endif
+
/* Ignore unknown extensions */
}
}