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 <jbarnes@virtuousgeek.org>
This commit is contained in:
Jesse Barnes
2009-11-10 13:28:01 -08:00
committed by Jesse Barnes
parent daf7fe69f7
commit efc82e7c70
6 changed files with 80 additions and 9 deletions

View File

@@ -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 */

View File

@@ -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

View File

@@ -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.*/

View File

@@ -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)) {

View File

@@ -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

View File

@@ -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;
}