I'm a Mesa novice, so I'm sure there are better ways to do this. And this only works due to Eric's recent changes to avoid a full GetBuffers call in DRI2GetBuffers (we can just update the private list and call intel_update_renderbuffers to pick up the new GEM names, etc.).
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 27cc1be..5a60426 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -670,6 +670,9 @@ struct __DRIdri2ExtensionRec { __DRIcontext *shared, void *loaderPrivate); + void (*setBuffers)(__DRIdrawable *drawable, + __DRIbuffer *buffers, + int count); }; #endif diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c index f967432..f0bd6ef 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -299,3 +299,50 @@ void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, UnlockDisplay(dpy); SyncHandle(); } + +DRI2Buffer *DRI2SwapBuffers(Display *dpy, XID drawable) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2SwapBuffersReq *req; + xDRI2SwapBuffersReply rep; + xDRI2Buffer repBuffer; + DRI2Buffer *buffers; + int i; + + XextCheckExtension (dpy, info, dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2SwapBuffers, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2SwapBuffers; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + /* We expect a new front & back in return */ + buffers = Xmalloc(2 * sizeof(DRI2Buffer)); + if (buffers == NULL) { + _XEatData(dpy, 2 * sizeof repBuffer); + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + for (i = 0; i < 2; i++) { + _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); + buffers[i].attachment = repBuffer.attachment; + buffers[i].name = repBuffer.name; + buffers[i].pitch = repBuffer.pitch; + buffers[i].cpp = repBuffer.cpp; + buffers[i].flags = repBuffer.flags; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return buffers; +} diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h index 356c6bc..83e27f8 100644 --- a/src/glx/x11/dri2.h +++ b/src/glx/x11/dri2.h @@ -67,4 +67,7 @@ extern void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src); +extern DRI2Buffer * +DRI2SwapBuffers(Display *dpy, XID drawable); + #endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index b878f05..dc8e6d5 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -210,8 +210,29 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + __GLXscreenConfigs *psc = pdraw->psc; + DRI2Buffer *buffers; + int i, j; + + buffers = DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable); + if (buffers == NULL) + return; + + /* Update the front & back buffer objects */ + for (j = 0; j < 2; j++) { + for (i = 0; i < priv->bufferCount; i++) { + if (priv->buffers[i].attachment == buffers[j].attachment) { + priv->buffers[i].name = buffers[j].name; + priv->buffers[i].pitch = buffers[j].pitch; + priv->buffers[i].cpp = buffers[j].cpp; + priv->buffers[i].flags = buffers[j].flags; + } + } + } + + (*psc->dri2->setBuffers)(pdraw->driDrawable, priv->buffers, 2); - dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); + Xfree(buffers); } static void dri2DestroyScreen(__GLXscreenConfigs *psc) diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index ae79055..75afc45 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -488,6 +488,14 @@ dri2CreateNewDrawable(__DRIscreen *screen, return pdraw; } +static void +dri2SetBuffers(__DRIdrawable *draw, __DRIbuffer *buffers, int count) +{ + __DRIscreen *psp = draw->driScreenPriv; + + (*psp->DriverAPI.SetBuffers)(draw, buffers, count); +} + static void driDestroyDrawable(__DRIdrawable *pdp) @@ -832,6 +840,7 @@ const __DRIdri2Extension driDRI2Extension = { dri2CreateNewScreen, dri2CreateNewDrawable, dri2CreateNewContext, + dri2SetBuffers, }; /* This is the table of extensions that the loader will dlsym() for. */ diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index c95a5c8..2a6e1cd 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -225,6 +225,13 @@ struct __DriverAPIRec { /* DRI2 Entry point */ const __DRIconfig **(*InitScreen2) (__DRIscreen * priv); + + /** + * Update the render buffers with a new set + */ + void (*SetBuffers) ( __DRIdrawable *drawable, + __DRIbuffer *buffers, + int count); }; extern const struct __DriverAPIRec driDriverAPI; diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index d7ccfa0..f92fa90 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -169,6 +169,26 @@ intelGetString(GLcontext * ctx, GLenum name) } } +/* + * DRI may give us with a new set of buffers after a flip or swap, so + * update the attachments here. + */ +void intelSetBuffers(__DRIdrawable *drawable, + __DRIbuffer *buffers, + int count) +{ + __DRIcontext *context = drawable->driContextPriv; + struct intel_framebuffer *intel_fb = drawable->driverPrivate; + struct intel_context *intel = context->driverPrivate; + struct intel_renderbuffer *rb; + struct intel_region *region; + const char *region_name; + int i; + + intel_update_renderbuffers(context, drawable); + intel_draw_buffer(&intel->ctx, &intel_fb->Base); +} + void intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) { diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index a522711..45e1e56 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -799,4 +799,6 @@ const struct __DriverAPIRec driDriverAPI = { .CopySubBuffer = intelCopySubBuffer, .InitScreen2 = intelInitScreen2, + + .SetBuffers = intelSetBuffers, }; diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h index e1036de..b23dcee 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.h +++ b/src/mesa/drivers/dri/intel/intel_screen.h @@ -103,4 +103,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv, extern struct intel_context *intelScreenContext(intelScreenPrivate *intelScreen); +extern void intelSetBuffers(__DRIdrawable *drawable, __DRIbuffer *buffers, + int count); + #endif ------------------------------------------------------------------------------ Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM) software. With Adobe AIR, Ajax developers can use existing skills and code to build responsive, highly engaging applications that combine the power of local resources and data with the reach of the web. Download the Adobe AIR SDK and Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com -- _______________________________________________ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel