Create new RRTransform datatype to hold all of the transform related
information, use that in lots of places to pass filters around.
---
 hw/xfree86/modes/xf86Crtc.h   |    3 +
 hw/xfree86/modes/xf86Rotate.c |   31 +++++-
 randr/randrstr.h              |   27 +++--
 randr/rrcrtc.c                |  239 ++++++++++++++++++++++++++++++++++-------
 4 files changed, 247 insertions(+), 53 deletions(-)

diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index ef8589e..a5bb11b 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 7967e5b..f201ae3 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--)
     {
@@ -380,13 +383,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 320e9f7..cdaebe9 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -78,6 +78,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;
@@ -104,6 +105,14 @@ struct _rrProperty {
     RRPropertyValueRec current, pending;
 };
 
+struct _rrTransform {
+    PictTransform   transform;
+    PictTransform   inverse;
+    PictFilterPtr   filter;
+    xFixed         *params;
+    int                    nparams;
+};
+
 struct _rrCrtc {
     RRCrtc         id;
     ScreenPtr      pScreen;
@@ -119,10 +128,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;
 };
@@ -612,10 +619,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
@@ -643,7 +648,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 0cb8638..e3ba4f8 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;
 }
 
@@ -1128,8 +1201,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;
@@ -1137,42 +1214,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;
 }
-- 
1.5.6.5

_______________________________________________
xorg mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to