summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@nokia.com>2010-11-01 20:27:25 +0200
committerVille Syrjälä <ville.syrjala@nokia.com>2010-11-26 18:01:05 +0200
commitb4ebde23d25bef1b891902d75b2db3aad92685b7 (patch)
tree3189956d8badbb85fdfe66d3c7d7dce87dd283fb /hw
parent7294236bdb29b4fa7a7bc27aff9c786c5a33c544 (diff)
xfree86/xv: Fix ReputImage clipping
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ä <ville.syrjala@nokia.com> Reviewed-by: Luc Verhaegen <luc.verhaegen@basyskom.de>
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/common/xf86xv.c38
1 files changed, 38 insertions, 0 deletions
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);