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 <jbarnes@virtuousgeek.org>tags/7.8-rc1
| @@ -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 | |||
| @@ -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); | |||
| }; | |||
| @@ -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 */ | |||
| @@ -85,4 +85,7 @@ DRI2CopyRegion(Display * dpy, XID drawable, | |||
| XserverRegion region, | |||
| CARD32 dest, CARD32 src); | |||
| extern void | |||
| DRI2SwapBuffers(Display *dpy, XID drawable); | |||
| #endif | |||
| @@ -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; | |||
| @@ -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)) { | |||
| @@ -380,6 +380,8 @@ struct __DRIdrawableRec { | |||
| * GLX_MESA_swap_control. | |||
| */ | |||
| unsigned int swap_interval; | |||
| GLboolean validBuffers; | |||
| }; | |||
| /** | |||