[PATCH xf86-video-ati 1/2] dri2: Update front buffer pixmap and name before exchanging buffers

Ville Syrjala syrjala at sci.fi
Wed May 4 13:51:26 PDT 2011


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 at sci.fi>
---
 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 e618cc5..5d1a382 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -626,12 +626,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;
@@ -642,6 +672,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;
 
@@ -721,7 +756,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,
@@ -736,7 +771,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 {
@@ -1098,7 +1133,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;
     }
-- 
1.7.3.4



More information about the xorg-devel mailing list