int driMinor;
int driPatch;
int swapAvailable;
+ int invalidateAvailable;
};
struct __GLXDRIcontextPrivateRec
{
__GLXDRIdrawablePrivate *pdraw;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+ __GLXdisplayPrivate *dpyPriv;
+ __GLXDRIdisplayPrivate *pdp;
pdraw = Xmalloc(sizeof(*pdraw));
if (!pdraw)
pdraw->base.drawable = drawable;
pdraw->base.psc = psc;
pdraw->bufferCount = 0;
+ pdraw->swap_interval = 1;
DRI2CreateDrawable(psc->dpy, xDrawable);
+ dpyPriv = __glXInitialize(psc->dpy);
+ pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;;
/* Create a new drawable */
pdraw->base.driDrawable =
(*psc->dri2->createNewDrawable) (psc->__driScreen,
return NULL;
}
+ /*
+ * Make sure server has the same swap interval we do for the new
+ * drawable.
+ */
+ if (pdp->swapAvailable)
+ DRI2SwapInterval(psc->dpy, xDrawable, pdraw->swap_interval);
+
return &pdraw->base;
}
+#ifdef X_DRI2GetMSC
+
static int
dri2DrawableGetMSC(__GLXscreenConfigs *psc, __GLXDRIdrawable *pdraw,
int64_t *ust, int64_t *msc, int64_t *sbc)
return DRI2GetMSC(psc->dpy, pdraw->xDrawable, ust, msc, sbc);
}
+#endif
+
+
+#ifdef X_DRI2WaitMSC
+
static int
dri2WaitForMSC(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc)
sbc);
}
+#endif /* X_DRI2WaitMSC */
+
static void
dri2CopySubBuffer(__GLXDRIdrawable *pdraw, int x, int y, int width, int height)
{
XFixesDestroyRegion(pdraw->psc->dpy, region);
}
-
static void
-dri2FlushFrontBuffer(__DRIdrawable * driDrawable, void *loaderPrivate)
+dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
{
- (void) driDrawable;
- dri2WaitGL((__GLXDRIdrawable *) loaderPrivate);
+ __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy);
+ __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->dri2Display;
+
+ /* Old servers don't send invalidate events */
+ if (!pdp->invalidateAvailable)
+ dri2InvalidateBuffers(priv->dpy, pdraw->base.drawable);
+
+ dri2WaitGL(loaderPrivate);
}
(*pdraw->psc->f->flush)(pdraw->driDrawable);
#endif
+ /* Old servers don't send invalidate events */
+ if (!pdp->invalidateAvailable)
+ dri2InvalidateBuffers(dpyPriv->dpy, pdraw->drawable);
+
/* Old servers can't handle swapbuffers */
if (!pdp->swapAvailable) {
dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
remainder, &ret);
#endif
-#if __DRI2_FLUSH_VERSION >= 2
- if (pdraw->psc->f)
- (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable);
-#endif
-
return ret;
}
return pdraw->buffers;
}
+#ifdef X_DRI2SwapInterval
+
static void
dri2SetSwapInterval(__GLXDRIdrawable *pdraw, int interval)
{
return priv->swap_interval;
}
+#endif /* X_DRI2SwapInterval */
+
static const __DRIdri2LoaderExtension dri2LoaderExtension = {
{__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
dri2GetBuffers,
NULL
};
+_X_HIDDEN void
+dri2InvalidateBuffers(Display *dpy, XID drawable)
+{
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+
+#if __DRI2_FLUSH_VERSION >= 3
+ if (pdraw && pdraw->psc->f)
+ pdraw->psc->f->invalidate(pdraw->driDrawable);
+#endif
+}
+
static __GLXDRIscreen *
dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
__GLXdisplayPrivate * priv)
if (psp == NULL)
return NULL;
- /* Initialize per screen dynamic client GLX extensions */
- psc->ext_list_first_time = GL_TRUE;
-
if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
&driverName, &deviceName)) {
XFree(psp);
#ifdef X_DRI2SwapInterval
psp->setSwapInterval = dri2SetSwapInterval;
psp->getSwapInterval = dri2GetSwapInterval;
+#endif
+#if defined(X_DRI2GetMSC) && defined(X_DRI2WaitMSC) && defined(X_DRI2SwapInterval)
+ __glXEnableDirectExtension(psc, "GLX_OML_sync_control");
#endif
}
}
pdp->driPatch = 0;
- pdp->swapAvailable = 0;
-#ifdef X_DRI2SwapBuffers
- if (pdp->driMinor >= 2)
- pdp->swapAvailable = 1;
-#endif
+ pdp->swapAvailable = (pdp->driMinor >= 2);
+ pdp->invalidateAvailable = (pdp->driMinor >= 3);
pdp->base.destroyDisplay = dri2DestroyDisplay;
pdp->base.createScreen = dri2CreateScreen;