Interim work on rotation support with new xf86 code.

Yes, there are lots of bits tied together here, and we should split this
patch apart.

Move I830 mode setting to xf86 mode setting.

Make mode setting function also set the base address. This should fix
problems where the base gets set incorrectly at times.

Add driver-independent rotation support, requires driver-specific hooks for
shadow pixmap allocation, otherwise it uses Render for painting.
This commit is contained in:
Keith Packard 2007-01-16 12:14:55 +11:00
parent bfeda3bfc5
commit 37946c9c8a
10 changed files with 71 additions and 60 deletions

View File

@ -221,6 +221,7 @@ enum last_3d {
LAST_3D_ROTATION
};
#if 0
typedef struct _I830PipeRec {
Bool enabled;
int x;
@ -233,6 +234,7 @@ typedef struct _I830PipeRec {
RRCrtcPtr randr_crtc;
#endif
} I830PipeRec, *I830PipePtr;
#endif
typedef struct _I830Rec {
unsigned char *MMIOBase;

View File

@ -314,7 +314,7 @@ i830_crt_detect(xf86OutputPtr output)
if (intel_output->load_detect_temp)
{
xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
xf86CrtcSetMode (crtc, &mode, RR_Rotate_0);
xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
}
connected = i830_crt_detect_load (crtc, output);

View File

@ -492,7 +492,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
{
xf86CrtcPtr crtc = xf86_config->crtc[pipe];
DisplayModePtr mode = &crtc->curMode;
DisplayModePtr mode = &crtc->mode;
int thisx = x - crtc->x;
int thisy = y - crtc->y;

View File

@ -358,9 +358,6 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
(void) INREG(dspbase);
}
crtc->x = x;
crtc->y = y;
}
/**
@ -601,7 +598,8 @@ i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
*/
static void
i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
DisplayModePtr adjusted_mode,
int x, int y)
{
ScrnInfoPtr pScrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
@ -837,7 +835,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
OUTREG(dspcntr_reg, dspcntr);
/* Flush the plane changes */
i830PipeSetBase(crtc, crtc->x, crtc->y);
i830PipeSetBase(crtc, x, y);
i830WaitForVblank(pScrn);
}
@ -901,7 +899,7 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation)
{
ok = xf86CrtcSetMode(crtc,
i830PipeFindClosestMode(crtc, pMode),
rotation);
rotation, 0, 0);
if (!ok)
goto done;
crtc->desiredMode = *pMode;

View File

@ -3020,7 +3020,10 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
(*pI830->AccelInfoRec->Sync)(pScrn);
pI830->AccelInfoRec->NeedToSync = FALSE;
}
/* XXX should have xf86-based frame adjuster */
i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y);
crtc->x = output->initial_x + x;
crtc->y = output->initial_y + y;
}
}
@ -3138,14 +3141,17 @@ I830EnterVT(int scrnIndex, int flags)
xf86CrtcPtr crtc = xf86_config->crtc[i];
/* Mark that we'll need to re-set the mode for sure */
memset(&crtc->curMode, 0, sizeof(crtc->curMode));
memset(&crtc->mode, 0, sizeof(crtc->mode));
if (!crtc->desiredMode.CrtcHDisplay)
{
crtc->desiredMode = *i830PipeFindClosestMode (crtc, pScrn->currentMode);
crtc->desiredRotation = RR_Rotate_0;
crtc->desiredX = 0;
crtc->desiredY = 0;
}
if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation))
if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
crtc->desiredX, crtc->desiredY))
return FALSE;
}

View File

@ -393,8 +393,8 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
int crtc_width = crtc->x + crtc->curMode.HDisplay;
int crtc_height = crtc->y + crtc->curMode.VDisplay;
int crtc_width = crtc->x + crtc->mode.HDisplay;
int crtc_height = crtc->y + crtc->mode.VDisplay;
if (crtc->enabled && crtc_width > width)
width = crtc_width;
@ -533,7 +533,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
xf86CrtcPtr crtc = randr_crtc->devPrivate;
xf86OutputPtr output;
int i, j;
DisplayModePtr curMode = &crtc->curMode;
DisplayModePtr mode = &crtc->mode;
Bool ret;
randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
@ -541,7 +541,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
return FALSE;
x = crtc->x;
y = crtc->y;
rotation = crtc->curRotation;
rotation = crtc->rotation;
numOutputs = 0;
randr_mode = NULL;
for (i = 0; i < config->num_output; i++)
@ -558,7 +558,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
for (j = 0; j < randr_output->numModes; j++)
{
DisplayModePtr outMode = randr_output->modes[j]->devPrivate;
if (xf86ModesEqual(curMode, outMode))
if (xf86ModesEqual(mode, outMode))
{
randr_mode = randr_output->modes[j];
break;
@ -587,7 +587,6 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
xf86CrtcPtr crtc = randr_crtc->devPrivate;
DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
Bool changed = FALSE;
Bool pos_changed;
int o, ro;
xf86CrtcPtr *save_crtcs;
Bool save_enabled = crtc->enabled;
@ -595,12 +594,11 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
if ((mode != NULL) != crtc->enabled)
changed = TRUE;
else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
else if (mode && !xf86ModesEqual (&crtc->mode, mode))
changed = TRUE;
pos_changed = changed;
if (x != crtc->x || y != crtc->y)
pos_changed = TRUE;
changed = TRUE;
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
@ -627,18 +625,11 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
/* XXX need device-independent mode setting code through an API */
if (changed)
{
I830Ptr pI830 = I830PTR(pScrn);
crtc->enabled = mode != NULL;
/* Sync the engine before adjust mode */
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
(*pI830->AccelInfoRec->Sync)(pScrn);
pI830->AccelInfoRec->NeedToSync = FALSE;
}
if (mode)
{
if (!xf86CrtcSetMode (crtc, mode, rotation))
if (!xf86CrtcSetMode (crtc, mode, rotation, x, y))
{
crtc->enabled = save_enabled;
for (o = 0; o < config->num_output; o++)
@ -649,14 +640,16 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
DEALLOCATE_LOCAL(save_crtcs);
return FALSE;
}
/*
* Save the last successful setting for EnterVT
*/
crtc->desiredMode = *mode;
crtc->desiredRotation = rotation;
crtc->desiredX = x;
crtc->desiredY = y;
}
xf86DisableUnusedFunctions (pScrn);
i830DumpRegs(pScrn);
}
if (pos_changed && mode)
i830PipeSetBase(crtc, x, y);
DEALLOCATE_LOCAL(save_crtcs);
return xf86RandR12CrtcNotify (randr_crtc);
}
@ -817,6 +810,8 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
return TRUE;
}
/*
* Query the hardware for the current state, then mirror
* that to RandR

View File

@ -1065,7 +1065,7 @@ i830_tv_detect(xf86OutputPtr output)
/* we only need the pixel clock set correctly here */
mode = reported_modes[0];
xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
xf86CrtcSetMode (crtc, &mode, RR_Rotate_0);
xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
}
i830_tv_detect_type (crtc, output);
i830ReleaseLoadDetectPipe (output);

View File

@ -87,7 +87,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
#ifdef RANDR_12_INTERFACE
crtc->randr_crtc = NULL;
#endif
crtc->curRotation = RR_Rotate_0;
crtc->rotation = RR_Rotate_0;
crtc->desiredRotation = RR_Rotate_0;
if (xf86_config->crtc)
crtcs = xrealloc (xf86_config->crtc,
@ -145,7 +145,8 @@ xf86CrtcInUse (xf86CrtcPtr crtc)
* Sets the given video mode on the given crtc
*/
Bool
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int x, int y)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@ -166,6 +167,8 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
didLock = crtc->funcs->lock (crtc);
/* XXX short-circuit changes to base location only */
/* Pass our mode to the outputs and the CRTC to give them a chance to
* adjust it according to limitations or output properties, and also
* a chance to reject the mode entirely.
@ -211,7 +214,7 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
/* Set up the DPLL and any output state that needs to adjust or depend
* on the DPLL.
*/
crtc->funcs->mode_set(crtc, mode, adjusted_mode);
crtc->funcs->mode_set(crtc, mode, adjusted_mode, x, y);
for (i = 0; i < xf86_config->num_output; i++)
{
xf86OutputPtr output = xf86_config->output[i];
@ -228,7 +231,10 @@ xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
output->funcs->dpms(output, DPMSModeOn);
}
crtc->curMode = *mode;
crtc->mode = *mode;
crtc->x = x;
crtc->y = y;
crtc->rotation = rotation;
/* XXX free adjustedmode */
ret = TRUE;
@ -1401,7 +1407,7 @@ xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
if (!crtc->enabled)
{
crtc->funcs->dpms(crtc, DPMSModeOff);
memset(&crtc->curMode, 0, sizeof(crtc->curMode));
memset(&crtc->mode, 0, sizeof(crtc->mode));
}
}
}

View File

@ -70,7 +70,6 @@ typedef struct _xf86CrtcFuncs {
void
(*restore)(xf86CrtcPtr crtc);
/**
* Lock CRTC prior to mode setting, mostly for DRI.
* Returns whether unlock is needed
@ -102,7 +101,8 @@ typedef struct _xf86CrtcFuncs {
void
(*mode_set)(xf86CrtcPtr crtc,
DisplayModePtr mode,
DisplayModePtr adjusted_mode);
DisplayModePtr adjusted_mode,
int x, int y);
/* Set the color ramps for the CRTC to the given values. */
void
@ -141,13 +141,6 @@ struct _xf86Crtc {
*/
Bool enabled;
/**
* Position on screen
*
* Locates this CRTC within the frame buffer
*/
int x, y;
/** Track whether cursor is within CRTC range */
Bool cursorInRange;
@ -161,9 +154,15 @@ struct _xf86Crtc {
* It will be cleared when the VT is not active or
* during server startup
*/
DisplayModeRec curMode;
Rotation curRotation;
DisplayModeRec mode;
Rotation rotation;
PixmapPtr rotatedPixmap;
/**
* Position on screen
*
* Locates this CRTC within the frame buffer
*/
int x, y;
/**
* Desired mode
@ -175,6 +174,7 @@ struct _xf86Crtc {
*/
DisplayModeRec desiredMode;
Rotation desiredRotation;
int desiredX, desiredY;
/** crtc-specific functions */
const xf86CrtcFuncsRec *funcs;
@ -396,6 +396,10 @@ typedef struct _xf86CrtcConfig {
/* For crtc-based rotation */
DamagePtr rotationDamage;
/* DGA */
unsigned int dga_flags;
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern int xf86CrtcConfigPrivateIndex;
@ -448,7 +452,8 @@ xf86FreeCrtc (xf86CrtcPtr crtc);
* Sets the given video mode on the given crtc
*/
Bool
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
int x, int y);
/*
* Assign crtc rotation during mode set

View File

@ -128,7 +128,7 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
transform.matrix[2][2] = 1;
transform.matrix[0][2] = crtc->x;
transform.matrix[1][2] = crtc->y;
switch (crtc->curRotation & 0xf) {
switch (crtc->rotation & 0xf) {
case RR_Rotate_0:
transform.matrix[0][0] = 1;
transform.matrix[1][1] = 1;
@ -137,28 +137,28 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
/* XXX probably wrong */
transform.matrix[0][1] = 1;
transform.matrix[1][0] = -1;
transform.matrix[1][2] += crtc->curMode.HDisplay;
transform.matrix[1][2] += crtc->mode.HDisplay;
break;
case RR_Rotate_180:
/* XXX probably wrong */
transform.matrix[0][0] = -1;
transform.matrix[1][1] = -1;
transform.matrix[0][2] += crtc->curMode.HDisplay;
transform.matrix[1][2] += crtc->curMode.VDisplay;
transform.matrix[0][2] += crtc->mode.HDisplay;
transform.matrix[1][2] += crtc->mode.VDisplay;
break;
case RR_Rotate_270:
/* XXX probably wrong */
transform.matrix[0][1] = -1;
transform.matrix[1][0] = 1;
transform.matrix[0][2] += crtc->curMode.VDisplay;
transform.matrix[0][2] += crtc->mode.VDisplay;
break;
}
/* handle reflection */
if (crtc->curRotation & RR_Reflect_X)
if (crtc->rotation & RR_Reflect_X)
{
/* XXX figure this out */
}
if (crtc->curRotation & RR_Reflect_Y)
if (crtc->rotation & RR_Reflect_Y)
{
/* XXX figure this out too */
}
@ -191,16 +191,16 @@ xf86RotateRedisplay(ScreenPtr pScreen)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
if (crtc->curRotation != RR_Rotate_0)
if (crtc->rotation != RR_Rotate_0)
{
BoxRec box;
RegionRec crtc_damage;
/* compute portion of damage that overlaps crtc */
box.x1 = crtc->x;
box.x2 = crtc->x + mode_width (&crtc->curMode, crtc->curRotation);
box.x2 = crtc->x + mode_width (&crtc->mode, crtc->rotation);
box.y1 = crtc->y;
box.y2 = crtc->y + mode_height (&crtc->curMode, crtc->curRotation);
box.y2 = crtc->y + mode_height (&crtc->mode, crtc->rotation);
REGION_INIT(pScreen, &crtc_damage, &box, 1);
REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
@ -319,6 +319,5 @@ bail1:
}
/* All done */
crtc->curRotation = rotation;
return TRUE;
}