summaryrefslogtreecommitdiff
path: root/src/radeon_dri2.c
diff options
context:
space:
mode:
authorVille Syrjala <syrjala@sci.fi>2011-05-04 23:51:26 +0300
committerAlex Deucher <alexander.deucher@amd.com>2011-08-01 09:10:35 -0400
commit9493563c1ef4b51af0ee8a44cb4e7c5bb280347e (patch)
tree5507e821f4930ec8c49aad0565aab1bbf6b6e88e /src/radeon_dri2.c
parent8c9266ed2da22a510243f9a952c14d4423f48a2b (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>
Diffstat (limited to 'src/radeon_dri2.c')
-rw-r--r--src/radeon_dri2.c45
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;
}