int driPatch;
int swapAvailable;
int invalidateAvailable;
+
+ __glxHashTable *dri2Hash;
+
+ const __DRIextension *loader_extensions[4];
};
struct __GLXDRIcontextPrivateRec
int swap_interval;
};
-static void dri2WaitX(__GLXDRIdrawable * pdraw);
-
static void
dri2DestroyContext(__GLXDRIcontext * context,
__GLXscreenConfigs * psc, Display * dpy)
}
static void
-dri2DestroyDrawable(__GLXDRIdrawable * pdraw)
+dri2DestroyDrawable(__GLXDRIdrawable *pdraw)
{
const __DRIcoreExtension *core = pdraw->psc->core;
+ __GLXdisplayPrivate *dpyPriv;
+ __GLXDRIdisplayPrivate *pdp;
+
+ dpyPriv = __glXInitialize(pdraw->psc->dpy);
+ pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
+ __glxHashDelete(pdp->dri2Hash, pdraw->xDrawable);
(*core->destroyDrawable) (pdraw->driDrawable);
DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->xDrawable);
Xfree(pdraw);
return NULL;
}
+ if (__glxHashInsert(pdp->dri2Hash, xDrawable, pdraw)) {
+ (*psc->core->destroyDrawable) (pdraw->base.driDrawable);
+ DRI2DestroyDrawable(psc->dpy, xDrawable);
+ Xfree(pdraw);
+ return None;
+ }
+
+
#ifdef X_DRI2SwapInterval
/*
* Make sure server has the same swap interval we do for the new
/* Refresh the fake front (if present) after we just damaged the real
* front.
*/
- dri2WaitX(pdraw);
+ DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
+ DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+ XFixesDestroyRegion(pdraw->psc->dpy, region);
}
static void
NULL,
};
-static const __DRIextension *loader_extensions[] = {
- &dri2LoaderExtension.base,
- &systemTimeExtension.base,
- NULL
-};
-
-static const __DRIextension *loader_extensions_old[] = {
- &dri2LoaderExtension_old.base,
- &systemTimeExtension.base,
- NULL
+#ifdef __DRI_USE_INVALIDATE
+static const __DRIuseInvalidateExtension dri2UseInvalidate = {
+ { __DRI_USE_INVALIDATE, __DRI_USE_INVALIDATE_VERSION }
};
+#endif
_X_HIDDEN void
dri2InvalidateBuffers(Display *dpy, XID drawable)
{
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+ __GLXDRIdrawable *pdraw =
+ dri2GetGlxDrawableFromXDrawableId(dpy, drawable);
#if __DRI2_FLUSH_VERSION >= 3
if (pdraw && pdraw->psc->f)
#endif
}
+static void
+dri2_bind_tex_image(Display * dpy,
+ GLXDrawable drawable,
+ int buffer, const int *attrib_list)
+{
+ GLXContext gc = __glXGetCurrentContext();
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+ __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
+ __GLXDRIdisplayPrivate *pdp =
+ (__GLXDRIdisplayPrivate *) dpyPriv->dri2Display;
+
+ if (pdraw != NULL) {
+
+#if __DRI2_FLUSH_VERSION >= 3
+ if (!pdp->invalidateAvailable && pdraw->psc->f)
+ pdraw->psc->f->invalidate(pdraw->driDrawable);
+#endif
+
+ if (pdraw->psc->texBuffer->base.version >= 2 &&
+ pdraw->psc->texBuffer->setTexBuffer2 != NULL) {
+ (*pdraw->psc->texBuffer->setTexBuffer2) (gc->__driContext,
+ pdraw->textureTarget,
+ pdraw->textureFormat,
+ pdraw->driDrawable);
+ }
+ else {
+ (*pdraw->psc->texBuffer->setTexBuffer) (gc->__driContext,
+ pdraw->textureTarget,
+ pdraw->driDrawable);
+ }
+ }
+}
+
+static void
+dri2_release_tex_image(Display * dpy, GLXDrawable drawable, int buffer)
+{
+}
+
+static const struct glx_context_vtable dri2_context_vtable = {
+ dri2_bind_tex_image,
+ dri2_release_tex_image,
+};
+
static __GLXDRIscreen *
dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
__GLXdisplayPrivate * priv)
goto handle_error;
}
+
/* If the server does not support the protocol for
* DRI2GetBuffersWithFormat, don't supply that interface to the driver.
*/
psc->__driScreen =
- psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1)
- ? loader_extensions_old
- : loader_extensions),
+ psc->dri2->createNewScreen(screen, psc->fd,
+ (const __DRIextension **)
+ &pdp->loader_extensions[0],
&driver_configs, psc);
if (psc->__driScreen == NULL) {
psp->copySubBuffer = dri2CopySubBuffer;
__glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
+ psc->direct_context_vtable = &dri2_context_vtable;
+
Xfree(driverName);
Xfree(deviceName);
Xfree(dpy);
}
+_X_HIDDEN __GLXDRIdrawable *
+dri2GetGlxDrawableFromXDrawableId(Display *dpy, XID id)
+{
+ __GLXdisplayPrivate *d = __glXInitialize(dpy);
+ __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *) d->dri2Display;
+ __GLXDRIdrawable *pdraw;
+
+ if (__glxHashLookup(pdp->dri2Hash, id, (void *) &pdraw) == 0)
+ return pdraw;
+
+ return NULL;
+}
+
/*
* Allocate, initialize and return a __DRIdisplayPrivate object.
* This is called from __glXInitialize() when we are given a new
dri2CreateDisplay(Display * dpy)
{
__GLXDRIdisplayPrivate *pdp;
- int eventBase, errorBase;
+ int eventBase, errorBase, i;
if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
return NULL;
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++] = &systemTimeExtension.base;
+
+#ifdef __DRI_USE_INVALIDATE
+ pdp->loader_extensions[i++] = &dri2UseInvalidate.base;
+#endif
+ pdp->loader_extensions[i++] = NULL;
+
+ pdp->dri2Hash = __glxHashCreate();
+ if (pdp->dri2Hash == NULL) {
+ Xfree(pdp);
+ return NULL;
+ }
+
return &pdp->base;
}