summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@dulcimer.keithp.com>2007-06-04 23:52:23 -0700
committerKeith Packard <keithp@dulcimer.keithp.com>2007-06-04 23:52:23 -0700
commite986f6cb62f8644c5fa835bd7dfb7b014c2677c5 (patch)
tree17230687501b937321c6b3e25c1b409b7589c335
parent0984c1fc0963f1ebab31f5b8fce5ad4c387fbd2c (diff)
Automatically switch overlay when crtcs are reconfigured.
As crtcs are disabled and enabled, make sure the automatic crtc selection mechanism drives overlay configuration at each request to display an image.
-rw-r--r--src/i830_video.c127
1 files changed, 57 insertions, 70 deletions
diff --git a/src/i830_video.c b/src/i830_video.c
index 155bcc1f..382b1ebb 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -345,27 +345,55 @@ CompareOverlay(I830Ptr pI830, CARD32 * overlay, int size)
}
#endif
-static int
-I830CrtcPipe (xf86CrtcPtr crtc)
-{
- if (crtc == NULL)
- return 0;
- return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe;
-}
+static void
+I830SetOneLineModeRatio(ScrnInfoPtr pScrn);
-static xf86CrtcPtr
-I830CrtcForPipe (ScrnInfoPtr pScrn, int pipe)
+static void
+i830_overlay_switch_to_crtc (ScrnInfoPtr pScrn, xf86CrtcPtr crtc)
{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
+ I830Ptr pI830 = I830PTR(pScrn);
+ I830PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
+ I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
+ int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
- for (c = 0; c < xf86_config->num_crtc; c++)
+ if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE)
+ pPriv->overlayOK = FALSE;
+ else
+ pPriv->overlayOK = TRUE;
+
+ if (!pPriv->overlayOK)
+ return;
+
+ /* Check we have an LFP connected */
+ if (i830PipeHasType(crtc, I830_OUTPUT_LVDS))
{
- xf86CrtcPtr crtc = xf86_config->crtc[c];
- if (I830CrtcPipe (crtc) == pipe)
- return crtc;
+
+ int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
+ CARD32 size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
+ CARD32 active;
+ CARD32 hsize, vsize;
+
+ hsize = (size >> 16) & 0x7FF;
+ vsize = size & 0x7FF;
+ active = INREG(vtotal_reg) & 0x7FF;
+
+ if (vsize < active && hsize > 1024)
+ I830SetOneLineModeRatio(pScrn);
+
+ if (pPriv->scaleRatio & 0xFFFE0000)
+ {
+ /* Possible bogus ratio, using in-accurate fallback */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Bogus panel fit register, Xvideo positioning may not "
+ "be accurate.\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Using fallback ratio - was 0x%x, now 0x%x\n",
+ pPriv->scaleRatio,
+ (int)(((float)active * 65536)/(float)vsize));
+
+ pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
+ }
}
- return NULL;
}
/*
@@ -383,7 +411,6 @@ i830_overlay_on(ScrnInfoPtr pScrn)
I830OverlayRegPtr overlay = I830OVERLAYREG(pI830);
I830PortPrivPtr pPriv = pI830->adaptor->pPortPrivates[0].ptr;
Bool deactivate = FALSE;
- xf86CrtcPtr crtc0 = NULL;
if (*pI830->overlayOn)
return;
@@ -633,7 +660,7 @@ I830ResetVideo(ScrnInfoPtr pScrn)
* Select which pipe the overlay is enabled on.
*/
overlay->OCONFIG &= ~OVERLAY_PIPE_MASK;
- if (I830CrtcPipe (pPriv->current_crtc) == 0)
+ if (i830_crtc_pipe (pPriv->current_crtc) == 0)
overlay->OCONFIG |= OVERLAY_PIPE_A;
else
overlay->OCONFIG |= OVERLAY_PIPE_B;
@@ -1717,9 +1744,6 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
OVERLAY_DEBUG("I830DisplayVideo: %dx%d (pitch %d)\n", width, height,
dstPitch);
- if (!pPriv->overlayOK)
- return;
-
#if VIDEO_DEBUG
CompareOverlay(pI830, (CARD32 *) overlay, 0x100);
#endif
@@ -1737,9 +1761,14 @@ i830_display_video(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
if (crtc != pPriv->current_crtc)
{
pPriv->current_crtc = crtc;
- I830ResetVideo (pScrn);
+ i830_overlay_switch_to_crtc (pScrn, crtc);
+ if (pPriv->overlayOK)
+ I830ResetVideo (pScrn);
}
+ if (!pPriv->overlayOK)
+ return;
+
switch (crtc->rotation & 0xf) {
case RR_Rotate_0:
dstBox->x1 -= crtc->x;
@@ -2271,7 +2300,7 @@ I830PutImage(ScrnInfoPtr pScrn,
if (pI830->entityPrivate) {
if (pI830->entityPrivate->XvInUse != -1 &&
- pI830->entityPrivate->XvInUse != I830CrtcPipe (pPriv->current_crtc)) {
+ pI830->entityPrivate->XvInUse != i830_crtc_pipe (pPriv->current_crtc)) {
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
return Success; /* faked for trying to share it */
@@ -2282,7 +2311,7 @@ I830PutImage(ScrnInfoPtr pScrn,
}
}
- pI830->entityPrivate->XvInUse = I830CrtcPipe (pPriv->current_crtc);;
+ pI830->entityPrivate->XvInUse = i830_crtc_pipe (pPriv->current_crtc);;
}
/* overlay limits */
@@ -2766,7 +2795,7 @@ I830DisplaySurface(XF86SurfacePtr surface,
if (pI830->entityPrivate) {
if (pI830->entityPrivate->XvInUse != -1 &&
- pI830->entityPrivate->XvInUse != I830CrtcPipe (pI830Priv->current_crtc)) {
+ pI830->entityPrivate->XvInUse != i830_crtc_pipe (pI830Priv->current_crtc)) {
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
return Success; /* faked for trying to share it */
@@ -2777,7 +2806,7 @@ I830DisplaySurface(XF86SurfacePtr surface,
}
}
- pI830->entityPrivate->XvInUse = I830CrtcPipe (pI830Priv->current_crtc);
+ pI830->entityPrivate->XvInUse = i830_crtc_pipe (pI830Priv->current_crtc);
}
x1 = src_x;
@@ -2861,7 +2890,6 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv;
- I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (pI830->adaptor == NULL)
return;
@@ -2872,53 +2900,12 @@ i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
pPriv = GET_PORT_PRIVATE(pScrn);
- /* Check if it's the crtc the overlay is on */
if (crtc != pPriv->current_crtc)
return;
+ /* Check if it's the crtc the overlay is on */
if (on) {
- int size, hsize, vsize, active;
- int pipeconf_reg = intel_crtc->pipe == 0 ? PIPEACONF : PIPEBCONF;
- char pipename = intel_crtc->pipe == 0 ? 'A' : 'B';
-
- pPriv->overlayOK = TRUE;
-
- if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Disabling XVideo output because Pipe %c is in "
- "double-wide mode.\n", pipename);
- pPriv->overlayOK = FALSE;
- } else if (!pPriv->overlayOK) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Re-enabling XVideo output because Pipe %c is now in "
- "single-wide mode.\n", pipename);
- pPriv->overlayOK = TRUE;
- }
-
- /* Check we have an LFP connected */
- if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) {
- int vtotal_reg = intel_crtc->pipe ? VTOTAL_A : VTOTAL_B;
- size = intel_crtc->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
- hsize = (size >> 16) & 0x7FF;
- vsize = size & 0x7FF;
- active = INREG(vtotal_reg) & 0x7FF;
-
- if (vsize < active && hsize > 1024)
- I830SetOneLineModeRatio(pScrn);
-
- if (pPriv->scaleRatio & 0xFFFE0000) {
- /* Possible bogus ratio, using in-accurate fallback */
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Bogus panel fit register, Xvideo positioning may not "
- "be accurate.\n");
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Using fallback ratio - was 0x%x, now 0x%x\n",
- pPriv->scaleRatio,
- (int)(((float)active * 65536)/(float)vsize));
-
- pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
- }
- }
+ i830_overlay_switch_to_crtc (pScrn, crtc);
} else {
/* We stop the video when mode switching, so we don't lock up
* the engine. The overlayOK will determine whether we can re-enable