From b4ebde23d25bef1b891902d75b2db3aad92685b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 1 Nov 2010 20:27:25 +0200 Subject: [PATCH] xfree86/xv: Fix ReputImage clipping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PutImage/PutStill respect the GC clip, however ReputImage does not. PutImage/PutStill are supposed to be oneshot operations so ReputImage should never expand the area covered by the clip, instead it should only shrink if the window clip shrinks. So commandeer clientClip into use by ReputImage and initially make it a copy of the original GC composite clip. Whenever ReputImage needs reclipping update clientClip with the newly calculated composite clip. Signed-off-by: Ville Syrjälä Reviewed-by: Luc Verhaegen --- hw/xfree86/common/xf86xv.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c index 8ccdf065a..f1cdfe6f8 100644 --- a/hw/xfree86/common/xf86xv.c +++ b/hw/xfree86/common/xf86xv.c @@ -703,6 +703,27 @@ xf86XVCopyClip( portPriv->subWindowMode = pGC->subWindowMode; } +static void +xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv, + GCPtr pGC, + DrawablePtr pDraw) +{ + if (!portPriv->clientClip) + portPriv->clientClip = RegionCreate(NullBox, 1); + /* Keep the original GC composite clip around for ReputImage */ + RegionCopy(portPriv->clientClip, pGC->pCompositeClip); + RegionTranslate(portPriv->clientClip, + -pDraw->x, -pDraw->y); + + /* get rid of the old clip list */ + if (portPriv->pCompositeClip && portPriv->FreeCompositeClip) + RegionDestroy(portPriv->pCompositeClip); + + portPriv->pCompositeClip = pGC->pCompositeClip; + portPriv->FreeCompositeClip = FALSE; + portPriv->subWindowMode = pGC->subWindowMode; +} + static int xf86XVRegetVideo(XvPortRecPrivatePtr portPriv) { @@ -863,6 +884,11 @@ xf86XVReputImage(XvPortRecPrivatePtr portPriv) xf86XVUpdateCompositeClip(portPriv); + /* the clip can get smaller over time */ + RegionCopy(portPriv->clientClip, portPriv->pCompositeClip); + RegionTranslate(portPriv->clientClip, + -portPriv->pDraw->x, -portPriv->pDraw->y); + /* translate the video region to the screen */ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x; WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y; @@ -1411,6 +1437,8 @@ xf86XVPutStill( WinBox.x2 = WinBox.x1 + drw_w; WinBox.y2 = WinBox.y1 + drw_h; + xf86XVCopyCompositeClip(portPriv, pGC, pDraw); + RegionInit(&WinRegion, &WinBox, 1); RegionNull(&ClipRegion); RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); @@ -1479,6 +1507,10 @@ PUT_STILL_BAILOUT: portPriv->isOn = XV_PENDING; } + /* This clip was copied and only good for one shot */ + if(!portPriv->FreeCompositeClip) + portPriv->pCompositeClip = NULL; + RegionUninit(&WinRegion); RegionUninit(&ClipRegion); @@ -1700,6 +1732,8 @@ xf86XVPutImage( if(!portPriv->pScrn->vtSema) return Success; /* Success ? */ + xf86XVCopyCompositeClip(portPriv, pGC, pDraw); + WinBox.x1 = pDraw->x + drw_x; WinBox.y1 = pDraw->y + drw_y; WinBox.x2 = WinBox.x1 + drw_w; @@ -1776,6 +1810,10 @@ PUT_IMAGE_BAILOUT: portPriv->isOn = XV_PENDING; } + /* This clip was copied and only good for one shot */ + if(!portPriv->FreeCompositeClip) + portPriv->pCompositeClip = NULL; + RegionUninit(&WinRegion); RegionUninit(&ClipRegion);