summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-29 16:37:12 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-29 16:40:06 +0100
commite2615cdeef078dbd2e834b68c437f098a92b941d (patch)
treeee77321a7873c3578d280f9b54aef8500d8a2e64
parent8b2039187fc23f5e9dddf4081f8b1ab6f4c01416 (diff)
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@chris-wilson.co.uk>
-rw-r--r--src/i830_dri.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/i830_dri.c b/src/i830_dri.c
index 61abd36f..bd75b9e2 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;
}