diff options
Diffstat (limited to 'src/smi_video.c')
-rw-r--r-- | src/smi_video.c | 380 |
1 files changed, 115 insertions, 265 deletions
diff --git a/src/smi_video.c b/src/smi_video.c index 3bc4f8b..79fb087 100644 --- a/src/smi_video.c +++ b/src/smi_video.c @@ -41,8 +41,7 @@ Author of changes: Corvin Zahn <zahn@zac.de> Date: 2.11.2001 */ -/* $XdotOrg: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c,v 1.14 2003/12/08 16:03:58 alanh Exp $ */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c,v 1.13 2003/11/10 18:22:26 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/siliconmotion/smi_video.c,v 1.11 2003/04/23 21:51:44 tsi Exp $ */ #include "smi.h" #include "smi_video.h" @@ -120,9 +119,6 @@ static Bool SMI_ClipVideo(ScrnInfoPtr pScrn, BoxPtr dst, static void SMI_DisplayVideo(ScrnInfoPtr pScrn, int id, int offset, short width, short height, int pitch, int x1, int y1, int x2, int y2, BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h); -static void SMI_DisplayVideo0730(ScrnInfoPtr pScrn, int id, int offset, - short width, short height, int pitch, int x1, int y1, int x2, int y2, - BoxPtr dstBox, short vid_w, short vid_h, short drw_w, short drw_h); static void SMI_BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadMask); #if 0 @@ -134,6 +130,11 @@ static void SMI_WaitForSync(ScrnInfoPtr pScrn); static void SMI_InitOffscreenImages(ScreenPtr pScreen); static FBAreaPtr SMI_AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int numLines); +static void SMI_CopyData(unsigned char *src, unsigned char *dst, int srcPitch, + int dstPitch, int height, int width); +static void SMI_CopyYV12Data(unsigned char *src1, unsigned char *src2, + unsigned char *src3, unsigned char *dst, int srcPitch1, int srcPitch2, + int dstPitch, int height, int width); static int SMI_AllocSurface(ScrnInfoPtr pScrn, int id, unsigned short width, unsigned short height, @@ -150,11 +151,7 @@ static int SMI_SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attr, INT32 value); static int SetAttr(ScrnInfoPtr pScrn, int i, int value); static int SetAttrSAA7110(ScrnInfoPtr pScrn, int i, int value); static int SetAttrSAA7111(ScrnInfoPtr pScrn, int i, int value); -static void SetKeyReg(SMIPtr pSmi, int reg, int value); -#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) -static Bool RegionsEqual(RegionPtr A, RegionPtr B); -#endif /** * Atoms */ @@ -460,55 +457,6 @@ static I2CByte SAA7111InitData[] = /**************************************************************************/ -/* To allow this ddx to work on 4_3_0 and above, we need to include this */ -#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) -static Bool -RegionsEqual( - RegionPtr A, - RegionPtr B -) -{ - int *dataA, *dataB; - int num; - - ENTER_PROC("RegionsEqual"); - - num = REGION_NUM_RECTS(A); - if (num != REGION_NUM_RECTS(B)) - { - LEAVE_PROC("RegionsEqual"); - return(FALSE); - } - - if ( (A->extents.x1 != B->extents.x1) - || (A->extents.y1 != B->extents.y1) - || (A->extents.x2 != B->extents.x2) - || (A->extents.y2 != B->extents.y2) - ) - { - LEAVE_PROC("RegionsEqual"); - return(FALSE); - } - - dataA = (int*) REGION_RECTS(A); - dataB = (int*) REGION_RECTS(B); - - while (num--) - { - if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) - { - return(FALSE); - } - dataA += 2; - dataB += 2; - } - - LEAVE_PROC("RegionsEqual"); - return(TRUE); -} -#endif - - /** * generates XF86VideoEncoding[i] with video norm norm, video input format * input and video input channel channel @@ -712,7 +660,7 @@ SetAttr(ScrnInfoPtr pScrn, int i, int value) if (i == XV_BRIGHTNESS) { int my_value = (value <= 128? value + 128 : value - 128); - SetKeyReg(pSmi, 0x5C, 0xEDEDED | (my_value << 24)); + WRITE_VPR(pSmi, 0x5C, 0xEDEDED | (my_value << 24)); } else if (pPort->I2CDev.SlaveAddr == SAA7110) { return SetAttrSAA7110(pScrn, i, value); } @@ -902,10 +850,7 @@ SMI_SetupVideo( ptrAdaptor->pImages = SMI_VideoImages; #if SMI_USE_CAPTURE - if (pSmi->Chipset == SMI_COUGAR3DR) - ptrAdaptor->PutVideo = NULL; - else - ptrAdaptor->PutVideo = SMI_PutVideo; + ptrAdaptor->PutVideo = SMI_PutVideo; ptrAdaptor->PutStill = NULL; ptrAdaptor->GetVideo = NULL; ptrAdaptor->GetStill = NULL; @@ -961,11 +906,7 @@ SMI_SetupVideo( } else smiPortPtr->I2CDev.SlaveAddr = 0; -#if defined(REGION_NULL) - REGION_NULL(pScreen, &smiPortPtr->clip); -#else REGION_INIT(pScreen, &smiPortPtr->clip, NullBox, 0); -#endif pSmi->ptrAdaptor = ptrAdaptor; pSmi->BlockHandler = pScreen->BlockHandler; @@ -1002,26 +943,26 @@ SMI_ResetVideo( switch (pScrn->depth) { case 8: - SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0x00FF); - SetKeyReg(pSmi, FPR08, 0); + WRITE_VPR(pSmi, 0x04, pPort->Attribute[XV_COLORKEY] & 0x00FF); + WRITE_VPR(pSmi, 0x08, 0); break; case 15: case 16: - SetKeyReg(pSmi, FPR04, pPort->Attribute[XV_COLORKEY] & 0xFFFF); - SetKeyReg(pSmi, FPR08, 0); + WRITE_VPR(pSmi, 0x04, pPort->Attribute[XV_COLORKEY] & 0xFFFF); + WRITE_VPR(pSmi, 0x08, 0); break; default: r = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.red) >> pScrn->offset.red; g = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.green) >> pScrn->offset.green; b = (pPort->Attribute[XV_COLORKEY] & pScrn->mask.blue) >> pScrn->offset.blue; - SetKeyReg(pSmi, FPR04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); - SetKeyReg(pSmi, FPR08, 0); + WRITE_VPR(pSmi, 0x04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); + WRITE_VPR(pSmi, 0x08, 0); break; } - SetKeyReg(pSmi, FPR5C, 0xEDEDED | (pPort->Attribute[XV_BRIGHTNESS] << 24)); + WRITE_VPR(pSmi, 0x5C, 0xEDEDED | (pPort->Attribute[XV_BRIGHTNESS] << 24)); LEAVE_PROC("SMI_ResetVideo"); } @@ -1293,11 +1234,7 @@ SMI_PutVideo( vid_address = (pPort->area->box.y1 * fbPitch); DEBUG((VERBLEV, "test RegionsEqual\n")); -#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) - if (!RegionsEqual(&pPort->clip, clipBoxes)) -#else if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) -#endif { DEBUG((VERBLEV, "RegionCopy\n")); REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); @@ -1398,21 +1335,11 @@ SMI_StopVideo( { if (pPort->videoStatus & CLIENT_VIDEO_ON) { - if (pSmi->Chipset == SMI_COUGAR3DR) - { - WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); - } - else - { - WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008); - } + WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x01000008); #if SMI_USE_CAPTURE - if (pSmi->Chipset != SMI_COUGAR3DR) - { - WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001); - WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000); - } - /* #864 OUT_SEQ(pSmi, 0x21, IN_SEQ(pSmi, 0x21) | 0x04); */ + WRITE_CPR(pSmi, 0x00, READ_CPR(pSmi, 0x00) & ~0x00000001); + WRITE_VPR(pSmi, 0x54, READ_VPR(pSmi, 0x54) & ~0x00F00000); +/* #864 OUT_SEQ(pSmi, 0x21, IN_SEQ(pSmi, 0x21) | 0x04); */ #endif } if (pPort->area != NULL) @@ -1457,19 +1384,19 @@ SMI_SetPortAttribute( switch (pScrn->depth) { case 8: - SetKeyReg(pSmi, FPR04, value & 0x00FF); + WRITE_VPR(pSmi, 0x04, value & 0x00FF); break; case 15: case 16: - SetKeyReg(pSmi, FPR04, value & 0xFFFF); + WRITE_VPR(pSmi, 0x04, value & 0xFFFF); break; default: r = (value & pScrn->mask.red) >> pScrn->offset.red; g = (value & pScrn->mask.green) >> pScrn->offset.green; b = (value & pScrn->mask.blue) >> pScrn->offset.blue; - SetKeyReg(pSmi, FPR04, + WRITE_VPR(pSmi, 0x04, ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3)); break; } @@ -1686,49 +1613,37 @@ SMI_PutImage( offset = (pPort->area->box.y1 * fbPitch) + (top * dstPitch); dstStart = pSmi->FBBase + offset + left; - switch(id) { - case FOURCC_YV12: - case FOURCC_I420: - top &= ~1; - tmp = ((top >> 1) * srcPitch2) + (left >> 2); - offset2 += tmp; - offset3 += tmp; - if(id == FOURCC_I420) { - tmp = offset2; - offset2 = offset3; - offset3 = tmp; - } - nLines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; - xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), - buf + offset2, buf + offset3, dstStart, - srcPitch, srcPitch2, dstPitch, nLines, nPixels); - break; - case FOURCC_UYVY: - case FOURCC_YUY2: - default: - buf += (top * srcPitch) + left; - nLines = ((y2 + 0xffff) >> 16) - top; - xf86XVCopyPacked(buf, dstStart, srcPitch, dstPitch, nLines, nPixels); - break; - } + switch (id) + { + case FOURCC_YV12: + case FOURCC_I420: + top &= ~1; + tmp = ((top >> 1) * srcPitch2) + (left >> 2); + offset2 += tmp; + offset3 += tmp; + nLines = ((((y2 + 0xFFFF) >> 16) + 1) & ~1) - top; + SMI_CopyYV12Data(buf + (top * srcPitch) + (left >> 1), + buf + offset2, buf + offset3, dstStart, srcPitch, srcPitch2, + dstPitch, nLines, nPixels); + break; + + default: + buf += (top * srcPitch) + left; + nLines = ((y2 + 0xFFFF) >> 16) - top; + SMI_CopyData(buf, dstStart, srcPitch, dstPitch, nLines, + nPixels * bpp); + break; + } -#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,3,99,0,0) - if (!RegionsEqual(&pPort->clip, clipBoxes)) -#else if (!REGION_EQUAL(pScrn->pScreen, &pPort->clip, clipBoxes)) -#endif { REGION_COPY(pScrn->pScreen, &pPort->clip, clipBoxes); xf86XVFillKeyHelper(pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes); } - if (pSmi->Chipset != SMI_COUGAR3DR) - SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, - &dstBox, src_w, src_h, drw_w, drw_h); - else - SMI_DisplayVideo0730(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, - &dstBox, src_w, src_h, drw_w, drw_h); + SMI_DisplayVideo(pScrn, id, offset, width, height, dstPitch, x1, y1, x2, y2, + &dstBox, src_w, src_h, drw_w, drw_h); pPort->videoStatus = CLIENT_VIDEO_ON; LEAVE_PROC("SMI_PutImage"); @@ -1866,9 +1781,8 @@ SMI_ClipVideo( INT32 height ) { - ScreenPtr pScreen = pScrn->pScreen; INT32 vscale, hscale; - BoxPtr extents = REGION_EXTENTS(pScreen, reg); + BoxPtr extents = REGION_EXTENTS(pScrn, reg); int diff; ENTER_PROC("SMI_ClipVideo"); @@ -1963,9 +1877,9 @@ SMI_ClipVideo( ) { RegionRec clipReg; - REGION_INIT(pScreen, &clipReg, dst, 1); - REGION_INTERSECT(pScreen, reg, reg, &clipReg); - REGION_UNINIT(pScreen, &clipReg); + REGION_INIT(pScrn, &clipReg, dst, 1); + REGION_INTERSECT(pScrn, reg, reg, &clipReg); + REGION_UNINIT(pScrn, &clipReg); } DEBUG((VERBLEV, "ClipVideo(%d): x1=%d y1=%d x2=%d y2=%d\n", __LINE__, *x1 >> 16, *y1 >> 16, *x2 >> 16, *y2 >> 16)); @@ -2059,90 +1973,6 @@ SMI_DisplayVideo( } static void -SMI_DisplayVideo0730( - ScrnInfoPtr pScrn, - int id, - int offset, - short width, - short height, - int pitch, - int x1, - int y1, - int x2, - int y2, - BoxPtr dstBox, - short vid_w, - short vid_h, - short drw_w, - short drw_h -) -{ - SMIPtr pSmi = SMIPTR(pScrn); - CARD32 fpr00; - int hstretch, vstretch; - - ENTER_PROC("SMI_DisplayVideo0730"); - - fpr00 = READ_FPR(pSmi, 0x00) & ~(FPR00_MASKBITS); - - switch (id) - { - case FOURCC_YV12: - case FOURCC_I420: - case FOURCC_YUY2: - fpr00 |= FPR00_FMT_YUV422; - break; - - case FOURCC_RV15: - fpr00 |= FPR00_FMT_15P; - break; - - case FOURCC_RV16: - fpr00 |= FPR00_FMT_16P; - break; - - case FOURCC_RV24: - fpr00 |= FPR00_FMT_24P; - break; - - case FOURCC_RV32: - fpr00 |= FPR00_FMT_32P; - break; - } - - /* the formulas for calculating the stretch values do not match the - documentation, but they're the same as the ddraw driver and they work */ - if (drw_w > vid_w) - { - hstretch = (8192 * vid_w / drw_w); - } - else - { - hstretch = 0; - } - - if (drw_h > vid_h) - { - vstretch = (8192 * vid_h / drw_h); - } - else - { - vstretch = 0; - } - - - WRITE_FPR(pSmi, FPR00, fpr00 | FPR00_VWIENABLE | FPR00_VWIKEYENABLE); - WRITE_FPR(pSmi, FPR14, (dstBox->x1) | (dstBox->y1 << 16)); - WRITE_FPR(pSmi, FPR18, (dstBox->x2) | (dstBox->y2 << 16)); - WRITE_FPR(pSmi, FPR1C, offset >> 3); - WRITE_FPR(pSmi, FPR20, (pitch >> 3) | ((pitch >> 3) << 16)); - WRITE_FPR(pSmi, FPR24, (hstretch & 0xFF00) | ((vstretch & 0xFF00)>>8)); - WRITE_FPR(pSmi, FPR68, ((hstretch & 0x00FF)<<8) | (vstretch & 0x00FF)); - - LEAVE_PROC("SMI_DisplayVideo0730"); -} - -static void SMI_BlockHandler( int i, pointer blockData, @@ -2166,14 +1996,7 @@ SMI_BlockHandler( { if (pPort->offTime < currentTime.milliseconds) { - if (pSmi->Chipset == SMI_COUGAR3DR) - { - WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); - } - else - { - WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); - } + WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); pPort->videoStatus = FREE_TIMER; pPort->freeTime = currentTime.milliseconds + FREE_DELAY; } @@ -2349,6 +2172,65 @@ SMI_AllocateMemory( return(area); } +static void +SMI_CopyData( + unsigned char *src, + unsigned char *dst, + int srcPitch, + int dstPitch, + int height, + int width +) +{ + ENTER_PROC("SMI_CopyData"); + + while (height-- > 0) + { + memcpy(dst, src, width); + src += srcPitch; + dst += dstPitch; + } + + LEAVE_PROC("SMI_CopyData"); +} + +static void +SMI_CopyYV12Data( + unsigned char *src1, + unsigned char *src2, + unsigned char *src3, + unsigned char *dst, + int srcPitch1, + int srcPitch2, + int dstPitch, + int height, + int width +) +{ + CARD32 *pDst = (CARD32 *) dst; + int i, j; + + ENTER_PROC("SMI_CopyYV12Data"); + + for (j = 0; j < height; j++) + { + for (i =0; i < width; i++) + { + pDst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | + (src3[i] << 8) | (src2[i] << 24); + } + pDst += dstPitch >> 2; + src1 += srcPitch1; + if (j & 1) + { + src2 += srcPitch2; + src3 += srcPitch2; + } + } + + LEAVE_PROC("SMI_CopyYV12Data"); +} + static int SMI_AllocSurface( ScrnInfoPtr pScrn, @@ -2525,25 +2407,15 @@ SMI_DisplaySurface( xf86XVFillKeyHelper(surface->pScrn->pScreen, pPort->Attribute[XV_COLORKEY], clipBoxes); - if (pSmi->Chipset != SMI_COUGAR3DR) - { - SMI_ResetVideo(surface->pScrn); - SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0], - surface->width, surface->height, surface->pitches[0], x1, y1, x2, - y2, &dstBox, vid_w, vid_h, drw_w, drw_h); - } - else - { - SMI_ResetVideo(surface->pScrn); - SMI_DisplayVideo0730(surface->pScrn, surface->id, surface->offsets[0], - surface->width, surface->height, surface->pitches[0], x1, y1, x2, - y2, &dstBox, vid_w, vid_h, drw_w, drw_h); - } + SMI_ResetVideo(surface->pScrn); + SMI_DisplayVideo(surface->pScrn, surface->id, surface->offsets[0], + surface->width, surface->height, surface->pitches[0], x1, y1, x2, + y2, &dstBox, vid_w, vid_h, drw_w, drw_h); ptrOffscreen->isOn = TRUE; if (pPort->videoStatus & CLIENT_VIDEO_ON) { - REGION_EMPTY(surface->pScrn->pScreen, &pPort->clip); + REGION_EMPTY(pScrn->pScreen, &pPort->clip); UpdateCurrentTime(); pPort->videoStatus = FREE_TIMER; pPort->freeTime = currentTime.milliseconds + FREE_DELAY; @@ -2565,15 +2437,7 @@ SMI_StopSurface( if (ptrOffscreen->isOn) { SMIPtr pSmi = SMIPTR(surface->pScrn); - if (pSmi->Chipset == SMI_COUGAR3DR) - { - WRITE_FPR(pSmi, FPR00, READ_FPR(pSmi, 0x00) & ~(FPR00_VWIENABLE)); - } - else - { - WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); - } - + WRITE_VPR(pSmi, 0x00, READ_VPR(pSmi, 0x00) & ~0x00000008); ptrOffscreen->isOn = FALSE; } @@ -2606,20 +2470,6 @@ SMI_SetSurfaceAttribute( return(SMI_SetPortAttribute(pScrn, attr, value, (pointer) pSmi->ptrAdaptor->pPortPrivates[0].ptr)); } - -static void -SetKeyReg(SMIPtr pSmi, int reg, int value) -{ - if (pSmi->Chipset == SMI_COUGAR3DR) - { - WRITE_FPR(pSmi, reg, value); - } - else - { - WRITE_VPR(pSmi, reg, value); - } -} - #else /* SMI_USE_VIDEO */ void SMI_InitVideo(ScreenPtr pScreen) {} #endif |