diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-29 16:37:12 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-29 16:40:06 +0100 |
commit | e2615cdeef078dbd2e834b68c437f098a92b941d (patch) | |
tree | ee77321a7873c3578d280f9b54aef8500d8a2e64 /src/i830_dri.c | |
parent | 8b2039187fc23f5e9dddf4081f8b1ab6f4c01416 (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>
Diffstat (limited to 'src/i830_dri.c')
-rw-r--r-- | src/i830_dri.c | 44 |
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; } |