summaryrefslogtreecommitdiff
path: root/glamor
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2014-04-06 07:44:20 +0100
committerEric Anholt <eric@anholt.net>2014-06-15 23:20:09 +0100
commit98b6158bc1e32aaca375829452266e013a520e14 (patch)
tree5b95b2aa5a9d1aee35b103d92e9b8b17931a1650 /glamor
parent34884e16bf7c97434e7883d025c6814e083b0def (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.h12
-rw-r--r--glamor/glamor_xv.c104
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)
{