diff options
author | Keith Packard <keithp@keithp.com> | 2008-03-19 12:15:39 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2008-11-24 13:24:40 -0800 |
commit | 6fe9c15731be5f5afabacb3aa3ed71b840f4238b (patch) | |
tree | 234c3584789da29033ba209ab101d86be8491d2f | |
parent | 49db14e4ac26070ed86088419483888dda18b603 (diff) |
Allow drivers to set crtc transforms.
Track curent transform down in the mode setting code so that it may be set
separately from RandR.
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.c | 56 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.h | 11 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86RandR12.c | 36 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86RandR12.h | 2 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Rename.h | 1 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Rotate.c | 50 | ||||
-rw-r--r-- | randr/randrstr.h | 4 | ||||
-rw-r--r-- | randr/rrcrtc.c | 56 |
8 files changed, 150 insertions, 66 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 9f11037b7..bccda0ee9 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -237,8 +237,8 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen) * Sets the given video mode on the given crtc */ _X_EXPORT Bool -xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, - int x, int y) +xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + RRTransformPtr transform, int x, int y) { ScrnInfoPtr scrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -249,6 +249,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, DisplayModeRec saved_mode; int saved_x, saved_y; Rotation saved_rotation; + RRTransformRec saved_transform; + Bool saved_transform_present; if (crtc->funcs->set_mode_major) return crtc->funcs->set_mode_major(crtc, mode, rotation, x, y); @@ -269,6 +271,9 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, saved_x = crtc->x; saved_y = crtc->y; saved_rotation = crtc->rotation; + saved_transform = crtc->transform; + saved_transform_present = crtc->transformPresent; + /* Update crtc values up front so the driver can rely on them for mode * setting. */ @@ -276,6 +281,11 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, crtc->x = x; crtc->y = y; crtc->rotation = rotation; + if (transform) { + crtc->transform = *transform; + crtc->transformPresent = TRUE; + } else + crtc->transformPresent = FALSE; /* Shift offsets that move us out of virtual size */ if (x + mode->HDisplay > xf86_config->maxWidth || @@ -322,9 +332,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, goto done; } - if (!xf86CrtcRotate (crtc, mode, rotation)) { + if (!xf86CrtcRotate (crtc)) goto done; - } /* Prepare the outputs and CRTCs before setting the mode. */ for (i = 0; i < xf86_config->num_output; i++) { @@ -356,17 +365,11 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, { xf86OutputPtr output = xf86_config->output[i]; if (output->crtc == crtc) - { output->funcs->commit(output); -#ifdef RANDR_12_INTERFACE - if (output->randr_output) - RRPostPendingProperties (output->randr_output); -#endif - } } #ifdef RANDR_12_INTERFACE if (crtc->randr_crtc) - RRCrtcPostPendingTransform (crtc->randr_crtc); + RRCrtcSetTransform (crtc->randr_crtc, transform); #endif /* XXX free adjustedmode */ @@ -380,6 +383,8 @@ done: crtc->y = saved_y; crtc->rotation = saved_rotation; crtc->mode = saved_mode; + crtc->transform = saved_transform; + crtc->transformPresent = saved_transform_present; } if (didLock) @@ -388,6 +393,17 @@ done: return ret; } +/** + * Sets the given video mode on the given crtc, but without providing + * a transform + */ +_X_EXPORT Bool +xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + int x, int y) +{ + return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y); +} + /* * Output functions */ @@ -740,12 +756,12 @@ xf86CrtcScreenInit (ScreenPtr screen) xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270 | RR_Reflect_X | RR_Reflect_Y); - xf86RandR12SetTransform (screen, TRUE); + xf86RandR12SetTransformSupport (screen, TRUE); } else { xf86RandR12SetRotations (screen, RR_Rotate_0); - xf86RandR12SetTransform (screen, FALSE); + xf86RandR12SetTransformSupport (screen, FALSE); } /* Wrap CreateScreenResources so we can initialize the RandR code */ @@ -2236,6 +2252,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) crtc->desiredRotation = output->initial_rotation; crtc->desiredX = output->initial_x; crtc->desiredY = output->initial_y; + crtc->desiredTransformPresent = FALSE; crtc->enabled = TRUE; crtc->x = output->initial_x; crtc->y = output->initial_y; @@ -2367,6 +2384,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn) xf86CrtcPtr crtc = config->crtc[c]; xf86OutputPtr output = NULL; int o; + RRTransformPtr transform; /* Skip disabled CRTCs */ if (!crtc->enabled) @@ -2397,12 +2415,17 @@ xf86SetDesiredModes (ScrnInfoPtr scrn) return FALSE; crtc->desiredMode = *mode; crtc->desiredRotation = RR_Rotate_0; + crtc->desiredTransformPresent = FALSE; crtc->desiredX = 0; crtc->desiredY = 0; } - if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) + if (crtc->desiredTransformPresent) + transform = &crtc->desiredTransform; + else + transform = NULL; + if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation, + transform, crtc->desiredX, crtc->desiredY)) return FALSE; } @@ -2531,12 +2554,13 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) crtc->enabled = FALSE; continue; } - if (!xf86CrtcSetMode (crtc, crtc_mode, rotation, 0, 0)) + if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0)) ok = FALSE; else { crtc->desiredMode = *crtc_mode; crtc->desiredRotation = rotation; + crtc->desiredTransformPresent = FALSE; crtc->desiredX = 0; crtc->desiredY = 0; } diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index 026ec7803..4b6f7d2a1 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -313,6 +313,10 @@ struct _xf86Crtc { int filter_width; int filter_height; Bool transform_in_use; + RRTransformRec transform; + Bool transformPresent; + RRTransformRec desiredTransform; + Bool desiredTransformPresent; /** * Bounding box in screen space */ @@ -665,6 +669,11 @@ xf86CrtcDestroy (xf86CrtcPtr crtc); /** * Sets the given video mode on the given crtc */ + +Bool +xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, + RRTransformPtr transform, int x, int y); + Bool xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, int x, int y); @@ -673,7 +682,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation, * Assign crtc rotation during mode set */ Bool -xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation); +xf86CrtcRotate (xf86CrtcPtr crtc); /* * free shadow memory allocated for all crtcs diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index f247a882f..49add634a 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -569,7 +569,7 @@ xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) } _X_EXPORT void -xf86RandR12SetTransform (ScreenPtr pScreen, Bool transforms) +xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms) { XF86RandRInfoPtr randrp; #if RANDR_13_INTERFACE @@ -588,7 +588,7 @@ xf86RandR12SetTransform (ScreenPtr pScreen, Bool transforms) for (c = 0; c < config->num_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; - RRCrtcSetTransform (crtc->randr_crtc, transforms); + RRCrtcSetTransformSupport (crtc->randr_crtc, transforms); } #endif } @@ -751,18 +751,19 @@ xf86RandRModeConvert (ScrnInfoPtr scrn, } static Bool -xf86RandR12CrtcSet (ScreenPtr pScreen, - RRCrtcPtr randr_crtc, - RRModePtr randr_mode, - int x, - int y, - Rotation rotation, - int num_randr_outputs, - RROutputPtr *randr_outputs) +xf86RandR12CrtcSet (ScreenPtr pScreen, + RRCrtcPtr randr_crtc, + RRModePtr randr_mode, + int x, + int y, + Rotation rotation, + int num_randr_outputs, + RROutputPtr *randr_outputs) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); xf86CrtcPtr crtc = randr_crtc->devPrivate; + RRTransformPtr transform; Bool changed = FALSE; int o, ro; xf86CrtcPtr *save_crtcs; @@ -780,7 +781,11 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, if (rotation != crtc->rotation) changed = TRUE; - if (RRCrtcPendingTransform (randr_crtc)) + transform = RRCrtcGetTransform (randr_crtc); + if ((transform != NULL) != crtc->transformPresent) + changed = TRUE; + else if (transform && memcmp (&transform->transform, &crtc->transform.transform, + sizeof (transform->transform)) != 0) changed = TRUE; if (x != crtc->x || y != crtc->y) @@ -820,9 +825,10 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, if (randr_mode) { DisplayModeRec mode; + RRTransformPtr transform = RRCrtcGetTransform (randr_crtc); xf86RandRModeConvert (pScrn, randr_mode, &mode); - if (!xf86CrtcSetMode (crtc, &mode, rotation, x, y)) + if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y)) { crtc->enabled = save_enabled; for (o = 0; o < config->num_output; o++) @@ -838,6 +844,12 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, */ crtc->desiredMode = mode; crtc->desiredRotation = rotation; + if (transform) { + crtc->desiredTransform = *transform; + crtc->desiredTransformPresent = TRUE; + } else + crtc->desiredTransformPresent = FALSE; + crtc->desiredX = x; crtc->desiredY = y; } diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h index c361b4733..17a2dcc7f 100644 --- a/hw/xfree86/modes/xf86RandR12.h +++ b/hw/xfree86/modes/xf86RandR12.h @@ -31,7 +31,7 @@ Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen); Bool xf86RandR12Init(ScreenPtr pScreen); void xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotation); -void xf86RandR12SetTransform (ScreenPtr pScreen, Bool transforms); +void xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms); Bool xf86RandR12SetConfig(ScreenPtr pScreen, Rotation rotation, int rate, RRScreenSizePtr pSize); Rotation xf86RandR12GetRotation(ScreenPtr pScreen); diff --git a/hw/xfree86/modes/xf86Rename.h b/hw/xfree86/modes/xf86Rename.h index b8c1d70ef..e3418caad 100644 --- a/hw/xfree86/modes/xf86Rename.h +++ b/hw/xfree86/modes/xf86Rename.h @@ -38,6 +38,7 @@ #define xf86CrtcInUse XF86NAME(xf86CrtcInUse) #define xf86CrtcRotate XF86NAME(xf86CrtcRotate) #define xf86CrtcScreenInit XF86NAME(xf86CrtcScreenInit) +#define xf86CrtcSetModeTransform XF86NAME(xf86CrtcSetModeTransform) #define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode) #define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange) #define xf86CVTMode XF86NAME(xf86CVTMode) diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index efbacec8e..7d35c3494 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -349,8 +349,35 @@ xf86RotateCloseScreen (ScreenPtr screen) xf86RotateDestroy (xf86_config->crtc[c]); } +static Bool +xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb) +{ + ScrnInfoPtr pScrn = crtc->scrn; + /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + BoxRec b; + + if (!pScreen) + return TRUE; + b.x1 = 0; + b.y1 = 0; + b.x2 = crtc->mode.HDisplay; + b.y2 = crtc->mode.VDisplay; + if (crtc_to_fb) + pict_f_transform_bounds (crtc_to_fb, &b); + else { + b.x1 += crtc->x; + b.y1 += crtc->y; + b.x2 += crtc->x; + b.y2 += crtc->y; + } + + return (0 <= b.x1 && b.x2 <= pScreen->width && + 0 <= b.y1 && b.y2 <= pScreen->height); +} + _X_EXPORT Bool -xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) +xf86CrtcRotate (xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); @@ -364,20 +391,19 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) int new_width = 0; int new_height = 0; RRTransformPtr transform = NULL; - -#ifdef RANDR_12_INTERFACE - if (crtc->randr_crtc) - transform = RRCrtcGetTransform (crtc->randr_crtc); -#endif - if (!transform || - !RRComputeTransform (crtc->x, crtc->y, + + if (crtc->transformPresent) + transform = &crtc->transform; + + if (!RRComputeTransform (crtc->x, crtc->y, crtc->mode.HDisplay, crtc->mode.VDisplay, - rotation, + crtc->rotation, transform, &crtc_to_fb, &f_crtc_to_fb, - &f_fb_to_crtc)) + &f_fb_to_crtc) && + xf86CrtcFitsScreen (crtc, &f_crtc_to_fb)) { /* * If the untranslated transformation is the identity, @@ -400,8 +426,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) * matches the mode, not the pre-rotated copy in the * frame buffer */ - int width = mode->HDisplay; - int height = mode->VDisplay; + int width = crtc->mode.HDisplay; + int height = crtc->mode.VDisplay; void *shadowData = crtc->rotatedData; PixmapPtr shadow = crtc->rotatedPixmap; int old_width = shadow ? shadow->drawable.width : 0; diff --git a/randr/randrstr.h b/randr/randrstr.h index 5ac983d90..d4cfa67e6 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -545,7 +545,7 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations); * Set whether transforms are allowed on a CRTC */ void -RRCrtcSetTransform (RRCrtcPtr crtc, Bool transforms); +RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms); /* * Notify the extension that the Crtc has been reconfigured, @@ -639,7 +639,7 @@ RRCrtcGetTransform (RRCrtcPtr crtc); * Mark the pending transform as current */ void -RRCrtcPostPendingTransform (RRCrtcPtr crtc); +RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform); /* * Check whether the pending and current transforms are the same diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c index d7ea6f22b..091517a05 100644 --- a/randr/rrcrtc.c +++ b/randr/rrcrtc.c @@ -91,12 +91,23 @@ RRTransformSetFilter (RRTransformPtr dst, static Bool RRTransformCopy (RRTransformPtr dst, RRTransformPtr src) { - if (!RRTransformSetFilter (dst, src->filter, - src->params, src->nparams, src->width, src->height)) - return FALSE; - dst->transform = src->transform; - dst->f_transform = src->f_transform; - dst->f_inverse = src->f_inverse; + if (src) + { + if (!RRTransformSetFilter (dst, src->filter, + src->params, src->nparams, src->width, src->height)) + return FALSE; + dst->transform = src->transform; + dst->f_transform = src->f_transform; + dst->f_inverse = src->f_inverse; + } + else + { + if (!RRTransformSetFilter (dst, NULL, NULL, 0, 0, 0)) + return FALSE; + PictureTransformInitIdentity (&dst->transform); + pict_f_transform_init_identity (&dst->f_transform); + pict_f_transform_init_identity (&dst->f_inverse); + } return TRUE; } @@ -170,7 +181,7 @@ RRCrtcSetRotations (RRCrtcPtr crtc, Rotation rotations) * Set whether transforms are allowed on a CRTC */ void -RRCrtcSetTransform (RRCrtcPtr crtc, Bool transforms) +RRCrtcSetTransformSupport (RRCrtcPtr crtc, Bool transforms) { crtc->transforms = transforms; } @@ -439,21 +450,21 @@ RRCrtcGetTransform (RRCrtcPtr crtc) } /* - * Mark the pending transform as current + * Called when driver applies a transform to a crtc */ void -RRCrtcPostPendingTransform (RRCrtcPtr crtc) +RRCrtcSetTransform (RRCrtcPtr crtc, RRTransformPtr transform) { if (!crtc->mode) return; - RRTransformCopy (&crtc->client_current_transform, - &crtc->client_pending_transform); + RRTransformCopy (&crtc->client_current_transform, transform); + RRComputeTransform (crtc->x, crtc->y, crtc->mode->mode.width, crtc->mode->mode.height, crtc->rotation, - &crtc->client_current_transform, + transform, &crtc->transform, &crtc->f_transform, &crtc->f_inverse); @@ -1091,23 +1102,25 @@ ProcRRSetCrtcConfig (ClientPtr client) } #ifdef RANDR_12_INTERFACE -#if 0 /* * Check screen size bounds if the DDX provides a 1.2 interface * for setting screen size. Else, assume the CrtcSet sets - * the size along with the mode + * the size along with the mode. If the driver supports transforms, + * then it must allow crtcs to display a subset of the screen, so + * only do this check for drivers without transform support. */ - if (pScrPriv->rrScreenSetSize) + if (pScrPriv->rrScreenSetSize && !crtc->transforms) { int source_width; int source_height; - PictTransform transform, inverse; + PictTransform transform; + struct pict_f_transform f_transform, f_inverse; - RRComputeTransform (mode, stuff->rotation, - stuff->x, stuff->y, - &crtc->client_pending_transform.transform, - &crtc->client_pending_transform.inverse, - &transform, &inverse); + RRComputeTransform (stuff->x, stuff->y, + mode->mode.width, mode->mode.height, + rotation, + &crtc->client_pending_transform, + &transform, &f_transform, &f_inverse); RRModeGetScanoutSize (mode, &transform, &source_width, &source_height); if (stuff->x + source_width > pScreen->width) @@ -1127,7 +1140,6 @@ ProcRRSetCrtcConfig (ClientPtr client) } } #endif -#endif } /* |