[PATCH] dri2: Update the fake front on SwapBuffers (bug 27305).

Francisco Jerez currojerez at riseup.net
Tue Mar 30 06:41:54 PDT 2010


It wasn't a problem before the invalidate changes (fa5103a02
specifically) because the SwapBuffers request was unconditionally
followed by a GetBuffers request (and GetBuffers updated the fake
front). On DRI2.3 the client is only required to re-sync buffers when
it gets an explicit invalidate event, so we cannot rely on this
behavior anymore.

It was reported to make the following piglit/glean test cases regress:
texgen, coloredTexPerf2, coloredLitPerf2.

Signed-off-by: Francisco Jerez <currojerez at riseup.net>
---
 hw/xfree86/dri2/dri2.c |   32 ++++++++++++++++++--------------
 1 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 41006da..f05bb5e 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -217,6 +217,14 @@ find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
     return -1;
 }
 
+static void
+get_drawable_region(DrawablePtr draw, RegionPtr region)
+{
+    BoxRec box = { 0, 0, draw->width, draw->height };
+
+    REGION_INIT(draw->pScreen, region, &box, 0);
+}
+
 static Bool
 allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
 			 DRI2DrawablePtr pPriv,
@@ -344,15 +352,9 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
      * applications that call glXWaitX before calling glDrawBuffer.
      */
     if (have_fake_front && buffers_changed) {
-	BoxRec box;
 	RegionRec region;
 
-	box.x1 = 0;
-	box.y1 = 0;
-	box.x2 = pPriv->width;
-	box.y2 = pPriv->height;
-	REGION_INIT(pDraw->pScreen, &region, &box, 0);
-
+	get_drawable_region(pDraw, &region);
 	DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
 		       DRI2BufferFrontLeft);
     }
@@ -605,6 +607,7 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
     ScreenPtr	    pScreen = pDraw->pScreen;
     DRI2DrawablePtr pPriv;
     CARD64          ust = 0;
+    RegionRec       region;
 
     pPriv = DRI2GetDrawable(pDraw);
     if (pPriv == NULL) {
@@ -620,6 +623,12 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 	return;
     }
 
+    /* If we're using a fake front, update it with the front buffer
+     * contents.  */
+    get_drawable_region(pDraw, &region);
+    DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+		   DRI2BufferFrontLeft);
+
     ust = ((CARD64)tv_sec * 1000000) + tv_usec;
     if (swap_complete)
 	swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
@@ -682,18 +691,13 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 
     /* Old DDX, just blit */
     if (!ds->ScheduleSwap) {
-	BoxRec box;
 	RegionRec region;
 
-	box.x1 = 0;
-	box.y1 = 0;
-	box.x2 = pDraw->width;
-	box.y2 = pDraw->height;
-	REGION_INIT(pScreen, &region, &box, 0);
-
 	pPriv->swapsPending++;
 
+	get_drawable_region(pDraw, &region);
 	(*ds->CopyRegion)(pDraw, &region, pDestBuffer, pSrcBuffer);
+
 	DRI2SwapComplete(client, pDraw, target_msc, 0, 0, DRI2_BLIT_COMPLETE,
 			 func, data);
 	return Success;
-- 
1.6.4.4



More information about the xorg-devel mailing list