summaryrefslogtreecommitdiff
path: root/vmwgfx
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2011-12-08 13:14:57 +0100
committerThomas Hellstrom <thellstrom@vmware.com>2011-12-08 17:35:18 +0100
commitafd2f828b8a8b2ccc6ebe4d56104db3d03d08493 (patch)
tree715291954f0e69f571ab002c22170dca3f1129c5 /vmwgfx
parent121dba0093d24eb0aefa3d27a22f05f85ac66f72 (diff)
vmwgfx: Reduce system resource usage with textured video
Use U and V textures and corresponding dma buffers that match the size of the input UV data rather than using textures and DMA buffers that match the Y data. This simplifies data copy and reduces the amount of image data transfered to the host by up to 50% (YV12). It also reduces dma buffer- and surface memory usage correspondingly. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Reviewed-by: Jakob Bornecrantz <jakob@vmware.com>
Diffstat (limited to 'vmwgfx')
-rw-r--r--vmwgfx/vmwgfx_tex_video.c66
1 files changed, 48 insertions, 18 deletions
diff --git a/vmwgfx/vmwgfx_tex_video.c b/vmwgfx/vmwgfx_tex_video.c
index 2cc44bd..cc94c20 100644
--- a/vmwgfx/vmwgfx_tex_video.c
+++ b/vmwgfx/vmwgfx_tex_video.c
@@ -294,7 +294,8 @@ query_best_size(ScrnInfoPtr pScrn,
}
static int
-check_yuv_surfaces(struct xorg_xv_port_priv *priv, int width, int height)
+check_yuv_surfaces(struct xorg_xv_port_priv *priv, int id,
+ int width, int height)
{
struct xa_surface **yuv = priv->yuv;
struct vmwgfx_dmabuf **bounce = priv->bounce[priv->current_set];
@@ -303,6 +304,25 @@ check_yuv_surfaces(struct xorg_xv_port_priv *priv, int width, int height)
size_t size;
for (i=0; i<3; ++i) {
+
+ /*
+ * Adjust u,v texture size and DMA buffer to what's required by
+ * the format.
+ */
+ if (i == 1) {
+ switch(id) {
+ case FOURCC_YV12:
+ height /= 2;
+ /* Fall through */
+ case FOURCC_YUY2:
+ case FOURCC_UYVY:
+ width /= 2;
+ break;
+ default:
+ break;
+ }
+ }
+
if (!yuv[i])
yuv[i] = xa_surface_create(priv->xat, width, height, 8,
xa_type_yuv_component,
@@ -392,7 +412,7 @@ copy_packed_data(ScrnInfoPtr pScrn,
int top,
unsigned short w, unsigned short h)
{
- int i, j;
+ int i;
struct vmwgfx_dmabuf **bounce = port->bounce[port->current_set];
char *ymap, *vmap, *umap;
unsigned char y1, y2, u, v;
@@ -431,18 +451,11 @@ copy_packed_data(ScrnInfoPtr pScrn,
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];
- }
- }
- }
+ memcpy(ymap, y, w*h);
+ memcpy(vmap, v, w*h/4);
+ memcpy(umap, u, w*h/4);
break;
+ }
case FOURCC_UYVY:
for (i = 0; i < y_array_size; i +=2 ) {
/* extracting two pixels */
@@ -455,8 +468,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
ymap[yidx++] = y1;
ymap[yidx++] = y2;
umap[uidx++] = u;
- umap[uidx++] = u;
- vmap[vidx++] = v;
vmap[vidx++] = v;
}
break;
@@ -473,8 +484,6 @@ copy_packed_data(ScrnInfoPtr pScrn,
ymap[yidx++] = y1;
ymap[yidx++] = y2;
umap[uidx++] = u;
- umap[uidx++] = u;
- vmap[vidx++] = v;
vmap[vidx++] = v;
}
break;
@@ -509,6 +518,27 @@ copy_packed_data(ScrnInfoPtr pScrn,
srf = port->yuv[i];
buf = bounce[i];
+ if (i == 1) {
+ switch(id) {
+ case FOURCC_YV12:
+ h /= 2;
+ /* Fall through */
+ case FOURCC_YUY2:
+ case FOURCC_UYVY:
+ w /= 2;
+ break;
+ default:
+ break;
+ }
+
+ box.x1 = 0;
+ box.x2 = w;
+ box.y1 = 0;
+ box.y2 = h;
+
+ REGION_RESET(pScrn->pScreen, &reg, &box);
+ }
+
if (xa_surface_handle(srf, &handle, &stride) != 0) {
ret = BadAlloc;
break;
@@ -629,7 +659,7 @@ put_image(ScrnInfoPtr pScrn,
width, height))
return Success;
- ret = check_yuv_surfaces(pPriv, width, height);
+ ret = check_yuv_surfaces(pPriv, id, width, height);
if (ret)
return ret;