[PATCH v3 4/6] xf86/xv: Fill color key on expose

Pauli ext-pauli.nieminen at nokia.com
Wed Jan 19 14:46:44 PST 2011


From: Pauli Nieminen <ext-pauli.nieminen at nokia.com>

If window gets exposed but clipboxes doesn't change drivers would avoid
color key fill. This makes XResizeWindo&co to lose colorkey if
background is painted.

To help drivers to avoid filling colorkey for each put server can
provide helper function if there is exposed areas. Server can subtract
exposed areas from filled region.

As a side effect we can avoid useless color key fills if window only
moves in screen without background fills.

v3:
* Change tracking to filled area to account for client initiated clip
  changes
* Make overlaid XvPutImage behavior like textured XvPutImage or PutImage
* Make region dynamically allocated only when required.

Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
---
 hw/xfree86/common/xf86xv.c     |   66 ++++++++++++++++++++++++++++++++++++----
 hw/xfree86/common/xf86xv.h     |    7 +++-
 hw/xfree86/common/xf86xvpriv.h |    1 +
 3 files changed, 66 insertions(+), 8 deletions(-)

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 6dcd497..3960940 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -331,6 +331,8 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
 		RegionDestroy(pPriv->clientClip);
 	     if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
 		RegionDestroy(pPriv->pCompositeClip);
+	     if (pPriv->ckeyFilled)
+		RegionDestroy(pPriv->ckeyFilled);
 	     free(pPriv);
 	  }
       }
@@ -1016,7 +1018,6 @@ static void
 xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
 {
      XF86XVWindowPtr winPriv, prevPriv = NULL;
-
      winPriv = GET_XF86XV_WINDOW(pWin);
 
      while(winPriv) {
@@ -1033,6 +1034,10 @@ xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
 	winPriv = winPriv->next;
      }
      portPriv->pDraw = NULL;
+     if (portPriv->ckeyFilled) {
+	RegionDestroy(portPriv->ckeyFilled);
+	portPriv->ckeyFilled = NULL;
+     }
 }
 
 static void
@@ -1165,6 +1170,21 @@ xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
      if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
 	visible = !AreasExposed;
 
+     /*
+      * Subtract exposed areas from overlaid image to match textured video
+      * behavior.
+      */
+     if (!pPriv->type && pPriv->clientClip)
+	    RegionSubtract(pPriv->clientClip, pPriv->clientClip, reg1);
+
+     if (visible && pPriv->ckeyFilled) {
+        RegionRec tmp;
+        RegionNull(&tmp);
+        RegionCopy(&tmp, reg1);
+        RegionTranslate(&tmp, pWin->drawable.x, pWin->drawable.y);
+        RegionSubtract(pPriv->ckeyFilled, pPriv->ckeyFilled, &tmp);
+     }
+
      WinPriv = WinPriv->next;
      xf86XVReputOrStopPort(pPriv, pWin, visible);
   }
@@ -1859,13 +1879,47 @@ xf86XVQueryImageAttributes(
 			format->id, width, height, pitches, offsets);
 }
 
+Bool
+xf86XVGetPortFillArea (DrawablePtr pDraw, pointer data, RegionPtr clipboxes, RegionPtr fillboxes)
+{
+    WindowPtr pWin = (WindowPtr)pDraw;
+    XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+    XvPortRecPrivatePtr portPriv = NULL;
+
+    while (WinPriv) {
+	XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+	if (data == pPriv->DevPriv.ptr) {
+	    portPriv = pPriv;
+	    break;
+	}
+
+	WinPriv = WinPriv->next;
+    }
+
+    if (!portPriv)
+	return FALSE;
+
+    if (!portPriv->ckeyFilled)
+	portPriv->ckeyFilled = RegionCreate(NULL, 0);
+
+    RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled);
+
+    if (!RegionNotEmpty(fillboxes))
+	return FALSE;
+
+    RegionCopy(portPriv->ckeyFilled, clipboxes);
+
+    return TRUE;
+}
+
 void
-xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes)
 {
    ScreenPtr pScreen = pDraw->pScreen;
    ChangeGCVal pval[2];
-   BoxPtr pbox = RegionRects(clipboxes);
-   int i, nbox = RegionNumRects(clipboxes);
+   BoxPtr pbox = RegionRects(fillboxes);
+   int i, nbox = RegionNumRects(fillboxes);
    xRectangle *rects;
    GCPtr gc;
 
@@ -1894,9 +1948,9 @@ xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
 }
 
 void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes)
 {
-    xf86XVFillKeyHelperDrawable (&pScreen->root->drawable, key, clipboxes);
+    xf86XVFillKeyHelperDrawable (&pScreen->root->drawable, key, fillboxes);
 }
 
 /* xf86XVClipVideoHelper -
diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h
index 47061fe..3243ccc 100644
--- a/hw/xfree86/common/xf86xv.h
+++ b/hw/xfree86/common/xf86xv.h
@@ -239,10 +239,13 @@ extern _X_EXPORT XF86VideoAdaptorPtr xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr p
 extern _X_EXPORT void xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr);
 
 extern _X_EXPORT void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes);
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr fillboxes);
 
 extern _X_EXPORT void
-xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes);
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr fillboxes);
+
+extern _X_EXPORT Bool
+xf86XVGetPortFillArea (DrawablePtr pDraw, pointer data, RegionPtr clipboxes, RegionPtr fillboxes);
 
 extern _X_EXPORT Bool
 xf86XVClipVideoHelper(
diff --git a/hw/xfree86/common/xf86xvpriv.h b/hw/xfree86/common/xf86xvpriv.h
index 4572218..3f1106d 100644
--- a/hw/xfree86/common/xf86xvpriv.h
+++ b/hw/xfree86/common/xf86xvpriv.h
@@ -68,6 +68,7 @@ typedef struct {
    unsigned char type;
    unsigned int subWindowMode;
    RegionPtr clientClip;
+   RegionPtr ckeyFilled;
    RegionPtr pCompositeClip;
    Bool FreeCompositeClip;
    XvAdaptorRecPrivatePtr AdaptorRec;
-- 
1.7.0.4



More information about the xorg-devel mailing list