diff options
author | Ville Syrjala <syrjala@sci.fi> | 2011-05-04 23:51:26 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2011-08-01 09:10:35 -0400 |
commit | 9493563c1ef4b51af0ee8a44cb4e7c5bb280347e (patch) | |
tree | 5507e821f4930ec8c49aad0565aab1bbf6b6e88e | |
parent | 8c9266ed2da22a510243f9a952c14d4423f48a2b (diff) |
dri2: Update front buffer pixmap and name before exchanging buffers
Buffer exchange assumes that the front buffer pixmap and name
information is accurate. That may not be the case eg. if the window
has been (un)redirected since the buffer was created.
Signed-off-by: Ville Syrjala <syrjala@sci.fi>
-rw-r--r-- | src/radeon_dri2.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c index 1133319d..46573a7c 100644 --- a/src/radeon_dri2.c +++ b/src/radeon_dri2.c @@ -662,12 +662,42 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr client, } static Bool -can_exchange(ScrnInfoPtr pScrn, +update_front(DrawablePtr draw, DRI2BufferPtr front) +{ + int r; + PixmapPtr pixmap; + struct dri2_buffer_priv *priv = front->driverPrivate; + struct radeon_exa_pixmap_priv *driver_priv; + + if (draw->type == DRAWABLE_PIXMAP) + pixmap = (PixmapPtr)draw; + else + pixmap = (*draw->pScreen->GetWindowPixmap)((WindowPtr)draw); + + pixmap->refcnt++; + + exaMoveInPixmap(pixmap); + driver_priv = exaGetPixmapDriverPrivate(pixmap); + r = radeon_gem_get_kernel_name(driver_priv->bo, &front->name); + if (r) { + (*draw->pScreen->DestroyPixmap)(pixmap); + return FALSE; + } + (*draw->pScreen->DestroyPixmap)(priv->pixmap); + front->pitch = pixmap->devKind; + front->cpp = pixmap->drawable.bitsPerPixel / 8; + priv->pixmap = pixmap; + + return TRUE; +} + +static Bool +can_exchange(ScrnInfoPtr pScrn, DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) { struct dri2_buffer_priv *front_priv = front->driverPrivate; struct dri2_buffer_priv *back_priv = back->driverPrivate; - PixmapPtr front_pixmap = front_priv->pixmap; + PixmapPtr front_pixmap; PixmapPtr back_pixmap = back_priv->pixmap; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); int i; @@ -678,6 +708,11 @@ can_exchange(ScrnInfoPtr pScrn, return FALSE; } + if (!update_front(draw, front)) + return FALSE; + + front_pixmap = front_priv->pixmap; + if (front_pixmap->drawable.width != back_pixmap->drawable.width) return FALSE; @@ -757,7 +792,7 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, case DRI2_FLIP: if (info->allowPageFlip && DRI2CanFlip(drawable) && - can_exchange(scrn, event->front, event->back) && + can_exchange(scrn, drawable, event->front, event->back) && radeon_dri2_schedule_flip(scrn, event->client, drawable, @@ -772,7 +807,7 @@ void radeon_dri2_frame_event_handler(unsigned int frame, unsigned int tv_sec, /* else fall through to exchange/blit */ case DRI2_SWAP: if (DRI2CanExchange(drawable) && - can_exchange(scrn, event->front, event->back)) { + can_exchange(scrn, drawable, event->front, event->back)) { radeon_dri2_exchange_buffers(drawable, event->front, event->back); swap_type = DRI2_EXCHANGE_COMPLETE; } else { @@ -1134,7 +1169,7 @@ static int radeon_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, /* Flips need to be submitted one frame before */ if (info->allowPageFlip && DRI2CanFlip(draw) && - can_exchange(scrn, front, back)) { + can_exchange(scrn, draw, front, back)) { swap_type = DRI2_FLIP; flip = 1; } |