xf86-video-intel: src/i830_dri.c

Chris Wilson ickle at kemper.freedesktop.org
Sat May 29 08:41:44 PDT 2010


 src/i830_dri.c |   44 ++++++++++++++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 6 deletions(-)

New commits:
commit e2615cdeef078dbd2e834b68c437f098a92b941d
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat May 29 16:37:12 2010 +0100

    dri: Only flip if the front and back pixmaps match.
    
    An unredirected window (thanks Michel for the reminder) is backed by the
    Screen pixmap, and so uses a reference of that as its front buffer. The
    back buffer is a pixmap appropriately sized for the drawable. When the
    application requests to swap its buffers, obviously we cannot simply
    exchange the front and back buffer as they do not match, but need to copy
    the appropriate region from the back to the front.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/i830_dri.c b/src/i830_dri.c
index 61abd36..bd75b9e 100644
--- a/src/i830_dri.c
+++ b/src/i830_dri.c
@@ -608,6 +608,32 @@ void I830DRI2FlipEventHandler(unsigned int frame, unsigned int tv_sec,
 	xfree(flip);
 }
 
+static Bool
+can_swap(DRI2BufferPtr front, DRI2BufferPtr back)
+{
+	I830DRI2BufferPrivatePtr front_priv = front->driverPrivate;
+	I830DRI2BufferPrivatePtr back_priv = back->driverPrivate;
+	PixmapPtr front_pixmap = front_priv->pixmap;
+	PixmapPtr back_pixmap = back_priv->pixmap;
+
+	if (front_pixmap->drawable.width != back_pixmap->drawable.width)
+		return FALSE;
+
+	if (front_pixmap->drawable.height != back_pixmap->drawable.height)
+		return FALSE;
+
+	/* XXX should we be checking depth instead of bpp? */
+#if 0
+	if (front_pixmap->drawable.depth != back_pixmap->drawable.depth)
+		return FALSE;
+#else
+	if (front_pixmap->drawable.bpp != back_pixmap->drawable.bpp)
+		return FALSE;
+#endif
+
+	return TRUE;
+}
+
 /*
  * ScheduleSwap is responsible for requesting a DRM vblank event for the
  * appropriate frame.
@@ -638,12 +664,19 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	intel_screen_private *intel = intel_get_screen_private(scrn);
 	drmVBlank vbl;
 	int ret, pipe = I830DRI2DrawablePipe(draw), flip = 0;
-	DRI2FrameEventPtr swap_info;
+	DRI2FrameEventPtr swap_info = NULL;
 	enum DRI2FrameEventType swap_type = DRI2_SWAP;
 	CARD64 current_msc;
 	BoxRec box;
 	RegionRec region;
 
+	/* Drawable not displayed... just complete the swap */
+	if (pipe == -1)
+	    goto blit_fallback;
+
+	if (!can_swap(front, back))
+		goto blit_fallback;
+
 	/* Truncate to match kernel interfaces; means occasional overflow
 	 * misses, but that's generally not a big deal */
 	*target_msc &= 0xffffffff;
@@ -651,9 +684,7 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	remainder &= 0xffffffff;
 
 	swap_info = xcalloc(1, sizeof(DRI2FrameEventRec));
-
-	/* Drawable not displayed... just complete the swap */
-	if (pipe == -1 || !swap_info)
+	if (!swap_info)
 	    goto blit_fallback;
 
 	swap_info->drawable_id = draw->id;
@@ -681,8 +712,9 @@ I830DRI2ScheduleSwap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front,
 	current_msc = vbl.reply.sequence;
 
 	/* Flips need to be submitted one frame before */
-	if (DRI2CanFlip(draw) && !intel->shadow_present &&
-	    intel->use_pageflipping) {
+	if (intel->use_pageflipping &&
+	    !intel->shadow_present &&
+	    DRI2CanFlip(draw)) {
 	    swap_type = DRI2_FLIP;
 	    flip = 1;
 	}


More information about the xorg-commit mailing list