diff options
author | Eric Anholt <eric@anholt.net> | 2014-04-06 07:44:20 +0100 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2014-06-15 23:20:09 +0100 |
commit | 98b6158bc1e32aaca375829452266e013a520e14 (patch) | |
tree | 5b95b2aa5a9d1aee35b103d92e9b8b17931a1650 /glamor | |
parent | 34884e16bf7c97434e7883d025c6814e083b0def (diff) |
glamor: Share code for put_image handling.
The difference between the two is that XF86 has the clip helper that
lets you upload less data when rendering video that's clipped. I
don't think that's really worth the trouble, especially in a world of
compositors, so I've dropped it to get to shared code.
It turns out the clipping code was broken on xf86-video-intel anyway.
To reproduce, run without a compositor, and use another window to clip
the top half of your XV output on the glamor XV adaptor: the rendering
got confused about which half of the window was being drawn to.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Diffstat (limited to 'glamor')
-rw-r--r-- | glamor/glamor_priv.h | 12 | ||||
-rw-r--r-- | glamor/glamor_xv.c | 104 |
2 files changed, 116 insertions, 0 deletions
diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h index a0b1062d7..535d0ca08 100644 --- a/glamor/glamor_priv.h +++ b/glamor/glamor_priv.h @@ -1068,6 +1068,18 @@ int glamor_xv_get_port_attribute(glamor_port_private *port_priv, int glamor_xv_query_image_attributes(int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets); +int glamor_xv_put_image(glamor_port_private *port_priv, + DrawablePtr pDrawable, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes); void glamor_xv_core_init(ScreenPtr screen); void glamor_xv_render(glamor_port_private *port_priv); diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c index 4aaa866c5..1e8bdb885 100644 --- a/glamor/glamor_xv.c +++ b/glamor/glamor_xv.c @@ -380,6 +380,110 @@ glamor_xv_render(glamor_port_private *port_priv) DamageDamageRegion(port_priv->pDraw, &port_priv->clip); } +int +glamor_xv_put_image(glamor_port_private *port_priv, + DrawablePtr pDrawable, + short src_x, short src_y, + short drw_x, short drw_y, + short src_w, short src_h, + short drw_w, short drw_h, + int id, + unsigned char *buf, + short width, + short height, + Bool sync, + RegionPtr clipBoxes) +{ + ScreenPtr pScreen = pDrawable->pScreen; + int srcPitch, srcPitch2; + int top, nlines; + int s2offset, s3offset, tmp; + + s2offset = s3offset = srcPitch2 = 0; + + srcPitch = width; + srcPitch2 = width >> 1; + + if (!port_priv->src_pix[0] || + (width != port_priv->src_pix_w || height != port_priv->src_pix_h)) { + int i; + + for (i = 0; i < 3; i++) + if (port_priv->src_pix[i]) + glamor_destroy_pixmap(port_priv->src_pix[i]); + + port_priv->src_pix[0] = + glamor_create_pixmap(pScreen, width, height, 8, 0); + port_priv->src_pix[1] = + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix[2] = + glamor_create_pixmap(pScreen, width >> 1, height >> 1, 8, 0); + port_priv->src_pix_w = width; + port_priv->src_pix_h = height; + + if (!port_priv->src_pix[0] || !port_priv->src_pix[1] || + !port_priv->src_pix[2]) + return BadAlloc; + } + + top = (src_y) & ~1; + nlines = (src_y + height) - top; + + switch (id) { + case FOURCC_YV12: + case FOURCC_I420: + s2offset = srcPitch * height; + s3offset = s2offset + (srcPitch2 * ((height + 1) >> 1)); + s2offset += ((top >> 1) * srcPitch2); + s3offset += ((top >> 1) * srcPitch2); + if (id == FOURCC_YV12) { + tmp = s2offset; + s2offset = s3offset; + s3offset = tmp; + } + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[0], + 0, 0, srcPitch, nlines, + port_priv->src_pix[0]->devKind, + buf + (top * srcPitch), 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[1], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[1]->devKind, + buf + s2offset, 0); + + glamor_upload_sub_pixmap_to_texture(port_priv->src_pix[2], + 0, 0, srcPitch2, (nlines + 1) >> 1, + port_priv->src_pix[2]->devKind, + buf + s3offset, 0); + break; + default: + return BadMatch; + } + + if (pDrawable->type == DRAWABLE_WINDOW) + port_priv->pPixmap = pScreen->GetWindowPixmap((WindowPtr) pDrawable); + else + port_priv->pPixmap = (PixmapPtr) pDrawable; + + if (!RegionEqual(&port_priv->clip, clipBoxes)) { + RegionCopy(&port_priv->clip, clipBoxes); + } + + port_priv->src_x = src_x; + port_priv->src_y = src_y; + port_priv->src_w = src_w; + port_priv->src_h = src_h; + port_priv->dst_w = drw_w; + port_priv->dst_h = drw_h; + port_priv->drw_x = drw_x; + port_priv->drw_y = drw_y; + port_priv->w = width; + port_priv->h = height; + port_priv->pDraw = pDrawable; + glamor_xv_render(port_priv); + return Success; +} + void glamor_xv_init_port(glamor_port_private *port_priv) { |