xf86-video-intel: src/i830_dri.c src/i830.h src/i830_uxa.c

Chris Wilson ickle at kemper.freedesktop.org
Wed May 12 13:38:44 PDT 2010


 src/i830.h     |   12 +++++++++++-
 src/i830_dri.c |   55 ++++++++++++++++++++++++-------------------------------
 src/i830_uxa.c |   18 ++++--------------
 3 files changed, 39 insertions(+), 46 deletions(-)

New commits:
commit 9f54107f866a25cf670f81f7c52b8c108728c6a5
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue May 11 14:55:16 2010 +0100

    dri2: Handle reference counting across page flipping
    
    1. Instead of swapping bos, swap the entire private structure.
    
    2. If we update the pixmap bo for the Screen, make sure we update the
    reference inside intel->front_buffer so that xrandr still functions.
    
    Fixes:
    
      Bug 27922 - i965: Rapidly resizing OpenGL window causes GPU to hang.
      https://bugs.freedesktop.org/show_bug.cgi?id=27922
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830.h b/src/i830.h
index fdaa47e..9e1b4ca 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -154,7 +154,17 @@ struct intel_pixmap {
 	struct list flush, batch, in_flight;
 };
 
-struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap);
+extern int uxa_pixmap_index;
+
+static inline struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap)
+{
+	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
+}
+
+static inline void i830_set_pixmap_intel(PixmapPtr pixmap, struct intel_pixmap *intel)
+{
+	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel);
+}
 
 static inline Bool i830_uxa_pixmap_is_dirty(PixmapPtr pixmap)
 {
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 321faf6..9500dad 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -434,7 +434,9 @@ I830DRI2ExchangeBuffers(DrawablePtr draw, DRI2BufferPtr front,
 			DRI2BufferPtr back)
 {
 	I830DRI2BufferPrivatePtr front_priv, back_priv;
-	dri_bo *tmp_bo;
+	struct intel_pixmap *front_intel, *back_intel;
+	ScreenPtr screen;
+	intel_screen_private *intel;
 	int tmp;
 
 	front_priv = front->driverPrivate;
@@ -446,17 +448,21 @@ I830DRI2ExchangeBuffers(DrawablePtr draw, DRI2BufferPtr front,
 	back->name = tmp;
 
 	/* Swap pixmap bos */
-
-	/* Hold a ref on the front so the set calls below don't destroy it */
-	dri_bo_reference(i830_get_pixmap_bo(front_priv->pixmap));
-
-	tmp_bo = i830_get_pixmap_bo(front_priv->pixmap);
-	i830_set_pixmap_bo(front_priv->pixmap,
-			   i830_get_pixmap_bo(back_priv->pixmap));
-	i830_set_pixmap_bo(back_priv->pixmap, tmp_bo); /* should be screen */
-
-	/* Release our ref, the last set should have bumped it */
-	dri_bo_unreference(tmp_bo);
+	front_intel = i830_get_pixmap_intel(front_priv->pixmap);
+	back_intel = i830_get_pixmap_intel(back_priv->pixmap);
+	i830_set_pixmap_intel(front_priv->pixmap, back_intel);
+	i830_set_pixmap_intel(back_priv->pixmap, front_intel); /* should be screen */
+
+	/* Do we need to update the Screen? */
+	screen = draw->pScreen;
+	intel = intel_get_screen_private(xf86Screens[screen->myNum]);
+	if (front_intel->bo == intel->front_buffer) {
+	    dri_bo_unreference (intel->front_buffer);
+	    intel->front_buffer = back_intel->bo;
+	    dri_bo_reference (intel->front_buffer);
+	    i830_set_pixmap_intel(screen->GetScreenPixmap(screen),
+				  back_intel);
+	}
 }
 
 /*
@@ -469,9 +475,7 @@ I830DRI2ScheduleFlip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 {
 	ScreenPtr screen = draw->pScreen;
 	I830DRI2BufferPrivatePtr front_priv, back_priv;
-	dri_bo *tmp_bo;
 	DRI2FrameEventPtr flip_info;
-	Bool ret;
 
 	flip_info = xcalloc(1, sizeof(DRI2FrameEventRec));
 	if (!flip_info)
@@ -485,25 +489,12 @@ I830DRI2ScheduleFlip(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 
 	front_priv = front->driverPrivate;
 	back_priv = back->driverPrivate;
-	tmp_bo = i830_get_pixmap_bo(front_priv->pixmap);
-
-	I830DRI2ExchangeBuffers(draw, front, back);
 
 	/* Page flip the full screen buffer */
-	ret = drmmode_do_pageflip(screen,
-				  i830_get_pixmap_bo(front_priv->pixmap),
-				  i830_get_pixmap_bo(back_priv->pixmap),
-				  flip_info);
-
-	/* Unwind in case of failure */
-	if (!ret) {
-	    i830_set_pixmap_bo(back_priv->pixmap,
-			       i830_get_pixmap_bo(front_priv->pixmap));
-	    i830_set_pixmap_bo(front_priv->pixmap, tmp_bo);
-	    return FALSE;
-	}
-
-	return ret;
+	return drmmode_do_pageflip(screen,
+				   i830_get_pixmap_bo(front_priv->pixmap),
+				   i830_get_pixmap_bo(back_priv->pixmap),
+				   flip_info);
 }
 
 void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec,
@@ -535,6 +526,8 @@ void I830DRI2FrameEventHandler(unsigned int frame, unsigned int tv_sec,
 		    I830DRI2ScheduleFlip(event->client, drawable, event->front,
 					 event->back, event->event_complete,
 					 event->event_data)) {
+			I830DRI2ExchangeBuffers(drawable,
+						event->front, event->back);
 			break;
 		}
 		/* else fall through to exchange/blit */
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index 3f9610e..6a454ac 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -78,7 +78,7 @@ const int I830PatternROP[16] = {
 	ROP_1
 };
 
-static int uxa_pixmap_index;
+int uxa_pixmap_index;
 
 Bool
 i830_get_aperture_space(ScrnInfoPtr scrn, drm_intel_bo ** bo_table,
@@ -527,16 +527,6 @@ Bool i830_transform_is_affine(PictTransformPtr t)
 	return t->matrix[2][0] == 0 && t->matrix[2][1] == 0;
 }
 
-struct intel_pixmap *i830_get_pixmap_intel(PixmapPtr pixmap)
-{
-	return dixLookupPrivate(&pixmap->devPrivates, &uxa_pixmap_index);
-}
-
-static void i830_uxa_set_pixmap_intel(PixmapPtr pixmap, struct intel_pixmap *intel)
-{
-	dixSetPrivate(&pixmap->devPrivates, &uxa_pixmap_index, intel);
-}
-
 dri_bo *i830_get_pixmap_bo(PixmapPtr pixmap)
 {
 	struct intel_pixmap *intel;
@@ -604,7 +594,7 @@ void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo * bo)
 	}
 
   BAIL:
-	i830_uxa_set_pixmap_intel(pixmap, priv);
+	i830_set_pixmap_intel(pixmap, priv);
 }
 
 static Bool i830_uxa_prepare_access(PixmapPtr pixmap, uxa_access_t access)
@@ -985,7 +975,7 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
 				list_del(&priv->in_flight);
 				screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, NULL);
-				i830_uxa_set_pixmap_intel(pixmap, priv);
+				i830_set_pixmap_intel(pixmap, priv);
 				return pixmap;
 			}
 		}
@@ -1020,7 +1010,7 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 
 		list_init(&priv->batch);
 		list_init(&priv->flush);
-		i830_uxa_set_pixmap_intel(pixmap, priv);
+		i830_set_pixmap_intel(pixmap, priv);
 	}
 
 	return pixmap;


More information about the xorg-commit mailing list