glx/dri2: Require DRI2 >= 1.3 for working buffer invalidation

Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10808>
This commit is contained in:
Adam Jackson 2021-06-02 14:39:33 -04:00 committed by Marge Bot
parent dc73de630e
commit 4d0179af32
1 changed files with 24 additions and 83 deletions

View File

@ -69,8 +69,6 @@ struct dri2_display
int driMajor;
int driMinor;
int driPatch;
int swapAvailable;
int invalidateAvailable;
__glxHashTable *dri2Hash;
@ -133,8 +131,6 @@ dri2_bind_context(struct glx_context *context, struct glx_context *old,
struct dri2_screen *psc = (struct dri2_screen *) pcp->base.psc;
struct dri2_drawable *pdraw, *pread;
__DRIdrawable *dri_draw = NULL, *dri_read = NULL;
struct glx_display *dpyPriv = psc->base.display;
struct dri2_display *pdp;
pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw);
pread = (struct dri2_drawable *) driFetchDrawable(context, read);
@ -154,16 +150,6 @@ dri2_bind_context(struct glx_context *context, struct glx_context *old,
if (!(*psc->core->bindContext) (pcp->driContext, dri_draw, dri_read))
return GLXBadContext;
/* If the server doesn't send invalidate events, we may miss a
* resize before the rendering starts. Invalidate the buffers now
* so the driver will recheck before rendering starts. */
pdp = (struct dri2_display *) dpyPriv->dri2Display;
if (!pdp->invalidateAvailable && pdraw) {
dri2InvalidateBuffers(psc->base.dpy, pdraw->base.xDrawable);
if (pread != pdraw && pread)
dri2InvalidateBuffers(psc->base.dpy, pread->base.xDrawable);
}
return Success;
}
@ -623,7 +609,6 @@ static void
dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
{
struct glx_display *priv;
struct dri2_display *pdp;
struct glx_context *gc;
struct dri2_drawable *pdraw = loaderPrivate;
struct dri2_screen *psc;
@ -641,15 +626,10 @@ dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate)
if (priv == NULL)
return;
pdp = (struct dri2_display *) priv->dri2Display;
gc = __glXGetCurrentContext();
dri2Throttle(psc, pdraw, __DRI2_THROTTLE_FLUSHFRONT);
/* Old servers don't send invalidate events */
if (!pdp->invalidateAvailable)
dri2InvalidateBuffers(priv->dpy, pdraw->base.xDrawable);
dri2_wait_gl(gc);
}
@ -783,39 +763,26 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
int64_t remainder, Bool flush)
{
struct dri2_drawable *priv = (struct dri2_drawable *) pdraw;
struct glx_display *dpyPriv = __glXInitialize(priv->base.psc->dpy);
struct dri2_screen *psc = (struct dri2_screen *) priv->base.psc;
struct dri2_display *pdp =
(struct dri2_display *)dpyPriv->dri2Display;
int64_t ret = 0;
/* Check we have the right attachments */
if (!priv->have_back)
return ret;
/* Old servers can't handle swapbuffers */
if (!pdp->swapAvailable) {
__dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height,
__DRI2_THROTTLE_SWAPBUFFER, flush);
} else {
__DRIcontext *ctx = dri2GetCurrentContext();
unsigned flags = __DRI2_FLUSH_DRAWABLE;
if (flush)
flags |= __DRI2_FLUSH_CONTEXT;
dri2Flush(psc, ctx, priv, flags, __DRI2_THROTTLE_SWAPBUFFER);
__DRIcontext *ctx = dri2GetCurrentContext();
unsigned flags = __DRI2_FLUSH_DRAWABLE;
if (flush)
flags |= __DRI2_FLUSH_CONTEXT;
dri2Flush(psc, ctx, priv, flags, __DRI2_THROTTLE_SWAPBUFFER);
ret = dri2XcbSwapBuffers(pdraw->psc->dpy, pdraw,
target_msc, divisor, remainder);
}
ret = dri2XcbSwapBuffers(pdraw->psc->dpy, pdraw,
target_msc, divisor, remainder);
if (psc->show_fps_interval) {
show_fps(priv);
}
/* Old servers don't send invalidate events */
if (!pdp->invalidateAvailable)
dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable);
return ret;
}
@ -933,14 +900,6 @@ static const __DRIdri2LoaderExtension dri2LoaderExtension = {
.getBuffersWithFormat = dri2GetBuffersWithFormat,
};
static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
.base = { __DRI_DRI2_LOADER, 3 },
.getBuffers = dri2GetBuffers,
.flushFrontBuffer = dri2FlushFrontBuffer,
.getBuffersWithFormat = NULL,
};
const __DRIuseInvalidateExtension dri2UseInvalidate = {
.base = { __DRI_USE_INVALIDATE, 1 }
};
@ -975,20 +934,12 @@ dri2_bind_tex_image(__GLXDRIdrawable *base,
{
struct glx_context *gc = __glXGetCurrentContext();
struct dri2_context *pcp = (struct dri2_context *) gc;
struct glx_display *dpyPriv = __glXInitialize(gc->currentDpy);
struct dri2_drawable *pdraw = (struct dri2_drawable *) base;
struct dri2_display *pdp;
struct dri2_screen *psc;
pdp = (struct dri2_display *) dpyPriv->dri2Display;
if (pdraw != NULL) {
psc = (struct dri2_screen *) base->psc;
if (!pdp->invalidateAvailable && psc->f &&
psc->f->base.version >= 3 && psc->f->invalidate)
psc->f->invalidate(pdraw->driDrawable);
if (psc->texBuffer->base.version >= 2 &&
psc->texBuffer->setTexBuffer2 != NULL) {
(*psc->texBuffer->setTexBuffer2) (pcp->driContext,
@ -1038,8 +989,6 @@ static void
dri2BindExtensions(struct dri2_screen *psc, struct glx_display * priv,
const char *driverName)
{
const struct dri2_display *const pdp = (struct dri2_display *)
priv->dri2Display;
const unsigned mask = psc->dri2->getAPIMask(psc->driScreen);
const __DRIextension **extensions;
int i;
@ -1057,14 +1006,12 @@ dri2BindExtensions(struct dri2_screen *psc, struct glx_display * priv,
* systems running on drivers which don't support that extension.
* There's no way to test for its presence on this side, so instead
* of disabling it unconditionally, just disable it for drivers
* which are known to not support it, or for DDX drivers supporting
* only an older (pre-ScheduleSwap) version of DRI2.
* which are known to not support it.
*
* This is a hack which is required until:
* http://lists.x.org/archives/xorg-devel/2013-February/035449.html
* is merged and updated xserver makes it's way into distros:
* This was fixed in xserver 1.15.0 (190b03215), so now we only
* disable the broken driver.
*/
if (pdp->swapAvailable && strcmp(driverName, "vmwgfx") != 0) {
if (strcmp(driverName, "vmwgfx") != 0) {
__glXEnableDirectExtension(&psc->base, "GLX_INTEL_swap_event");
}
@ -1266,17 +1213,14 @@ dri2CreateScreen(int screen, struct glx_display * priv)
psp->bindTexImage = dri2_bind_tex_image;
psp->releaseTexImage = dri2_release_tex_image;
if (pdp->driMinor >= 2) {
psp->getDrawableMSC = dri2DrawableGetMSC;
psp->waitForMSC = dri2WaitForMSC;
psp->waitForSBC = dri2WaitForSBC;
psp->setSwapInterval = dri2SetSwapInterval;
psp->getSwapInterval = dri2GetSwapInterval;
psp->maxSwapInterval = INT_MAX;
__glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
}
psp->getDrawableMSC = dri2DrawableGetMSC;
psp->waitForMSC = dri2WaitForMSC;
psp->waitForSBC = dri2WaitForSBC;
psp->setSwapInterval = dri2SetSwapInterval;
psp->getSwapInterval = dri2GetSwapInterval;
psp->maxSwapInterval = INT_MAX;
__glXEnableDirectExtension(&psc->base, "GLX_OML_sync_control");
__glXEnableDirectExtension(&psc->base, "GLX_SGI_video_sync");
if (psc->config->base.version > 1 &&
@ -1390,23 +1334,20 @@ dri2CreateDisplay(Display * dpy)
return NULL;
}
if (pdp->driMinor < 3) {
free(pdp);
return NULL;
}
pdp->driPatch = 0;
pdp->swapAvailable = (pdp->driMinor >= 2);
pdp->invalidateAvailable = (pdp->driMinor >= 3);
pdp->base.destroyDisplay = dri2DestroyDisplay;
pdp->base.createScreen = dri2CreateScreen;
i = 0;
if (pdp->driMinor < 1)
pdp->loader_extensions[i++] = &dri2LoaderExtension_old.base;
else
pdp->loader_extensions[i++] = &dri2LoaderExtension.base;
pdp->loader_extensions[i++] = &dri2LoaderExtension.base;
pdp->loader_extensions[i++] = &dri2UseInvalidate.base;
pdp->loader_extensions[i++] = &driBackgroundCallable.base;
pdp->loader_extensions[i++] = NULL;
pdp->dri2Hash = __glxHashCreate();