When a buffer invalidation event is received from the X server, the "invalidate" hook of the DRI2 flush extension is executed: A generic implementation (dri2InvalidateDrawable) is provided that just bumps the "pStamp" sequence number in __DRIdrawableRec.
For old servers not supporting buffer invalidation events, the invalidate hook will be called after flushing the fake front/back buffer (that's typically once per frame -- not a lot worse than the situation we were in before). No effort has been made on preserving backwards compatibility with version 2 of the flush extension, but I think it's acceptable because AFAIK no released stack is making use of it. Note that this bumps the required dri2proto version to 2.3. --- configure.ac | 2 +- include/GL/internal/dri_interface.h | 14 +++++------ src/glx/x11/dri2.c | 23 +++++++++++++++--- src/glx/x11/dri2_glx.c | 32 +++++++++++++++++-------- src/glx/x11/glx_pbuffer.c | 4 --- src/glx/x11/glxclient.h | 4 +++ src/glx/x11/glxcmds.c | 4 --- src/mesa/drivers/dri/common/dri_util.c | 15 +++++++++++- src/mesa/drivers/dri/common/dri_util.h | 8 ++++-- src/mesa/drivers/dri/intel/intel_context.c | 1 - src/mesa/drivers/dri/intel/intel_screen.c | 9 +------ src/mesa/drivers/dri/intel/intel_tex_image.c | 4 ++- 12 files changed, 75 insertions(+), 45 deletions(-) diff --git a/configure.ac b/configure.ac index d01d0f1..d334abf 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_CANONICAL_HOST dnl Versions for external dependencies LIBDRM_REQUIRED=2.4.15 LIBDRM_RADEON_REQUIRED=2.4.17 -DRI2PROTO_REQUIRED=2.2 +DRI2PROTO_REQUIRED=2.3 GLPROTO_REQUIRED=1.4.11 dnl Check for progs diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index ec6238f..6399787 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -262,22 +262,20 @@ struct __DRItexBufferExtensionRec { * Used by drivers that implement DRI2 */ #define __DRI2_FLUSH "DRI2_Flush" -#define __DRI2_FLUSH_VERSION 2 +#define __DRI2_FLUSH_VERSION 3 struct __DRI2flushExtensionRec { __DRIextension base; void (*flush)(__DRIdrawable *drawable); /** - * Flush all rendering queue in the driver to the drm and - * invalidate all buffers. The driver will call out to - * getBuffers/getBuffersWithFormat before it starts rendering - * again. + * Ask the driver to call getBuffers/getBuffersWithFormat before + * it starts rendering again. * - * \param drawable the drawable to flush and invalidate + * \param drawable the drawable to invalidate * - * \since 2 + * \since 3 */ - void (*flushInvalidate)(__DRIdrawable *drawable); + void (*invalidate)(__DRIdrawable *drawable); }; diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c index 2cb5d34..931a90b 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -81,7 +81,7 @@ static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, dri2ExtensionName, &dri2ExtensionHooks, - 0, NULL) + DRI2NumberEvents, NULL) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) @@ -95,14 +95,15 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event; xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire; + switch (awire->type) { - case DRI2_EXCHANGE_COMPLETE: + case DRI2_SWAP_EXCHANGE: aevent->event_type = GLX_EXCHANGE_COMPLETE; break; - case DRI2_BLIT_COMPLETE: + case DRI2_SWAP_BLIT: aevent->event_type = GLX_BLIT_COMPLETE; break; - case DRI2_FLIP_COMPLETE: + case DRI2_SWAP_FLIP: aevent->event_type = GLX_FLIP_COMPLETE; break; default: @@ -115,6 +116,20 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo; return True; } + +#if __DRI2_FLUSH_VERSION >= 3 + case DRI2_InvalidateBuffers: + { + xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; + __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, awire->drawable, NULL); + + if (draw && draw->psc->f) + draw->psc->f->invalidate(draw->driDrawable); + + return False; + } +#endif + default: /* client doesn't support server event */ break; diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index 7b0c52b..d787d84 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -67,6 +67,7 @@ struct __GLXDRIdisplayPrivateRec int driMinor; int driPatch; int swapAvailable; + int invalidateAvailable; }; struct __GLXDRIcontextPrivateRec @@ -310,12 +311,27 @@ dri2WaitGL(__GLXDRIdrawable * pdraw) XFixesDestroyRegion(pdraw->psc->dpy, region); } +static void +dri2LegacyInvalidate(__GLXDRIdrawable *pdraw) +{ +#if __DRI2_FLUSH_VERSION >= 3 + __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *)pdraw; + __GLXdisplayPrivate *dpy = __glXInitialize(priv->base.psc->dpy); + __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)dpy->dri2Display; + + /* Force an invalidate call if the server doesn't + * support buffer invalidation events. */ + + if (!pdp->invalidateAvailable && pdraw->psc->f) + (*pdraw->psc->f->invalidate)(pdraw->driDrawable); +#endif +} static void dri2FlushFrontBuffer(__DRIdrawable * driDrawable, void *loaderPrivate) { - (void) driDrawable; - dri2WaitGL((__GLXDRIdrawable *) loaderPrivate); + dri2WaitGL(loaderPrivate); + dri2LegacyInvalidate(loaderPrivate); } @@ -378,17 +394,14 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, /* Old servers can't handle swapbuffers */ if (!pdp->swapAvailable) { dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); + dri2LegacyInvalidate(pdraw); + return 0; } DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor, remainder, &ret); -#if __DRI2_FLUSH_VERSION >= 2 - if (pdraw->psc->f) - (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); -#endif - return ret; } @@ -640,9 +653,8 @@ dri2CreateDisplay(Display * dpy) } pdp->driPatch = 0; - pdp->swapAvailable = 0; - if (pdp->driMinor >= 2) - pdp->swapAvailable = 1; + pdp->swapAvailable = (pdp->driMinor >= 2); + pdp->invalidateAvailable = (pdp->driMinor >= 3); pdp->base.destroyDisplay = dri2DestroyDisplay; pdp->base.createScreen = dri2CreateScreen; diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c index 501500a..15dffed 100644 --- a/src/glx/x11/glx_pbuffer.c +++ b/src/glx/x11/glx_pbuffer.c @@ -188,10 +188,6 @@ DestroyPbuffer(Display * dpy, GLXDrawable drawable) #ifdef GLX_DIRECT_RENDERING -extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy, - GLXDrawable drawable, - int *const scrn_num); - static GLenum determineTextureTarget(const int *attribs, int numAttribs) { diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index ded4f5a..970cbe0 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -793,6 +793,10 @@ extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable, GLboolean __driGetMscRateOML(__DRIdrawable * draw, int32_t * numerator, int32_t * denominator, void *private); + +extern __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int *const scrn_num); + #endif #endif /* !__GLX_client_h__ */ diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c index c3be974..da0dcf1 100644 --- a/src/glx/x11/glxcmds.c +++ b/src/glx/x11/glxcmds.c @@ -105,10 +105,6 @@ GarbageCollectDRIDrawables(Display * dpy, __GLXscreenConfigs * sc) XSetErrorHandler(oldXErrorHandler); } -extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy, - GLXDrawable drawable, - int *const scrn_num); - /** * Get the __DRIdrawable for the drawable associated with a GLXContext * diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 3649c29..705681e 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -454,7 +454,6 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; - pdp->validBuffers = GL_FALSE; if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, renderType == GLX_PIXMAP_BIT)) { @@ -488,6 +487,9 @@ dri2CreateNewDrawable(__DRIscreen *screen, pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); + pdraw->pStamp = _mesa_malloc(sizeof(unsigned int)); + *pdraw->pStamp = pdraw->lastStamp + 1; + return pdraw; } @@ -515,6 +517,11 @@ static void dri_put_drawable(__DRIdrawable *pdp) _mesa_free(pdp->pBackClipRects); pdp->pBackClipRects = NULL; } + if (psp->dri2.enabled && pdp->pStamp) { + _mesa_free(pdp->pStamp); + pdp->pStamp = NULL; + + } _mesa_free(pdp); } } @@ -948,4 +955,10 @@ driCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust, return usage; } +void +dri2InvalidateDrawable(__DRIdrawable *drawable) +{ + (*drawable->pStamp)++; +} + /*...@}*/ diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 95df702..d473091 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -295,7 +295,8 @@ struct __DRIdrawableRec { unsigned int index; /** - * Pointer to the "drawable has changed ID" stamp in the SAREA. + * Pointer to the "drawable has changed ID" stamp in the SAREA (or + * in malloc'ed memory if DRI2 is being used). */ unsigned int *pStamp; @@ -376,8 +377,6 @@ struct __DRIdrawableRec { * GLX_MESA_swap_control. */ unsigned int swap_interval; - - GLboolean validBuffers; }; /** @@ -550,4 +549,7 @@ driCalculateSwapUsage( __DRIdrawable *dPriv, extern GLint driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ); +extern void +dri2InvalidateDrawable(__DRIdrawable *drawable); + #endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index 3f6634c..d015540 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -376,7 +376,6 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) } } - drawable->validBuffers = GL_TRUE; driUpdateFramebufferSize(&intel->ctx, drawable); } diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index e240957..4591db8 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -125,17 +125,10 @@ intelDRI2Flush(__DRIdrawable *drawable) intel_batchbuffer_flush(intel->batch); } -static void -intelDRI2FlushInvalidate(__DRIdrawable *drawable) -{ - intelDRI2Flush(drawable); - drawable->validBuffers = GL_FALSE; -} - static const struct __DRI2flushExtensionRec intelFlushExtension = { { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, intelDRI2Flush, - intelDRI2FlushInvalidate, + dri2InvalidateDrawable, }; static const __DRIextension *intelScreenExtensions[] = { diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index 6f41eaf..0ecafab 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -742,8 +742,10 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, if (!intelObj) return; - if (!dPriv->validBuffers) + if (dPriv->lastStamp != *dPriv->pStamp) { + dPriv->lastStamp = *dPriv->pStamp; intel_update_renderbuffers(pDRICtx, dPriv); + } rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); /* If the region isn't set, then intel_update_renderbuffers was unable -- 1.6.4.4 ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ Mesa3d-dev mailing list Mesa3d-dev@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mesa3d-dev