[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.
This commit is contained in:
parent
acda790e43
commit
f50349e193
|
@ -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
|
||||
|
|
|
@ -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
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
237
randr/rrcrtc.c
237
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue