summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@neko.keithp.com>2007-01-29 21:25:13 -0800
committerKeith Packard <keithp@neko.keithp.com>2007-01-29 21:25:13 -0800
commitc8581254cb811f76aa6eae49d74489b543b3eb05 (patch)
tree95de90111a0088a78856647b3595db52787ad356
parent9da1791eeca446cd59e2e7d0803e8a7920dbbea5 (diff)
parentd329fa121b2401cadb991c2854e077cfa68e15e8 (diff)
Merge branch 'modesetting-rotation' into modesetting
This adds reasonably driver-independent rotation support to the common layer. The piece required in the driver is to allocate and redirect the crtc to a shadow frame buffer. The driver uses Render to perform the actual rotation operation (which leaves us free to do fun projective transforms at some point in the future :-).
-rw-r--r--src/Makefile.am1
-rw-r--r--src/i830.h23
-rw-r--r--src/i830_crt.c2
-rw-r--r--src/i830_cursor.c160
-rw-r--r--src/i830_display.c289
-rw-r--r--src/i830_display.h6
-rw-r--r--src/i830_driver.c99
-rw-r--r--src/i830_exa.c13
-rw-r--r--src/i830_lvds.c6
-rw-r--r--src/i830_memory.c240
-rw-r--r--src/i830_modes.c6
-rw-r--r--src/i830_randr.c46
-rw-r--r--src/i830_tv.c2
-rw-r--r--src/i830_video.c22
-rw-r--r--src/i830_xf86Crtc.c323
-rw-r--r--src/i830_xf86Crtc.h85
-rw-r--r--src/i830_xf86Modes.c26
-rw-r--r--src/i830_xf86Modes.h69
-rw-r--r--src/i830_xf86Rename.h66
-rw-r--r--src/i830_xf86Rotate.c401
-rw-r--r--src/local_xf86Rename.h23
21 files changed, 1326 insertions, 582 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 80cea10a..02e85768 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,6 +85,7 @@ i810_drv_la_SOURCES = \
i830_xf86cvt.c \
i830_xf86Crtc.h \
i830_xf86Crtc.c \
+ i830_xf86Rotate.c \
i915_3d.c \
i915_3d.h \
i915_reg.h \
diff --git a/src/i830.h b/src/i830.h
index 95bea2f0..9ffae94c 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -195,8 +195,19 @@ extern const char *i830_output_type_names[];
typedef struct _I830CrtcPrivateRec {
int pipe;
+
/* Lookup table values to be set when the CRTC is enabled */
CARD8 lut_r[256], lut_g[256], lut_b[256];
+
+#ifdef I830_USE_XAA
+ FBLinearPtr rotate_mem_xaa;
+#endif
+#ifdef I830_USE_EXA
+ ExaOffscreenArea *rotate_mem_exa;
+#endif
+
+ I830MemRange cursor_mem;
+ I830MemRange cursor_mem_argb;
} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
@@ -221,6 +232,7 @@ enum last_3d {
LAST_3D_ROTATION
};
+#if 0
typedef struct _I830PipeRec {
Bool enabled;
int x;
@@ -233,6 +245,7 @@ typedef struct _I830PipeRec {
RRCrtcPtr randr_crtc;
#endif
} I830PipeRec, *I830PipePtr;
+#endif
typedef struct _I830Rec {
unsigned char *MMIOBase;
@@ -271,8 +284,6 @@ typedef struct _I830Rec {
I830MemRange EXAStateMem; /* specific exa state for G965 */
#endif
/* Regions allocated either from the above pools, or from agpgart. */
- I830MemRange *CursorMem;
- I830MemRange *CursorMemARGB;
I830RingBuffer *LpRing;
#if REMAP_RESERVED
@@ -608,6 +619,14 @@ extern void i830WaitSync(ScrnInfoPtr pScrn);
/* i830_memory.c */
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
+#ifdef I830_USE_XAA
+FBLinearPtr
+i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
+ int granularity,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData);
+#endif /* I830_USE_EXA */
/* i830_modes.c */
DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 4e9e3706..573e6526 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -314,7 +314,7 @@ i830_crt_detect(xf86OutputPtr output)
if (intel_output->load_detect_temp)
{
xf86SetModeCrtc (&mode, INTERLACE_HALVE_V);
- i830PipeSetMode (crtc, &mode, FALSE);
+ xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
}
connected = i830_crt_detect_load (crtc, output);
diff --git a/src/i830_cursor.c b/src/i830_cursor.c
index 81cb3bd8..464eb6dd 100644
--- a/src/i830_cursor.c
+++ b/src/i830_cursor.c
@@ -94,9 +94,9 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc)
FatalError("Bad pipe number for cursor base setting\n");
if (pI830->CursorIsARGB)
- cursor_mem = pI830->CursorMemARGB;
+ cursor_mem = &intel_crtc->cursor_mem_argb;
else
- cursor_mem = pI830->CursorMem;
+ cursor_mem = &intel_crtc->cursor_mem;
if (pI830->CursorNeedsPhysical) {
OUTREG(cursor_base, cursor_mem->Physical);
@@ -251,21 +251,13 @@ I830CursorInit(ScreenPtr pScreen)
infoPtr->HideCursor = I830HideCursor;
infoPtr->ShowCursor = I830ShowCursor;
infoPtr->UseHWCursor = I830UseHWCursor;
-
- pI830->pCurs = NULL;
-
#ifdef ARGB_CURSOR
- pI830->CursorIsARGB = FALSE;
-
- if (pI830->CursorMemARGB->Start) {
- /* Use ARGB if we were able to allocate the 16kb needed */
- infoPtr->UseHWCursorARGB = I830UseHWCursorARGB;
- infoPtr->LoadCursorARGB = I830LoadCursorARGB;
- }
+ infoPtr->UseHWCursorARGB = I830UseHWCursorARGB;
+ infoPtr->LoadCursorARGB = I830LoadCursorARGB;
#endif
- if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical)
- return FALSE;
+ pI830->pCurs = NULL;
+
I830HideCursor(pScrn);
@@ -280,18 +272,16 @@ I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
pI830->pCurs = pCurs;
- DPRINTF(PFX, "I830UseHWCursor\n");
- if (pI830->CursorNeedsPhysical && !pI830->CursorMem->Physical)
- return FALSE;
-
return TRUE;
}
static void
-I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+I830CRTCLoadCursorImage(xf86CrtcPtr crtc, unsigned char *src)
{
+ ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
- CARD8 *pcurs = (CARD8 *) (pI830->FbBase + pI830->CursorMem->Start);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ CARD8 *pcurs = (CARD8 *) (pI830->FbBase + intel_crtc->cursor_mem.Start);
int x, y;
DPRINTF(PFX, "I830LoadCursorImage\n");
@@ -310,7 +300,7 @@ I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
(*(image + (x) / 8 + (y) * (128/8)) |=\
(int) (1 << (7-((x) % 8))))
- switch (pI830->rotation) {
+ switch (crtc->rotation) {
case RR_Rotate_90:
for (y = 0; y < 64; y++) {
for (x = 0; x < 64; x++) {
@@ -353,6 +343,17 @@ I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
}
}
+static void
+I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int pipe;
+
+ for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) {
+ I830CRTCLoadCursorImage(xf86_config->crtc[pipe], src);
+ }
+}
+
#ifdef ARGB_CURSOR
#include "cursorstr.h"
@@ -360,15 +361,22 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
DPRINTF(PFX, "I830UseHWCursorARGB\n");
pI830->pCurs = pCurs;
- if (pScrn->bitsPerPixel == 8)
- return FALSE;
+ /* Check that our ARGB allocations succeeded */
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+
+ if (!intel_crtc->cursor_mem_argb.Start)
+ return FALSE;
+ }
- if (pI830->CursorNeedsPhysical && !pI830->CursorMemARGB->Physical)
+ if (pScrn->bitsPerPixel == 8)
return FALSE;
if (pCurs->bits->height <= 64 && pCurs->bits->width <= 64)
@@ -377,10 +385,11 @@ static Bool I830UseHWCursorARGB (ScreenPtr pScreen, CursorPtr pCurs)
return FALSE;
}
-static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
+static void I830CRTCLoadCursorARGB (xf86CrtcPtr crtc, CursorPtr pCurs)
{
- I830Ptr pI830 = I830PTR(pScrn);
- CARD32 *dst = (CARD32 *) (pI830->FbBase + pI830->CursorMemARGB->Start);
+ I830Ptr pI830 = I830PTR(crtc->scrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ CARD32 *dst = (CARD32 *) (pI830->FbBase + intel_crtc->cursor_mem_argb.Start);
CARD32 *image = (CARD32 *)pCurs->bits->argb;
int x, y, w, h;
@@ -394,7 +403,7 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
w = pCurs->bits->width;
h = pCurs->bits->height;
- switch (pI830->rotation) {
+ switch (crtc->rotation) {
case RR_Rotate_90:
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++)
@@ -447,58 +456,69 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
*dst++ = 0;
}
}
+
+static void
+I830LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int pipe;
+
+ for (pipe = 0; pipe < xf86_config->num_crtc; pipe++) {
+ I830CRTCLoadCursorARGB(xf86_config->crtc[pipe], pCurs);
+ }
+}
#endif
static void
I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
Bool inrange;
- int oldx = x, oldy = y;
- int hotspotx = 0, hotspoty = 0;
+ int root_x = x, root_y = y;
int pipe;
- oldx += pScrn->frameX0; /* undo what xf86HWCurs did */
- oldy += pScrn->frameY0;
-
- switch (pI830->rotation) {
- case RR_Rotate_0:
- x = oldx;
- y = oldy;
- break;
- case RR_Rotate_90:
- x = oldy;
- y = pScrn->pScreen->width - oldx;
- hotspoty = I810_CURSOR_X;
- break;
- case RR_Rotate_180:
- x = pScrn->pScreen->width - oldx;
- y = pScrn->pScreen->height - oldy;
- hotspotx = I810_CURSOR_X;
- hotspoty = I810_CURSOR_Y;
- break;
- case RR_Rotate_270:
- x = pScrn->pScreen->height - oldy;
- y = oldx;
- hotspotx = I810_CURSOR_Y;
- break;
- }
-
- x -= hotspotx;
- y -= hotspoty;
+ root_x = x + pScrn->frameX0; /* undo what xf86HWCurs did */
+ root_y = y + pScrn->frameY0;
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
{
- xf86CrtcPtr crtc = xf86_config->crtc[pipe];
- DisplayModePtr mode = &crtc->curMode;
- int thisx = x - crtc->x;
- int thisy = y - crtc->y;
+ xf86CrtcPtr crtc = xf86_config->crtc[pipe];
+ DisplayModePtr mode = &crtc->mode;
+ int thisx = 0;
+ int thisy = 0;
+ int hotspotx = 0, hotspoty = 0;
if (!crtc->enabled)
continue;
+ switch (crtc->rotation) {
+ case RR_Rotate_0:
+ thisx = (root_x - crtc->x);
+ thisy = (root_y - crtc->y);
+ break;
+ case RR_Rotate_90:
+ thisx = (root_y - crtc->y);
+ thisy = mode->VDisplay - (root_x - crtc->x);
+ hotspoty = I810_CURSOR_X;
+ break;
+ case RR_Rotate_180:
+ thisx = mode->HDisplay - (root_x - crtc->x);
+ thisy = mode->VDisplay - (root_y - crtc->y);
+ hotspotx = I810_CURSOR_X;
+ hotspoty = I810_CURSOR_Y;
+ break;
+ case RR_Rotate_270:
+ thisx = mode->VDisplay - (root_y - crtc->y);
+ thisy = (root_x - crtc->x);
+ hotspotx = I810_CURSOR_Y;
+ break;
+ }
+
+ thisx -= hotspotx;
+ thisy -= hotspoty;
+
/*
* There is a screen display problem when the cursor position is set
* wholely outside of the viewport. We trap that here, turning the
@@ -541,19 +561,11 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
static void
I830ShowCursor(ScrnInfoPtr pScrn)
{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ I830Ptr pI830 = I830PTR(pScrn);
int pipe;
- DPRINTF(PFX, "I830ShowCursor\n");
- DPRINTF(PFX,
- "Value of CursorMem->Physical is %x, "
- " Value of CursorMem->Start is %x ",
- pI830->CursorMem->Physical, pI830->CursorMem->Start);
- DPRINTF(PFX,
- "Value of CursorMemARGB->Physical is %x, "
- " Value of CursorMemARGB->Start is %x ",
- pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
+ DPRINTF(PFX, "I830ShowCursor\n");
pI830->cursorOn = TRUE;
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
diff --git a/src/i830_display.c b/src/i830_display.c
index f47a9dbf..82029850 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -342,9 +342,12 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
- if (I830IsPrimary(pScrn))
+ if (crtc->rotatedPixmap != NULL) {
+ Start = (char *)crtc->rotatedPixmap->devPrivate.ptr -
+ (char *)pI830->FbBase;
+ } else if (I830IsPrimary(pScrn)) {
Start = pI830->FrontBuffer.Start;
- else {
+ } else {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
Start = pI8301->FrontBuffer2.Start;
}
@@ -358,9 +361,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;
}
/**
@@ -465,23 +465,6 @@ i830PipeFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
}
/**
- * Return whether any outputs are connected to the specified pipe
- */
-
-Bool
-i830PipeInUse (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
-
- for (i = 0; i < xf86_config->num_output; i++)
- if (xf86_config->output[i]->crtc == crtc)
- return TRUE;
- return FALSE;
-}
-
-/**
* Sets the power management mode of the pipe and plane.
*
* This code should probably grow support for turning the cursor off and back
@@ -581,6 +564,27 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
}
static Bool
+i830_crtc_lock (xf86CrtcPtr crtc)
+{
+ /* Sync the engine before mode switch */
+ i830WaitSync(crtc->scrn);
+
+#ifdef XF86DRI
+ return I830DRILock(crtc->scrn);
+#else
+ return FALSE;
+#endif
+}
+
+static void
+i830_crtc_unlock (xf86CrtcPtr crtc)
+{
+#ifdef XF86DRI
+ I830DRIUnlock (crtc->scrn);
+#endif
+}
+
+static Bool
i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
@@ -597,7 +601,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);
@@ -833,7 +838,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);
}
@@ -881,165 +886,111 @@ i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
}
/**
- * Sets the given video mode on the given pipe.
+ * Creates a locked-in-framebuffer pixmap of the given width and height for
+ * this CRTC's rotated shadow framebuffer.
*
- * Plane A is always output to pipe A, and plane B to pipe B. The plane
- * will not be enabled if plane_enable is FALSE, which is used for
- * load detection, when something else will be output to the pipe other than
- * display data.
+ * The current implementation uses fixed buffers allocated at startup at the
+ * maximal size.
*/
-Bool
-i830PipeSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode,
- Bool plane_enable)
+static PixmapPtr
+i830_crtc_shadow_create(xf86CrtcPtr crtc, int width, int height)
{
ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int i;
- Bool ret = FALSE;
-#ifdef XF86DRI
- Bool didLock = FALSE;
-#endif
- DisplayModePtr adjusted_mode;
-
- /* XXX: curMode */
-
- adjusted_mode = xf86DuplicateMode(pMode);
-
- crtc->enabled = i830PipeInUse (crtc);
-
- if (!crtc->enabled)
- {
- /* XXX disable crtc? */
- return TRUE;
- }
-
-#ifdef XF86DRI
- didLock = I830DRILock(pScrn);
-#endif
-
- /* 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.
+ ScreenPtr pScreen = pScrn->pScreen;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ unsigned long rotate_pitch;
+ PixmapPtr rotate_pixmap;
+ unsigned long rotate_offset;
+ int align = KB(4), size;
+
+ rotate_pitch = pI830->displayWidth * pI830->cpp;
+ size = rotate_pitch * height;
+
+#ifdef I830_USE_EXA
+ /* We could get close to what we want here by just creating a pixmap like
+ * normal, but we have to lock it down in framebuffer, and there is no
+ * setter for offscreen area locking in EXA currently. So, we just
+ * allocate offscreen memory and fake up a pixmap header for it.
*/
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
-
- if (output->crtc != crtc)
- continue;
-
- if (!output->funcs->mode_fixup(output, pMode, adjusted_mode)) {
- ret = FALSE;
- goto done;
+ if (pI830->useEXA) {
+ assert(intel_crtc->rotate_mem_exa == NULL);
+
+ intel_crtc->rotate_mem_exa = exaOffscreenAlloc(pScreen, size, align,
+ TRUE, NULL, NULL);
+ if (intel_crtc->rotate_mem_exa == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
}
+ rotate_offset = intel_crtc->rotate_mem_exa->offset;
}
-
- if (!crtc->funcs->mode_fixup(crtc, pMode, adjusted_mode)) {
- ret = FALSE;
- goto done;
- }
-
- /* Disable the outputs and CRTCs before setting the mode. */
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
-
- if (output->crtc != crtc)
- continue;
-
- /* Disable the output as the first thing we do. */
- output->funcs->dpms(output, DPMSModeOff);
- }
-
- crtc->funcs->dpms(crtc, DPMSModeOff);
-
- /* Set up the DPLL and any output state that needs to adjust or depend
- * on the DPLL.
- */
- crtc->funcs->mode_set(crtc, pMode, adjusted_mode);
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- if (output->crtc == crtc)
- output->funcs->mode_set(output, pMode, adjusted_mode);
+#endif /* I830_USE_EXA */
+#ifdef I830_USE_XAA
+ if (!pI830->useEXA) {
+ /* The XFree86 linear allocator operates in units of screen pixels,
+ * sadly.
+ */
+ size = (size + pI830->cpp - 1) / pI830->cpp;
+ align = (align + pI830->cpp - 1) / pI830->cpp;
+
+ assert(intel_crtc->rotate_mem_xaa == NULL);
+
+ intel_crtc->rotate_mem_xaa =
+ i830_xf86AllocateOffscreenLinear(pScreen, size, align,
+ NULL, NULL, NULL);
+ if (intel_crtc->rotate_mem_xaa == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
+ }
+ rotate_offset = pI830->FrontBuffer.Start +
+ intel_crtc->rotate_mem_xaa->offset * pI830->cpp;
}
-
- /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
- crtc->funcs->dpms(crtc, DPMSModeOn);
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- if (output->crtc == crtc)
- output->funcs->dpms(output, DPMSModeOn);
+#endif /* I830_USE_XAA */
+
+ rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
+ width, height,
+ pScrn->depth,
+ pScrn->bitsPerPixel,
+ rotate_pitch,
+ pI830->FbBase + rotate_offset);
+ if (rotate_pixmap == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
}
-
-#if 0
- /*
- * If the display isn't solid, it may be running out
- * of memory bandwidth. This code will dump out the
- * pipe status, if bit 31 is on, the fifo underran
- */
- for (i = 0; i < 4; i++) {
- i830WaitForVblank(pScrn);
-
- OUTREG(pipestat_reg, INREG(pipestat_reg) | 0x80000000);
-
- i830WaitForVblank(pScrn);
-
- temp = INREG(pipestat_reg);
- ErrorF ("pipe status 0x%x\n", temp);
- }
-#endif
-
- crtc->curMode = *pMode;
-
- /* XXX free adjustedmode */
- ret = TRUE;
-done:
-#ifdef XF86DRI
- if (didLock)
- I830DRIUnlock(pScrn);
-#endif
- return ret;
+ return rotate_pixmap;
}
-void
-i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
+static void
+i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap)
{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int o, pipe;
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n");
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- for (o = 0; o < xf86_config->num_output; o++)
- {
- xf86OutputPtr output = xf86_config->output[o];
- if (!output->crtc) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling output %s\n",
- output->name);
- (*output->funcs->dpms)(output, DPMSModeOff);
- }
+ FreeScratchPixmapHeader(rotate_pixmap);
+#ifdef I830_USE_EXA
+ if (pI830->useEXA && intel_crtc->rotate_mem_exa != NULL) {
+ exaOffscreenFree(pScrn->pScreen, intel_crtc->rotate_mem_exa);
+ intel_crtc->rotate_mem_exa = NULL;
}
-
- for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[pipe];
- I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
- int pipe = intel_crtc->pipe;
- char *pipe_name = pipe == 0 ? "A" : "B";
-
- if (!crtc->enabled) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling CRTC %s\n",
- pipe_name);
- crtc->funcs->dpms(crtc, DPMSModeOff);
-
- memset(&crtc->curMode, 0, sizeof(crtc->curMode));
- }
+#endif /* I830_USE_EXA */
+#ifdef I830_USE_XAA
+ if (!pI830->useEXA) {
+ xf86FreeOffscreenLinear(intel_crtc->rotate_mem_xaa);
+ intel_crtc->rotate_mem_xaa = NULL;
}
+#endif /* I830_USE_XAA */
}
+
/**
* This function configures the screens in clone mode on
* all active outputs using a mode similar to the specified mode.
*/
Bool
-i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
+i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
Bool ok = TRUE;
@@ -1049,9 +1000,9 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
if (crtc && crtc->enabled)
{
- ok = i830PipeSetMode(crtc,
- i830PipeFindClosestMode(crtc, pMode),
- TRUE);
+ ok = xf86CrtcSetMode(crtc,
+ i830PipeFindClosestMode(crtc, pMode),
+ rotation, 0, 0);
if (!ok)
goto done;
crtc->desiredMode = *pMode;
@@ -1061,7 +1012,7 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
(int)(pMode->HDisplay * pMode->VDisplay *
pMode->VRefresh / 1000000));
- i830DisableUnusedFunctions(pScrn);
+ xf86DisableUnusedFunctions(pScrn);
i830DescribeOutputConfiguration(pScrn);
@@ -1153,7 +1104,7 @@ i830GetLoadDetectPipe(xf86OutputPtr output)
return output->crtc;
for (i = 0; i < xf86_config->num_crtc; i++)
- if (!i830PipeInUse(xf86_config->crtc[i]))
+ if (!xf86CrtcInUse (xf86_config->crtc[i]))
break;
if (i == xf86_config->num_crtc)
@@ -1177,7 +1128,7 @@ i830ReleaseLoadDetectPipe(xf86OutputPtr output)
{
output->crtc = NULL;
intel_output->load_detect_temp = FALSE;
- i830DisableUnusedFunctions(pScrn);
+ xf86DisableUnusedFunctions(pScrn);
}
}
@@ -1185,9 +1136,13 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = {
.dpms = i830_crtc_dpms,
.save = NULL, /* XXX */
.restore = NULL, /* XXX */
+ .lock = i830_crtc_lock,
+ .unlock = i830_crtc_unlock,
.mode_fixup = i830_crtc_mode_fixup,
.mode_set = i830_crtc_mode_set,
.gamma_set = i830_crtc_gamma_set,
+ .shadow_create = i830_crtc_shadow_create,
+ .shadow_destroy = i830_crtc_shadow_destroy,
.destroy = NULL, /* XXX */
};
diff --git a/src/i830_display.h b/src/i830_display.h
index 66ab17e8..dc800553 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -30,16 +30,12 @@
/* i830_display.c */
DisplayModePtr
i830PipeFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode);
-Bool i830PipeSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode,
- Bool plane_enable);
-void i830DisableUnusedFunctions(ScrnInfoPtr pScrn);
-Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
+Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation);
void i830PipeSetBase(xf86CrtcPtr crtc, int x, int y);
void i830WaitForVblank(ScrnInfoPtr pScrn);
void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
-Bool i830PipeInUse(xf86CrtcPtr crtc);
void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
void i830_crtc_load_lut(xf86CrtcPtr crtc);
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 32729c17..d6d0df09 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -764,12 +764,6 @@ PreInitCleanup(ScrnInfoPtr pScrn)
if (pI830->LpRing)
xfree(pI830->LpRing);
pI830->LpRing = NULL;
- if (pI830->CursorMem)
- xfree(pI830->CursorMem);
- pI830->CursorMem = NULL;
- if (pI830->CursorMemARGB)
- xfree(pI830->CursorMemARGB);
- pI830->CursorMemARGB = NULL;
if (pI830->OverlayMem)
xfree(pI830->OverlayMem);
pI830->OverlayMem = NULL;
@@ -1526,12 +1520,10 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
/* Alloc our pointers for the primary head */
if (I830IsPrimary(pScrn)) {
pI830->LpRing = xalloc(sizeof(I830RingBuffer));
- pI830->CursorMem = xalloc(sizeof(I830MemRange));
- pI830->CursorMemARGB = xalloc(sizeof(I830MemRange));
pI830->OverlayMem = xalloc(sizeof(I830MemRange));
pI830->overlayOn = xalloc(sizeof(Bool));
pI830->used3D = xalloc(sizeof(int));
- if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB ||
+ if (!pI830->LpRing ||
!pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Could not allocate primary data structures.\n");
@@ -2563,17 +2555,13 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (I830IsPrimary(pScrn)) {
if (!pI830->LpRing)
pI830->LpRing = xalloc(sizeof(I830RingBuffer));
- if (!pI830->CursorMem)
- pI830->CursorMem = xalloc(sizeof(I830MemRange));
- if (!pI830->CursorMemARGB)
- pI830->CursorMemARGB = xalloc(sizeof(I830MemRange));
if (!pI830->OverlayMem)
pI830->OverlayMem = xalloc(sizeof(I830MemRange));
if (!pI830->overlayOn)
pI830->overlayOn = xalloc(sizeof(Bool));
if (!pI830->used3D)
pI830->used3D = xalloc(sizeof(int));
- if (!pI830->LpRing || !pI830->CursorMem || !pI830->CursorMemARGB ||
+ if (!pI830->LpRing ||
!pI830->OverlayMem || !pI830->overlayOn || !pI830->used3D) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Could not allocate primary data structures.\n");
@@ -2588,8 +2576,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (!I830IsPrimary(pScrn)) {
pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
pI830->LpRing = pI8301->LpRing;
- pI830->CursorMem = pI8301->CursorMem;
- pI830->CursorMemARGB = pI8301->CursorMemARGB;
pI830->OverlayMem = pI8301->OverlayMem;
pI830->overlayOn = pI8301->overlayOn;
pI830->used3D = pI8301->used3D;
@@ -2638,15 +2624,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
}
- if (!pI830->SWCursor) {
- if (pI830->CursorMem->Size == 0) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling HW cursor because the cursor memory "
- "allocation failed.\n");
- pI830->SWCursor = TRUE;
- }
- }
-
#ifdef I830_XV
if (pI830->XvEnabled) {
if (pI830->noAccel) {
@@ -2882,7 +2859,23 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
shadowSetup(pScreen);
/* support all rotations */
xf86RandR12Init (pScreen);
- xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_180 | RR_Rotate_270);
+ if (pI830->useEXA) {
+#ifdef I830_USE_EXA
+ if (pI830->EXADriverPtr->exa_minor >= 1) {
+ xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 |
+ RR_Rotate_180 | RR_Rotate_270);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "EXA version %d.%d too old to support rotation\n",
+ pI830->EXADriverPtr->exa_major,
+ pI830->EXADriverPtr->exa_minor);
+ xf86RandR12SetRotations (pScreen, RR_Rotate_0);
+ }
+#endif /* I830_USE_EXA */
+ } else {
+ xf86RandR12SetRotations (pScreen, RR_Rotate_0 | RR_Rotate_90 |
+ RR_Rotate_180 | RR_Rotate_270);
+ }
pI830->PointerMoved = pScrn->PointerMoved;
pScrn->PointerMoved = I830PointerMoved;
pI830->CreateScreenResources = pScreen->CreateScreenResources;
@@ -2997,6 +2990,8 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
/* Sync the engine before adjust frame */
i830WaitSync(pScrn);
i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y);
+ crtc->x = output->initial_x + x;
+ crtc->y = output->initial_y + y;
}
}
@@ -3107,18 +3102,24 @@ I830EnterVT(int scrnIndex, int flags)
ResetState(pScrn, FALSE);
SetHWOperatingState(pScrn);
- i830DisableUnusedFunctions(pScrn);
+ xf86DisableUnusedFunctions(pScrn);
for (i = 0; i < xf86_config->num_crtc; i++)
{
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 (!i830PipeSetMode (crtc, &crtc->desiredMode, TRUE))
+ if (!xf86CrtcSetMode (crtc, &crtc->desiredMode, crtc->desiredRotation,
+ crtc->desiredX, crtc->desiredY))
return FALSE;
}
@@ -3199,45 +3200,11 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
Bool ret = TRUE;
- PixmapPtr pspix = (*pScrn->pScreen->GetScreenPixmap) (pScrn->pScreen);
DPRINTF(PFX, "I830SwitchMode: mode == %p\n", mode);
- /* Sync the engine before mode switch */
- i830WaitSync(pScrn);
-
- /* Check if our currentmode is about to change. We do this so if we
- * are rotating, we don't need to call the mode setup again.
- */
- if (pI830->currentMode != mode) {
- if (!i830SetMode(pScrn, mode))
- ret = FALSE;
- }
-
- /* Kludge to detect Rotate or Vidmode switch. Not very elegant, but
- * workable given the implementation currently. We only need to call
- * the rotation function when we know that the framebuffer has been
- * disabled by the EnableDisableFBAccess() function.
- *
- * The extra WindowTable check detects a rotation at startup.
- */
- if ( (!WindowTable[pScrn->scrnIndex] || pspix->devPrivate.ptr == NULL) &&
- !pI830->DGAactive && (pScrn->PointerMoved == I830PointerMoved)) {
- if (!I830Rotate(pScrn, mode))
- ret = FALSE;
- }
-
- /* Either the original setmode or rotation failed, so restore the previous
- * video mode here, as we'll have already re-instated the original rotation.
- */
- if (!ret) {
- if (!i830SetMode(pScrn, pI830->currentMode)) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Failed to restore previous mode (SwitchMode)\n");
- }
- } else {
+ if (!i830SetMode(pScrn, mode, pI830->rotation))
pI830->currentMode = mode;
- }
return ret;
}
@@ -3309,10 +3276,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
xfree(pI830->LpRing);
pI830->LpRing = NULL;
- xfree(pI830->CursorMem);
- pI830->CursorMem = NULL;
- xfree(pI830->CursorMemARGB);
- pI830->CursorMemARGB = NULL;
xfree(pI830->OverlayMem);
pI830->OverlayMem = NULL;
xfree(pI830->overlayOn);
diff --git a/src/i830_exa.c b/src/i830_exa.c
index f1cd1e36..3fd5e4ae 100644
--- a/src/i830_exa.c
+++ b/src/i830_exa.c
@@ -418,7 +418,7 @@ I830EXAInit(ScreenPtr pScreen)
pI830->bufferOffset = 0;
pI830->EXADriverPtr->exa_major = 2;
- pI830->EXADriverPtr->exa_minor = 0;
+ pI830->EXADriverPtr->exa_minor = 1;
pI830->EXADriverPtr->memoryBase = pI830->FbBase;
pI830->EXADriverPtr->offScreenBase = pI830->Offscreen.Start;
pI830->EXADriverPtr->memorySize = pI830->Offscreen.End;
@@ -520,9 +520,14 @@ I830EXAInit(ScreenPtr pScreen)
}
if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
- xfree(pI830->EXADriverPtr);
- pI830->noAccel = TRUE;
- return FALSE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "EXA initialization failed; trying older version\n");
+ pI830->EXADriverPtr->exa_minor = 0;
+ if(!exaDriverInit(pScreen, pI830->EXADriverPtr)) {
+ xfree(pI830->EXADriverPtr);
+ pI830->noAccel = TRUE;
+ return FALSE;
+ }
}
I830SelectBuffer(pScrn, I830_SELECT_FRONT);
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index 0092dedb..59af13b9 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -270,10 +270,10 @@ i830_lvds_get_modes(xf86OutputPtr output)
xf86MonPtr edid_mon;
DisplayModePtr modes;
- edid_mon = i830_xf86OutputGetEDID (output, intel_output->pDDCBus);
- i830_xf86OutputSetEDID (output, edid_mon);
+ edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus);
+ xf86OutputSetEDID (output, edid_mon);
- modes = i830_xf86OutputGetEDIDModes (output);
+ modes = xf86OutputGetEDIDModes (output);
if (modes != NULL)
return modes;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 426242a9..24f0b296 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -769,6 +769,91 @@ I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
return TRUE;
}
+static Bool
+I830AllocateCursorBuffers(xf86CrtcPtr crtc, const int flags)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
+ int verbosity = dryrun ? 4 : 1;
+ const char *s = dryrun ? "[dryrun] " : "";
+ long size, alloced;
+ int cursFlags = 0;
+
+ /* Clear cursor info */
+ memset(&intel_crtc->cursor_mem, 0, sizeof(I830MemRange));
+ intel_crtc->cursor_mem.Key = -1;
+ memset(&intel_crtc->cursor_mem_argb, 0, sizeof(I830MemRange));
+ intel_crtc->cursor_mem_argb.Key = -1;
+
+ if (pI830->SWCursor)
+ return FALSE;
+
+ /*
+ * Mouse cursor -- The i810-i830 need a physical address in system
+ * memory from which to upload the cursor. We get this from
+ * the agpgart module using a special memory type.
+ */
+
+ size = HWCURSOR_SIZE;
+ cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
+ if (pI830->CursorNeedsPhysical)
+ cursFlags |= NEED_PHYSICAL_ADDR;
+
+ alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem,
+ &pI830->StolenPool, size,
+ GTT_PAGE_SIZE, flags | cursFlags);
+ if (alloced < size ||
+ (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem.Physical))
+ {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate HW cursor space.\n");
+ return FALSE;
+ }
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for HW cursor at 0x%lx", s,
+ alloced / 1024, intel_crtc->cursor_mem.Start);
+ if (pI830->CursorNeedsPhysical) {
+ xf86ErrorFVerb(verbosity, " (0x%08lx)",
+ intel_crtc->cursor_mem.Physical);
+ }
+ xf86ErrorFVerb(verbosity, "\n");
+ }
+
+ /* Allocate the ARGB cursor space. Its success is optional -- we won't set
+ * SWCursor if it fails.
+ */
+ size = HWCURSOR_SIZE_ARGB;
+ cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
+ if (pI830->CursorNeedsPhysical)
+ cursFlags |= NEED_PHYSICAL_ADDR;
+
+ alloced = I830AllocVidMem(pScrn, &intel_crtc->cursor_mem_argb,
+ &pI830->StolenPool, size,
+ GTT_PAGE_SIZE, flags | cursFlags);
+ if (alloced < size ||
+ (pI830->CursorNeedsPhysical && !intel_crtc->cursor_mem_argb.Physical)) {
+ if (!dryrun) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate HW (ARGB) cursor space.\n");
+ }
+ } else {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
+ "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s,
+ alloced / 1024, intel_crtc->cursor_mem_argb.Start);
+ if (pI830->CursorNeedsPhysical) {
+ xf86ErrorFVerb(verbosity, " (0x%08lx)",
+ intel_crtc->cursor_mem_argb.Physical);
+ }
+ xf86ErrorFVerb(verbosity, "\n");
+ }
+
+ return FALSE;
+}
+
/*
* Allocate memory for 2D operation. This includes the (front) framebuffer,
* ring buffer, scratch memory, HW cursor.
@@ -777,12 +862,13 @@ Bool
I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
{
I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
long size, alloced;
Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
int verbosity = dryrun ? 4 : 1;
const char *s = dryrun ? "[dryrun] " : "";
Bool tileable;
- int align, alignflags;
+ int align, alignflags, i;
DPRINTF(PFX, "I830Allocate2DMemory: inital is %s\n",
BOOLTOSTRING(flags & ALLOC_INITIAL));
@@ -814,7 +900,6 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->StolenPool.Free.Size);
if (flags & ALLOC_INITIAL) {
-
if (pI830->NeedRingBufferLow)
AllocateRingBuffer(pScrn, flags | FORCE_LOW);
@@ -979,63 +1064,18 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
}
#endif
- /* Clear cursor info */
- memset(pI830->CursorMem, 0, sizeof(I830MemRange));
- pI830->CursorMem->Key = -1;
- memset(pI830->CursorMemARGB, 0, sizeof(I830MemRange));
- pI830->CursorMemARGB->Key = -1;
-
- if (!pI830->SWCursor) {
- int cursFlags = 0;
- /*
- * Mouse cursor -- The i810-i830 need a physical address in system
- * memory from which to upload the cursor. We get this from
- * the agpgart module using a special memory type.
- */
-
- size = HWCURSOR_SIZE;
- cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
- if (pI830->CursorNeedsPhysical)
- cursFlags |= NEED_PHYSICAL_ADDR;
-
- alloced = I830AllocVidMem(pScrn, pI830->CursorMem,
- &(pI830->StolenPool), size,
- GTT_PAGE_SIZE, flags | cursFlags);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate HW cursor space.\n");
- }
- } else {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for HW cursor at 0x%lx", s,
- alloced / 1024, pI830->CursorMem->Start);
- if (pI830->CursorNeedsPhysical)
- xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMem->Physical);
- xf86ErrorFVerb(verbosity, "\n");
- }
-
- size = HWCURSOR_SIZE_ARGB;
- cursFlags = FROM_ANYWHERE | ALLOCATE_AT_TOP;
- if (pI830->CursorNeedsPhysical)
- cursFlags |= NEED_PHYSICAL_ADDR;
-
- alloced = I830AllocVidMem(pScrn, pI830->CursorMemARGB,
- &(pI830->StolenPool), size,
- GTT_PAGE_SIZE, flags | cursFlags);
- if (alloced < size) {
- if (!dryrun) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to allocate HW (ARGB) cursor space.\n");
- }
- } else {
- xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
- "%sAllocated %ld kB for HW (ARGB) cursor at 0x%lx", s,
- alloced / 1024, pI830->CursorMemARGB->Start);
- if (pI830->CursorNeedsPhysical)
- xf86ErrorFVerb(verbosity, " (0x%08lx)", pI830->CursorMemARGB->Physical);
- xf86ErrorFVerb(verbosity, "\n");
- }
+ if (!pI830->SWCursor && !dryrun) {
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ if (!I830AllocateCursorBuffers(xf86_config->crtc[i], flags) &&
+ pI830->SWCursor)
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling HW cursor because the cursor memory "
+ "allocation failed.\n");
+ pI830->SWCursor = TRUE;
+ break;
+ }
+ }
}
#ifdef I830_XV
@@ -1505,6 +1545,8 @@ Bool
I830FixupOffsets(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
DPRINTF(PFX, "I830FixupOffsets\n");
@@ -1512,8 +1554,14 @@ I830FixupOffsets(ScrnInfoPtr pScrn)
if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
I830FixOffset(pScrn, &(pI830->FrontBuffer2));
I830FixOffset(pScrn, &(pI830->FrontBuffer));
- I830FixOffset(pScrn, pI830->CursorMem);
- I830FixOffset(pScrn, pI830->CursorMemARGB);
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+
+ I830FixOffset(pScrn, &intel_crtc->cursor_mem);
+ I830FixOffset(pScrn, &intel_crtc->cursor_mem_argb);
+ }
+
I830FixOffset(pScrn, &(pI830->LpRing->mem));
I830FixOffset(pScrn, &(pI830->Scratch));
if (pI830->entityPrivate && pI830->entityPrivate->pScrn_2)
@@ -1896,6 +1944,9 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
return TRUE;
if (xf86AgpGARTSupported() && !pI830->GttBound) {
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
if (!xf86AcquireGART(pScrn->scrnIndex))
return FALSE;
@@ -1911,10 +1962,15 @@ I830BindAGPMemory(ScrnInfoPtr pScrn)
return FALSE;
if (!BindMemRange(pScrn, &(pI830->FrontBuffer)))
return FALSE;
- if (!BindMemRange(pScrn, pI830->CursorMem))
- return FALSE;
- if (!BindMemRange(pScrn, pI830->CursorMemARGB))
- return FALSE;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+
+ if (!BindMemRange(pScrn, &intel_crtc->cursor_mem))
+ return FALSE;
+ if (!BindMemRange(pScrn, &intel_crtc->cursor_mem_argb))
+ return FALSE;
+ }
if (!BindMemRange(pScrn, &(pI830->LpRing->mem)))
return FALSE;
if (!BindMemRange(pScrn, &(pI830->Scratch)))
@@ -1991,6 +2047,8 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
return TRUE;
if (xf86AgpGARTSupported() && pI830->GttBound) {
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
#if REMAP_RESERVED
/* "unbind" the pre-allocated region. */
@@ -2004,10 +2062,16 @@ I830UnbindAGPMemory(ScrnInfoPtr pScrn)
return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->FrontBuffer)))
return FALSE;
- if (!UnbindMemRange(pScrn, pI830->CursorMem))
- return FALSE;
- if (!UnbindMemRange(pScrn, pI830->CursorMemARGB))
- return FALSE;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ I830CrtcPrivatePtr intel_crtc = xf86_config->crtc[i]->driver_private;
+
+ if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem))
+ return FALSE;
+ if (!UnbindMemRange(pScrn, &intel_crtc->cursor_mem_argb))
+ return FALSE;
+ }
+
if (!UnbindMemRange(pScrn, &(pI830->LpRing->mem)))
return FALSE;
if (!UnbindMemRange(pScrn, &(pI830->Scratch)))
@@ -2079,3 +2143,41 @@ I830CheckAvailableMemory(ScrnInfoPtr pScrn)
return maxPages * 4;
}
+
+#ifdef I830_USE_XAA
+/**
+ * Allocates memory from the XF86 linear allocator, but also purges
+ * memory if possible to cause the allocation to succeed.
+ */
+FBLinearPtr
+i830_xf86AllocateOffscreenLinear(ScreenPtr pScreen, int length,
+ int granularity,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData)
+{
+ FBLinearPtr linear;
+ int max_size;
+
+ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+ removeCB, privData);
+ if (linear != NULL)
+ return linear;
+
+ /* The above allocation didn't succeed, so purge unlocked stuff and try
+ * again.
+ */
+ xf86QueryLargestOffscreenLinear(pScreen, &max_size, granularity,
+ PRIORITY_EXTREME);
+
+ if (max_size < length)
+ return NULL;
+
+ xf86PurgeUnlockedOffscreenAreas(pScreen);
+
+ linear = xf86AllocateOffscreenLinear(pScreen, length, granularity, moveCB,
+ removeCB, privData);
+
+ return linear;
+}
+#endif
diff --git a/src/i830_modes.c b/src/i830_modes.c
index b4e22c35..405dcc61 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -62,9 +62,9 @@ i830_ddc_get_modes (xf86OutputPtr output)
xf86MonPtr edid_mon;
DisplayModePtr modes;
- edid_mon = i830_xf86OutputGetEDID (output, intel_output->pDDCBus);
- i830_xf86OutputSetEDID (output, edid_mon);
+ edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus);
+ xf86OutputSetEDID (output, edid_mon);
- modes = i830_xf86OutputGetEDIDModes (output);
+ modes = xf86OutputGetEDIDModes (output);
return modes;
}
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 63888494..5eccf4bd 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -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;
@@ -494,8 +494,19 @@ void
xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
randrp->supported_rotations = rotations;
+
+#if RANDR_12_INTERFACE
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcSetRotations (crtc->randr_crtc, rotations);
+ }
+#endif
}
void
@@ -533,7 +544,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 +552,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
return FALSE;
x = crtc->x;
y = crtc->y;
- rotation = RR_Rotate_0;
+ rotation = crtc->rotation;
numOutputs = 0;
randr_mode = NULL;
for (i = 0; i < config->num_output; i++)
@@ -558,7 +569,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 +598,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 +605,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];
@@ -629,12 +638,9 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
{
crtc->enabled = mode != NULL;
- /* Sync the engine before adjust mode */
- i830WaitSync(pScrn);
-
if (mode)
{
- if (!i830PipeSetMode (crtc, mode, TRUE))
+ if (!xf86CrtcSetMode (crtc, mode, rotation, x, y))
{
crtc->enabled = save_enabled;
for (o = 0; o < config->num_output; o++)
@@ -645,14 +651,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;
}
- i830DisableUnusedFunctions (pScrn);
-
- i830DumpRegs(pScrn);
+ xf86DisableUnusedFunctions (pScrn);
}
- if (pos_changed && mode)
- i830PipeSetBase(crtc, x, y);
DEALLOCATE_LOCAL(save_crtcs);
return xf86RandR12CrtcNotify (randr_crtc);
}
@@ -830,6 +838,8 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
return TRUE;
}
+
+
/*
* Query the hardware for the current state, then mirror
* that to RandR
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 92e417e0..79b6ae8b 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -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);
- i830PipeSetMode (crtc, &mode, FALSE);
+ xf86CrtcSetMode (crtc, &mode, RR_Rotate_0, 0, 0);
}
i830_tv_detect_type (crtc, output);
i830ReleaseLoadDetectPipe (output);
diff --git a/src/i830_video.c b/src/i830_video.c
index a330eb5f..22f5bee4 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2073,8 +2073,6 @@ I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size,
#endif /* I830_USE_EXA */
#ifdef I830_USE_XAA
if (!pI830->useEXA) {
- int max_size;
-
/* Converts an offset from XAA's linear allocator to an offset from the
* start of fb.
*/
@@ -2100,25 +2098,11 @@ I830AllocateMemory(ScrnInfoPtr pScrn, struct linear_alloc *linear, int size,
xf86FreeOffscreenLinear(linear->xaa);
}
- linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, align,
- NULL, NULL, NULL);
- if (linear->xaa != NULL) {
- linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
- return;
- }
-
- xf86QueryLargestOffscreenLinear(pScreen, &max_size, align,
- PRIORITY_EXTREME);
-
- if (max_size < size) {
- ErrorF("No memory available\n");
- linear->offset = 0;
+ linear->xaa = i830_xf86AllocateOffscreenLinear(pScreen, size, align,
+ NULL, NULL, NULL);
+ if (linear->xaa == NULL)
return;
- }
- xf86PurgeUnlockedOffscreenAreas(pScreen);
- linear->xaa = xf86AllocateOffscreenLinear(pScreen, size, 4,
- NULL, NULL, NULL);
linear->offset = XAA_OFFSET_TO_OFFSET(linear->xaa->offset);
}
#endif /* I830_USE_XAA */
diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index 34fa7369..a2099149 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -87,6 +87,8 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
#ifdef RANDR_12_INTERFACE
crtc->randr_crtc = NULL;
#endif
+ crtc->rotation = RR_Rotate_0;
+ crtc->desiredRotation = RR_Rotate_0;
if (xf86_config->crtc)
crtcs = xrealloc (xf86_config->crtc,
(xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
@@ -121,6 +123,139 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
xfree (crtc);
}
+
+/**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+Bool
+xf86CrtcInUse (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int o;
+
+ for (o = 0; o < xf86_config->num_output; o++)
+ if (xf86_config->output[o]->crtc == crtc)
+ return TRUE;
+ return FALSE;
+}
+
+/**
+ * Sets the given video mode on the given crtc
+ */
+Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ int x, int y)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int i;
+ Bool ret = FALSE;
+ Bool didLock = FALSE;
+ DisplayModePtr adjusted_mode;
+ DisplayModeRec saved_mode;
+ int saved_x, saved_y;
+ Rotation saved_rotation;
+
+ adjusted_mode = xf86DuplicateMode(mode);
+
+ crtc->enabled = xf86CrtcInUse (crtc);
+
+ if (!crtc->enabled)
+ {
+ /* XXX disable crtc? */
+ return TRUE;
+ }
+
+ didLock = crtc->funcs->lock (crtc);
+
+ saved_mode = crtc->mode;
+ saved_x = crtc->x;
+ saved_y = crtc->y;
+ saved_rotation = crtc->rotation;
+ /* Update crtc values up front so the driver can rely on them for mode
+ * setting.
+ */
+ crtc->mode = *mode;
+ crtc->x = x;
+ crtc->y = y;
+ crtc->rotation = rotation;
+
+ /* 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.
+ */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+
+ if (output->crtc != crtc)
+ continue;
+
+ if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
+ goto done;
+ }
+ }
+
+ if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
+ goto done;
+ }
+
+ if (!xf86CrtcRotate (crtc, mode, rotation)) {
+ goto done;
+ }
+
+ /* Disable the outputs and CRTCs before setting the mode. */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+
+ if (output->crtc != crtc)
+ continue;
+
+ /* Disable the output as the first thing we do. */
+ output->funcs->dpms(output, DPMSModeOff);
+ }
+
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+
+ /* 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, x, y);
+ for (i = 0; i < xf86_config->num_output; i++)
+ {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->crtc == crtc)
+ output->funcs->mode_set(output, mode, adjusted_mode);
+ }
+
+ /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+ crtc->funcs->dpms(crtc, DPMSModeOn);
+ for (i = 0; i < xf86_config->num_output; i++)
+ {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->crtc == crtc)
+ output->funcs->dpms(output, DPMSModeOn);
+ }
+
+ /* XXX free adjustedmode */
+ ret = TRUE;
+done:
+ if (!ret) {
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ crtc->rotation = saved_rotation;
+ crtc->mode = saved_mode;
+ }
+
+ if (didLock)
+ crtc->funcs->unlock (crtc);
+
+ return ret;
+}
+
/*
* Output functions
*/
@@ -362,14 +497,14 @@ xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
}
static int
-xf86PickCrtcs (ScrnInfoPtr pScrn,
+xf86PickCrtcs (ScrnInfoPtr scrn,
xf86CrtcPtr *best_crtcs,
DisplayModePtr *modes,
int n,
int width,
int height)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int c, o, l;
xf86OutputPtr output;
xf86CrtcPtr crtc;
@@ -388,7 +523,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
*/
best_crtcs[n] = NULL;
best_crtc = NULL;
- best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1, width, height);
+ best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
if (modes[n] == NULL)
return best_score;
@@ -442,7 +577,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
}
crtcs[n] = crtc;
memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
- score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
+ score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
if (score > best_score)
{
best_crtc = crtc;
@@ -462,9 +597,9 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
*/
static void
-xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
+xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int width = 0, height = 0;
int o;
int c;
@@ -513,9 +648,9 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
#define POSITION_UNSET -100000
static Bool
-xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
+xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o;
int min_x, min_y;
@@ -563,7 +698,7 @@ xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
}
else
{
- xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
"Output %s position not of form \"x y\"\n",
output->name);
output->initial_x = output->initial_y = 0;
@@ -606,7 +741,7 @@ xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
}
if (!relative)
{
- xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
"Cannot position output %s relative to unknown output %s\n",
output->name, relative_name);
output->initial_x = 0;
@@ -655,7 +790,7 @@ xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
xf86OutputPtr output = config->output[o];
if (output->initial_x == POSITION_UNSET)
{
- xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
"Output position loop. Moving %s to 0,0\n",
output->name);
output->initial_x = output->initial_y = 0;
@@ -778,16 +913,16 @@ i830xf86SortModes (DisplayModePtr input)
#define DEBUG_REPROBE 1
void
-xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
+xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o;
if (maxX == 0 || maxY == 0)
- xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY);
+ xf86RandR12GetOriginalVirtualSize (scrn, &maxX, &maxY);
/* Elide duplicate modes before defaulting code uses them */
- xf86PruneDuplicateMonitorModes (pScrn->monitor);
+ xf86PruneDuplicateMonitorModes (scrn->monitor);
/* Probe the list of modes for each output. */
for (o = 0; o < config->num_output; o++)
@@ -837,7 +972,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
mon_rec.nVrefresh++;
sync_source = sync_config;
}
- config_modes = i830xf86GetMonitorModes (pScrn, conf_monitor);
+ config_modes = xf86GetMonitorModes (scrn, conf_monitor);
}
output_modes = (*output->funcs->get_modes) (output);
@@ -901,27 +1036,27 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
mon_rec.vrefresh[0].hi = 62.0;
mon_rec.nVrefresh = 1;
}
- default_modes = i830xf86GetDefaultModes (output->interlaceAllowed,
- output->doubleScanAllowed);
+ default_modes = xf86GetDefaultModes (output->interlaceAllowed,
+ output->doubleScanAllowed);
if (sync_source == sync_config)
{
/*
* Check output and config modes against sync range from config file
*/
- i830xf86ValidateModesSync (pScrn, output_modes, &mon_rec);
- i830xf86ValidateModesSync (pScrn, config_modes, &mon_rec);
+ xf86ValidateModesSync (scrn, output_modes, &mon_rec);
+ xf86ValidateModesSync (scrn, config_modes, &mon_rec);
}
/*
* Check default modes against sync range
*/
- i830xf86ValidateModesSync (pScrn, default_modes, &mon_rec);
+ xf86ValidateModesSync (scrn, default_modes, &mon_rec);
/*
* Check default modes against monitor max clock
*/
if (max_clock)
- i830xf86ValidateModesClocks(pScrn, default_modes,
- &min_clock, &max_clock, 1);
+ xf86ValidateModesClocks(scrn, default_modes,
+ &min_clock, &max_clock, 1);
output->probed_modes = NULL;
output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
@@ -932,7 +1067,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
* Check all modes against max size
*/
if (maxX && maxY)
- i830xf86ValidateModesSize (pScrn, output->probed_modes,
+ xf86ValidateModesSize (scrn, output->probed_modes,
maxX, maxY, 0);
/*
@@ -942,7 +1077,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
if (mode->status == MODE_OK)
mode->status = (*output->funcs->mode_valid)(output, mode);
- i830xf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE);
+ xf86PruneInvalidModes(scrn, &output->probed_modes, TRUE);
output->probed_modes = i830xf86SortModes (output->probed_modes);
@@ -975,11 +1110,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
#ifdef DEBUG_REPROBE
if (output->probed_modes != NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Printing probed modes for output %s\n",
output->name);
} else {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
"No remaining probed modes for output %s\n",
output->name);
}
@@ -993,7 +1128,7 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
#ifdef DEBUG_REPROBE
- xf86PrintModeline(pScrn->scrnIndex, mode);
+ xf86PrintModeline(scrn->scrnIndex, mode);
#endif
}
}
@@ -1006,12 +1141,12 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
/* XXX where does this function belong? Here? */
void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
void
-xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
+xf86SetScrnInfoModes (ScrnInfoPtr scrn)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
xf86OutputPtr output;
xf86CrtcPtr crtc;
DisplayModePtr last, mode;
@@ -1035,31 +1170,31 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
}
crtc = output->crtc;
- /* Clear any existing modes from pScrn->modes */
- while (pScrn->modes != NULL)
- xf86DeleteMode(&pScrn->modes, pScrn->modes);
+ /* Clear any existing modes from scrn->modes */
+ while (scrn->modes != NULL)
+ xf86DeleteMode(&scrn->modes, scrn->modes);
- /* Set pScrn->modes to the mode list for the 'compat' output */
- pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
+ /* Set scrn->modes to the mode list for the 'compat' output */
+ scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
- for (mode = pScrn->modes; mode; mode = mode->next)
+ for (mode = scrn->modes; mode; mode = mode->next)
if (xf86ModesEqual (mode, &crtc->desiredMode))
break;
- if (pScrn->modes != NULL) {
- /* For some reason, pScrn->modes is circular, unlike the other mode
+ if (scrn->modes != NULL) {
+ /* For some reason, scrn->modes is circular, unlike the other mode
* lists. How great is that?
*/
- for (last = pScrn->modes; last && last->next; last = last->next)
+ for (last = scrn->modes; last && last->next; last = last->next)
;
- last->next = pScrn->modes;
- pScrn->modes->prev = last;
+ last->next = scrn->modes;
+ scrn->modes->prev = last;
if (mode) {
- while (pScrn->modes != mode)
- pScrn->modes = pScrn->modes->next;
+ while (scrn->modes != mode)
+ scrn->modes = scrn->modes->next;
}
}
- pScrn->currentMode = pScrn->modes;
+ scrn->currentMode = scrn->modes;
}
/**
@@ -1070,9 +1205,9 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
*/
Bool
-xf86InitialConfiguration (ScrnInfoPtr pScrn)
+xf86InitialConfiguration (ScrnInfoPtr scrn)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o, c;
DisplayModePtr target_mode = NULL;
xf86CrtcPtr *crtcs;
@@ -1081,16 +1216,16 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
int width;
int height;
- if (pScrn->display->virtualX)
- width = pScrn->display->virtualX;
+ if (scrn->display->virtualX)
+ width = scrn->display->virtualX;
else
width = config->maxWidth;
- if (pScrn->display->virtualY)
- height = pScrn->display->virtualY;
+ if (scrn->display->virtualY)
+ height = scrn->display->virtualY;
else
height = config->maxHeight;
- xf86ProbeOutputModes (pScrn, width, height);
+ xf86ProbeOutputModes (scrn, width, height);
crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
@@ -1152,7 +1287,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
/*
* Set the position of each output
*/
- if (!xf86InitialOutputPositions (pScrn, modes))
+ if (!xf86InitialOutputPositions (scrn, modes))
{
xfree (crtcs);
xfree (modes);
@@ -1162,7 +1297,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
/*
* Assign CRTCs to fit output configuration
*/
- if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
+ if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
{
xfree (crtcs);
xfree (modes);
@@ -1171,8 +1306,8 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
/* XXX override xf86 common frame computation code */
- pScrn->display->frameX0 = 0;
- pScrn->display->frameY0 = 0;
+ scrn->display->frameX0 = 0;
+ scrn->display->frameY0 = 0;
for (c = 0; c < config->num_crtc; c++)
{
@@ -1201,24 +1336,24 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
}
}
- if (pScrn->display->virtualX == 0)
+ if (scrn->display->virtualX == 0)
{
/*
* Expand virtual size to cover potential mode switches
*/
- xf86DefaultScreenLimits (pScrn, &width, &height);
+ xf86DefaultScreenLimits (scrn, &width, &height);
- pScrn->display->virtualX = width;
- pScrn->display->virtualY = height;
+ scrn->display->virtualX = width;
+ scrn->display->virtualY = height;
}
- if (width > pScrn->virtualX)
- pScrn->virtualX = width;
- if (height > pScrn->virtualY)
- pScrn->virtualY = height;
+ if (width > scrn->virtualX)
+ scrn->virtualX = width;
+ if (height > scrn->virtualY)
+ scrn->virtualY = height;
- /* Mirror output modes to pScrn mode list */
- xf86SetScrnInfoModes (pScrn);
+ /* Mirror output modes to scrn mode list */
+ xf86SetScrnInfoModes (scrn);
xfree (crtcs);
xfree (modes);
@@ -1232,12 +1367,12 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
* Otherwise, it will affect CRTCs before outputs.
*/
void
-xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
+xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int i;
- if (!pScrn->vtSema)
+ if (!scrn->vtSema)
return;
if (mode == DPMSModeOff) {
@@ -1282,6 +1417,34 @@ xf86SaveScreen(ScreenPtr pScreen, int mode)
return TRUE;
}
+/**
+ * Disable all inactive crtcs and outputs
+ */
+void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int o, c;
+
+ for (o = 0; o < xf86_config->num_output; o++)
+ {
+ xf86OutputPtr output = xf86_config->output[o];
+ if (!output->crtc)
+ (*output->funcs->dpms)(output, DPMSModeOff);
+ }
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (!crtc->enabled)
+ {
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+ memset(&crtc->mode, 0, sizeof(crtc->mode));
+ }
+ }
+}
+
#ifdef RANDR_12_INTERFACE
#define EDID_ATOM_NAME "EDID_DATA"
@@ -1312,10 +1475,10 @@ xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
* Set the EDID information for the specified output
*/
void
-i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
{
- ScrnInfoPtr pScrn = output->scrn;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ ScrnInfoPtr scrn = output->scrn;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int i;
#ifdef RANDR_12_INTERFACE
int size;
@@ -1327,12 +1490,12 @@ i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
output->MonInfo = edid_mon;
/* Debug info for now, at least */
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
xf86PrintEDID(edid_mon);
/* Set the DDC properties for the 'compat' output */
if (output == config->output[config->compat_output])
- xf86SetDDCproperties(pScrn, edid_mon);
+ xf86SetDDCproperties(scrn, edid_mon);
#ifdef RANDR_12_INTERFACE
/* Set the RandR output properties */
@@ -1376,20 +1539,20 @@ i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
* stored in 'output'
*/
DisplayModePtr
-i830_xf86OutputGetEDIDModes (xf86OutputPtr output)
+xf86OutputGetEDIDModes (xf86OutputPtr output)
{
- ScrnInfoPtr pScrn = output->scrn;
+ ScrnInfoPtr scrn = output->scrn;
xf86MonPtr edid_mon = output->MonInfo;
if (!edid_mon)
return NULL;
- return xf86DDCGetModes(pScrn->scrnIndex, edid_mon);
+ return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
}
xf86MonPtr
-i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
{
- ScrnInfoPtr pScrn = output->scrn;
+ ScrnInfoPtr scrn = output->scrn;
- return xf86DoEDID_DDC2 (pScrn->scrnIndex, pDDCBus);
+ return xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus);
}
diff --git a/src/i830_xf86Crtc.h b/src/i830_xf86Crtc.h
index f8b561a2..6de2c923 100644
--- a/src/i830_xf86Crtc.h
+++ b/src/i830_xf86Crtc.h
@@ -24,8 +24,10 @@
#include <edid.h>
#include "randrstr.h"
+#include "i830_xf86Rename.h"
#include "i830_xf86Modes.h"
#include "xf86Parser.h"
+#include "damage.h"
/* Compat definitions for older X Servers. */
#ifndef M_T_PREFERRED
@@ -68,7 +70,19 @@ typedef struct _xf86CrtcFuncs {
void
(*restore)(xf86CrtcPtr crtc);
-
+ /**
+ * Lock CRTC prior to mode setting, mostly for DRI.
+ * Returns whether unlock is needed
+ */
+ Bool
+ (*lock) (xf86CrtcPtr crtc);
+
+ /**
+ * Unlock CRTC after mode setting, mostly for DRI
+ */
+ void
+ (*unlock) (xf86CrtcPtr crtc);
+
/**
* Callback to adjust the mode to be set in the CRTC.
*
@@ -87,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
@@ -95,6 +110,18 @@ typedef struct _xf86CrtcFuncs {
int size);
/**
+ * Create shadow pixmap for rotation support
+ */
+ PixmapPtr
+ (*shadow_create) (xf86CrtcPtr crtc, int width, int height);
+
+ /**
+ * Destroy shadow pixmap
+ */
+ void
+ (*shadow_destroy) (xf86CrtcPtr crtc, PixmapPtr pPixmap);
+
+ /**
* Clean up driver-specific bits of the crtc
*/
void
@@ -114,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;
@@ -134,7 +154,15 @@ struct _xf86Crtc {
* It will be cleared when the VT is not active or
* during server startup
*/
- DisplayModeRec curMode;
+ DisplayModeRec mode;
+ Rotation rotation;
+ PixmapPtr rotatedPixmap;
+ /**
+ * Position on screen
+ *
+ * Locates this CRTC within the frame buffer
+ */
+ int x, y;
/**
* Desired mode
@@ -145,6 +173,8 @@ struct _xf86Crtc {
* on VT switch.
*/
DisplayModeRec desiredMode;
+ Rotation desiredRotation;
+ int desiredX, desiredY;
/** crtc-specific functions */
const xf86CrtcFuncsRec *funcs;
@@ -379,6 +409,13 @@ typedef struct _xf86CrtcConfig {
int minWidth, minHeight;
int maxWidth, maxHeight;
+
+ /* For crtc-based rotation */
+ DamagePtr rotationDamage;
+
+ /* DGA */
+ unsigned int dga_flags;
+
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern int xf86CrtcConfigPrivateIndex;
@@ -427,6 +464,25 @@ xf86AllocCrtc (xf86OutputPtr output);
void
xf86FreeCrtc (xf86CrtcPtr crtc);
+/**
+ * Sets the given video mode on the given crtc
+ */
+Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ int x, int y);
+
+/*
+ * Assign crtc rotation during mode set
+ */
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation);
+
+/**
+ * Return whether any output is assigned to the crtc
+ */
+Bool
+xf86CrtcInUse (xf86CrtcPtr crtc);
+
/*
* Output functions
*/
@@ -456,20 +512,23 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
Bool
xf86SaveScreen(ScreenPtr pScreen, int mode);
+void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn);
+
/**
* Set the EDID information for the specified output
*/
void
-i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
/**
* Return the list of modes supported by the EDID information
* stored in 'output'
*/
DisplayModePtr
-i830_xf86OutputGetEDIDModes (xf86OutputPtr output);
+xf86OutputGetEDIDModes (xf86OutputPtr output);
xf86MonPtr
-i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
#endif /* _XF86CRTC_H_ */
diff --git a/src/i830_xf86Modes.c b/src/i830_xf86Modes.c
index a08d5a47..f620d4d5 100644
--- a/src/i830_xf86Modes.c
+++ b/src/i830_xf86Modes.c
@@ -303,7 +303,7 @@ xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
* This is not in xf86Modes.c, but would be part of the proposed new API.
*/
void
-i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
int flags)
{
DisplayModePtr mode;
@@ -324,7 +324,7 @@ i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
* This is not in xf86Modes.c, but would be part of the proposed new API.
*/
void
-i830xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
int maxX, int maxY, int maxPitch)
{
DisplayModePtr mode;
@@ -353,7 +353,7 @@ i830xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
* This is not in xf86Modes.c, but would be part of the proposed new API.
*/
void
-i830xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
MonPtr mon)
{
DisplayModePtr mode;
@@ -400,7 +400,7 @@ i830xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
* This is not in xf86Modes.c, but would be part of the proposed new API.
*/
void
-i830xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
int *min, int *max, int n_ranges)
{
DisplayModePtr mode;
@@ -434,7 +434,7 @@ i830xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
* This is not in xf86Modes.c, but would be part of the proposed new API.
*/
void
-i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
{
DisplayModePtr mode;
@@ -468,7 +468,7 @@ i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
* This is not in xf86Modes.c, but would be part of the proposed new API.
*/
void
-i830xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
Bool verbose)
{
DisplayModePtr mode;
@@ -524,13 +524,13 @@ xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
* Build a mode list from a list of config file modes
*/
static DisplayModePtr
-i830xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
+xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
{
DisplayModePtr head = NULL, prev = NULL, mode;
for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
{
- mode = xalloc(sizeof(DisplayModeRec));
+ mode = xcalloc(1, sizeof(DisplayModeRec));
if (!mode)
continue;
mode->name = xstrdup(conf_mode->ml_identifier);
@@ -539,8 +539,6 @@ i830xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
xfree (mode);
continue;
}
-
- memset(mode,'\0',sizeof(DisplayModeRec));
mode->type = 0;
mode->Clock = conf_mode->ml_clock;
mode->HDisplay = conf_mode->ml_hdisplay;
@@ -570,7 +568,7 @@ i830xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
* Build a mode list from a monitor configuration
*/
DisplayModePtr
-i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
+xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
{
DisplayModePtr modes = NULL;
XF86ConfModesLinkPtr modes_link;
@@ -591,18 +589,18 @@ i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
xf86configptr->conf_modes_lst);
if (modes_link->ml_modes)
modes = xf86ModesAdd (modes,
- i830xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
+ xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
}
return xf86ModesAdd (modes,
- i830xf86GetConfigModes (conf_monitor->mon_modeline_lst));
+ xf86GetConfigModes (conf_monitor->mon_modeline_lst));
}
/**
* Build a mode list containing all of the default modes
*/
DisplayModePtr
-i830xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
+xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
{
DisplayModePtr head = NULL, prev = NULL, mode;
int i;
diff --git a/src/i830_xf86Modes.h b/src/i830_xf86Modes.h
index a7d0839d..d032199d 100644
--- a/src/i830_xf86Modes.h
+++ b/src/i830_xf86Modes.h
@@ -29,67 +29,54 @@
#define _I830_XF86MODES_H_
#include "xorgVersion.h"
#include "xf86Parser.h"
+#include "i830_xf86Rename.h"
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-double i830_xf86ModeHSync(DisplayModePtr mode);
-double i830_xf86ModeVRefresh(DisplayModePtr mode);
-DisplayModePtr i830_xf86DuplicateMode(DisplayModePtr pMode);
-DisplayModePtr i830_xf86DuplicateModes(ScrnInfoPtr pScrn,
+double xf86ModeHSync(DisplayModePtr mode);
+double xf86ModeVRefresh(DisplayModePtr mode);
+DisplayModePtr xf86DuplicateMode(DisplayModePtr pMode);
+DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn,
DisplayModePtr modeList);
-void i830_xf86SetModeDefaultName(DisplayModePtr mode);
-void i830_xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-Bool i830_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
-void i830_xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
-DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
+void xf86SetModeDefaultName(DisplayModePtr mode);
+void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
+Bool xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
+void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
+DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
-DisplayModePtr i830_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
-DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
- Bool Reduced, Bool Interlaced);
-
-#define xf86ModeHSync i830_xf86ModeHSync
-#define xf86ModeVRefresh i830_xf86ModeVRefresh
-#define xf86DuplicateMode i830_xf86DuplicateMode
-#define xf86DuplicateModes i830_xf86DuplicateModes
-#define xf86SetModeDefaultName i830_xf86SetModeDefaultName
-#define xf86SetModeCrtc i830_xf86SetModeCrtc
-#define xf86ModesEqual i830_xf86ModesEqual
-#define xf86PrintModeline i830_xf86PrintModeline
-#define xf86ModesAdd i830_xf86ModesAdd
-#define xf86DDCGetModes i830_xf86DDCGetModes
-#define xf86CVTMode i830_xf86CVTMode
-#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
+DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
+DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
+ Bool Reduced, Bool Interlaced);
void
-i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int flags);
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int flags);
void
-i830xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int *min, int *max, int n_ranges);
+xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int *min, int *max, int n_ranges);
void
-i830xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int maxX, int maxY, int maxPitch);
+xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int maxX, int maxY, int maxPitch);
void
-i830xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- MonPtr mon);
+xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ MonPtr mon);
void
-i830xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
- Bool verbose);
+xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+ Bool verbose);
void
-i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int flags);
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int flags);
void
-i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
DisplayModePtr
-i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
+xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
DisplayModePtr
-i830xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
+xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
#endif /* _I830_XF86MODES_H_ */
diff --git a/src/i830_xf86Rename.h b/src/i830_xf86Rename.h
new file mode 100644
index 00000000..cf8de622
--- /dev/null
+++ b/src/i830_xf86Rename.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _XF86RENAME_H_
+#define _XF86RENAME_H_
+
+#include "local_xf86Rename.h"
+
+#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit)
+#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex)
+#define xf86CrtcCreate XF86NAME(xf86CrtcCreate)
+#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy)
+#define xf86CrtcInUse XF86NAME(xf86CrtcInUse)
+#define xf86CrtcRotate XF86NAME(xf86CrtcRotate)
+#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
+#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
+#define xf86CVTMode XF86NAME(xf86CVTMode)
+#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions)
+#define xf86DPMSSet XF86NAME(xf86DPMSSet)
+#define xf86DuplicateMode XF86NAME(xf86DuplicateMode)
+#define xf86DuplicateModes XF86NAME(xf86DuplicateModes)
+#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes)
+#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes)
+#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration)
+#define xf86ModeHSync XF86NAME(xf86ModeHSync)
+#define xf86ModesAdd XF86NAME(xf86ModesAdd)
+#define xf86ModesEqual XF86NAME(xf86ModesEqual)
+#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh)
+#define xf86OutputCreate XF86NAME(xf86OutputCreate)
+#define xf86OutputDestroy XF86NAME(xf86OutputDestroy)
+#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID)
+#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes)
+#define xf86OutputRename XF86NAME(xf86OutputRename)
+#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID)
+#define xf86PrintModeline XF86NAME(xf86PrintModeline)
+#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes)
+#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes)
+#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc)
+#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName)
+#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes)
+#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks)
+#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags)
+#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize)
+#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync)
+#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig)
+
+#endif /* _XF86RENAME_H_ */
diff --git a/src/i830_xf86Rotate.c b/src/i830_xf86Rotate.c
new file mode 100644
index 00000000..3b8be613
--- /dev/null
+++ b/src/i830_xf86Rotate.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+/*#include "i830.h" */
+#include "i830_xf86Crtc.h"
+#include "i830_xf86Modes.h"
+#include "i830_randr.h"
+#include "X11/extensions/render.h"
+#define DPMS_SERVER
+#include "X11/extensions/dpms.h"
+#include "X11/Xatom.h"
+
+static int
+mode_height (DisplayModePtr mode, Rotation rotation)
+{
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ return mode->VDisplay;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ return mode->HDisplay;
+ default:
+ return 0;
+ }
+}
+
+static int
+mode_width (DisplayModePtr mode, Rotation rotation)
+{
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ return mode->HDisplay;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ return mode->VDisplay;
+ default:
+ return 0;
+ }
+}
+
+/* borrowed from composite extension, move to Render and publish? */
+
+static VisualPtr
+compGetWindowVisual (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VisualID vid = wVisual (pWin);
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ if (pScreen->visuals[i].vid == vid)
+ return &pScreen->visuals[i];
+ return 0;
+}
+
+static PictFormatPtr
+compWindowFormat (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ return PictureMatchVisual (pScreen, pWin->drawable.depth,
+ compGetWindowVisual (pWin));
+}
+
+static void
+xf86RotateBox (BoxPtr dst, BoxPtr src, Rotation rotation,
+ int dest_width, int dest_height)
+{
+ switch (rotation & 0xf) {
+ default:
+ case RR_Rotate_0:
+ *dst = *src;
+ break;
+ case RR_Rotate_90:
+ dst->x1 = src->y1;
+ dst->y1 = dest_height - src->x2;
+ dst->x2 = src->y2;
+ dst->y2 = dest_height - src->x1;
+ break;
+ case RR_Rotate_180:
+ dst->x1 = dest_width - src->x2;
+ dst->y1 = dest_height - src->y2;
+ dst->x2 = dest_width - src->x1;
+ dst->y2 = dest_height - src->y1;
+ break;
+ case RR_Rotate_270:
+ dst->x1 = dest_width - src->y2;
+ dst->y1 = src->x1;
+ dst->y2 = src->x2;
+ dst->x2 = dest_width - src->y1;
+ break;
+ }
+ if (rotation & RR_Reflect_X) {
+ int x1 = dst->x1;
+ dst->x1 = dest_width - dst->x2;
+ dst->x2 = dest_width - x1;
+ }
+ if (rotation & RR_Reflect_Y) {
+ int y1 = dst->y1;
+ dst->y1 = dest_height - dst->y2;
+ dst->y2 = dest_height - y1;
+ }
+}
+
+static void
+xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ ScreenPtr screen = scrn->pScreen;
+ WindowPtr root = WindowTable[screen->myNum];
+ PixmapPtr dst_pixmap = crtc->rotatedPixmap;
+ PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]);
+ int error;
+ PicturePtr src, dst;
+ PictTransform transform;
+ int n = REGION_NUM_RECTS(region);
+ BoxPtr b = REGION_RECTS(region);
+ XID include_inferiors = IncludeInferiors;
+
+ src = CreatePicture (None,
+ &root->drawable,
+ format,
+ CPSubwindowMode,
+ &include_inferiors,
+ serverClient,
+ &error);
+ if (!src) {
+ ErrorF("couldn't create src pict\n");
+ return;
+ }
+ dst = CreatePicture (None,
+ &dst_pixmap->drawable,
+ format,
+ 0L,
+ NULL,
+ serverClient,
+ &error);
+ if (!dst) {
+ ErrorF("couldn't create src pict\n");
+ return;
+ }
+
+ memset (&transform, '\0', sizeof (transform));
+ transform.matrix[2][2] = IntToxFixed(1);
+ transform.matrix[0][2] = IntToxFixed(crtc->x);
+ transform.matrix[1][2] = IntToxFixed(crtc->y);
+ switch (crtc->rotation & 0xf) {
+ default:
+ case RR_Rotate_0:
+ transform.matrix[0][0] = IntToxFixed(1);
+ transform.matrix[1][1] = IntToxFixed(1);
+ break;
+ case RR_Rotate_90:
+ transform.matrix[0][1] = IntToxFixed(-1);
+ transform.matrix[1][0] = IntToxFixed(1);
+ transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay);
+ break;
+ case RR_Rotate_180:
+ transform.matrix[0][0] = IntToxFixed(-1);
+ transform.matrix[1][1] = IntToxFixed(-1);
+ transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay);
+ transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
+ break;
+ case RR_Rotate_270:
+ transform.matrix[0][1] = IntToxFixed(1);
+ transform.matrix[1][0] = IntToxFixed(-1);
+ transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
+ break;
+ }
+
+ /* handle reflection */
+ if (crtc->rotation & RR_Reflect_X)
+ {
+ /* XXX figure this out */
+ }
+ if (crtc->rotation & RR_Reflect_Y)
+ {
+ /* XXX figure this out too */
+ }
+
+ error = SetPictureTransform (src, &transform);
+ if (error) {
+ ErrorF("Couldn't set transform\n");
+ return;
+ }
+
+ while (n--)
+ {
+ BoxRec dst_box;
+
+ xf86RotateBox (&dst_box, b, crtc->rotation,
+ crtc->mode.HDisplay, crtc->mode.VDisplay);
+ CompositePicture (PictOpSrc,
+ src, NULL, dst,
+ dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
+ dst_box.x2 - dst_box.x1,
+ dst_box.y2 - dst_box.y1);
+ b++;
+ }
+ FreePicture (src, None);
+ FreePicture (dst, None);
+}
+
+static void
+xf86RotateRedisplay(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ DamagePtr damage = xf86_config->rotationDamage;
+ RegionPtr region;
+
+ if (!damage)
+ return;
+ region = DamageRegion(damage);
+ if (REGION_NOTEMPTY(pScreen, region))
+ {
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ 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->mode, crtc->rotation);
+ box.y1 = crtc->y;
+ 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);
+
+ /* update damaged region */
+ if (REGION_NOTEMPTY(pScreen, &crtc_damage))
+ xf86RotateCrtcRedisplay (crtc, &crtc_damage);
+
+ REGION_UNINIT (pScreen, &crtc_damage);
+ }
+ }
+ DamageEmpty(damage);
+ }
+}
+
+static void
+xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead)
+{
+ ScreenPtr pScreen = (ScreenPtr) data;
+
+ xf86RotateRedisplay(pScreen);
+}
+
+static void
+xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask)
+{
+}
+
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+
+ if (rotation == RR_Rotate_0)
+ {
+ /* Free memory from rotation */
+ if (crtc->rotatedPixmap)
+ {
+ crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap);
+ crtc->rotatedPixmap = NULL;
+ }
+
+ if (xf86_config->rotationDamage)
+ {
+ /* Free damage structure */
+ DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotationDamage);
+ DamageDestroy (xf86_config->rotationDamage);
+ xf86_config->rotationDamage = NULL;
+ /* Free block/wakeup handler */
+ RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
+ xf86RotateWakeupHandler,
+ (pointer) pScreen);
+ }
+ }
+ else
+ {
+ /*
+ * these are the size of the shadow pixmap, which
+ * matches the mode, not the pre-rotated copy in the
+ * frame buffer
+ */
+ int width = mode->HDisplay;
+ int height = mode->VDisplay;
+ PixmapPtr shadow = crtc->rotatedPixmap;
+ int old_width = shadow ? shadow->drawable.width : 0;
+ int old_height = shadow ? shadow->drawable.height : 0;
+ BoxRec damage_box;
+ RegionRec damage_region;
+
+ /* Allocate memory for rotation */
+ if (old_width != width || old_height != height)
+ {
+ if (shadow)
+ {
+ crtc->funcs->shadow_destroy (crtc, shadow);
+ crtc->rotatedPixmap = NULL;
+ }
+ shadow = crtc->funcs->shadow_create (crtc, width, height);
+ if (!shadow)
+ goto bail1;
+ crtc->rotatedPixmap = shadow;
+ }
+
+ if (!xf86_config->rotationDamage)
+ {
+ /* Create damage structure */
+ xf86_config->rotationDamage = DamageCreate (NULL, NULL,
+ DamageReportNone,
+ TRUE, pScreen, pScreen);
+ if (!xf86_config->rotationDamage)
+ goto bail2;
+
+ /* Hook damage to screen pixmap */
+ DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotationDamage);
+
+ /* Assign block/wakeup handler */
+ if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler,
+ xf86RotateWakeupHandler,
+ (pointer) pScreen))
+ {
+ goto bail3;
+ }
+ damage_box.x1 = 0;
+ damage_box.y1 = 0;
+ damage_box.x2 = mode_width (mode, rotation);
+ damage_box.y2 = mode_height (mode, rotation);
+ REGION_INIT (pScreen, &damage_region, &damage_box, 1);
+ DamageDamageRegion (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ &damage_region);
+ REGION_UNINIT (pScreen, &damage_region);
+ }
+ if (0)
+ {
+bail3:
+ DamageDestroy (xf86_config->rotationDamage);
+ xf86_config->rotationDamage = NULL;
+
+bail2:
+ if (shadow)
+ {
+ crtc->funcs->shadow_destroy (crtc, shadow);
+ crtc->rotatedPixmap = NULL;
+ }
+bail1:
+ if (old_width && old_height)
+ crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+ old_width,
+ old_height);
+ return FALSE;
+ }
+ }
+
+ /* All done */
+ return TRUE;
+}
diff --git a/src/local_xf86Rename.h b/src/local_xf86Rename.h
new file mode 100644
index 00000000..e1e788f3
--- /dev/null
+++ b/src/local_xf86Rename.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#define XF86NAME(x) intel_##x