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 <jbarnes@virtuousgeek.org>tags/7.8-rc1
| @@ -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 */ | |||
| @@ -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 | |||
| @@ -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.*/ | |||
| @@ -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)) { | |||
| @@ -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 | |||
| @@ -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; | |||
| } | |||