[PATCH v2 10/15] xfree86/xv: Fix ReputImage clipping

ville.syrjala at nokia.com ville.syrjala at nokia.com
Tue Nov 2 11:05:56 PDT 2010


From: Ville Syrjälä <ville.syrjala at nokia.com>

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 at nokia.com>
---
 hw/xfree86/common/xf86xv.c |   38 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 955276d..a8c0a34 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -706,6 +706,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)
 {
@@ -866,6 +887,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;
@@ -1406,6 +1432,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);
@@ -1474,6 +1502,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);
 
@@ -1695,6 +1727,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;
@@ -1771,6 +1805,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);
 
-- 
1.7.2.2



More information about the xorg-devel mailing list