Signed-off-by: Eric Anholt <e...@anholt.net> --- hw/kdrive/ephyr/Makefile.am | 5 + hw/kdrive/ephyr/ephyr.c | 4 +- hw/kdrive/ephyr/ephyr.h | 10 ++ hw/kdrive/ephyr/ephyr_glamor_xv.c | 244 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 262 insertions(+), 1 deletion(-) create mode 100644 hw/kdrive/ephyr/ephyr_glamor_xv.c
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index 00a53d0..10c5917 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -35,9 +35,14 @@ XV_SRCS = ephyrvideo.c endif if GLAMOR +if XV +GLAMOR_XV_SRCS = ephyr_glamor_xv.c +endif + GLAMOR_SRCS = \ ephyr_glamor_glx.c \ ephyr_glamor_glx.h \ + $(GLAMOR_XV_SRCS) \ $() endif diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index def50d8..17a862a 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -650,7 +650,9 @@ ephyrInitScreen(ScreenPtr pScreen) #ifdef XV if (!ephyrNoXV) { - if (!ephyrInitVideo(pScreen)) { + if (ephyr_glamor) + ephyr_glamor_xv_init(pScreen); + else if (!ephyrInitVideo(pScreen)) { EPHYR_LOG_ERROR("failed to initialize xvideo\n"); } else { diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 34ce460..609a641 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -221,4 +221,14 @@ void ephyr_glamor_host_paint_rect(ScreenPtr pScreen); Bool ephyrInitVideo(ScreenPtr pScreen); +/* ephyr_glamor_xv.c */ +#ifdef GLAMOR +void ephyr_glamor_xv_init(ScreenPtr screen); +#else /* !GLAMOR */ +static inline void +ephyr_glamor_xv_init(ScreenPtr screen) +{ +} +#endif /* !GLAMOR */ + #endif diff --git a/hw/kdrive/ephyr/ephyr_glamor_xv.c b/hw/kdrive/ephyr/ephyr_glamor_xv.c new file mode 100644 index 0000000..3fc9747 --- /dev/null +++ b/hw/kdrive/ephyr/ephyr_glamor_xv.c @@ -0,0 +1,244 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include <kdrive-config.h> +#endif + +#include "kdrive.h" +#include "kxv.h" +#include "ephyr.h" +#include "glamor_priv.h" + +#include <X11/extensions/Xv.h> +#include "fourcc.h" + +#define NUM_FORMATS 3 + +static KdVideoFormatRec Formats[NUM_FORMATS] = { + {15, TrueColor}, {16, TrueColor}, {24, TrueColor} +}; + +static void +ephyr_glamor_xv_stop_video(KdScreenInfo *screen, void *data, Bool cleanup) +{ + if (!cleanup) + return; + + glamor_xv_stop_video(data); +} + +static int +ephyr_glamor_xv_set_port_attribute(KdScreenInfo *screen, + Atom attribute, INT32 value, void *data) +{ + return glamor_xv_set_port_attribute(data, attribute, value); +} + +static int +ephyr_glamor_xv_get_port_attribute(KdScreenInfo *screen, + Atom attribute, INT32 *value, void *data) +{ + return glamor_xv_get_port_attribute(data, attribute, value); +} + +static void +ephyr_glamor_xv_query_best_size(KdScreenInfo *screen, + Bool motion, + short vid_w, short vid_h, + short drw_w, short drw_h, + unsigned int *p_w, unsigned int *p_h, + void *data) +{ + *p_w = drw_w; + *p_h = drw_h; +} + +static int +ephyr_glamor_xv_query_image_attributes(KdScreenInfo *screen, + int id, + unsigned short *w, unsigned short *h, + int *pitches, int *offsets) +{ + return glamor_xv_query_image_attributes(id, w, h, pitches, offsets); +} + +static int +ephyr_glamor_xv_put_image(KdScreenInfo *screen, + 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 *data) +{ + ScreenPtr pScreen = pDrawable->pScreen; + glamor_port_private *port_priv = (glamor_port_private *) data; + 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 +ephyr_glamor_xv_init(ScreenPtr screen) +{ + KdVideoAdaptorRec *adaptor; + glamor_port_private *port_privates; + KdVideoEncodingRec encoding = { + 0, + "XV_IMAGE", + /* These sizes should probably be GL_MAX_TEXTURE_SIZE instead + * of 2048, but our context isn't set up yet. + */ + 2048, 2048, + {1, 1} + }; + int i; + + glamor_xv_core_init(screen); + + adaptor = xnfcalloc(1, sizeof(*adaptor)); + + adaptor->name = "glamor textured video"; + adaptor->type = XvWindowMask | XvInputMask | XvImageMask; + adaptor->flags = 0; + adaptor->nEncodings = 1; + adaptor->pEncodings = &encoding; + + adaptor->pFormats = Formats; + adaptor->nFormats = NUM_FORMATS; + + adaptor->nPorts = 16; /* Some absurd number */ + port_privates = xnfcalloc(adaptor->nPorts, + sizeof(glamor_port_private)); + adaptor->pPortPrivates = xnfcalloc(adaptor->nPorts, + sizeof(glamor_port_private *)); + for (i = 0; i < adaptor->nPorts; i++) { + adaptor->pPortPrivates[i].ptr = &port_privates[i]; + glamor_xv_init_port(&port_privates[i]); + } + + adaptor->pAttributes = glamor_xv_attributes; + adaptor->nAttributes = glamor_xv_num_attributes; + + adaptor->pImages = glamor_xv_images; + adaptor->nImages = glamor_xv_num_images; + + adaptor->StopVideo = ephyr_glamor_xv_stop_video; + adaptor->SetPortAttribute = ephyr_glamor_xv_set_port_attribute; + adaptor->GetPortAttribute = ephyr_glamor_xv_get_port_attribute; + adaptor->QueryBestSize = ephyr_glamor_xv_query_best_size; + adaptor->PutImage = ephyr_glamor_xv_put_image; + adaptor->QueryImageAttributes = ephyr_glamor_xv_query_image_attributes; + + KdXVScreenInit(screen, adaptor, 1); +} -- 1.9.2 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel