mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-04 23:28:05 +02:00
Compute stride for other formats than YV12 correctly in xglXvPutImage. Add
some decent YUY2 conversion code and enable YUV2 image format again.
This commit is contained in:
parent
6296f79886
commit
75846b85b0
4 changed files with 290 additions and 17 deletions
269
fb/fbmmx.c
269
fb/fbmmx.c
|
|
@ -2416,9 +2416,9 @@ mmx_pack8888 (CARD8 *image)
|
|||
}
|
||||
|
||||
static __inline__ CARD32
|
||||
loadyv12 (CARD8 *py,
|
||||
CARD8 *pu,
|
||||
CARD8 *pv)
|
||||
loadyuv (CARD8 *py,
|
||||
CARD8 *pu,
|
||||
CARD8 *pv)
|
||||
{
|
||||
INT16 y, u, v;
|
||||
INT32 r, g, b;
|
||||
|
|
@ -2560,7 +2560,7 @@ loadyv12_scanline (ScanlineBuf *slb,
|
|||
|
||||
while (w && (unsigned long) py & 7)
|
||||
{
|
||||
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
|
||||
*((CARD32 *) pd) = loadyuv (py, pu, pv);
|
||||
|
||||
pd += 4;
|
||||
py += 1;
|
||||
|
|
@ -2589,7 +2589,7 @@ loadyv12_scanline (ScanlineBuf *slb,
|
|||
|
||||
while (w)
|
||||
{
|
||||
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
|
||||
*((CARD32 *) pd) = loadyuv (py, pu, pv);
|
||||
|
||||
pd += 4;
|
||||
py += 1;
|
||||
|
|
@ -2606,6 +2606,51 @@ loadyv12_scanline (ScanlineBuf *slb,
|
|||
return slb->line[i];
|
||||
}
|
||||
|
||||
static __inline__ CARD8 *
|
||||
loadyuy2_scanline (ScanlineBuf *slb,
|
||||
int y,
|
||||
CARD8 *src,
|
||||
int stride,
|
||||
int x,
|
||||
int width)
|
||||
{
|
||||
CARD8 *py, *pu, *pv, *pd;
|
||||
int i, w;
|
||||
|
||||
y = _y_to_scanline (slb, y);
|
||||
|
||||
for (i = 0; slb->lock[i]; i++);
|
||||
|
||||
slb->y[i] = y;
|
||||
slb->lock[i] = TRUE;
|
||||
|
||||
py = src + stride * (y >> 0);
|
||||
pu = py + 1;
|
||||
pv = py + 3;
|
||||
|
||||
pd = slb->line[i];
|
||||
|
||||
w = width;
|
||||
|
||||
while (w)
|
||||
{
|
||||
*((CARD32 *) pd) = loadyuv (py, pu, pv);
|
||||
|
||||
pd += 4;
|
||||
py += 2;
|
||||
|
||||
if (w & 1)
|
||||
{
|
||||
pu += 4;
|
||||
pv += 4;
|
||||
}
|
||||
|
||||
w--;
|
||||
}
|
||||
|
||||
return slb->line[i];
|
||||
}
|
||||
|
||||
static __inline__ CARD8
|
||||
interpolate_bilinear (int distx,
|
||||
int idistx,
|
||||
|
|
@ -2857,7 +2902,7 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
|
|||
|
||||
while (w && (unsigned long) py & 7)
|
||||
{
|
||||
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
|
||||
*((CARD32 *) pd) = loadyuv (py, pu, pv);
|
||||
|
||||
pd += 4;
|
||||
py += 1;
|
||||
|
|
@ -2886,7 +2931,7 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
|
|||
|
||||
while (w)
|
||||
{
|
||||
*((CARD32 *) pd) = loadyv12 (py, pu, pv);
|
||||
*((CARD32 *) pd) = loadyuv (py, pu, pv);
|
||||
|
||||
pd += 4;
|
||||
py += 1;
|
||||
|
|
@ -2916,5 +2961,215 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
|
|||
_mm_empty ();
|
||||
}
|
||||
|
||||
/* TODO: MMX code for yuy2 */
|
||||
void
|
||||
fbCompositeSrc_yuy2x8888mmx (CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height)
|
||||
{
|
||||
PictTransform *transform = pSrc->transform;
|
||||
CARD8 *dst, *src;
|
||||
FbBits *srcBits;
|
||||
FbStride srcStride;
|
||||
int srcXoff;
|
||||
int srcYoff;
|
||||
FbBits *dstBits;
|
||||
FbStride dstStride;
|
||||
int dstXoff;
|
||||
int dstYoff;
|
||||
int bpp, offset, w;
|
||||
CARD8 *pd;
|
||||
|
||||
fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, bpp, srcXoff, srcYoff);
|
||||
fbGetDrawable (pDst->pDrawable, dstBits, dstStride, bpp, dstXoff, dstYoff);
|
||||
|
||||
dst = (CARD8 *) dstBits;
|
||||
dstStride *= sizeof (FbBits);
|
||||
|
||||
src = (CARD8 *) srcBits;
|
||||
srcStride *= sizeof (FbBits);
|
||||
|
||||
if (transform)
|
||||
{
|
||||
/* transformation is a Y coordinate flip, this is achieved by
|
||||
moving start offsets for each plane and changing sign of stride */
|
||||
if (pSrc->transform->matrix[0][0] == (1 << 16) &&
|
||||
pSrc->transform->matrix[1][1] == -(1 << 16) &&
|
||||
pSrc->transform->matrix[0][2] == 0 &&
|
||||
pSrc->transform->matrix[1][2] == (pSrc->pDrawable->height << 16))
|
||||
{
|
||||
src = src + (pSrc->pDrawable->height - 1) * srcStride;
|
||||
|
||||
srcStride = -srcStride;
|
||||
|
||||
transform = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dst += dstStride * (yDst + dstYoff) + ((xDst + dstXoff) << 2);
|
||||
|
||||
if (transform)
|
||||
{
|
||||
ScanlineBuf slb;
|
||||
CARD8 _scanline_buf[8192];
|
||||
CARD8 *ps, *ps0, *ps1;
|
||||
int x, x0, y, line, xStep, yStep;
|
||||
int distx, idistx, disty, idisty;
|
||||
int srcEnd = pSrc->pDrawable->width << 16;
|
||||
|
||||
x0 = pSrc->transform->matrix[0][2] + ((xSrc + srcXoff) << 16);
|
||||
y = pSrc->transform->matrix[1][2] + ((ySrc + srcYoff) << 16);
|
||||
|
||||
xStep = pSrc->transform->matrix[0][0];
|
||||
yStep = pSrc->transform->matrix[1][1];
|
||||
|
||||
init_scanline_buffer (&slb,
|
||||
_scanline_buf, sizeof (_scanline_buf),
|
||||
pSrc->pDrawable->width << 2,
|
||||
pSrc->pDrawable->height);
|
||||
|
||||
while (height--)
|
||||
{
|
||||
disty = (y >> 8) & 0xff;
|
||||
idisty = 256 - disty;
|
||||
line = y >> 16;
|
||||
|
||||
ps0 = get_scanline (&slb, line);
|
||||
ps1 = get_scanline (&slb, line + 1);
|
||||
|
||||
if (!ps0)
|
||||
ps0 = loadyuy2_scanline (&slb, line,
|
||||
src, srcStride,
|
||||
0, pSrc->pDrawable->width);
|
||||
|
||||
if (!ps1)
|
||||
ps1 = loadyuy2_scanline (&slb, line + 1,
|
||||
src, srcStride,
|
||||
0, pSrc->pDrawable->width);
|
||||
|
||||
pd = dst;
|
||||
|
||||
x = x0;
|
||||
w = width;
|
||||
|
||||
if (pSrc->filter == PictFilterBilinear)
|
||||
{
|
||||
while (w && x < 0)
|
||||
{
|
||||
interpolate_bilinear_8888 (0, 256, disty, idisty,
|
||||
ps0, ps1, 0, pd);
|
||||
|
||||
x += xStep;
|
||||
pd += 4;
|
||||
w -= 1;
|
||||
}
|
||||
|
||||
while (w && x < srcEnd)
|
||||
{
|
||||
distx = (x >> 8) & 0xff;
|
||||
idistx = 256 - distx;
|
||||
|
||||
interpolate_bilinear_8888 (distx, idistx, disty, idisty,
|
||||
ps0, ps1, (x >> 14) & ~3, pd);
|
||||
|
||||
x += xStep;
|
||||
pd += 4;
|
||||
w -= 1;
|
||||
}
|
||||
|
||||
while (w)
|
||||
{
|
||||
interpolate_bilinear_8888 (256, 0, disty, idisty,
|
||||
ps0, ps1, (x >> 14) & ~3, pd);
|
||||
|
||||
pd += 4;
|
||||
w -= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (w && x < 0)
|
||||
{
|
||||
*(CARD32 *) pd = *(CARD32 *) ps0;
|
||||
|
||||
x += xStep;
|
||||
pd += 4;
|
||||
w -= 1;
|
||||
}
|
||||
|
||||
while (w && x < srcEnd)
|
||||
{
|
||||
*(CARD32 *) pd = ((CARD32 *) ps0)[x >> 16];
|
||||
|
||||
x += xStep;
|
||||
pd += 4;
|
||||
w -= 1;
|
||||
}
|
||||
|
||||
while (w)
|
||||
{
|
||||
*(CARD32 *) pd = ((CARD32 *) ps0)[x >> 16];
|
||||
|
||||
pd += 4;
|
||||
w -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
y += yStep;
|
||||
dst += dstStride;
|
||||
|
||||
release_scanlines (&slb);
|
||||
}
|
||||
|
||||
fini_scanline_buffer (&slb);
|
||||
}
|
||||
else
|
||||
{
|
||||
CARD8 *py, *pu, *pv;
|
||||
|
||||
src += srcStride * (ySrc >> 0) + srcYoff + (xSrc + srcXoff);
|
||||
|
||||
while (height)
|
||||
{
|
||||
py = src;
|
||||
pu = src + 1;
|
||||
pv = src + 3;
|
||||
pd = dst;
|
||||
|
||||
w = width;
|
||||
|
||||
while (w)
|
||||
{
|
||||
*((CARD32 *) pd) = loadyuv (py, pu, pv);
|
||||
|
||||
pd += 4;
|
||||
py += 2;
|
||||
|
||||
if (w & 1)
|
||||
{
|
||||
pu += 4;
|
||||
pv += 4;
|
||||
}
|
||||
|
||||
w--;
|
||||
}
|
||||
|
||||
dst += dstStride;
|
||||
src += srcStride;
|
||||
|
||||
height--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* RENDER */
|
||||
#endif /* USE_MMX */
|
||||
|
|
|
|||
14
fb/fbmmx.h
14
fb/fbmmx.h
|
|
@ -231,4 +231,18 @@ fbCompositeSrc_yv12x8888mmx (CARD8 op,
|
|||
CARD16 width,
|
||||
CARD16 height);
|
||||
|
||||
void
|
||||
fbCompositeSrc_yuy2x8888mmx (CARD8 op,
|
||||
PicturePtr pSrc,
|
||||
PicturePtr pMask,
|
||||
PicturePtr pDst,
|
||||
INT16 xSrc,
|
||||
INT16 ySrc,
|
||||
INT16 xMask,
|
||||
INT16 yMask,
|
||||
INT16 xDst,
|
||||
INT16 yDst,
|
||||
CARD16 width,
|
||||
CARD16 height);
|
||||
|
||||
#endif /* USE_MMX */
|
||||
|
|
|
|||
11
fb/fbpict.c
11
fb/fbpict.c
|
|
@ -874,8 +874,8 @@ fbComposite (CARD8 op,
|
|||
maskAlphaMap = pMask->alphaMap != 0;
|
||||
}
|
||||
|
||||
/* YV12 is only used internally for XVideo */
|
||||
if (pSrc->format == PICT_yv12)
|
||||
/* YUV is only used internally for XVideo */
|
||||
if (pSrc->format == PICT_yv12 || pSrc->format == PICT_yuy2)
|
||||
{
|
||||
#ifdef USE_MMX
|
||||
/* non rotating transformation */
|
||||
|
|
@ -890,7 +890,12 @@ fbComposite (CARD8 op,
|
|||
case PICT_a8r8g8b8:
|
||||
case PICT_x8r8g8b8:
|
||||
if (fbHaveMMX())
|
||||
func = fbCompositeSrc_yv12x8888mmx;
|
||||
{
|
||||
if (pSrc->format == PICT_yv12)
|
||||
func = fbCompositeSrc_yv12x8888mmx;
|
||||
else
|
||||
func = fbCompositeSrc_yuy2x8888mmx;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ xglXvPutImage (ClientPtr client,
|
|||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
PicturePtr pSrc;
|
||||
PictTransform transform;
|
||||
int depth, bpp, noVisual = FALSE;
|
||||
int depth, bpp, stride, noVisual = FALSE;
|
||||
CARD32 format;
|
||||
|
||||
XGL_SCREEN_PRIV (pScreen);
|
||||
|
|
@ -306,11 +306,14 @@ xglXvPutImage (ClientPtr client,
|
|||
XGL_DRAWABLE_PIXMAP (pDrawable);
|
||||
XGL_PIXMAP_PRIV (pPixmap);
|
||||
|
||||
stride = ((srcWidth + 7) & ~7);
|
||||
|
||||
switch (pImage->id) {
|
||||
case GLITZ_FOURCC_YUY2:
|
||||
bpp = depth = 16;
|
||||
format = PICT_yuy2;
|
||||
noVisual = !pScreenPriv->pXvVisual[XGL_XV_FORMAT_YUY2].format.surface;
|
||||
stride *= 2;
|
||||
break;
|
||||
case GLITZ_FOURCC_YV12:
|
||||
depth = bpp = 12;
|
||||
|
|
@ -321,6 +324,7 @@ xglXvPutImage (ClientPtr client,
|
|||
depth = 24;
|
||||
bpp = 32;
|
||||
format = PICT_x8r8g8b8;
|
||||
stride *= 4;
|
||||
break;
|
||||
default:
|
||||
return BadImplementation;
|
||||
|
|
@ -339,7 +343,7 @@ xglXvPutImage (ClientPtr client,
|
|||
srcWidth, srcHeight,
|
||||
depth, bpp, -1, (pointer) data);
|
||||
|
||||
XGL_GET_PIXMAP_PRIV (pPortPriv->pPixmap)->stride = -((srcWidth + 7) & ~7);
|
||||
XGL_GET_PIXMAP_PRIV (pPortPriv->pPixmap)->stride = -stride;
|
||||
|
||||
pPortPriv->pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
|
||||
|
||||
|
|
@ -594,11 +598,6 @@ xglXvInitAdaptors (ScreenPtr pScreen)
|
|||
pAdaptor->nImages = sizeof (xvImages) / sizeof (XvImageRec);
|
||||
pAdaptor->pImages = xvImages;
|
||||
|
||||
/* XXX: Disable YUY2 format as it's not accelerated and the software
|
||||
fallback got issues. */
|
||||
pAdaptor->nImages = sizeof (xvImages) / sizeof (XvImageRec) - 1;
|
||||
pAdaptor->pImages = &xvImages[1];
|
||||
|
||||
/* TODO: Currently no attributes */
|
||||
pAdaptor->nAttributes = 0;
|
||||
pAdaptor->pAttributes = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue