Commit 6fe9c157 authored by Keith Packard's avatar Keith Packard

Allow drivers to set crtc transforms.

Track curent transform down in the mode setting code so that it may be set
separately from RandR.
parent 49db14e4
......@@ -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;
}
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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);
......
......@@ -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)
......
......@@ -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;
......
......@@ -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
......
......@@ -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)
......@@ -1126,7 +1139,6 @@ ProcRRSetCrtcConfig (ClientPtr client)
return BadValue;
}
}
#endif
#endif
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment