xserver: Branch 'master' - 8 commits

Keith Packard keithp at kemper.freedesktop.org
Fri Feb 18 11:44:31 PST 2011


 hw/xfree86/common/xf86xv.c     |  210 +++++++++++++++----------
 hw/xfree86/common/xf86xv.h     |    3 
 hw/xfree86/common/xf86xvpriv.h |    6 
 randr/rrcrtc.c                 |  332 ++++++++++++++++++++++++-----------------
 4 files changed, 333 insertions(+), 218 deletions(-)

New commits:
commit b17381aa746ec1407ec57a588d5cc11e0fd4962e
Merge: 82d2666... 5d020c3...
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Feb 18 11:43:41 2011 -0800

    Merge remote branch 'suokko/xv_color_key_fill'

commit 82d2666afd88f57b6a7b885b2b305fd36b450947
Author: Keith Packard <keithp at keithp.com>
Date:   Wed Feb 16 22:58:10 2011 -0800

    randr: Add 'set' fields to SetCrtcConfigs request
    
    This permits clients to perform incremental configuration changes
    instead of requiring a complete new configuration to be written.
    
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 5fe6900..07e9019 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1483,63 +1483,82 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
     PixmapPtr		pixmap;
     int			rc, i, j;
     Rotation		rotation;
+    int			numOutputs;
 
     VERIFY_RR_CRTC(x->crtc, crtc, DixSetAttrAccess);
 
-    if (x->mode == None)
-    {
-	mode = NULL;
-	if (x->nOutput > 0)
-	    return BadMatch;
+    mode = crtc->mode;
+    numOutputs = crtc->numOutputs;
+
+    if (x->set & RR_SetCrtcOutputs)
+	numOutputs = x->nOutput;
+
+    if (x->set & RR_SetCrtcMode) {
+	if (x->mode == None)
+	    mode = NULL;
+	else
+	{
+	    VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess);
+	    if (x->nOutput == 0)
+		return BadMatch;
+	}
     }
-    else
+
+    if (numOutputs)
     {
-	VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess);
-	if (x->nOutput == 0)
+	if (mode == NULL)
 	    return BadMatch;
-    }
-    if (x->nOutput)
-    {
-	outputs = malloc(x->nOutput * sizeof (RROutputPtr));
+	outputs = malloc(numOutputs * sizeof (RROutputPtr));
 	if (!outputs)
 	    return BadAlloc;
     }
-    else
+    else {
+	if (mode != NULL)
+	    return BadMatch;
 	outputs = NULL;
-
-    if (x->pixmap == None)
-	pixmap = NULL;
-    else if (x->pixmap == RR_CurrentScanoutPixmap)
-	pixmap = crtc->scanoutPixmap;
-    else
-    {
-	rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap,
-				     RT_PIXMAP, client, DixWriteAccess);
-	if (rc != Success) {
-	    free(outputs);
-	    return rc;
-	}
-	/* XXX check to make sure this is a scanout pixmap */
     }
 
-    for (i = 0; i < x->nOutput; i++)
-    {
-	rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
-				     RROutputType, client, DixSetAttrAccess);
-	if (rc != Success)
+    if (x->set & RR_SetCrtcPixmap) {
+	if (x->pixmap == None)
+	    pixmap = NULL;
+	else
 	{
-	    free(outputs);
-	    return rc;
+	    rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap,
+					 RT_PIXMAP, client, DixWriteAccess);
+	    if (rc != Success) {
+		free(outputs);
+		return rc;
+	    }
+	    /* XXX check to make sure this is a scanout pixmap */
 	}
-	/* validate crtc for this output */
-	for (j = 0; j < outputs[i]->numCrtcs; j++)
-	    if (outputs[i]->crtcs[j] == crtc)
-		break;
-	if (j == outputs[i]->numCrtcs)
+    } else
+	pixmap = crtc->scanoutPixmap;
+
+    if (x->set & RR_SetCrtcOutputs) {
+	for (i = 0; i < numOutputs; i++)
 	{
-	    free(outputs);
-	    return BadMatch;
+	    rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
+					 RROutputType, client, DixSetAttrAccess);
+	    if (rc != Success)
+	    {
+		free(outputs);
+		return rc;
+	    }
+	    /* validate crtc for this output */
+	    for (j = 0; j < outputs[i]->numCrtcs; j++)
+		if (outputs[i]->crtcs[j] == crtc)
+		    break;
+	    if (j == outputs[i]->numCrtcs)
+	    {
+		free(outputs);
+		return BadMatch;
+	    }
 	}
+    } else
+	memcpy(outputs, crtc->outputs, numOutputs * sizeof (RROutputPtr));
+
+    for (i = 0; i < numOutputs; i++)
+    {
 	/* validate mode for this output */
 	for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
 	{
@@ -1555,10 +1574,11 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
 	    return BadMatch;
 	}
     }
+
     /* validate clones */
-    for (i = 0; i < x->nOutput; i++)
+    for (i = 0; i < numOutputs; i++)
     {
-	for (j = 0; j < x->nOutput; j++)
+	for (j = 0; j < numOutputs; j++)
 	{
 	    int k;
 	    if (i == j)
@@ -1579,46 +1599,68 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
     if (crtc->pScreen != screen)
 	return BadMatch;
 
+    rotation = crtc->rotation;
+    if (x->set & RR_SetCrtcRotation) {
+	/*
+	 * Validate requested rotation
+	 */
+	rotation = (Rotation) x->rotation;
+
+	/* test the rotation bits only! */
+	switch (rotation & 0xf) {
+	case RR_Rotate_0:
+	case RR_Rotate_90:
+	case RR_Rotate_180:
+	case RR_Rotate_270:
+	    break;
+	default:
+	    /*
+	     * Invalid rotation
+	     */
+	    client->errorValue = x->rotation;
+	    free(outputs);
+	    return BadValue;
+	}
+    }
+
     scr_priv = rrGetScrPriv(screen);
 
     config->crtc = crtc;
-    config->x = x->x;
-    config->y = x->y;
+    config->x = crtc->x;
+    config->y = crtc->y;
+    if (x->set & RR_SetCrtcPosition) {
+	config->x = x->x;
+	config->y = x->y;
+    }
     config->mode = mode;
-    config->rotation = x->rotation;
-    config->numOutputs = x->nOutput;
+    config->rotation = rotation;
+    config->numOutputs = numOutputs;
     config->outputs = outputs;
-    PictTransform_from_xRenderTransform(&config->sprite_position_transform,
-					     &x->spritePositionTransform);
-    PictTransform_from_xRenderTransform(&config->sprite_image_transform,
-					     &x->spriteImageTransform);
-    pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform,
-					     &config->sprite_position_transform);
-    pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform,
-					     &config->sprite_image_transform);
-    config->pixmap = pixmap;
-    config->pixmap_x = x->xPixmap;
-    config->pixmap_y = x->yPixmap;
-
-    /*
-     * Validate requested rotation
-     */
-    rotation = (Rotation) x->rotation;
 
-    /* test the rotation bits only! */
-    switch (rotation & 0xf) {
-    case RR_Rotate_0:
-    case RR_Rotate_90:
-    case RR_Rotate_180:
-    case RR_Rotate_270:
-	break;
-    default:
-	/*
-	 * Invalid rotation
-	 */
-	client->errorValue = x->rotation;
-	free(outputs);
-	return BadValue;
+    if (x->set & RR_SetCrtcSpritePositionTransform) {
+	PictTransform_from_xRenderTransform(&config->sprite_position_transform,
+					    &x->spritePositionTransform);
+	pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform,
+						 &config->sprite_position_transform);
+    } else {
+	config->sprite_position_transform = crtc->client_sprite_position_transform;
+	config->sprite_position_f_transform = crtc->client_sprite_f_position_transform;
+    }
+    if (x->set & RR_SetCrtcSpriteImageTransform) {
+	PictTransform_from_xRenderTransform(&config->sprite_image_transform,
+					    &x->spriteImageTransform);
+	pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform,
+						 &config->sprite_image_transform);
+    } else {
+	config->sprite_image_transform = crtc->client_sprite_image_transform;
+	config->sprite_image_f_transform = crtc->client_sprite_f_image_transform;
+    }
+    config->pixmap = pixmap;
+    config->pixmap_x = crtc->x;
+    config->pixmap_y = crtc->y;
+    if (x->set & RR_SetCrtcPixmapPosition) {
+	config->pixmap_x = x->xPixmap;
+	config->pixmap_y = x->yPixmap;
     }
 
     if (mode)
@@ -1628,7 +1670,7 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
 	    /*
 	     * requested rotation or reflection not supported by screen
 	     */
-	    client->errorValue = x->rotation;
+	    client->errorValue = rotation;
 	    free(outputs);
 	    return BadMatch;
 	}
@@ -1639,13 +1681,13 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
 	 */
 	if (pixmap)
 	{
-	    if (x->xPixmap + mode->mode.width > pixmap->drawable.width) {
-		client->errorValue = x->xPixmap;
+	    if (config->pixmap_x + mode->mode.width > pixmap->drawable.width) {
+		client->errorValue = config->pixmap_x;
 		free(outputs);
 		return BadValue;
 	    }
-	    if (x->yPixmap + mode->mode.height > pixmap->drawable.height) {
-		client->errorValue = x->yPixmap;
+	    if (config->pixmap_y + mode->mode.height > pixmap->drawable.height) {
+		client->errorValue = config->pixmap_y;
 		free(outputs);
 		return BadValue;
 	    }
@@ -1687,13 +1729,15 @@ ProcRRSetCrtcConfigs (ClientPtr client)
     int			    num_configs = 0;
     int			    rc, i;
     int			    extra_len;
-    int			    num_output_ids;
+    int			    num_output_ids = 0;
 
     REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq);
 
     extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq));
 
-    num_configs = stuff->nConfigs;
+    num_configs = 0;
+    if (stuff->set & RR_SetScreenCrtcs)
+	num_configs = stuff->nConfigs;
 
     /* Check request length against number of configs specified */
     if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len)
@@ -1702,10 +1746,11 @@ ProcRRSetCrtcConfigs (ClientPtr client)
     extra_len -= num_configs * (sizeof (xRRCrtcConfig) >> 2);
     x_configs = (xRRCrtcConfig *) (stuff + 1);
 
-    /* Check remaining request length against number of outputs */
-    num_output_ids = 0;
-    for (i = 0; i < num_configs; i++)
-	num_output_ids += x_configs[i].nOutput;
+    if (stuff->set & RR_SetScreenCrtcs) {
+	/* Check remaining request length against number of outputs */
+	for (i = 0; i < num_configs; i++)
+	    num_output_ids += x_configs[i].nOutput;
+    }
 
     if (extra_len != num_output_ids)
 	return BadLength;
@@ -1724,57 +1769,84 @@ ProcRRSetCrtcConfigs (ClientPtr client)
 	goto sendReply;
     }
 
-    if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
-    {
-	client->errorValue = 0;
-	return BadValue;
+    if (stuff->set & RR_SetScreenSizeInMillimeters) {
+	if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
+	{
+	    client->errorValue = 0;
+	    return BadValue;
+	}
+	screen_config.mm_width = stuff->widthInMillimeters;
+	screen_config.mm_height = stuff->heightInMillimeters;
+    } else {
+	screen_config.mm_width = screen->mmWidth;
+	screen_config.mm_height = screen->mmHeight;
     }
 
-    if (stuff->screenPixmapWidth < scr_priv->minWidth ||
-	scr_priv->maxWidth < stuff->screenPixmapWidth)
-    {
-	client->errorValue = stuff->screenPixmapWidth;
-	return BadValue;
-    }
-    if (stuff->screenPixmapHeight < scr_priv->minHeight ||
-	scr_priv->maxHeight < stuff->screenPixmapHeight)
-    {
-	client->errorValue = stuff->screenPixmapHeight;
-	return BadValue;
+    if (stuff->set & RR_SetScreenPixmapSize) {
+	if (stuff->screenPixmapWidth < scr_priv->minWidth ||
+	    scr_priv->maxWidth < stuff->screenPixmapWidth)
+	{
+	    client->errorValue = stuff->screenPixmapWidth;
+	    return BadValue;
+	}
+	if (stuff->screenPixmapHeight < scr_priv->minHeight ||
+	    scr_priv->maxHeight < stuff->screenPixmapHeight)
+	{
+	    client->errorValue = stuff->screenPixmapHeight;
+	    return BadValue;
+	}
+	screen_config.screen_pixmap_width = stuff->screenPixmapWidth;
+	screen_config.screen_pixmap_height = stuff->screenPixmapHeight;
+    } else {
+	PixmapPtr	screen_pixmap = screen->GetScreenPixmap(screen);
+	screen_config.screen_pixmap_width = screen_pixmap->drawable.width;
+	screen_config.screen_pixmap_height = screen_pixmap->drawable.height;
+    }
+
+    if (stuff->set & RR_SetScreenSize) {
+	if (stuff->screenWidth <= 0 || stuff->screenWidth > 32767) {
+	    client->errorValue = stuff->screenWidth;
+	    return BadValue;
+	}
+	screen_config.screen_width = stuff->screenWidth;
+
+	if (stuff->screenHeight <= 0 || stuff->screenHeight > 32767) {
+	    client->errorValue = stuff->screenHeight;
+	    return BadValue;
+	}
+	screen_config.screen_height = stuff->screenHeight;
+    } else {
+	WindowPtr root = screen->root;
+	screen_config.screen_width = root->drawable.width;
+	screen_config.screen_height = root->drawable.height;
     }
 
-    screen_config.screen_pixmap_width = stuff->screenPixmapWidth;
-    screen_config.screen_pixmap_height = stuff->screenPixmapHeight;
-    screen_config.screen_width = stuff->screenWidth;
-    screen_config.screen_height = stuff->screenHeight;
-    screen_config.mm_width = stuff->widthInMillimeters;
-    screen_config.mm_height = stuff->heightInMillimeters;
+    if (num_configs > 0) {
 
-    output_ids = (RROutput *) (x_configs + num_configs);
+	output_ids = (RROutput *) (x_configs + num_configs);
+	/*
+	 * Convert protocol crtc configurations into
+	 * server crtc configurations
+	 */
+	configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
+	if (configs == NULL)
+	    return BadAlloc;
+	for (i = 0; i < num_configs; i++) {
+	    rc = RRConvertCrtcConfig(client, screen, &screen_config,
+				     &configs[i],
+				     &x_configs[i], output_ids);
+	    if (rc != Success) {
+		rep.status = RRSetConfigFailed;
+		goto sendReply;
+	    }
+	    output_ids += x_configs[i].nOutput;
+	}
 
-    /*
-     * Convert protocol crtc configurations into
-     * server crtc configurations
-     */
-    configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
-    if (num_configs > 0 && configs == NULL)
-	return BadAlloc;
-    for (i = 0; i < num_configs; i++) {
-	rc = RRConvertCrtcConfig(client, screen, &screen_config,
-				 &configs[i],
-				 &x_configs[i], output_ids);
-	if (rc != Success) {
+	if (!RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
+	{
 	    rep.status = RRSetConfigFailed;
 	    goto sendReply;
 	}
-	output_ids += x_configs[i].nOutput;
-    }
-
-    if (num_configs &&
-	!RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
-    {
-	rep.status = RRSetConfigFailed;
-	goto sendReply;
     }
     rep.status = RRSetConfigSuccess;
     scr_priv->lastSetTime = currentTime;
commit 5d020c31351594c104fb46615ce41f256cd8e8b9
Author: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
Date:   Fri Jan 14 15:03:28 2011 +0200

    xf86/xv: Only register PostValidateTree hook when there is work to do
    
    If none of Xv ports were affected by window tree modifications we don't
    want scan the port list. To avoid useless scanning of port list
    PostValidateTree hook is only registered when ClipNotify was called for
    any port.
    
    Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index ea286df..53ebe8f 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -100,6 +100,8 @@ static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
 static void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind);
 static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
 
+#define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1)
+
 /* ScrnInfoRec functions */
 
 static Bool xf86XVEnterVT(int, int);
@@ -283,7 +285,7 @@ xf86XVScreenInit(
 
   ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
   ScreenPriv->WindowExposures = pScreen->WindowExposures;
-  ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
+  ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
   ScreenPriv->ClipNotify = pScreen->ClipNotify;
   ScreenPriv->EnterVT = pScrn->EnterVT;
   ScreenPriv->LeaveVT = pScrn->LeaveVT;
@@ -292,7 +294,6 @@ xf86XVScreenInit(
 
   pScreen->DestroyWindow = xf86XVDestroyWindow;
   pScreen->WindowExposures = xf86XVWindowExposures;
-  pScreen->PostValidateTree = xf86XVPostValidateTree;
   pScreen->ClipNotify = xf86XVClipNotify;
   pScrn->EnterVT = xf86XVEnterVT;
   pScrn->LeaveVT = xf86XVLeaveVT;
@@ -1165,12 +1166,11 @@ xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind)
 
     xf86XVReputOrStopAllPorts(pScrn, TRUE);
 
-    if (ScreenPriv->PostValidateTree) {
-	pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
+    pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
+    if (pScreen->PostValidateTree) {
 	(*pScreen->PostValidateTree)(pWin, pLayerWin, kind);
-	ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
-	pScreen->PostValidateTree = xf86XVPostValidateTree;
     }
+    ScreenPriv->PostValidateTree = PostValidateTreeUndefined;
 }
 
 static void
@@ -1247,6 +1247,11 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
 
      pPriv->clipChanged = TRUE;
 
+     if (ScreenPriv->PostValidateTree == PostValidateTreeUndefined) {
+        ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
+        pScreen->PostValidateTree = xf86XVPostValidateTree;
+     }
+
      WinPriv = WinPriv->next;
   }
 
@@ -1274,7 +1279,6 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
 
   pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
   pScreen->WindowExposures = ScreenPriv->WindowExposures;
-  pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
   pScreen->ClipNotify = ScreenPriv->ClipNotify;
 
   pScrn->EnterVT = ScreenPriv->EnterVT;
commit ddf32df5cc2e73b833f6e414276d938fdc38869e
Author: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
Date:   Thu Jan 13 20:50:16 2011 +0200

    xf86/xv: Use PostValidateTree to do reput
    
    ValidateTree calls first ClipNotify and later might call
    WindowExposures. To avoid useless double reput ClipNotify delays reput
    to WindowExposures or PostValidateTree.
    
    PostValidatTree checks all ports if there is clip changes. On clip
    changes reput is done to move or scale the overlay.
    
    Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 21e0035..ea286df 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -97,6 +97,7 @@ static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
 
 static Bool xf86XVDestroyWindow(WindowPtr pWin);
 static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
+static void xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind);
 static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
 
 /* ScrnInfoRec functions */
@@ -282,6 +283,7 @@ xf86XVScreenInit(
 
   ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
   ScreenPriv->WindowExposures = pScreen->WindowExposures;
+  ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
   ScreenPriv->ClipNotify = pScreen->ClipNotify;
   ScreenPriv->EnterVT = pScrn->EnterVT;
   ScreenPriv->LeaveVT = pScrn->LeaveVT;
@@ -290,6 +292,7 @@ xf86XVScreenInit(
 
   pScreen->DestroyWindow = xf86XVDestroyWindow;
   pScreen->WindowExposures = xf86XVWindowExposures;
+  pScreen->PostValidateTree = xf86XVPostValidateTree;
   pScreen->ClipNotify = xf86XVClipNotify;
   pScrn->EnterVT = xf86XVEnterVT;
   pScrn->LeaveVT = xf86XVLeaveVT;
@@ -1038,6 +1041,7 @@ xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
 	RegionDestroy(portPriv->ckeyFilled);
 	portPriv->ckeyFilled = NULL;
      }
+     portPriv->clipChanged = FALSE;
 }
 
 static void
@@ -1072,7 +1076,7 @@ xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv,
 }
 
 static void
-xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
+xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn, Bool onlyChanged)
 {
     ScreenPtr pScreen = pScrn->pScreen;
     XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
@@ -1090,6 +1094,9 @@ xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
 	    if (pPriv->isOn == XV_OFF || !pWin)
 		continue;
 
+	    if (onlyChanged && !pPriv->clipChanged)
+		continue;
+
 	    visible = pWin->visibility == VisibilityUnobscured ||
 		      pWin->visibility == VisibilityPartiallyObscured;
 
@@ -1101,6 +1108,8 @@ xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn)
 		visible = FALSE;
 
 	    xf86XVReputOrStopPort(pPriv, pWin, visible);
+
+	    pPriv->clipChanged = FALSE;
 	}
     }
 }
@@ -1139,6 +1148,30 @@ xf86XVDestroyWindow(WindowPtr pWin)
   return ret;
 }
 
+static void
+xf86XVPostValidateTree(WindowPtr pWin, WindowPtr pLayerWin, VTKind kind)
+{
+    ScreenPtr pScreen;
+    XF86XVScreenPtr ScreenPriv;
+    ScrnInfoPtr pScrn;
+
+    if (pWin)
+	pScreen = pWin->drawable.pScreen;
+    else
+	pScreen = pLayerWin->drawable.pScreen;
+
+    ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+    pScrn = xf86Screens[pScreen->myNum];
+
+    xf86XVReputOrStopAllPorts(pScrn, TRUE);
+
+    if (ScreenPriv->PostValidateTree) {
+	pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
+	(*pScreen->PostValidateTree)(pWin, pLayerWin, kind);
+	ScreenPriv->PostValidateTree = pScreen->PostValidateTree;
+	pScreen->PostValidateTree = xf86XVPostValidateTree;
+    }
+}
 
 static void
 xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
@@ -1187,10 +1220,11 @@ xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
 
      WinPriv = WinPriv->next;
      xf86XVReputOrStopPort(pPriv, pWin, visible);
+
+     pPriv->clipChanged = FALSE;
   }
 }
 
-
 static void
 xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
 {
@@ -1200,9 +1234,6 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
   XvPortRecPrivatePtr pPriv;
 
   while(WinPriv) {
-     Bool visible = pWin->visibility == VisibilityUnobscured ||
-		    pWin->visibility == VisibilityPartiallyObscured;
-
      pPriv = WinPriv->PortRec;
 
      if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
@@ -1214,15 +1245,9 @@ xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
         (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
                                          pWin, dx, dy);
 
-     /*
-      * Stop and remove still/images if
-      * ReputImage isn't supported.
-      */
-     if (!pPriv->type && !pPriv->AdaptorRec->ReputImage)
-	visible = FALSE;
+     pPriv->clipChanged = TRUE;
 
      WinPriv = WinPriv->next;
-     xf86XVReputOrStopPort(pPriv, pWin, visible);
   }
 
   if(ScreenPriv->ClipNotify) {
@@ -1249,6 +1274,7 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
 
   pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
   pScreen->WindowExposures = ScreenPriv->WindowExposures;
+  pScreen->PostValidateTree = ScreenPriv->PostValidateTree;
   pScreen->ClipNotify = ScreenPriv->ClipNotify;
 
   pScrn->EnterVT = ScreenPriv->EnterVT;
@@ -1355,7 +1381,7 @@ xf86XVAdjustFrame(int index, int x, int y, int flags)
 	pScrn->AdjustFrame = xf86XVAdjustFrame;
   }
 
-  xf86XVReputOrStopAllPorts(pScrn);
+  xf86XVReputOrStopAllPorts(pScrn, FALSE);
 }
 
 static void
@@ -1376,7 +1402,7 @@ xf86XVModeSet(ScrnInfoPtr pScrn)
 	pScrn->ModeSet = xf86XVModeSet;
     }
 
-    xf86XVReputOrStopAllPorts(pScrn);
+    xf86XVReputOrStopAllPorts(pScrn, FALSE);
 }
 
 /**** XvAdaptorRec fields ****/
diff --git a/hw/xfree86/common/xf86xvpriv.h b/hw/xfree86/common/xf86xvpriv.h
index 3f1106d..2a459f1 100644
--- a/hw/xfree86/common/xf86xvpriv.h
+++ b/hw/xfree86/common/xf86xvpriv.h
@@ -40,6 +40,7 @@ typedef struct {
    DestroyWindowProcPtr		DestroyWindow;
    ClipNotifyProcPtr		ClipNotify;
    WindowExposuresProcPtr	WindowExposures;
+   PostValidateTreeProcPtr	PostValidateTree;
    void                         (*AdjustFrame)(int, int, int, int);
    Bool                         (*EnterVT)(int, int);
    void                         (*LeaveVT)(int, int);
@@ -73,6 +74,7 @@ typedef struct {
    Bool FreeCompositeClip;
    XvAdaptorRecPrivatePtr AdaptorRec;
    XvStatus isOn;
+   Bool clipChanged;
    int vid_x, vid_y, vid_w, vid_h;
    int drw_x, drw_y, drw_w, drw_h;
    DevUnion DevPriv;
commit 5678a41f6bc0ef8965bd50a88c5ef01ba7eb8b24
Author: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
Date:   Mon Jan 17 16:58:00 2011 +0200

    xf86/xv: Fill color key on expose
    
    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.
    
    v4:
    * Simplify new driver interface to reduce duplicate code
    
    Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 6dcd497..21e0035 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);
   }
@@ -1860,12 +1880,12 @@ xf86XVQueryImageAttributes(
 }
 
 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,11 +1914,57 @@ 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);
 }
 
+void
+xf86XVFillKeyHelperPort (DrawablePtr pDraw, pointer data, CARD32 key, RegionPtr clipboxes, Bool fillEverything)
+{
+    WindowPtr pWin = (WindowPtr)pDraw;
+    XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+    XvPortRecPrivatePtr portPriv = NULL;
+    RegionRec reg;
+    RegionPtr fillboxes;
+
+    while (WinPriv) {
+	XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+	if (data == pPriv->DevPriv.ptr) {
+	    portPriv = pPriv;
+	    break;
+	}
+
+	WinPriv = WinPriv->next;
+    }
+
+    if (!portPriv)
+	return;
+
+    if (!portPriv->ckeyFilled)
+	portPriv->ckeyFilled = RegionCreate(NULL, 0);
+
+    if (!fillEverything) {
+	RegionNull(&reg);
+	fillboxes = &reg;
+	RegionSubtract(fillboxes, clipboxes, portPriv->ckeyFilled);
+
+	if (!RegionNotEmpty(fillboxes))
+	    goto out;
+    } else
+	fillboxes = clipboxes;
+
+
+    RegionCopy(portPriv->ckeyFilled, clipboxes);
+
+    xf86XVFillKeyHelperDrawable(pDraw, key, fillboxes);
+out:
+    if (!fillEverything)
+        RegionUninit(&reg);
+}
+
+
 /* xf86XVClipVideoHelper -
 
    Takes the dst box in standard X BoxRec form (top and left
diff --git a/hw/xfree86/common/xf86xv.h b/hw/xfree86/common/xf86xv.h
index 47061fe..f0d8495 100644
--- a/hw/xfree86/common/xf86xv.h
+++ b/hw/xfree86/common/xf86xv.h
@@ -244,6 +244,9 @@ xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes);
 extern _X_EXPORT void
 xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes);
 
+extern _X_EXPORT void
+xf86XVFillKeyHelperPort (DrawablePtr pDraw, pointer data, CARD32 key, RegionPtr clipboxes, Bool fillEverything);
+
 extern _X_EXPORT Bool
 xf86XVClipVideoHelper(
     BoxPtr dst,
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;
commit 9b048ca420864e19862f63f4a491a4da0ff9b54f
Author: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
Date:   Mon Jan 17 15:07:28 2011 +0200

    xf86/xv: Remove unused variable from XvPortRecPrivate
    
    Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/hw/xfree86/common/xf86xvpriv.h b/hw/xfree86/common/xf86xvpriv.h
index c667926..4572218 100644
--- a/hw/xfree86/common/xf86xvpriv.h
+++ b/hw/xfree86/common/xf86xvpriv.h
@@ -72,7 +72,6 @@ typedef struct {
    Bool FreeCompositeClip;
    XvAdaptorRecPrivatePtr AdaptorRec;
    XvStatus isOn;
-   Bool moved;
    int vid_x, vid_y, vid_w, vid_h;
    int drw_x, drw_y, drw_w, drw_h;
    DevUnion DevPriv;
commit 4f8f803280894a8c41691e350b7a34bfd719fe05
Author: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
Date:   Thu Jan 13 20:21:09 2011 +0200

    xf86/xv: Remove unused GC pointers
    
    Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index f1a87f1..6dcd497 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -280,8 +280,6 @@ xf86XVScreenInit(
 
   pScrn = xf86Screens[pScreen->myNum];
 
-  ScreenPriv->videoGC = NULL;  /* for the helper */
-
   ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
   ScreenPriv->WindowExposures = pScreen->WindowExposures;
   ScreenPriv->ClipNotify = pScreen->ClipNotify;
@@ -1123,9 +1121,6 @@ xf86XVDestroyWindow(WindowPtr pWin)
 
      pPriv->pDraw = NULL;
      tmp = WinPriv;
-     if(WinPriv->pGC) {
-       FreeGC(WinPriv->pGC, 0);
-     }
      WinPriv = WinPriv->next;
      free(tmp);
   }
@@ -1232,11 +1227,6 @@ xf86XVCloseScreen(int i, ScreenPtr pScreen)
 
   if(!ScreenPriv) return TRUE;
 
-  if(ScreenPriv->videoGC) {
-     FreeGC(ScreenPriv->videoGC, 0);
-     ScreenPriv->videoGC = NULL;
-  }
-
   pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
   pScreen->WindowExposures = ScreenPriv->WindowExposures;
   pScreen->ClipNotify = ScreenPriv->ClipNotify;
diff --git a/hw/xfree86/common/xf86xvpriv.h b/hw/xfree86/common/xf86xvpriv.h
index 88e7a0e..c667926 100644
--- a/hw/xfree86/common/xf86xvpriv.h
+++ b/hw/xfree86/common/xf86xvpriv.h
@@ -43,7 +43,6 @@ typedef struct {
    void                         (*AdjustFrame)(int, int, int, int);
    Bool                         (*EnterVT)(int, int);
    void                         (*LeaveVT)(int, int);
-   GCPtr			videoGC;
    xf86ModeSetProc		*ModeSet;
 } XF86XVScreenRec, *XF86XVScreenPtr;
 
@@ -82,7 +81,6 @@ typedef struct {
 typedef struct _XF86XVWindowRec{
    XvPortRecPrivatePtr PortRec;
    struct _XF86XVWindowRec *next;
-   GCPtr pGC;
 } XF86XVWindowRec, *XF86XVWindowPtr;
 
 #endif  /* _XF86XVPRIV_H_ */
commit e012f2312b4bcdf31bb5d622ddd34571f3c12429
Author: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
Date:   Thu Jan 13 20:19:18 2011 +0200

    xf86/xv: Remove copy paste code.
    
    xf86XVFillKeyHelperDrawable can be used to implement
    xf86XVFillKeyHelper.
    
    V2:
    * Remove RegionTranslate that clobbered parameter region.
    
    Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
    Reviewed-by: Ville Syrjälä <ville.syrjala at nokia.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 016db1f..f1a87f1 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -1869,62 +1869,10 @@ xf86XVQueryImageAttributes(
 			format->id, width, height, pitches, offsets);
 }
 
-
 void
 xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
 {
    ScreenPtr pScreen = pDraw->pScreen;
-   WindowPtr pWin = (WindowPtr)pDraw;
-   XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
-   GCPtr pGC = NULL;
-   BoxPtr pbox = RegionRects(clipboxes);
-   int i, nbox = RegionNumRects(clipboxes);
-   xRectangle *rects;
-
-   if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
-   if(pPriv)
-      pGC = pPriv->pGC;
-
-   if(!pGC) {
-       int status;
-       XID pval[2];
-       pval[0] = key;
-       pval[1] = IncludeInferiors;
-       pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status,
-		      (XID)0, serverClient);
-       if(!pGC) return;
-       ValidateGC(pDraw, pGC);
-       if (pPriv) pPriv->pGC = pGC;
-   } else if (key != pGC->fgPixel){
-       ChangeGCVal val;
-       val.val = key;
-       ChangeGC(NullClient, pGC, GCForeground, &val);
-       ValidateGC(pDraw, pGC);
-   }
-
-   RegionTranslate(clipboxes, -pDraw->x, -pDraw->y);
-
-   rects = malloc(nbox * sizeof(xRectangle));
-
-   for(i = 0; i < nbox; i++, pbox++) {
-      rects[i].x = pbox->x1;
-      rects[i].y = pbox->y1;
-      rects[i].width = pbox->x2 - pbox->x1;
-      rects[i].height = pbox->y2 - pbox->y1;
-   }
-
-   (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
-
-   if (!pPriv) FreeGC(pGC, 0);
-
-   free(rects);
-}
-
-void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
-{
-   DrawablePtr root = &pScreen->root->drawable;
    ChangeGCVal pval[2];
    BoxPtr pbox = RegionRects(clipboxes);
    int i, nbox = RegionNumRects(clipboxes);
@@ -1933,28 +1881,34 @@ xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
 
    if(!xf86Screens[pScreen->myNum]->vtSema) return;
 
-   gc = GetScratchGC(root->depth, pScreen);
+   gc = GetScratchGC(pDraw->depth, pScreen);
    pval[0].val = key;
    pval[1].val = IncludeInferiors;
    (void) ChangeGC(NullClient, gc, GCForeground|GCSubwindowMode, pval);
-   ValidateGC(root, gc);
+   ValidateGC(pDraw, gc);
 
    rects = malloc(nbox * sizeof(xRectangle));
 
    for(i = 0; i < nbox; i++, pbox++) 
    {
-      rects[i].x = pbox->x1;
-      rects[i].y = pbox->y1;
+      rects[i].x = pbox->x1 - pDraw->x;
+      rects[i].y = pbox->y1 - pDraw->y;
       rects[i].width = pbox->x2 - pbox->x1;
       rects[i].height = pbox->y2 - pbox->y1;
    }
    
-   (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
+   (*gc->ops->PolyFillRect)(pDraw, gc, nbox, rects);
    
    free(rects);
    FreeScratchGC (gc);
 }
 
+void
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
+{
+    xf86XVFillKeyHelperDrawable (&pScreen->root->drawable, key, clipboxes);
+}
+
 /* xf86XVClipVideoHelper -
 
    Takes the dst box in standard X BoxRec form (top and left


More information about the xorg-commit mailing list