diff options
author | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2011-05-08 14:20:15 +0000 |
---|---|---|
committer | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2011-05-08 14:20:15 +0000 |
commit | 325de3365c2357add4bac870f699185114fdf7c6 (patch) | |
tree | 10aa4f817974ba589bfafbc04f048facacf6964b | |
parent | 3b51d384e50b062f6d771a414fed5c62deda3d9b (diff) |
Fix cursor garbare after suspend/hibernate/resume on VX855/VX900 chipsets #405
-rw-r--r-- | src/via_swov.c | 18 | ||||
-rw-r--r-- | src/via_video.c | 89 |
2 files changed, 77 insertions, 30 deletions
diff --git a/src/via_swov.c b/src/via_swov.c index 1f9aff9..c2c7d6f 100644 --- a/src/via_swov.c +++ b/src/via_swov.c @@ -392,6 +392,7 @@ viaOverlayGetV1V3Format(VIAPtr pVia, int vport, /* 1 or 3, as in V1 or V3 */ if (videoFlag & VIDEO_HQV_INUSE) { switch (pVia->swov.SrcFourCC) { case FOURCC_YV12: + case FOURCC_I420: case FOURCC_XVMC: *pHQVCtl |= HQV_YUV420; break; @@ -421,6 +422,7 @@ viaOverlayGetV1V3Format(VIAPtr pVia, int vport, /* 1 or 3, as in V1 or V3 */ } else { switch (pVia->swov.SrcFourCC) { case FOURCC_YV12: + case FOURCC_I420: case FOURCC_XVMC: if (vport == 1) { *pVidCtl |= V1_YCbCr420; @@ -503,6 +505,7 @@ viaOverlayGetSrcStartAddress(VIAPtr pVia, break; case FOURCC_YV12: + case FOURCC_I420: case FOURCC_XVMC: if (videoFlag & VIDEO_HQV_INUSE) @@ -763,6 +766,7 @@ viaOverlayGetFetch(VIAPtr pVia, unsigned long videoFlag, switch (pVia->swov.SrcFourCC) { case FOURCC_YV12: + case FOURCC_I420: case FOURCC_XVMC: n = 0; /* 2^n = 1 byte per pixel (Y channel in planar YUV) */ break; @@ -1146,7 +1150,7 @@ AddHQVSurface(ScrnInfoPtr pScrn, unsigned int numbuf, CARD32 fourcc) !(pVia->swov.gdwVideoFlagSW & VIDEO_1_INUSE)) proReg = PRO_HQV1_OFFSET; - isplanar = ((fourcc == FOURCC_YV12) || (fourcc == FOURCC_XVMC)); + isplanar = ((fourcc == FOURCC_YV12) || (fourcc == FOURCC_I420) || (fourcc == FOURCC_XVMC)); width = pVia->swov.SWDevice.gdwSWSrcWidth; height = pVia->swov.SWDevice.gdwSWSrcHeight; @@ -1189,6 +1193,7 @@ CreateSurface(ScrnInfoPtr pScrn, CARD32 FourCC, CARD16 Width, isplanar = FALSE; switch (FourCC) { case FOURCC_YV12: + case FOURCC_I420: case FOURCC_XVMC: isplanar = TRUE; pitch = ALIGN_TO(Width, 32); @@ -1281,9 +1286,10 @@ ViaSwovSurfaceCreate(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv, break; case FOURCC_YV12: + case FOURCC_I420: retCode = CreateSurface(pScrn, FourCC, Width, Height, TRUE); if (retCode == Success) - retCode = AddHQVSurface(pScrn, numbuf, FOURCC_YV12); + retCode = AddHQVSurface(pScrn, numbuf, FourCC); break; case FOURCC_XVMC: @@ -1345,6 +1351,7 @@ ViaSwovSurfaceDestroy(ScrnInfoPtr pScrn, viaPortPrivPtr pPriv) break; case FOURCC_YV12: + case FOURCC_I420: VIAFreeLinear(&pVia->swov.SWfbMem); case FOURCC_XVMC: pVia->swov.SrcFourCC = 0; @@ -1509,6 +1516,7 @@ SetupFIFOs(VIAPtr pVia, unsigned long videoFlag, { if (miniCtl & V1_Y_INTERPOLY) { if (pVia->swov.SrcFourCC == FOURCC_YV12 + || pVia->swov.SrcFourCC == FOURCC_I420 || pVia->swov.SrcFourCC == FOURCC_XVMC) { if (videoFlag & VIDEO_HQV_INUSE) { if (videoFlag & VIDEO_1_INUSE) @@ -1542,6 +1550,7 @@ SetupFIFOs(VIAPtr pVia, unsigned long videoFlag, } } else { if (pVia->swov.SrcFourCC == FOURCC_YV12 + || pVia->swov.SrcFourCC == FOURCC_I420 || pVia->swov.SrcFourCC == FOURCC_XVMC) { if (videoFlag & VIDEO_HQV_INUSE) { if (videoFlag & VIDEO_1_INUSE) @@ -1891,6 +1900,7 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag, pVia->swov.overlayRecordV1.dwOffset = dwOffset; if (pVia->swov.SrcFourCC == FOURCC_YV12 + || pVia->swov.SrcFourCC == FOURCC_I420 || pVia->swov.SrcFourCC == FOURCC_XVMC) { YCBCRREC YCbCr; @@ -1983,6 +1993,7 @@ Upd_Video(ScrnInfoPtr pScrn, unsigned long videoFlag, SetHQVFetch(pVia, hqvSrcFetch, oriSrcHeight); if (pVia->swov.SrcFourCC == FOURCC_YV12 + || pVia->swov.SrcFourCC == FOURCC_I420 || pVia->swov.SrcFourCC == FOURCC_XVMC) { if (videoFlag & VIDEO_1_INUSE) SaveVideoRegister(pVia, V1_STRIDE, srcPitch << 1); @@ -2292,6 +2303,7 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate) (pVia->swov.SrcFourCC == FOURCC_RV16) || (pVia->swov.SrcFourCC == FOURCC_RV32) || (pVia->swov.SrcFourCC == FOURCC_YV12) || + (pVia->swov.SrcFourCC == FOURCC_I420) || (pVia->swov.SrcFourCC == FOURCC_XVMC)) { videoFlag = pVia->swov.gdwVideoFlagSW; } @@ -2366,6 +2378,7 @@ VIAVidUpdateOverlay(ScrnInfoPtr pScrn, LPDDUPDATEOVERLAY pUpdate) (pVia->swov.SrcFourCC == FOURCC_RV16) || (pVia->swov.SrcFourCC == FOURCC_RV32) || (pVia->swov.SrcFourCC == FOURCC_YV12) || + (pVia->swov.SrcFourCC == FOURCC_I420) || (pVia->swov.SrcFourCC == FOURCC_XVMC)) { pVia->swov.SWDevice.gdwSWDstLeft = pUpdate->DstLeft + panDX; pVia->swov.SWDevice.gdwSWDstTop = pUpdate->DstTop + panDY; @@ -2425,6 +2438,7 @@ ViaOverlayHide(ScrnInfoPtr pScrn) (pVia->swov.SrcFourCC == FOURCC_RV16) || (pVia->swov.SrcFourCC == FOURCC_RV32) || (pVia->swov.SrcFourCC == FOURCC_YV12) || + (pVia->swov.SrcFourCC == FOURCC_I420) || (pVia->swov.SrcFourCC == FOURCC_XVMC)) videoFlag = pVia->swov.gdwVideoFlagSW; diff --git a/src/via_video.c b/src/via_video.c index 58538d8..1797cfd 100644 --- a/src/via_video.c +++ b/src/via_video.c @@ -117,10 +117,14 @@ static int viaSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); static int viaPutImage(ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char *, short, short, Bool, RegionPtr, pointer, DrawablePtr); -static void nv12Blit(unsigned char *nv12Chroma, - const unsigned char *uBuffer, - const unsigned char *vBuffer, - unsigned width, unsigned srcPitch, unsigned dstPitch, unsigned lines); +static void nv12Blit(unsigned char *dst, + const unsigned char *src1, + const unsigned char *src2, + unsigned srcPitch, unsigned dstPitch, unsigned width, unsigned height); +static void UVBlit(unsigned char *dst, + const unsigned char *src1, + const unsigned char *src2, + unsigned srcPitch, unsigned dstPitch, unsigned width, unsigned height); static Atom xvBrightness, xvContrast, xvColorKey, xvHue, xvSaturation, xvAutoPaint; @@ -158,11 +162,12 @@ static XF86AttributeRec AttributesG[NUM_ATTRIBUTES_G] = { {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"} }; -#define NUM_IMAGES_G 6 +#define NUM_IMAGES_G 7 static XF86ImageRec ImagesG[NUM_IMAGES_G] = { XVIMAGE_YUY2, XVIMAGE_YV12, + XVIMAGE_I420, { /* * Below, a dummy picture type that is used in XvPutImage only to do @@ -963,6 +968,7 @@ Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc, proReg) & ~HQV_FLIP_ODD) | HQV_SW_FLIP | HQV_FLIP_STATUS); break; case FOURCC_YV12: + case FOURCC_I420: default: while ((VIDInD(HQV_CONTROL + proReg) & HQV_SW_FLIP) && --count); @@ -984,22 +990,7 @@ Flip(VIAPtr pVia, viaPortPrivPtr pPriv, int fourcc, } } -/* - * Slow and dirty. NV12 blit. - */ -static void -nv12cp(unsigned char *dst, - const unsigned char *src, int dstPitch, int w, int h, int yuv422) -{ - /* - * Blit luma component as a fake YUY2 assembler blit. - */ - - (*viaFastVidCpy) (dst, src, dstPitch, w >> 1, h, TRUE); - nv12Blit(dst + dstPitch * h, src + w * h + (w >> 1) * (h >> 1), - src + w * h, w >> 1, w >> 1, dstPitch, h >> 1); -} #ifdef XF86DRI @@ -1023,7 +1014,7 @@ viaDmaBlitImage(VIAPtr pVia, bounceBuffer = ((unsigned long)src & 15); nv12Conversion = (pVia->VideoEngine == VIDEO_ENGINE_CME && - id == FOURCC_YV12); + (id == FOURCC_YV12 || id == FOURCC_I420)); switch (id) { case FOURCC_YUY2: @@ -1038,6 +1029,7 @@ viaDmaBlitImage(VIAPtr pVia, break; case FOURCC_YV12: + case FOURCC_I420: default: bounceStride = ALIGN_TO(width, 16); bounceLines = height; @@ -1053,8 +1045,9 @@ viaDmaBlitImage(VIAPtr pVia, pPort->dmaBounceBuffer = 0; } size = bounceStride * bounceLines + 16; - if (FOURCC_YV12 == id) + if (id == FOURCC_YV12 || id == FOURCC_I420) { size += ALIGN_TO(bounceStride >> 1, 16) * bounceLines; + } pPort->dmaBounceBuffer = (unsigned char *)malloc(size); pPort->dmaBounceLines = bounceLines; pPort->dmaBounceStride = bounceStride; @@ -1093,14 +1086,22 @@ viaDmaBlitImage(VIAPtr pVia, lumaSync = blit.sync; - if (id == FOURCC_YV12) { + if (id == FOURCC_YV12 || id == FOURCC_I420) { unsigned tmp = ALIGN_TO(width >> 1, 16); if (nv12Conversion) { - nv12Blit(bounceBase + bounceStride * height, - src + bounceStride * height + tmp * (height >> 1), - src + bounceStride * height, width >> 1, tmp, - bounceStride, height >> 1); + if (id == FOURCC_YV12) { + nv12Blit(bounceBase + bounceStride * height, + src + bounceStride * height + tmp * (height >> 1), + src + bounceStride * height, + tmp, bounceStride, width >> 1, height >> 1); + } else if (id == FOURCC_I420) { + /* TODO Check if this code will work properly with FOURCC_I420 */ + nv12Blit(bounceBase + bounceStride * height, + src + bounceStride * height, + src + bounceStride * height + tmp * (height >> 1), + tmp, bounceStride, width >> 1, height >> 1); + } } else if (bounceBuffer) { (*viaFastVidCpy) (base + bounceStride * height, src + bounceStride * height, tmp, tmp >> 1, height, 1); @@ -1227,13 +1228,45 @@ viaPutImage(ScrnInfoPtr pScrn, switch (id) { case FOURCC_YV12: if (pVia->VideoEngine == VIDEO_ENGINE_CME) { - nv12cp(pVia->swov.SWDevice. + int srcYSize = width * height; + /* Copy Y component */ + (*viaFastVidCpy) (pVia->swov.SWDevice. + lpSWOverlaySurface[pVia->dwFrameNum & 1], + buf, dstPitch, width >> 1, height, TRUE); + + /* Copy U and V component */ + nv12Blit(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum & 1] + dstPitch * height, + buf + srcYSize + (srcYSize >> 2), /* Size of UV component is 1/4 of Y */ + buf + srcYSize, + width >> 1, dstPitch, width >> 1, height >> 1); + } else { + (*viaFastVidCpy)(pVia->swov.SWDevice. lpSWOverlaySurface[pVia->dwFrameNum & 1], buf, dstPitch, width, height, 0); + } + break; + case FOURCC_I420: + if (pVia->VideoEngine == VIDEO_ENGINE_CME) { + int srcYSize = width * height; + + (*viaFastVidCpy) (pVia->swov.SWDevice. + lpSWOverlaySurface[pVia->dwFrameNum & 1], + buf, dstPitch, width >> 1, height, TRUE); + + nv12Blit(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum & 1] + dstPitch*height, + buf + srcYSize, + buf + srcYSize + (srcYSize >> 2), /* UV component is 1/4 of Y */ + width >> 1, dstPitch, width >> 1, height >> 1); } else { + int srcYSize = width * height; (*viaFastVidCpy)(pVia->swov.SWDevice. lpSWOverlaySurface[pVia->dwFrameNum & 1], buf, dstPitch, width, height, 0); + + nv12Blit(pVia->swov.SWDevice.lpSWOverlaySurface[pVia->dwFrameNum & 1] + dstPitch * height, + buf + srcYSize + (srcYSize >> 2), + buf + srcYSize, + width >> 1, dstPitch, width, height >> 1); } break; case FOURCC_RV32: |