st/xorg: fix yv12 plus some cleanups in the upload code
This commit is contained in:
@@ -213,17 +213,67 @@ check_yuv_textures(struct xorg_xv_port_priv *priv, int width, int height)
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
query_image_attributes(ScrnInfoPtr pScrn,
|
||||
int id,
|
||||
unsigned short *w, unsigned short *h,
|
||||
int *pitches, int *offsets)
|
||||
{
|
||||
int size, tmp;
|
||||
|
||||
if (*w > IMAGE_MAX_WIDTH)
|
||||
*w = IMAGE_MAX_WIDTH;
|
||||
if (*h > IMAGE_MAX_HEIGHT)
|
||||
*h = IMAGE_MAX_HEIGHT;
|
||||
|
||||
*w = (*w + 1) & ~1;
|
||||
if (offsets)
|
||||
offsets[0] = 0;
|
||||
|
||||
switch (id) {
|
||||
case FOURCC_YV12:
|
||||
*h = (*h + 1) & ~1;
|
||||
size = (*w + 3) & ~3;
|
||||
if (pitches) {
|
||||
pitches[0] = size;
|
||||
}
|
||||
size *= *h;
|
||||
if (offsets) {
|
||||
offsets[1] = size;
|
||||
}
|
||||
tmp = ((*w >> 1) + 3) & ~3;
|
||||
if (pitches) {
|
||||
pitches[1] = pitches[2] = tmp;
|
||||
}
|
||||
tmp *= (*h >> 1);
|
||||
size += tmp;
|
||||
if (offsets) {
|
||||
offsets[2] = size;
|
||||
}
|
||||
size += tmp;
|
||||
break;
|
||||
case FOURCC_UYVY:
|
||||
case FOURCC_YUY2:
|
||||
default:
|
||||
size = *w << 1;
|
||||
if (pitches)
|
||||
pitches[0] = size;
|
||||
size *= *h;
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
copy_packed_data(ScrnInfoPtr pScrn,
|
||||
struct xorg_xv_port_priv *port,
|
||||
int id,
|
||||
unsigned char *buf,
|
||||
int srcPitch,
|
||||
int left,
|
||||
int top,
|
||||
int w, int h)
|
||||
unsigned short w, unsigned short h)
|
||||
{
|
||||
unsigned char *src;
|
||||
int i, j;
|
||||
struct pipe_texture **dst = port->yuv[port->current_set];
|
||||
struct pipe_transfer *ytrans, *utrans, *vtrans;
|
||||
@@ -233,8 +283,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
|
||||
int yidx, uidx, vidx;
|
||||
int y_array_size = w * h;
|
||||
|
||||
src = buf + (top * srcPitch) + (left << 1);
|
||||
|
||||
ytrans = screen->get_tex_transfer(screen, dst[0],
|
||||
0, 0, 0,
|
||||
PIPE_TRANSFER_WRITE,
|
||||
@@ -256,15 +304,22 @@ copy_packed_data(ScrnInfoPtr pScrn,
|
||||
|
||||
switch (id) {
|
||||
case FOURCC_YV12: {
|
||||
for (i = 0; i < w; ++i) {
|
||||
for (j = 0; j < h; ++j) {
|
||||
/*XXX use src? */
|
||||
y1 = buf[j*w + i];
|
||||
u = buf[(j/2) * (w/2) + i/2 + y_array_size];
|
||||
v = buf[(j/2) * (w/2) + i/2 + y_array_size + y_array_size/4];
|
||||
ymap[yidx++] = y1;
|
||||
umap[uidx++] = u;
|
||||
vmap[vidx++] = v;
|
||||
int pitches[3], offsets[3];
|
||||
unsigned char *y, *u, *v;
|
||||
query_image_attributes(pScrn, FOURCC_YV12,
|
||||
&w, &h, pitches, offsets);
|
||||
|
||||
y = buf + offsets[0];
|
||||
v = buf + offsets[1];
|
||||
u = buf + offsets[2];
|
||||
for (i = 0; i < h; ++i) {
|
||||
for (j = 0; j < w; ++j) {
|
||||
int yoffset = (w*i+j);
|
||||
int ii = (i|1), jj = (j|1);
|
||||
int vuoffset = (w/2)*(ii/2) + (jj/2);
|
||||
ymap[yidx++] = y[yoffset];
|
||||
umap[uidx++] = u[vuoffset];
|
||||
vmap[vidx++] = v[vuoffset];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -511,7 +566,6 @@ put_image(ScrnInfoPtr pScrn,
|
||||
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
|
||||
PixmapPtr pPixmap;
|
||||
INT32 x1, x2, y1, y2;
|
||||
int srcPitch;
|
||||
BoxRec dstBox;
|
||||
int ret;
|
||||
|
||||
@@ -530,21 +584,12 @@ put_image(ScrnInfoPtr pScrn,
|
||||
width, height))
|
||||
return Success;
|
||||
|
||||
switch (id) {
|
||||
case FOURCC_UYVY:
|
||||
case FOURCC_YUY2:
|
||||
case FOURCC_YV12:
|
||||
default:
|
||||
srcPitch = width << 1;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = check_yuv_textures(pPriv, width, height);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
copy_packed_data(pScrn, pPriv, id, buf, srcPitch,
|
||||
copy_packed_data(pScrn, pPriv, id, buf,
|
||||
src_x, src_y, width, height);
|
||||
|
||||
if (pDraw->type == DRAWABLE_WINDOW) {
|
||||
@@ -562,38 +607,6 @@ put_image(ScrnInfoPtr pScrn,
|
||||
return Success;
|
||||
}
|
||||
|
||||
static int
|
||||
query_image_attributes(ScrnInfoPtr pScrn,
|
||||
int id,
|
||||
unsigned short *w, unsigned short *h,
|
||||
int *pitches, int *offsets)
|
||||
{
|
||||
int size;
|
||||
|
||||
if (*w > IMAGE_MAX_WIDTH)
|
||||
*w = IMAGE_MAX_WIDTH;
|
||||
if (*h > IMAGE_MAX_HEIGHT)
|
||||
*h = IMAGE_MAX_HEIGHT;
|
||||
|
||||
*w = (*w + 1) & ~1;
|
||||
if (offsets)
|
||||
offsets[0] = 0;
|
||||
|
||||
switch (id) {
|
||||
case FOURCC_UYVY:
|
||||
case FOURCC_YUY2:
|
||||
case FOURCC_YV12:
|
||||
default:
|
||||
size = *w << 1;
|
||||
if (pitches)
|
||||
pitches[0] = size;
|
||||
size *= *h;
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static struct xorg_xv_port_priv *
|
||||
port_priv_create(struct xorg_renderer *r)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user