diff options
Diffstat (limited to 'src/glx')
-rw-r--r-- | src/glx/x11/dri2_glx.c | 64 | ||||
-rw-r--r-- | src/glx/x11/glxclient.h | 1 | ||||
-rw-r--r-- | src/glx/x11/glxextensions.c | 2 |
3 files changed, 63 insertions, 4 deletions
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index 2bee67780b..41861d5d27 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -60,6 +60,9 @@ struct __GLXDRIdisplayPrivateRec { int driMajor; int driMinor; int driPatch; + + unsigned long configureSeqno; + Bool (*oldConfigProc)(Display *, XEvent *, xEvent *); }; struct __GLXDRIcontextPrivateRec { @@ -73,6 +76,7 @@ struct __GLXDRIdrawablePrivateRec { __DRIbuffer buffers[5]; int bufferCount; int width, height; + unsigned long configureSeqno; }; static void dri2DestroyContext(__GLXDRIcontext *context, @@ -166,6 +170,7 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc, pdraw->base.xDrawable = xDrawable; pdraw->base.drawable = drawable; pdraw->base.psc = psc; + pdraw->configureSeqno = ~0; DRI2CreateDrawable(psc->dpy, xDrawable); @@ -223,9 +228,30 @@ dri2GetBuffers(__DRIdrawable *driDrawable, 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) @@ -233,6 +259,7 @@ dri2GetBuffers(__DRIdrawable *driDrawable, pdraw->width = *width; pdraw->height = *height; + pdraw->bufferCount = *out_count; /* This assumes the DRI2 buffer attachment tokens matches the * __DRIbuffer tokens. */ @@ -282,8 +309,10 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, return NULL; psc->driver = driOpenDriver(driverName); - if (psc->driver == NULL) + if (psc->driver == NULL) { + ErrorMessageF("driver pointer missing\n"); goto handle_error; + } extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS); if (extensions == NULL) { @@ -309,11 +338,15 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen, return NULL; } - if (drmGetMagic(psc->fd, &magic)) + if (drmGetMagic(psc->fd, &magic)) { + ErrorMessageF("failed to get magic\n"); return NULL; + } - if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) + if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) { + ErrorMessageF("failed to authenticate magic %d\n", magic); return NULL; + } psc->__driScreen = psc->dri2->createNewScreen(screen, psc->fd, @@ -359,6 +392,28 @@ static void dri2DestroyDisplay(__GLXDRIdisplay *dpy) 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 @@ -381,6 +436,9 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy) return NULL; } + pdp->oldConfigProc = XESetWireToEvent(dpy, ConfigureNotify, + dri2ConfigureNotifyProc); + pdp->driPatch = 0; pdp->base.destroyDisplay = dri2DestroyDisplay; diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 467b0ebb7f..9332eb64d3 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -602,6 +602,7 @@ extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint, const GLvoid *, GLint); /* Initialize the GLX extension for dpy */ +extern __GLXdisplayPrivate * __glXGetPrivateFromDisplay(Display *dpy); extern __GLXdisplayPrivate *__glXInitialize(Display*); extern void __glXPreferEGL(int state); diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c index d061fa9333..051433a006 100644 --- a/src/glx/x11/glxextensions.c +++ b/src/glx/x11/glxextensions.c @@ -99,7 +99,7 @@ static const struct extension_info known_glx_extensions[] = { { GLX(SGIS_color_range), VER(0,0), N, N, N, N }, { GLX(SGIS_multisample), VER(0,0), Y, Y, N, N }, { GLX(SGIX_fbconfig), VER(1,3), Y, Y, N, N }, - { GLX(SGIX_pbuffer), VER(1,3), Y, N, N, N }, + { GLX(SGIX_pbuffer), VER(1,3), Y, Y, N, N }, { GLX(SGIX_swap_barrier), VER(0,0), N, N, N, N }, { GLX(SGIX_swap_group), VER(0,0), N, N, N, N }, { GLX(SGIX_visual_select_group), VER(0,0), Y, Y, N, N }, |