xserver: Branch 'transform-proposal' - 2 commits

Keith Packard keithp at kemper.freedesktop.org
Sat Mar 15 00:37:17 PDT 2008


 hw/xfree86/modes/xf86Crtc.h   |    3 
 hw/xfree86/modes/xf86Rotate.c |   31 ++++-
 randr/randrstr.h              |   27 +++-
 randr/rrcrtc.c                |  239 ++++++++++++++++++++++++++++++++++--------
 render/filter.c               |   57 +++++++---
 render/picturestr.h           |    9 +
 6 files changed, 294 insertions(+), 72 deletions(-)

New commits:
commit 715b158e159739e1b01d306cd3f0e506ec652a36
Author: Keith Packard <keithp at keithp.com>
Date:   Sat Mar 15 00:36:45 2008 -0700

    [RANDR] Support filters in CRTC transforms.
    
    Create new RRTransform datatype to hold all of the transform related
    information, use that in lots of places to pass filters around.

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index b87a325..6f3fcd4 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -306,6 +306,9 @@ struct _xf86Crtc {
      */
     PictTransform   crtc_to_framebuffer;
     PictTransform   framebuffer_to_crtc;
+    PictFilterPtr   filter;
+    xFixed	    *params;
+    int		    nparams;
     Bool	    transform_in_use;
     /**
      * Bounding box in screen space
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e1b8ef2..91b1861 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -109,6 +109,9 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
     error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
     if (error)
 	return;
+    if (crtc->transform_in_use && crtc->filter)
+	SetPicturePictFilter (src, crtc->filter,
+			      crtc->params, crtc->nparams);
 
     while (n--)
     {
@@ -363,13 +366,33 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
     }
     
 #ifdef RANDR_12_INTERFACE
+    if (crtc->randr_crtc)
     {
-	PictTransform	user_forward, user_reverse;
-	if (crtc->randr_crtc && RRCrtcGetTransform (crtc->randr_crtc, &user_forward, &user_reverse))
+	xFixed		*new_params = NULL;
+	int		new_nparams = 0;
+	PictFilterPtr   new_filter = NULL;
+
+	RRTransformPtr	transform = RRCrtcGetTransform (crtc->randr_crtc);
+	if (transform)
 	{
-	    PictureTransformMultiply (&crtc_to_fb, &user_forward, &crtc_to_fb);
-	    PictureTransformMultiply (&fb_to_crtc, &fb_to_crtc, &user_reverse);
+	    if (transform->nparams) {
+		new_params = xalloc (transform->nparams * sizeof (xFixed));
+		if (new_params) {
+		    memcpy (new_params, transform->params,
+			    transform->nparams * sizeof (xFixed));
+		    new_nparams = transform->nparams;
+		    new_filter = transform->filter;
+		}
+	    } else
+		new_filter = transform->filter;
+	    PictureTransformMultiply (&crtc_to_fb, &transform->transform, &crtc_to_fb);
+	    PictureTransformMultiply (&fb_to_crtc, &fb_to_crtc, &transform->inverse);
 	}
+	if (crtc->params)
+	    xfree (crtc->params);
+	crtc->params = new_params;
+	crtc->nparams = new_nparams;
+	crtc->filter = new_filter;
     }
 #endif
     /*
diff --git a/randr/randrstr.h b/randr/randrstr.h
index fe58293..e6e65d0 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -75,6 +75,7 @@ typedef struct _rrPropertyValue	RRPropertyValueRec, *RRPropertyValuePtr;
 typedef struct _rrProperty	RRPropertyRec, *RRPropertyPtr;
 typedef struct _rrCrtc		RRCrtcRec, *RRCrtcPtr;
 typedef struct _rrOutput	RROutputRec, *RROutputPtr;
+typedef struct _rrTransform	RRTransformRec, *RRTransformPtr;
 
 struct _rrMode {
     int		    refcnt;
@@ -101,6 +102,14 @@ struct _rrProperty {
     RRPropertyValueRec	current, pending;
 };
 
+struct _rrTransform {
+    PictTransform   transform;
+    PictTransform   inverse;
+    PictFilterPtr   filter;
+    xFixed	    *params;
+    int		    nparams;
+};
+
 struct _rrCrtc {
     RRCrtc	    id;
     ScreenPtr	    pScreen;
@@ -116,10 +125,8 @@ struct _rrCrtc {
     CARD16	    *gammaBlue;
     CARD16	    *gammaGreen;
     void	    *devPrivate;
-    PictTransform   client_pending_transform;
-    PictTransform   client_pending_inverse;
-    PictTransform   client_current_transform;
-    PictTransform   client_current_inverse;
+    RRTransformRec  client_pending_transform;
+    RRTransformRec  client_current_transform;
     PictTransform   transform;
     PictTransform   inverse;
 };
@@ -609,10 +616,8 @@ RRComputeTransform (RRModePtr		mode,
 /*
  * Return crtc transform
  */
-Bool
-RRCrtcGetTransform (RRCrtcPtr crtc,
-		    PictTransformPtr crtc_to_fb,
-		    PictTransformPtr fb_to_crtc);
+RRTransformPtr
+RRCrtcGetTransform (RRCrtcPtr crtc);
 
 /*
  * Mark the pending transform as current
@@ -640,7 +645,11 @@ RRCrtcDestroy (RRCrtcPtr crtc);
 int
 RRCrtcTransformSet (RRCrtcPtr		crtc,
 		    PictTransformPtr	transform,
-		    PictTransformPtr	inverse);
+		    PictTransformPtr	inverse,
+		    char		*filter,
+		    int			filter_len,
+		    xFixed		*params,
+		    int			nparams);
 
 /*
  * Initialize crtc type
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 0ca93a6..8da8ad2 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -48,6 +48,52 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
     }
 }
 
+static void
+RRTransformInit (RRTransformPtr transform)
+{
+    PictureTransformInitIdentity (&transform->transform);
+    PictureTransformInitIdentity (&transform->inverse);
+    transform->filter = NULL;
+    transform->params = NULL;
+    transform->nparams = 0;
+}
+
+static Bool
+RRTransformSetFilter (RRTransformPtr	dst,
+		      PictFilterPtr	filter,
+		      xFixed		*params,
+		      int		nparams)
+{
+    xFixed  *new_params;
+
+    if (nparams)
+    {
+	new_params = xalloc (nparams * sizeof (xFixed));
+	if (!new_params)
+	    return FALSE;
+	memcpy (new_params, params, nparams * sizeof (xFixed));
+    }
+    else
+	new_params = NULL;
+    if (dst->params)
+	xfree (dst->params);
+    dst->filter = filter;
+    dst->params = new_params;
+    dst->nparams = nparams;
+    return TRUE;
+}
+
+static Bool
+RRTransformCopy (RRTransformPtr dst, RRTransformPtr src)
+{
+    if (!RRTransformSetFilter (dst, src->filter,
+			       src->params, src->nparams))
+	return FALSE;
+    dst->transform = src->transform;
+    dst->inverse = src->inverse;
+    return TRUE;
+}
+
 /*
  * Create a CRTC
  */
@@ -89,10 +135,8 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
     crtc->gammaRed = crtc->gammaBlue = crtc->gammaGreen = NULL;
     crtc->changed = FALSE;
     crtc->devPrivate = devPrivate;
-    PictureTransformInitIdentity (&crtc->client_pending_transform);
-    PictureTransformInitIdentity (&crtc->client_pending_inverse);
-    PictureTransformInitIdentity (&crtc->client_current_transform);
-    PictureTransformInitIdentity (&crtc->client_current_inverse);
+    RRTransformInit (&crtc->client_pending_transform);
+    RRTransformInit (&crtc->client_current_transform);
     PictureTransformInitIdentity (&crtc->transform);
     PictureTransformInitIdentity (&crtc->inverse);
 
@@ -368,14 +412,14 @@ RRCrtcSet (RRCrtcPtr    crtc,
 /*
  * Return crtc transform
  */
-Bool
-RRCrtcGetTransform (RRCrtcPtr crtc,
-		    PictTransformPtr crtc_to_fb,
-		    PictTransformPtr fb_to_crtc)
+RRTransformPtr
+RRCrtcGetTransform (RRCrtcPtr crtc)
 {
-    *crtc_to_fb = crtc->client_pending_transform;
-    *fb_to_crtc = crtc->client_pending_inverse;
-    return !PictureTransformIsIdentity (crtc_to_fb);
+    RRTransformPtr  transform = &crtc->client_pending_transform;
+
+    if (PictureTransformIsIdentity (&transform->transform))
+	return NULL;
+    return transform;
 }
 
 /*
@@ -384,11 +428,11 @@ RRCrtcGetTransform (RRCrtcPtr crtc,
 void
 RRCrtcPostPendingTransform (RRCrtcPtr crtc)
 {
-    crtc->client_current_transform = crtc->client_pending_transform;
-    crtc->client_current_inverse = crtc->client_pending_inverse;
+    RRTransformCopy (&crtc->client_current_transform,
+		     &crtc->client_pending_transform);
     RRComputeTransform (crtc->mode, crtc->rotation, crtc->x, crtc->y,
-			&crtc->client_current_transform,
-			&crtc->client_current_inverse,
+			&crtc->client_current_transform.transform,
+			&crtc->client_current_transform.inverse,
 			&crtc->transform,
 			&crtc->inverse);
 }
@@ -399,8 +443,8 @@ RRCrtcPostPendingTransform (RRCrtcPtr crtc)
 Bool
 RRCrtcPendingTransform (RRCrtcPtr crtc)
 {
-    return memcmp (&crtc->client_current_transform,
-		   &crtc->client_pending_transform,
+    return memcmp (&crtc->client_current_transform.transform,
+		   &crtc->client_pending_transform.transform,
 		   sizeof (PictTransform)) != 0;
 }
 
@@ -546,12 +590,41 @@ RRCrtcGammaSetSize (RRCrtcPtr	crtc,
 int
 RRCrtcTransformSet (RRCrtcPtr		crtc,
 		    PictTransformPtr	transform,
-		    PictTransformPtr	inverse)
+		    PictTransformPtr	inverse,
+		    char		*filter_name,
+		    int			filter_len,
+		    xFixed		*params,
+		    int			nparams)
 {
+    PictFilterPtr   filter = NULL;
+
     if (!PictureTransformIsInverse (transform, inverse))
 	return BadMatch;
-    crtc->client_pending_transform = *transform;
-    crtc->client_pending_inverse = *inverse;
+    if (filter_len)
+    {
+	filter = PictureFindFilter (crtc->pScreen,
+				    filter_name,
+				    filter_len);
+	if (!filter)
+	    return BadName;
+	if (filter->ValidateParams)
+	{
+	    if (!filter->ValidateParams (crtc->pScreen, filter->id,
+					 params, nparams))
+		return BadMatch;
+	}
+    }
+    else
+    {
+	if (nparams)
+	    return BadMatch;
+    }
+    if (!RRTransformSetFilter (&crtc->client_pending_transform,
+			       filter, params, nparams))
+	return BadAlloc;
+
+    crtc->client_pending_transform.transform = *transform;
+    crtc->client_pending_transform.inverse = *inverse;
     return Success;
 }
 
@@ -1119,8 +1192,12 @@ ProcRRSetCrtcTransform (ClientPtr client)
     REQUEST(xRRSetCrtcTransformReq);
     RRCrtcPtr		    crtc;
     PictTransform	    transform, inverse;
+    char		    *filter;
+    int			    nbytes;
+    xFixed		    *params;
+    int			    nparams;
 
-    REQUEST_SIZE_MATCH (xRRSetCrtcTransformReq);
+    REQUEST_AT_LEAST_SIZE(xRRSetCrtcTransformReq);
     crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess);
     if (!crtc)
 	return RRErrorBase + BadRRCrtc;
@@ -1128,42 +1205,124 @@ ProcRRSetCrtcTransform (ClientPtr client)
     PictTransform_from_xRenderTransform (&transform, &stuff->transform);
     PictTransform_from_xRenderTransform (&inverse, &stuff->inverse);
 
-    return RRCrtcTransformSet (crtc, &transform, &inverse);
+    filter = (char *) (stuff + 1);
+    nbytes = stuff->nbytesFilter;
+    params = (xFixed *) (filter + ((nbytes + 3) & ~3));
+    nparams = ((xFixed *) stuff + client->req_len) - params;
+    if (nparams < 0)
+	return BadLength;
+
+    return RRCrtcTransformSet (crtc, &transform, &inverse,
+			       filter, nbytes, params, nparams);
 }
 
 
 #define CrtcTransformExtra	(SIZEOF(xRRGetCrtcTransformReply) - 32)
 				
+static int
+transform_filter_length (RRTransformPtr transform)
+{
+    int	nbytes, nparams;
+
+    if (transform->filter == NULL)
+	return 0;
+    nbytes = strlen (transform->filter->name);
+    nparams = transform->nparams;
+    return ((nbytes + 3) & ~3) + (nparams * sizeof (xFixed));
+}
+
+static int
+transform_filter_encode (ClientPtr client, char *output,
+			 CARD16	*nbytesFilter,
+			 CARD16	*nparamsFilter,
+			 RRTransformPtr transform)
+{
+    char    *output_orig = output;
+    int	    nbytes, nparams;
+    int	    n;
+
+    if (transform->filter == NULL) {
+	*nbytesFilter = 0;
+	*nparamsFilter = 0;
+	return 0;
+    }
+    nbytes = strlen (transform->filter->name);
+    nparams = transform->nparams;
+    *nbytesFilter = nbytes;
+    *nparamsFilter = nparams;
+    memcpy (output, transform->filter->name, nbytes);
+    output += nbytes;
+    while ((nbytes & 3) != 0)
+	*output++ = 0;
+    memcpy (output, transform->params, nparams * sizeof (xFixed));
+    if (client->swapped) {
+	swaps (nbytesFilter, n);
+	swaps (nparamsFilter, n);
+	SwapLongs ((CARD32 *) output, nparams * sizeof (xFixed));
+    }
+    output += nparams * sizeof (xFixed);
+    return output - output_orig;
+}
+
+static void
+transform_encode (ClientPtr client, xRenderTransform *wire, PictTransform *pict)
+{
+    xRenderTransform_from_PictTransform (wire, pict);
+    if (client->swapped)
+	SwapLongs ((CARD32 *) wire, sizeof (xRenderTransform));
+}
+
 int
 ProcRRGetCrtcTransform (ClientPtr client)
 {
     REQUEST(xRRGetCrtcTransformReq);
-    xRRGetCrtcTransformReply	reply;
+    xRRGetCrtcTransformReply	*reply;
     RRCrtcPtr			crtc;
-    int				n;
+    int				n, nextra;
+    RRTransformPtr		current, pending;
+    char			*extra;
 
     REQUEST_SIZE_MATCH (xRRGetCrtcTransformReq);
     crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess);
     if (!crtc)
 	return RRErrorBase + BadRRCrtc;
 
-    reply.type = X_Reply;
-    reply.sequenceNumber = client->sequence;
-    reply.length = CrtcTransformExtra >> 2;
-    
-    xRenderTransform_from_PictTransform (&reply.pendingTransform,
-					 &crtc->client_pending_transform);
-    xRenderTransform_from_PictTransform (&reply.pendingInverse,
-					 &crtc->client_pending_inverse);
-    xRenderTransform_from_PictTransform (&reply.currentTransform,
-					 &crtc->client_current_transform);
-    xRenderTransform_from_PictTransform (&reply.currentInverse,
-					 &crtc->client_current_inverse);
+    pending = &crtc->client_pending_transform;
+    current = &crtc->client_current_transform;
+
+    nextra = (transform_filter_length (pending) +
+	      transform_filter_length (current));
+
+    reply = xalloc (sizeof (xRRGetCrtcTransformReply) + nextra);
+    if (!reply)
+	return BadAlloc;
+
+    extra = (char *) (reply + 1);
+    reply->type = X_Reply;
+    reply->sequenceNumber = client->sequence;
+    reply->length = (CrtcTransformExtra + nextra) >> 2;
+
+    /* XXX deal with DDXen that can't do transforms */
+    reply->hasTransforms = xTrue;
+
+    transform_encode (client, &reply->pendingTransform, &pending->transform);
+    transform_encode (client, &reply->pendingInverse, &pending->inverse);
+    extra += transform_filter_encode (client, extra,
+				      &reply->pendingNbytesFilter,
+				      &reply->pendingNparamsFilter,
+				      pending);
+
+    transform_encode (client, &reply->currentTransform, &current->transform);
+    transform_encode (client, &reply->currentInverse, &current->inverse);
+    extra += transform_filter_encode (client, extra,
+				      &reply->currentNbytesFilter,
+				      &reply->currentNparamsFilter,
+				      current);
+
     if (client->swapped) {
-	swaps (&reply.sequenceNumber, n);
-	swapl (&reply.length, n);
-	SwapLongs ((CARD32 *) &reply.pendingTransform, 40);
+	swaps (&reply->sequenceNumber, n);
+	swapl (&reply->length, n);
     }
-    WriteToClient (client, sizeof (xRRGetCrtcTransformReply), (char *) &reply);
+    WriteToClient (client, sizeof (xRRGetCrtcTransformReply) + nextra, (char *) reply);
     return client->noClientException;
 }
commit 207869447a15c2a75f16bdfb6de2df6b7b3a2717
Author: Keith Packard <keithp at keithp.com>
Date:   Fri Mar 14 13:46:30 2008 -0700

    [render] Split out filter finding from filter setting.
    
    To prepare for RandR using filters in transforms, split out
    code paths so that the RandR code can validate the filter name and
    parameters during the transform set operation so that use of the filter
    later will not have unreportable errors.

diff --git a/render/filter.c b/render/filter.c
index 092313f..bc742e5 100644
--- a/render/filter.c
+++ b/render/filter.c
@@ -213,7 +213,7 @@ PictureFindFilter (ScreenPtr pScreen, char *name, int len)
 }
 
 static Bool
-convolutionFilterValidateParams (PicturePtr pPicture,
+convolutionFilterValidateParams (ScreenPtr pScreen,
                                  int	   filter,
                                  xFixed	   *params,
                                  int	   nparams)
@@ -270,29 +270,51 @@ int
 SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams)
 {
     PictFilterPtr	pFilter;
-    xFixed		*new_params;
-    int			i, s, result;
+    ScreenPtr		pScreen;
 
-    pFilter = PictureFindFilter (screenInfo.screens[0], name, len);
+    if (pPicture->pDrawable != NULL)
+	pScreen = pPicture->pDrawable->pScreen;
+    else
+	pScreen = screenInfo.screens[0];
+
+    pFilter = PictureFindFilter (pScreen, name, len);
+
+    if (!pFilter)
+	return BadName;
 
-    if (pPicture->pDrawable == NULL) {
+    if (pPicture->pDrawable == NULL)
+    {
+	int s;
 	/* For source pictures, the picture isn't tied to a screen.  So, ensure
 	 * that all screens can handle a filter we set for the picture.
 	 */
-	for (s = 0; s < screenInfo.numScreens; s++) {
-	    if (PictureFindFilter (screenInfo.screens[s], name, len)->id !=
-		pFilter->id)
-	    {
+	for (s = 1; s < screenInfo.numScreens; s++)
+	{
+	    PictFilterPtr   pScreenFilter;
+	    pScreenFilter = PictureFindFilter (screenInfo.screens[s],
+					       name, len);
+	    if (!pScreenFilter || pScreenFilter->id != pFilter->id)
 		return BadMatch;
-	    }
 	}
     }
+    return SetPicturePictFilter (pPicture, pFilter, params, nparams);
+}
+
+int
+SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
+		      xFixed *params, int nparams)
+{
+    ScreenPtr	pScreen;
+    int		i;
+
+    if (pPicture->pDrawable)
+	pScreen = pPicture->pDrawable->pScreen;
+    else
+	pScreen = screenInfo.screens[0];
 
-    if (!pFilter)
-	return BadName;
     if (pFilter->ValidateParams)
     {
-	if (!(*pFilter->ValidateParams) (pPicture, pFilter->id, params, nparams))
+	if (!(*pFilter->ValidateParams) (pScreen, pFilter->id, params, nparams))
 	    return BadMatch;
     }
     else if (nparams)
@@ -300,7 +322,7 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
 
     if (nparams != pPicture->filter_nparams)
     {
-	new_params = xalloc (nparams * sizeof (xFixed));
+	xFixed *new_params = xalloc (nparams * sizeof (xFixed));
 	if (!new_params)
 	    return BadAlloc;
 	xfree (pPicture->filter_params);
@@ -311,9 +333,10 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
 	pPicture->filter_params[i] = params[i];
     pPicture->filter = pFilter->id;
 
-    if (pPicture->pDrawable) {
-	ScreenPtr pScreen = pPicture->pDrawable->pScreen;
-	PictureScreenPtr ps = GetPictureScreen(pScreen);
+    if (pPicture->pDrawable)
+    {
+	PictureScreenPtr    ps = GetPictureScreen(pScreen);
+	int		    result;
 
 	result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
 					     params, nparams);
diff --git a/render/picturestr.h b/render/picturestr.h
index d9dec18..805c85c 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -184,7 +184,7 @@ typedef struct _Picture {
     SourcePictPtr   pSourcePict;
 } PictureRec;
 
-typedef Bool (*PictFilterValidateParamsProcPtr) (PicturePtr pPicture, int id,
+typedef Bool (*PictFilterValidateParamsProcPtr) (ScreenPtr pScreen, int id,
 						 xFixed *params, int nparams);
 typedef struct {
     char			    *name;
@@ -476,7 +476,12 @@ PictFilterPtr
 PictureFindFilter (ScreenPtr pScreen, char *name, int len);
 
 int
-SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams);
+SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
+		      xFixed *params, int nparams);
+
+int
+SetPictureFilter (PicturePtr pPicture, char *name, int len,
+		  xFixed *params, int nparams);
 
 Bool
 PictureFinishInit (void);


More information about the xorg-commit mailing list