aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <[email protected]>2009-07-17 03:30:29 -0400
committerJesse Barnes <[email protected]>2010-01-08 12:29:50 -0500
commita35f6bb207efe3c959bbd16a37f2049e5aceeea9 (patch)
tree63229cca1d391ccfc284a3f72852e09240f97c66
parent1baaf111c8c42ed7f7218c46038f32eb51b9c6eb (diff)
DRI2: add SwapBuffers support
Support the new DRI2 protocol request, DRI2SwapBuffers, in both direct and indirect rendering context. This request allows the display server to optimize back->front swaps (e.g. through page flipping) and allows us to more easily support other GLX features like swap interval and the OML sync extension in DRI2. Signed-off-by: Jesse Barnes <[email protected]>
-rw-r--r--configure.ac2
-rw-r--r--include/GL/internal/dri_interface.h14
-rw-r--r--src/glx/x11/dri2.c16
-rw-r--r--src/glx/x11/dri2.h3
-rw-r--r--src/glx/x11/dri2_glx.c32
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c1
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h2
7 files changed, 67 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index b2a969bc8c9..fd300504bf7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@ AC_CANONICAL_HOST
dnl Versions for external dependencies
LIBDRM_REQUIRED=2.4.15
LIBDRM_RADEON_REQUIRED=2.4.17
-DRI2PROTO_REQUIRED=1.99.3
+DRI2PROTO_REQUIRED=2.2
dnl Check for progs
AC_PROG_CPP
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 910c9166b5e..ec6238f8734 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -262,10 +262,22 @@ struct __DRItexBufferExtensionRec {
* Used by drivers that implement DRI2
*/
#define __DRI2_FLUSH "DRI2_Flush"
-#define __DRI2_FLUSH_VERSION 1
+#define __DRI2_FLUSH_VERSION 2
struct __DRI2flushExtensionRec {
__DRIextension base;
void (*flush)(__DRIdrawable *drawable);
+
+ /**
+ * Flush all rendering queue in the driver to the drm and
+ * invalidate all buffers. The driver will call out to
+ * getBuffers/getBuffersWithFormat before it starts rendering
+ * again.
+ *
+ * \param drawable the drawable to flush and invalidate
+ *
+ * \since 2
+ */
+ void (*flushInvalidate)(__DRIdrawable *drawable);
};
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index dad04470a00..a0f8901d42d 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -380,4 +380,20 @@ DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
SyncHandle();
}
+void DRI2SwapBuffers(Display *dpy, XID drawable)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2SwapBuffersReq *req;
+
+ XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+ LockDisplay(dpy);
+ GetReq(DRI2SwapBuffers, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2SwapBuffers;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h
index a6fe66e136d..ba6eff5e4f7 100644
--- a/src/glx/x11/dri2.h
+++ b/src/glx/x11/dri2.h
@@ -85,4 +85,7 @@ DRI2CopyRegion(Display * dpy, XID drawable,
XserverRegion region,
CARD32 dest, CARD32 src);
+extern void
+DRI2SwapBuffers(Display *dpy, XID drawable);
+
#endif
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index 89efe3ab292..114cad2ae7d 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -35,6 +35,7 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/Xdamage.h>
+#include "glapi.h"
#include "glxclient.h"
#include "glcontextmodes.h"
#include "xf86dri.h"
@@ -64,6 +65,7 @@ struct __GLXDRIdisplayPrivateRec
int driMajor;
int driMinor;
int driPatch;
+ int swapAvailable;
};
struct __GLXDRIcontextPrivateRec
@@ -240,7 +242,7 @@ dri2SwapBuffers(__GLXDRIdrawable * pdraw)
}
static void
-dri2WaitX(__GLXDRIdrawable * pdraw)
+dri2WaitX(__GLXDRIdrawable *pdraw)
{
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
XRectangle xrect;
@@ -342,6 +344,31 @@ process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers,
}
+static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
+{
+ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+ __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv->base.psc->dpy);
+ __GLXDRIdisplayPrivate *pdp =
+ (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
+ __GLXscreenConfigs *psc = pdraw->psc;
+
+#ifdef __DRI2_FLUSH
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
+ /* Old servers can't handle swapbuffers */
+ if (!pdp->swapAvailable)
+ return dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+
+ DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable);
+
+#if __DRI2_FLUSH_VERSION >= 2
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
+#endif
+}
+
static __DRIbuffer *
dri2GetBuffers(__DRIdrawable * driDrawable,
int *width, int *height,
@@ -559,6 +586,9 @@ dri2CreateDisplay(Display * dpy)
}
pdp->driPatch = 0;
+ pdp->swapAvailable = 0;
+ if (pdp->driMinor >= 2)
+ pdp->swapAvailable = 1;
pdp->base.destroyDisplay = dri2DestroyDisplay;
pdp->base.createScreen = dri2CreateScreen;
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 547f18a009e..cd271ede091 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -454,6 +454,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
pdp->driScreenPriv = psp;
pdp->driContextPriv = &psp->dummyContextPriv;
+ pdp->validBuffers = GL_FALSE;
if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
renderType == GLX_PIXMAP_BIT)) {
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index c95a5c8299a..c3046d6b186 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -380,6 +380,8 @@ struct __DRIdrawableRec {
* GLX_MESA_swap_control.
*/
unsigned int swap_interval;
+
+ GLboolean validBuffers;
};
/**