diff options
author | David Reveman <c99drn@cs.umu.se> | 2006-04-13 13:44:32 +0000 |
---|---|---|
committer | David Reveman <c99drn@cs.umu.se> | 2006-04-13 13:44:32 +0000 |
commit | 5e4ef5afc5247a5f1e4512af3dd8b8da6ce609cc (patch) | |
tree | 15cf08e1d199dccffdc337a00913e557f13e9548 | |
parent | eb16fa53237549d6a1a96abd355699439339ca9e (diff) |
XVideo improvements
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | hw/xgl/egl/xeglinit.c | 9 | ||||
-rw-r--r-- | hw/xgl/glx/xglxinit.c | 2 | ||||
-rw-r--r-- | hw/xgl/xgl.h | 5 | ||||
-rw-r--r-- | hw/xgl/xglinit.c | 2 | ||||
-rw-r--r-- | hw/xgl/xglparse.c | 30 | ||||
-rw-r--r-- | hw/xgl/xglscreen.c | 2 | ||||
-rw-r--r-- | hw/xgl/xglxv.c | 134 |
8 files changed, 172 insertions, 26 deletions
@@ -1,5 +1,19 @@ 2006-04-13 David Reveman <davidr@novell.com> + * hw/xgl/xglparse.c (xglProcessArgument, xglUseMsg): + * hw/xgl/xglxv.c: + * hw/xgl/egl/xeglinit.c: + * hw/xgl/glx/xglxinit.c: + * hw/xgl/xglinit.c: + * hw/xgl/xglscreen.c (xglScreenInit): + * hw/xgl/xgl.h: Add xvfilter and noyuv options. xvfilter can be used + to set the filter used for XVideo, currently available filters are + nearest and linear (default is linear). Nearest filter can improve + performance signifcantly when XVideo isn't accelerated. noyuv + option can be used to force use of software YUV to RGB conversions, + which can improve performance when GL_ARB_fragment_program support + isn't fast enough. + * fb/fbpict.c (fbComposite): * fb/fbmmx.h: * fb/fbmmx.c: Add fast YUV conversion code. diff --git a/hw/xgl/egl/xeglinit.c b/hw/xgl/egl/xeglinit.c index 7547a6a46..372b232a9 100644 --- a/hw/xgl/egl/xeglinit.c +++ b/hw/xgl/egl/xeglinit.c @@ -32,7 +32,14 @@ static xglScreenInfoRec xglScreenInfo = { FALSE, XGL_DEFAULT_PBO_MASK, FALSE, - FALSE + FALSE, + FilterBilinear, + { + { FALSE, FALSE, { 0, 0, 0, 0 } }, + { FALSE, FALSE, { 0, 0, 0, 0 } }, + { FALSE, FALSE, { 0, 0, 0, 0 } }, + { FALSE, FALSE, { 0, 0, 0, 0 } } + } }; #ifdef GLXEXT diff --git a/hw/xgl/glx/xglxinit.c b/hw/xgl/glx/xglxinit.c index 4de4ae668..a1fdb9853 100644 --- a/hw/xgl/glx/xglxinit.c +++ b/hw/xgl/glx/xglxinit.c @@ -33,6 +33,8 @@ xglScreenInfoRec xglScreenInfo = { FALSE, XGL_DEFAULT_PBO_MASK, FALSE, + FALSE, + FilterBilinear, { { FALSE, FALSE, { 0, 0, 0, 0 } }, { FALSE, FALSE, { 0, 0, 0, 0 } }, diff --git a/hw/xgl/xgl.h b/hw/xgl/xgl.h index cd4cec162..2a841bdbf 100644 --- a/hw/xgl/xgl.h +++ b/hw/xgl/xgl.h @@ -102,6 +102,8 @@ typedef struct _xglScreenInfo { Bool yInverted; int pboMask; Bool lines; + Bool noYuv; + char *xvFilter; xglScreenAccelInfoRec accel; } xglScreenInfoRec, *xglScreenInfoPtr; @@ -255,6 +257,8 @@ typedef struct _xglScreen { Bool yInverted; int pboMask; Bool lines; + Bool noYuv; + char *xvFilter; xglGeometryRec scratchGeometry; xglScreenAccelInfoRec accel; @@ -372,6 +376,7 @@ typedef struct _xglXvPort { PixmapPtr pPixmap; PicturePtr pSrc; PicturePtr pDst; + PicturePtr pTmp; } xglXvPortRec, *xglXvPortPtr; #endif diff --git a/hw/xgl/xglinit.c b/hw/xgl/xglinit.c index a016a16dc..50b374d2d 100644 --- a/hw/xgl/xglinit.c +++ b/hw/xgl/xglinit.c @@ -44,6 +44,8 @@ xglScreenInfoRec xglScreenInfo = { FALSE, XGL_DEFAULT_PBO_MASK, FALSE, + FALSE, + FilterBilinear, { { FALSE, FALSE, { 0, 0, 0, 0 } }, { FALSE, FALSE, { 0, 0, 0, 0 } }, diff --git a/hw/xgl/xglparse.c b/hw/xgl/xglparse.c index 5292692a4..e3e3028c4 100644 --- a/hw/xgl/xglparse.c +++ b/hw/xgl/xglparse.c @@ -188,6 +188,13 @@ xglUseMsg (void) ErrorF ("-yinverted Y is upside-down\n"); ErrorF ("-lines " "accelerate lines that are not vertical or horizontal\n"); + ErrorF ("-noyuv " + "turns off hardware color-space conversion of YUV data\n"); + +#ifdef XV + ErrorF ("-xvfilter [nearest|linear] set xvideo filter\n"); +#endif + ErrorF ("-vbo " "use vertex buffer objects for streaming of vertex data\n"); ErrorF ("-pbomask [1|4|8|16|32] " @@ -225,6 +232,29 @@ xglProcessArgument (int argc, xglScreenInfo.lines = TRUE; return 1; } + else if (!strcmp (argv[i], "-noyuv")) + { + xglScreenInfo.noYuv = TRUE; + return 1; + } + +#ifdef XV + else if (!strcmp (argv[i], "-xvfilter")) + { + if ((i + 1) < argc) + { + if (!strcasecmp (argv[i + 1], "nearest")) + xglScreenInfo.xvFilter = FilterNearest; + else if (!strcasecmp (argv[i + 1], "linear")) + xglScreenInfo.xvFilter = FilterBilinear; + } + else + return 1; + + return 2; + } +#endif + else if (!strcmp (argv[i], "-vbo")) { xglScreenInfo.geometryUsage = GEOMETRY_USAGE_STREAM; diff --git a/hw/xgl/xglscreen.c b/hw/xgl/xglscreen.c index 4bd86c18f..b7d7b2db9 100644 --- a/hw/xgl/xglscreen.c +++ b/hw/xgl/xglscreen.c @@ -173,6 +173,8 @@ xglScreenInit (ScreenPtr pScreen) pScreenPriv->yInverted = xglScreenInfo.yInverted; pScreenPriv->pboMask = xglScreenInfo.pboMask; pScreenPriv->lines = xglScreenInfo.lines; + pScreenPriv->noYuv = xglScreenInfo.noYuv; + pScreenPriv->xvFilter = xglScreenInfo.xvFilter; pScreenPriv->accel = xglScreenInfo.accel; if (monitorResolution) diff --git a/hw/xgl/xglxv.c b/hw/xgl/xglxv.c index aaa66c738..faef674c4 100644 --- a/hw/xgl/xglxv.c +++ b/hw/xgl/xglxv.c @@ -200,6 +200,12 @@ xglXvFreePort (XvPortPtr pPort) pPortPriv->pSrc = (PicturePtr) 0; } + if (pPortPriv->pTmp) + { + FreePicture ((pointer) pPortPriv->pTmp, 0); + pPortPriv->pTmp = (PicturePtr) 0; + } + if (pPortPriv->pPixmap) { ScreenPtr pScreen; @@ -239,6 +245,37 @@ xglXvStopVideo (ClientPtr client, return Success; } +static PicturePtr +xglXvCreateDstPict (DrawablePtr pDrawable, + Mask vmask, + XID *vlist, + int *error) +{ + ScreenPtr pScreen = pDrawable->pScreen; + PictFormatPtr pFormat = 0; + int i; + + for (i = 0; i < pScreen->numVisuals; i++) + { + if (pScreen->visuals[i].nplanes == pDrawable->depth) + { + pFormat = PictureMatchVisual (pScreen, pDrawable->depth, + &pScreen->visuals[i]); + break; + } + } + + if (!pFormat) + { + *error = BadImplementation; + return (PicturePtr) 0; + } + + return CreatePicture (0, pDrawable, + pFormat, vmask, vlist, serverClient, + error); +} + static int xglXvPutImage (ClientPtr client, DrawablePtr pDrawable, @@ -259,8 +296,9 @@ xglXvPutImage (ClientPtr client, CARD16 height) { ScreenPtr pScreen = pDrawable->pScreen; + PicturePtr pSrc; PictTransform transform; - int depth, bpp; + int depth, bpp, noVisual = FALSE; CARD32 format; XGL_SCREEN_PRIV (pScreen); @@ -272,10 +310,12 @@ xglXvPutImage (ClientPtr client, case GLITZ_FOURCC_YUY2: bpp = depth = 16; format = PICT_yuy2; + noVisual = !pScreenPriv->pXvVisual[XGL_XV_FORMAT_YUY2].format.surface; break; case GLITZ_FOURCC_YV12: depth = bpp = 12; format = PICT_yv12; + noVisual = !pScreenPriv->pXvVisual[XGL_XV_FORMAT_YV12].format.surface; break; case GLITZ_FOURCC_RGB: depth = 24; @@ -326,34 +366,21 @@ xglXvPutImage (ClientPtr client, } SetPictureFilter (pPortPriv->pSrc, - FilterBilinear, strlen (FilterBilinear), + pScreenPriv->xvFilter, + strlen (pScreenPriv->xvFilter), 0, 0); } + pSrc = pPortPriv->pSrc; + if (!pPortPriv->pDst || pPortPriv->pDst->pDrawable != pDrawable) { - PictFormatPtr pFormat = 0; - int i, error; - - for (i = 0; i < pScreen->numVisuals; i++) - { - if (pScreen->visuals[i].nplanes == pDrawable->depth) - { - pFormat = PictureMatchVisual (pScreen, pDrawable->depth, - &pScreen->visuals[i]); - break; - } - } - - if (!pFormat) - return BadImplementation; + int error; if (pPortPriv->pDst) FreePicture ((pointer) pPortPriv->pDst, 0); - pPortPriv->pDst = CreatePicture (0, pDrawable, - pFormat, 0, 0, serverClient, - &error); + pPortPriv->pDst = xglXvCreateDstPict (pDrawable, 0, NULL, &error); if (!pPortPriv->pDst) { xglXvFreePort (pPort); @@ -361,6 +388,66 @@ xglXvPutImage (ClientPtr client, } } + if (pPixmap != pScreenPriv->pScreenPixmap && !pPixmapPriv->target) + xglEnablePixmapAccel (pPixmap, &pScreenPriv->accel.xv); + + /* software color-space conversion */ + if (pPixmapPriv->target && (noVisual || pScreenPriv->noYuv)) + { + if (!pPortPriv->pTmp || + srcWidth != pPortPriv->pTmp->pDrawable->width || + srcHeight != pPortPriv->pTmp->pDrawable->height) + { + static XID value = RepeatPad; + int error; + + if (pPortPriv->pTmp) + FreePicture ((pointer) pPortPriv->pTmp, 0); + + pPixmap = (*pScreen->CreatePixmap) (pScreen, + srcWidth, srcHeight, + pDrawable->depth); + if (!pPixmap) + { + xglXvFreePort (pPort); + return BadAlloc; + } + + pPortPriv->pTmp = xglXvCreateDstPict (&pPixmap->drawable, + CPRepeat, &value, + &error); + if (!pPortPriv->pTmp) + { + (*pScreen->DestroyPixmap) (pPixmap); + xglXvFreePort (pPort); + return error; + } + + /* no accelerated drawing */ + XGL_GET_PIXMAP_PRIV (pPixmap)->target = xglPixmapTargetNo; + + (*pScreen->DestroyPixmap) (pPixmap); + + SetPictureFilter (pPortPriv->pTmp, + pScreenPriv->xvFilter, + strlen (pScreenPriv->xvFilter), + 0, 0); + } + + SetPictureTransform (pSrc, 0); + + CompositePicture (PictOpSrc, + pSrc, + (PicturePtr) 0, + pPortPriv->pTmp, + 0, 0, + 0, 0, + 0, 0, + srcWidth, srcHeight); + + pSrc = pPortPriv->pTmp; + } + transform.matrix[0][0] = ((srcWidth << 16) + (dstWidth >> 1)) / dstWidth; transform.matrix[0][1] = 0; @@ -376,13 +463,10 @@ xglXvPutImage (ClientPtr client, transform.matrix[2][1] = 0; transform.matrix[2][2] = 1 << 16; - SetPictureTransform (pPortPriv->pSrc, &transform); - - if (pPixmap != pScreenPriv->pScreenPixmap && !pPixmapPriv->target) - xglEnablePixmapAccel (pPixmap, &pScreenPriv->accel.xv); + SetPictureTransform (pSrc, &transform); CompositePicture (PictOpSrc, - pPortPriv->pSrc, + pSrc, (PicturePtr) 0, pPortPriv->pDst, srcX, srcY, |