diff options
author | Thomas Hellstrom <thellstrom@vmware.com> | 2011-12-08 13:14:57 +0100 |
---|---|---|
committer | Thomas Hellstrom <thellstrom@vmware.com> | 2011-12-08 17:35:18 +0100 |
commit | afd2f828b8a8b2ccc6ebe4d56104db3d03d08493 (patch) | |
tree | 715291954f0e69f571ab002c22170dca3f1129c5 | |
parent | 121dba0093d24eb0aefa3d27a22f05f85ac66f72 (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>
-rw-r--r-- | vmwgfx/vmwgfx_tex_video.c | 66 |
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, ®, &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; |