int driMajor;
int driMinor;
int driPatch;
+
+ unsigned long configureSeqno;
+ Bool (*oldConfigProc)(Display *, XEvent *, xEvent *);
};
struct __GLXDRIcontextPrivateRec {
__DRIbuffer buffers[5];
int bufferCount;
int width, height;
+ unsigned long configureSeqno;
};
static void dri2DestroyContext(__GLXDRIcontext *context,
pdraw->base.xDrawable = xDrawable;
pdraw->base.drawable = drawable;
pdraw->base.psc = psc;
+ pdraw->configureSeqno = ~0;
DRI2CreateDrawable(psc->dpy, xDrawable);
int *out_count, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ __GLXdisplayPrivate *dpyPriv = __glXInitialize(pdraw->base.psc->dpy);
+ __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
DRI2Buffer *buffers;
int i;
+ /**
+ * Check if a ConfigureNotify has come in since we last asked for the
+ * buffers associated with this drawable. If not, we can assume that they're
+ * the same set at glViewport time, and save a synchronous round-trip to the
+ * X Server.
+ */
+ if (pdraw->configureSeqno == pdp->configureSeqno &&
+ count == pdraw->bufferCount) {
+ for (i = 0; i < count; i++) {
+ if (pdraw->buffers[i].attachment != attachments[i])
+ break;
+ }
+ if (i == count) {
+ *out_count = pdraw->bufferCount;
+ return pdraw->buffers;
+ }
+ }
+ pdraw->configureSeqno = pdp->configureSeqno;
+
buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
width, height, attachments, count, out_count);
if (buffers == NULL)
pdraw->width = *width;
pdraw->height = *height;
+ pdraw->bufferCount = *out_count;
/* This assumes the DRI2 buffer attachment tokens matches the
* __DRIbuffer tokens. */
Xfree(dpy);
}
+/**
+ * Makes a note on receiving ConfigureNotify that we need to re-check the
+ * DRI2 buffers, as window sizes may have resulted in reallocation.
+ */
+static Bool dri2ConfigureNotifyProc(Display *dpy, XEvent *re, xEvent *event)
+{
+ __GLXdisplayPrivate *dpyPriv = __glXInitialize(dpy);
+ __GLXDRIdisplayPrivate *pdp;
+ Bool ret;
+
+ /* We should always be able to find our pdp, as it only gets torn down
+ * when the Display is torn down.
+ */
+ pdp = (__GLXDRIdisplayPrivate *)dpyPriv->dri2Display;
+
+ ret = pdp->oldConfigProc(dpy, re, event);
+
+ pdp->configureSeqno = re->xconfigure.serial;
+
+ return ret;
+}
+
/*
* Allocate, initialize and return a __DRIdisplayPrivate object.
* This is called from __glXInitialize() when we are given a new
return NULL;
}
+ pdp->oldConfigProc = XESetWireToEvent(dpy, ConfigureNotify,
+ dri2ConfigureNotifyProc);
+
pdp->driPatch = 0;
pdp->base.destroyDisplay = dri2DestroyDisplay;