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, ¤t->transform);
+ transform_encode (client, &reply->currentInverse, ¤t->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