From efc82e7c703f9160cfdbe6d97e166ca6f5e75d86 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 10 Nov 2009 13:28:01 -0800 Subject: [PATCH] DRI2: add SwapInterval support Add support for the DRI2SwapInterval protocol request. This allows direct rendered clients to control their swap interval per the SGI_swap_control extension. Signed-off-by: Jesse Barnes --- src/glx/x11/dri2.c | 17 +++++++++++++++++ src/glx/x11/dri2.h | 3 +++ src/glx/x11/dri2_glx.c | 21 +++++++++++++++++++++ src/glx/x11/dri_common.c | 9 +++------ src/glx/x11/glxclient.h | 2 ++ src/glx/x11/glxcmds.c | 37 ++++++++++++++++++++++++++++++++++--- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c index 922edbdcf52..9ce633c40d4 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -537,4 +537,21 @@ Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, return True; } +void DRI2SwapInterval(Display *dpy, XID drawable, int interval) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2SwapIntervalReq *req; + + XextSimpleCheckExtension (dpy, info, dri2ExtensionName); + + LockDisplay(dpy); + GetReq(DRI2SwapInterval, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2SwapInterval; + req->drawable = drawable; + req->interval = interval; + UnlockDisplay(dpy); + SyncHandle(); +} + #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h index ae6030842cb..114e9f8f965 100644 --- a/src/glx/x11/dri2.h +++ b/src/glx/x11/dri2.h @@ -100,4 +100,7 @@ extern Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust, CARD64 *msc, CARD64 *sbc); +extern void +DRI2SwapInterval(Display *dpy, XID drawable, int interval); + #endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index 86bfe46a855..83149062f31 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -47,6 +47,7 @@ #include "xf86drm.h" #include "dri2.h" #include "dri_common.h" +#include "../../mesa/drivers/dri/common/dri_util.h" #undef DRI2_MINOR #define DRI2_MINOR 1 @@ -83,6 +84,7 @@ struct __GLXDRIdrawablePrivateRec int width, height; int have_back; int have_fake_front; + int swap_interval; }; static void dri2WaitX(__GLXDRIdrawable * pdraw); @@ -438,6 +440,23 @@ dri2GetBuffersWithFormat(__DRIdrawable * driDrawable, return pdraw->buffers; } +static void +dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval) +{ + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + + DRI2SwapInterval(priv->base.psc->dpy, pdraw->xDrawable, interval); + priv->swap_interval = interval; +} + +static unsigned int +dri2GetSwapInterval(__GLXDRIdrawable *pdraw) +{ + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + + return priv->swap_interval; +} + static const __DRIdri2LoaderExtension dri2LoaderExtension = { {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION}, dri2GetBuffers, @@ -559,6 +578,8 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen, psp->getDrawableMSC = dri2DrawableGetMSC; psp->waitForMSC = dri2WaitForMSC; psp->waitForSBC = dri2WaitForSBC; + psp->setSwapInterval = dri2SetSwapInterval; + psp->getSwapInterval = dri2GetSwapInterval; /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always * available.*/ diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c index a94c752194a..d1b77f308dd 100644 --- a/src/glx/x11/dri_common.c +++ b/src/glx/x11/dri_common.c @@ -390,12 +390,9 @@ dri2BindExtensions(__GLXscreenConfigs *psc) } #endif -#ifdef __DRI2_MEDIA_STREAM_COUNTER - if (strcmp(extensions[i]->name, __DRI2_MEDIA_STREAM_COUNTER) == 0) { - psc->msc = (__DRI2mediaStreamCounterExtension *) extensions[i]; - __glXEnableDirectExtension(psc, "GLX_SGI_video_sync"); - } -#endif + __glXEnableDirectExtension(psc, "GLX_SGI_video_sync"); + __glXEnableDirectExtension(psc, "GLX_SGI_swap_control"); + __glXEnableDirectExtension(psc, "GLX_MESA_swap_control"); #ifdef __DRI2_FLUSH if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) { diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 2b835a0a9ca..ded4f5a434a 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -148,6 +148,8 @@ struct __GLXDRIscreenRec { int64_t *msc, int64_t *sbc); int (*waitForSBC)(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); + void (*setSwapInterval)(__GLXDRIdrawable *pdraw, int interval); + int (*getSwapInterval)(__GLXDRIdrawable *pdraw); }; struct __GLXDRIcontextRec diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index c7ccaaa0b5f..fefdd99f559 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -1884,6 +1884,7 @@ __glXSwapIntervalSGI(int interval) { xGLXVendorPrivateReq *req; GLXContext gc = __glXGetCurrentContext(); + __GLXscreenConfigs *psc; Display *dpy; CARD32 *interval_ptr; CARD8 opcode; @@ -1912,6 +1913,16 @@ __glXSwapIntervalSGI(int interval) } } #endif + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + + if (gc->driContext && psc->driScreen && psc->driScreen->setSwapInterval) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, + NULL); + psc->driScreen->setSwapInterval(pdraw, interval); + return 0; + } + dpy = gc->currentDpy; opcode = __glXSetupForCommand(dpy); if (!opcode) { @@ -1943,13 +1954,13 @@ __glXSwapIntervalSGI(int interval) static int __glXSwapIntervalMESA(unsigned int interval) { -#ifdef __DRI_SWAP_CONTROL GLXContext gc = __glXGetCurrentContext(); if (interval < 0) { return GLX_BAD_VALUE; } +#ifdef __DRI_SWAP_CONTROL if (gc != NULL && gc->driContext) { __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy, gc->screen); @@ -1963,10 +1974,20 @@ __glXSwapIntervalMESA(unsigned int interval) } } } -#else - (void) interval; #endif + if (gc != NULL && gc->driContext) { + __GLXscreenConfigs *psc; + + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + if (psc->driScreen && psc->driScreen->setSwapInterval) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, NULL); + psc->driScreen->setSwapInterval(pdraw, interval); + return 0; + } + } + return GLX_BAD_CONTEXT; } @@ -1990,6 +2011,16 @@ __glXGetSwapIntervalMESA(void) } } #endif + if (gc != NULL && gc->driContext) { + __GLXscreenConfigs *psc; + + psc = GetGLXScreenConfigs( gc->currentDpy, gc->screen); + if (psc->driScreen && psc->driScreen->getSwapInterval) { + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy, + gc->currentDrawable, NULL); + return psc->driScreen->getSwapInterval(pdraw); + } + } return 0; } -- 2.30.2