This involved removing a pile of matrix code from the DDX, as well as moving a bit of transform logic from DDX to DIX. --- hw/xfree86/modes/xf86Crtc.c | 4 + hw/xfree86/modes/xf86RandR12.c | 3 + hw/xfree86/modes/xf86Rotate.c | 212 +--------------------------------------- randr/randrstr.h | 45 +++++++++ randr/rrcrtc.c | 203 +++++++++++++++++++++++++++++++++++++- randr/rrdispatch.c | 5 +- randr/rrsdispatch.c | 23 +++++ 7 files changed, 283 insertions(+), 212 deletions(-)
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 0ba0477..a40bf18 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -351,6 +351,10 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, #endif } } +#ifdef RANDR_12_INTERFACE + if (crtc->randr_crtc) + RRCrtcPostPendingTransform (crtc->randr_crtc); +#endif /* XXX free adjustedmode */ ret = TRUE; diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 2ae8ea7..6e14bd7 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -755,6 +755,9 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, if (rotation != crtc->rotation) changed = TRUE; + if (RRCrtcPendingTransform (randr_crtc)) + changed = TRUE; + if (x != crtc->x || y != crtc->y) changed = TRUE; for (o = 0; o < config->num_output; o++) diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index 5ab2bf8..7967e5b 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -70,205 +70,9 @@ compWindowFormat (WindowPtr pWin) #define F(x) IntToxFixed(x) -static void -PictureTransformIdentity (PictTransformPtr matrix) -{ - int i; - memset (matrix, '\0', sizeof (PictTransform)); - for (i = 0; i < 3; i++) - matrix->matrix[i][i] = F(1); -} - -static Bool -PictureTransformMultiply (PictTransformPtr dst, PictTransformPtr l, PictTransformPtr r) -{ - PictTransform d; - int dx, dy; - int o; - - for (dy = 0; dy < 3; dy++) - for (dx = 0; dx < 3; dx++) - { - xFixed_48_16 v; - xFixed_32_32 partial; - v = 0; - for (o = 0; o < 3; o++) - { - partial = (xFixed_32_32) l->matrix[dy][o] * (xFixed_32_32) r->matrix[o][dx]; - v += partial >> 16; - } - if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16) - return FALSE; - d.matrix[dy][dx] = (xFixed) v; - } - *dst = d; - return TRUE; -} - -static void -PictureTransformInitScale (PictTransformPtr t, xFixed sx, xFixed sy) -{ - memset (t, '\0', sizeof (PictTransform)); - t->matrix[0][0] = sx; - t->matrix[1][1] = sy; - t->matrix[2][2] = F (1); -} - -static xFixed -fixed_inverse (xFixed x) -{ - return (xFixed) ((((xFixed_48_16) F(1)) * F(1)) / x); -} - -static Bool -PictureTransformScale (PictTransformPtr forward, - PictTransformPtr reverse, - xFixed sx, xFixed sy) -{ - PictTransform t; - - PictureTransformInitScale (&t, sx, sy); - if (!PictureTransformMultiply (forward, &t, forward)) - return FALSE; - PictureTransformInitScale (&t, fixed_inverse (sx), fixed_inverse (sy)); - if (!PictureTransformMultiply (reverse, reverse, &t)) - return FALSE; - return TRUE; -} - -static void -PictureTransformInitRotate (PictTransformPtr t, xFixed c, xFixed s) -{ - memset (t, '\0', sizeof (PictTransform)); - t->matrix[0][0] = c; - t->matrix[0][1] = -s; - t->matrix[1][0] = s; - t->matrix[1][1] = c; - t->matrix[2][2] = F (1); -} - -static Bool -PictureTransformRotate (PictTransformPtr forward, - PictTransformPtr reverse, - xFixed c, xFixed s) -{ - PictTransform t; - PictureTransformInitRotate (&t, c, s); - if (!PictureTransformMultiply (forward, &t, forward)) - return FALSE; - - PictureTransformInitRotate (&t, c, -s); - if (!PictureTransformMultiply (reverse, reverse, &t)) - return FALSE; - return TRUE; -} - -static void -PictureTransformInitTranslate (PictTransformPtr t, xFixed tx, xFixed ty) -{ - memset (t, '\0', sizeof (PictTransform)); - t->matrix[0][0] = F (1); - t->matrix[0][2] = tx; - t->matrix[1][1] = F (1); - t->matrix[1][2] = ty; - t->matrix[2][2] = F (1); -} - -static Bool -PictureTransformTranslate (PictTransformPtr forward, - PictTransformPtr reverse, - xFixed tx, xFixed ty) -{ - PictTransform t; - PictureTransformInitTranslate (&t, tx, ty); - if (!PictureTransformMultiply (forward, &t, forward)) - return FALSE; - - PictureTransformInitTranslate (&t, -tx, -ty); - if (!PictureTransformMultiply (reverse, reverse, &t)) - return FALSE; - return TRUE; -} - -static void -PictureTransformBounds (BoxPtr b, PictTransformPtr matrix) -{ - PictVector v[4]; - int i; - int x1, y1, x2, y2; - - v[0].vector[0] = F (b->x1); v[0].vector[1] = F (b->y1); v[0].vector[2] = F(1); - v[1].vector[0] = F (b->x2); v[1].vector[1] = F (b->y1); v[1].vector[2] = F(1); - v[2].vector[0] = F (b->x2); v[2].vector[1] = F (b->y2); v[2].vector[2] = F(1); - v[3].vector[0] = F (b->x1); v[3].vector[1] = F (b->y2); v[3].vector[2] = F(1); - for (i = 0; i < 4; i++) - { - PictureTransformPoint (matrix, &v[i]); - x1 = xFixedToInt (v[i].vector[0]); - y1 = xFixedToInt (v[i].vector[1]); - x2 = xFixedToInt (xFixedCeil (v[i].vector[0])); - y2 = xFixedToInt (xFixedCeil (v[i].vector[1])); - if (i == 0) - { - b->x1 = x1; b->y1 = y1; - b->x2 = x2; b->y2 = y2; - } - else - { - if (x1 < b->x1) b->x1 = x1; - if (y1 < b->y1) b->y1 = y1; - if (x2 > b->x2) b->x2 = x2; - if (y2 > b->y2) b->y2 = y2; - } - } -} - -static Bool -PictureTransformIsIdentity(PictTransform *t) -{ - return ((t->matrix[0][0] == t->matrix[1][1]) && - (t->matrix[0][0] == t->matrix[2][2]) && - (t->matrix[0][0] != 0) && - (t->matrix[0][1] == 0) && - (t->matrix[0][2] == 0) && - (t->matrix[1][0] == 0) && - (t->matrix[1][2] == 0) && - (t->matrix[2][0] == 0) && - (t->matrix[2][1] == 0)); -} - #define toF(x) ((float) (x) / 65536.0f) static void -PictureTransformErrorF (PictTransform *t) -{ - ErrorF ("{ { %f %f %f } { %f %f %f } { %f %f %f } }", - toF(t->matrix[0][0]), toF(t->matrix[0][1]), toF(t->matrix[0][2]), - toF(t->matrix[1][0]), toF(t->matrix[1][1]), toF(t->matrix[1][2]), - toF(t->matrix[2][0]), toF(t->matrix[2][1]), toF(t->matrix[2][2])); -} - -static Bool -PictureTransformIsInverse (char *where, PictTransform *a, PictTransform *b) -{ - PictTransform t; - - PictureTransformMultiply (&t, a, b); - if (!PictureTransformIsIdentity (&t)) - { - ErrorF ("%s: ", where); - PictureTransformErrorF (a); - ErrorF (" * "); - PictureTransformErrorF (b); - ErrorF (" = "); - PictureTransformErrorF (&t); - ErrorF ("\n"); - return FALSE; - } - return TRUE; -} - -static void xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region) { ScrnInfoPtr scrn = crtc->scrn; @@ -516,9 +320,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; PictTransform crtc_to_fb, fb_to_crtc; - PictureTransformIdentity (&crtc_to_fb); - PictureTransformIdentity (&fb_to_crtc); - PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc); + PictureTransformInitIdentity (&crtc_to_fb); + PictureTransformInitIdentity (&fb_to_crtc); if (rotation != RR_Rotate_0) { xFixed rot_cos, rot_sin, rot_dx, rot_dy; @@ -548,10 +351,7 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) } PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin); - PictureTransformIsInverse ("rotate", &crtc_to_fb, &fb_to_crtc); - PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy); - PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc); /* reflection */ scale_x = F (1); @@ -576,19 +376,14 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) } PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y); - PictureTransformIsInverse ("scale", &crtc_to_fb, &fb_to_crtc); - PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy); - PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc); - } #ifdef RANDR_12_INTERFACE { PictTransform user_forward, user_reverse; - if (RRCrtcGetTransform (crtc->randr_crtc, &user_forward, &user_reverse)) + if (crtc->randr_crtc && RRCrtcGetTransform (crtc->randr_crtc, &user_forward, &user_reverse)) { - PictureTransformIsInverse ("user", &user_forward, &user_reverse); PictureTransformMultiply (&crtc_to_fb, &user_forward, &crtc_to_fb); PictureTransformMultiply (&fb_to_crtc, &fb_to_crtc, &user_reverse); } @@ -614,7 +409,6 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) PixmapPtr shadow; PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, F(crtc->x), F(crtc->y)); - PictureTransformIsInverse ("offset", &crtc_to_fb, &fb_to_crtc); /* * these are the size of the shadow pixmap, which diff --git a/randr/randrstr.h b/randr/randrstr.h index 4692ddf..320e9f7 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -119,6 +119,12 @@ struct _rrCrtc { CARD16 *gammaBlue; CARD16 *gammaGreen; void *devPrivate; + PictTransform client_pending_transform; + PictTransform client_pending_inverse; + PictTransform client_current_transform; + PictTransform client_current_inverse; + PictTransform transform; + PictTransform inverse; }; struct _rrOutput { @@ -587,6 +593,23 @@ void RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height); /* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +Bool +RRComputeTransform (RRModePtr mode, + Rotation rotation, + int x, + int y, + PictTransformPtr client_transform, + PictTransformPtr client_inverse, + PictTransformPtr transform, + PictTransformPtr inverse); + +/* * Return crtc transform */ Bool @@ -601,11 +624,27 @@ void RRCrtcPostPendingTransform (RRCrtcPtr crtc); /* + * Check whether the pending and current transforms are the same + */ +Bool +RRCrtcPendingTransform (RRCrtcPtr crtc); + +/* * Destroy a Crtc at shutdown */ void RRCrtcDestroy (RRCrtcPtr crtc); + +/* + * Set the pending CRTC transformation + */ + +int +RRCrtcTransformSet (RRCrtcPtr crtc, + PictTransformPtr transform, + PictTransformPtr inverse); + /* * Initialize crtc type */ @@ -631,6 +670,12 @@ ProcRRGetCrtcGamma (ClientPtr client); int ProcRRSetCrtcGamma (ClientPtr client); +int +ProcRRSetCrtcTransform (ClientPtr client); + +int +ProcRRGetCrtcTransform (ClientPtr client); + /* rrdispatch.c */ Bool RRClientKnowsRates (ClientPtr pClient); diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index 38b3452..0cb8638 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -89,6 +89,12 @@ 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); + PictureTransformInitIdentity (&crtc->transform); + PictureTransformInitIdentity (&crtc->inverse); if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc)) return NULL; @@ -290,7 +296,8 @@ RRCrtcSet (RRCrtcPtr crtc, crtc->rotation == rotation && crtc->numOutputs == numOutputs && !memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) && - !RRCrtcPendingProperties (crtc)) + !RRCrtcPendingProperties (crtc) && + !RRCrtcPendingTransform (crtc)) { ret = TRUE; } @@ -366,7 +373,9 @@ RRCrtcGetTransform (RRCrtcPtr crtc, PictTransformPtr crtc_to_fb, PictTransformPtr fb_to_crtc) { - return FALSE; + *crtc_to_fb = crtc->client_pending_transform; + *fb_to_crtc = crtc->client_pending_inverse; + return !PictureTransformIsIdentity (crtc_to_fb); } /* @@ -375,6 +384,24 @@ RRCrtcGetTransform (RRCrtcPtr crtc, void RRCrtcPostPendingTransform (RRCrtcPtr crtc) { + crtc->client_current_transform = crtc->client_pending_transform; + crtc->client_current_inverse = crtc->client_pending_inverse; + RRComputeTransform (crtc->mode, crtc->rotation, crtc->x, crtc->y, + &crtc->client_current_transform, + &crtc->client_current_inverse, + &crtc->transform, + &crtc->inverse); +} + +/* + * Check whether the pending and current transforms are the same + */ +Bool +RRCrtcPendingTransform (RRCrtcPtr crtc) +{ + return memcmp (&crtc->client_current_transform, + &crtc->client_pending_transform, + sizeof (PictTransform)) != 0; } /* @@ -513,6 +540,122 @@ RRCrtcGammaSetSize (RRCrtcPtr crtc, } /* + * Set the pending CRTC transformation + */ + +int +RRCrtcTransformSet (RRCrtcPtr crtc, + PictTransformPtr transform, + PictTransformPtr inverse) +{ + if (!PictureTransformIsInverse (transform, inverse)) + return BadMatch; + crtc->client_pending_transform = *transform; + crtc->client_pending_inverse = *inverse; + return Success; +} + +#define F(x) IntToxFixed(x) + +/* + * Compute the complete transformation matrix including + * client-specified transform, rotation/reflection values and the crtc + * offset. + * + * Return TRUE if the resulting transform is not a simple translation. + */ +Bool +RRComputeTransform (RRModePtr mode, + Rotation rotation, + int x, + int y, + PictTransformPtr client_transform, + PictTransformPtr client_inverse, + PictTransformPtr transform, + PictTransformPtr inverse) +{ + PictureTransformInitIdentity (transform); + PictureTransformInitIdentity (inverse); + if (rotation != RR_Rotate_0) + { + xFixed rot_cos, rot_sin, rot_dx, rot_dy; + xFixed scale_x, scale_y, scale_dx, scale_dy; + int mode_w = mode->mode.width; + int mode_h = mode->mode.height; + + /* rotation */ + switch (rotation & 0xf) { + default: + case RR_Rotate_0: + rot_cos = F ( 1); rot_sin = F ( 0); + rot_dx = F ( 0); rot_dy = F ( 0); + break; + case RR_Rotate_90: + rot_cos = F ( 0); rot_sin = F ( 1); + rot_dx = F ( mode_h); rot_dy = F (0); + break; + case RR_Rotate_180: + rot_cos = F (-1); rot_sin = F ( 0); + rot_dx = F (mode_w); rot_dy = F ( mode_h); + break; + case RR_Rotate_270: + rot_cos = F ( 0); rot_sin = F (-1); + rot_dx = F ( 0); rot_dy = F ( mode_w); + break; + } + + PictureTransformRotate (inverse, transform, rot_cos, rot_sin); + PictureTransformTranslate (inverse, transform, rot_dx, rot_dy); + + /* reflection */ + scale_x = F (1); + scale_dx = 0; + scale_y = F (1); + scale_dy = 0; + if (rotation & RR_Reflect_X) + { + scale_x = F(-1); + if (rotation & (RR_Rotate_0|RR_Rotate_180)) + scale_dx = F(mode_w); + else + scale_dx = F(mode_h); + } + if (rotation & RR_Reflect_Y) + { + scale_y = F(-1); + if (rotation & (RR_Rotate_0|RR_Rotate_180)) + scale_dy = F(mode_h); + else + scale_dy = F(mode_w); + } + + PictureTransformScale (inverse, transform, scale_x, scale_y); + PictureTransformTranslate (inverse, transform, scale_dx, scale_dy); + } + +#ifdef RANDR_12_INTERFACE + { + PictureTransformMultiply (inverse, client_inverse, inverse); + PictureTransformMultiply (transform, transform, client_transform); + } +#endif + /* + * Compute the class of the resulting transform + */ + if (PictureTransformIsIdentity (transform)) + { + PictureTransformInitTranslate (inverse, F (-x), F (-y)); + PictureTransformInitTranslate (transform, F ( x), F ( y)); + return FALSE; + } + else + { + PictureTransformTranslate (inverse, transform, x, y); + return TRUE; + } +} + +/* * Initialize crtc type */ Bool @@ -977,3 +1120,59 @@ ProcRRSetCrtcGamma (ClientPtr client) return Success; } +/* Version 1.3 additions */ + +int +ProcRRSetCrtcTransform (ClientPtr client) +{ + REQUEST(xRRSetCrtcTransformReq); + RRCrtcPtr crtc; + PictTransform transform, inverse; + + REQUEST_SIZE_MATCH (xRRSetCrtcTransformReq); + crtc = LookupCrtc (client, stuff->crtc, DixWriteAccess); + if (!crtc) + return RRErrorBase + BadRRCrtc; + + PictTransform_from_xRenderTransform (&transform, &stuff->transform); + PictTransform_from_xRenderTransform (&inverse, &stuff->inverse); + + return RRCrtcTransformSet (crtc, &transform, &inverse); +} + + +#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32) + +int +ProcRRGetCrtcTransform (ClientPtr client) +{ + REQUEST(xRRGetCrtcTransformReq); + xRRGetCrtcTransformReply reply; + RRCrtcPtr crtc; + int n; + + 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); + if (client->swapped) { + swaps (&reply.sequenceNumber, n); + swapl (&reply.length, n); + SwapLongs ((CARD32 *) &reply.pendingTransform, 40); + } + WriteToClient (client, sizeof (xRRGetCrtcTransformReply), (char *) &reply); + return client->noClientException; +} diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c index 72c68e3..20b471c 100644 --- a/randr/rrdispatch.c +++ b/randr/rrdispatch.c @@ -23,7 +23,7 @@ #include "randrstr.h" #define SERVER_RANDR_MAJOR 1 -#define SERVER_RANDR_MINOR 2 +#define SERVER_RANDR_MINOR 3 Bool RRClientKnowsRates (ClientPtr pClient) @@ -211,5 +211,8 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = { ProcRRGetCrtcGammaSize, /* 22 */ ProcRRGetCrtcGamma, /* 23 */ ProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + ProcRRSetCrtcTransform, /* 25 */ + ProcRRGetCrtcTransform, /* 26 */ }; diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c index 5037b9e..66a0e16 100644 --- a/randr/rrsdispatch.c +++ b/randr/rrsdispatch.c @@ -364,6 +364,26 @@ SProcRRSetCrtcGamma (ClientPtr client) return (*ProcRandrVector[stuff->randrReqType]) (client); } +static int +SProcRRSetCrtcTransform (ClientPtr client) +{ + REQUEST(xRRSetCrtcTransformReq); + + REQUEST_SIZE_MATCH(xRRSetCrtcTransformReq); + (void) stuff; + return BadImplementation; +} + +static int +SProcRRGetCrtcTransform (ClientPtr client) +{ + REQUEST(xRRGetCrtcTransformReq); + + REQUEST_SIZE_MATCH(xRRGetCrtcTransformReq); + (void) stuff; + return BadImplementation; +} + int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { SProcRRQueryVersion, /* 0 */ /* we skip 1 to make old clients fail pretty immediately */ @@ -394,5 +414,8 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = { SProcRRGetCrtcGammaSize, /* 22 */ SProcRRGetCrtcGamma, /* 23 */ SProcRRSetCrtcGamma, /* 24 */ +/* V1.3 additions */ + SProcRRSetCrtcTransform, /* 25 */ + SProcRRGetCrtcTransform, /* 26 */ }; -- 1.5.6.5 _______________________________________________ xorg mailing list xorg@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/xorg