[PATCH 5/8] glamor: Split the XV code into XF86-dependent parts and generic.
walter harms
wharms at bfs.de
Tue May 6 00:23:45 PDT 2014
Am 05.05.2014 22:09, schrieb Eric Anholt:
> I want to expose this from Xephyr as well, both to be able to test XV
> changes rapidly, and beause the XV passthrough to the host's overlay
> really doesn't work out well when we glXSwapBuffers() over the
> colorkey.
>
> Signed-off-by: Eric Anholt <eric at anholt.net>
> ---
> glamor/Makefile.am | 1 +
> glamor/glamor_priv.h | 19 +-
> glamor/glamor_xv.c | 337 +++++++--------------------------
> hw/xfree86/glamor_egl/Makefile.am | 3 +-
> hw/xfree86/glamor_egl/glamor_xf86_xv.c | 287 ++++++++++++++++++++++++++++
> 5 files changed, 375 insertions(+), 272 deletions(-)
> create mode 100644 hw/xfree86/glamor_egl/glamor_xf86_xv.c
>
> diff --git a/glamor/Makefile.am b/glamor/Makefile.am
> index bde58b6..a3dcb18 100644
> --- a/glamor/Makefile.am
> +++ b/glamor/Makefile.am
> @@ -46,6 +46,7 @@ libglamor_la_SOURCES = \
> glamor_fbo.c\
> glamor_compositerects.c\
> glamor_utils.h\
> + glamor_xv.c \
> glamor.h
>
> libglamor_egl_stubs_la_SOURCES = glamor_egl_stubs.c
> diff --git a/glamor/glamor_priv.h b/glamor/glamor_priv.h
> index a2a21fc..dfa2cfa 100644
> --- a/glamor/glamor_priv.h
> +++ b/glamor/glamor_priv.h
> @@ -34,6 +34,7 @@
> #define NDEBUG
> #endif
> #include "glamor.h"
> +#include "xvdix.h"
>
> #include <epoxy/gl.h>
> #if GLAMOR_HAS_GBM
> @@ -1036,8 +1037,22 @@ typedef struct {
> int src_pix_w, src_pix_h;
> } glamor_port_private;
>
> -void glamor_init_xv_shader(ScreenPtr screen);
> -void glamor_fini_xv_shader(ScreenPtr screen);
> +extern XvAttributeRec glamor_xv_attributes[];
> +extern int glamor_xv_num_attributes;
> +extern XvImageRec glamor_xv_images[];
> +extern int glamor_xv_num_images;
> +
> +void glamor_xv_init_port(glamor_port_private *port_priv);
> +void glamor_xv_stop_video(glamor_port_private *port_priv);
> +int glamor_xv_set_port_attribute(glamor_port_private *port_priv,
> + Atom attribute, INT32 value);
> +int glamor_xv_get_port_attribute(glamor_port_private *port_priv,
> + Atom attribute, INT32 *value);
> +int glamor_xv_query_image_attributes(int id,
> + unsigned short *w, unsigned short *h,
> + int *pitches, int *offsets);
> +void glamor_xv_core_init(ScreenPtr screen);
> +void glamor_xv_render(glamor_port_private *port_priv);
>
> #include"glamor_utils.h"
>
> diff --git a/glamor/glamor_xv.c b/glamor/glamor_xv.c
> index 369b02b..4aaa866 100644
> --- a/glamor/glamor_xv.c
> +++ b/glamor/glamor_xv.c
> @@ -36,12 +36,10 @@
> #include <dix-config.h>
> #endif
>
> -#include "xf86xv.h"
> -#define GLAMOR_FOR_XORG
> #include "glamor_priv.h"
>
> #include <X11/extensions/Xv.h>
> -#include "fourcc.h"
> +#include "../hw/xfree86/common/fourcc.h"
> /* Reference color space transform data */
> typedef struct tagREF_TRANSFORM {
> float RefLuma;
> @@ -90,7 +88,28 @@ static const char *xv_ps = GLAMOR_DEFAULT_PRECISION
> "gl_FragColor = temp1;\n"
> "}\n";
>
> -void
> +#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
> +
> +XvAttributeRec glamor_xv_attributes[] = {
> + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_BRIGHTNESS"},
> + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_CONTRAST"},
> + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_SATURATION"},
> + {XvSettable | XvGettable, -1000, 1000, (char *)"XV_HUE"},
> + {XvSettable | XvGettable, 0, 1, (char *)"XV_COLORSPACE"},
> + {0, 0, 0, NULL}
> +};
> +int glamor_xv_num_attributes = ARRAY_SIZE(glamor_xv_attributes) - 1;
you should decide for one version. Either use an upperlimit (glamor_xv_num_attributes)
or and terminating symbol like NULL/0. If you use the first you can remove glamor_xv_num_attributes,
the second can eliminate {0, 0, 0, NULL}.
just my cents, again
re,
wh
> +
> +Atom glamorBrightness, glamorContrast, glamorSaturation, glamorHue,
> + glamorColorspace, glamorGamma;
> +
> +XvImageRec glamor_xv_images[] = {
> + XVIMAGE_YV12,
> + XVIMAGE_I420,
> +};
> +int glamor_xv_num_images = ARRAY_SIZE(glamor_xv_images);
> +
> +static void
> glamor_init_xv_shader(ScreenPtr screen)
> {
> glamor_screen_private *glamor_priv;
> @@ -113,43 +132,12 @@ glamor_init_xv_shader(ScreenPtr screen)
> }
>
> #define ClipValue(v,min,max) ((v) < (min) ? (min) : (v) > (max) ? (max) : (v))
> -#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
> -
> -static Atom xvBrightness, xvContrast, xvSaturation, xvHue, xvColorspace,
> - xvGamma;
> -
> -#define NUM_ATTRIBUTES 5
> -static XF86AttributeRec Attributes_glamor[NUM_ATTRIBUTES + 1] = {
> - {XvSettable | XvGettable, -1000, 1000, "XV_BRIGHTNESS"},
> - {XvSettable | XvGettable, -1000, 1000, "XV_CONTRAST"},
> - {XvSettable | XvGettable, -1000, 1000, "XV_SATURATION"},
> - {XvSettable | XvGettable, -1000, 1000, "XV_HUE"},
> - {XvSettable | XvGettable, 0, 1, "XV_COLORSPACE"},
> - {0, 0, 0, NULL}
> -};
> -
> -#define NUM_FORMATS 3
> -
> -static XF86VideoFormatRec Formats[NUM_FORMATS] = {
> - {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
> -};
> -
> -#define NUM_IMAGES 2
>
> -static XF86ImageRec Images[NUM_IMAGES] = {
> - XVIMAGE_YV12,
> - XVIMAGE_I420,
> -};
> -
> -static void
> -glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
> +void
> +glamor_xv_stop_video(glamor_port_private *port_priv)
> {
> - glamor_port_private *port_priv = (glamor_port_private *) data;
> int i;
>
> - if (!cleanup)
> - return;
> -
> for (i = 0; i < 3; i++) {
> if (port_priv->src_pix[i]) {
> glamor_destroy_pixmap(port_priv->src_pix[i]);
> @@ -158,46 +146,42 @@ glamor_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
> }
> }
>
> -static int
> -glamor_xv_set_port_attribute(ScrnInfoPtr pScrn,
> - Atom attribute, INT32 value, void *data)
> +int
> +glamor_xv_set_port_attribute(glamor_port_private *port_priv,
> + Atom attribute, INT32 value)
> {
> - glamor_port_private *port_priv = (glamor_port_private *) data;
> -
> - if (attribute == xvBrightness)
> + if (attribute == glamorBrightness)
> port_priv->brightness = ClipValue(value, -1000, 1000);
> - else if (attribute == xvHue)
> + else if (attribute == glamorHue)
> port_priv->hue = ClipValue(value, -1000, 1000);
> - else if (attribute == xvContrast)
> + else if (attribute == glamorContrast)
> port_priv->contrast = ClipValue(value, -1000, 1000);
> - else if (attribute == xvSaturation)
> + else if (attribute == glamorSaturation)
> port_priv->saturation = ClipValue(value, -1000, 1000);
> - else if (attribute == xvGamma)
> + else if (attribute == glamorGamma)
> port_priv->gamma = ClipValue(value, 100, 10000);
> - else if (attribute == xvColorspace)
> + else if (attribute == glamorColorspace)
> port_priv->transform_index = ClipValue(value, 0, 1);
> else
> return BadMatch;
> return Success;
> }
>
> -static int
> -glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
> - Atom attribute, INT32 *value, void *data)
> +int
> +glamor_xv_get_port_attribute(glamor_port_private *port_priv,
> + Atom attribute, INT32 *value)
> {
> - glamor_port_private *port_priv = (glamor_port_private *) data;
> -
> - if (attribute == xvBrightness)
> + if (attribute == glamorBrightness)
> *value = port_priv->brightness;
> - else if (attribute == xvHue)
> + else if (attribute == glamorHue)
> *value = port_priv->hue;
> - else if (attribute == xvContrast)
> + else if (attribute == glamorContrast)
> *value = port_priv->contrast;
> - else if (attribute == xvSaturation)
> + else if (attribute == glamorSaturation)
> *value = port_priv->saturation;
> - else if (attribute == xvGamma)
> + else if (attribute == glamorGamma)
> *value = port_priv->gamma;
> - else if (attribute == xvColorspace)
> + else if (attribute == glamorColorspace)
> *value = port_priv->transform_index;
> else
> return BadMatch;
> @@ -205,20 +189,8 @@ glamor_xv_get_port_attribute(ScrnInfoPtr pScrn,
> return Success;
> }
>
> -static void
> -glamor_xv_query_best_size(ScrnInfoPtr pScrn,
> - 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
> -glamor_xv_query_image_attributes(ScrnInfoPtr pScrn,
> - int id,
> +int
> +glamor_xv_query_image_attributes(int id,
> unsigned short *w, unsigned short *h,
> int *pitches, int *offsets)
> {
> @@ -258,8 +230,8 @@ static REF_TRANSFORM trans[2] = {
> {1.1643, 0.0, 1.7927, -0.2132, -0.5329, 2.1124, 0.0} /* BT.709 */
> };
>
> -static void
> -glamor_display_textured_video(glamor_port_private *port_priv)
> +void
> +glamor_xv_render(glamor_port_private *port_priv)
> {
> ScreenPtr screen = port_priv->pPixmap->drawable.pScreen;
> glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
> @@ -282,6 +254,9 @@ glamor_display_textured_video(glamor_port_private *port_priv)
> int ref = port_priv->transform_index;
> GLint uloc, sampler_loc;
>
> + if (!glamor_priv->xv_prog)
> + glamor_init_xv_shader(screen);
> +
> cont = RTFContrast(port_priv->contrast);
> bright = RTFBrightness(port_priv->brightness);
> gamma = (float) port_priv->gamma / 1000.0;
> @@ -405,202 +380,26 @@ glamor_display_textured_video(glamor_port_private *port_priv)
> DamageDamageRegion(port_priv->pDraw, &port_priv->clip);
> }
>
> -static int
> -glamor_xv_put_image(ScrnInfoPtr pScrn,
> - 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, DrawablePtr pDrawable)
> +void
> +glamor_xv_init_port(glamor_port_private *port_priv)
> {
> - ScreenPtr screen = pDrawable->pScreen;
> - glamor_port_private *port_priv = (glamor_port_private *) data;
> - INT32 x1, x2, y1, y2;
> - int srcPitch, srcPitch2;
> - BoxRec dstBox;
> - int top, nlines;
> - int s2offset, s3offset, tmp;
> -
> - s2offset = s3offset = srcPitch2 = 0;
> -
> - /* Clip */
> - x1 = src_x;
> - x2 = src_x + src_w;
> - y1 = src_y;
> - y2 = src_y + src_h;
> -
> - dstBox.x1 = drw_x;
> - dstBox.x2 = drw_x + drw_w;
> - dstBox.y1 = drw_y;
> - dstBox.y2 = drw_y + drw_h;
> - if (!xf86XVClipVideoHelper
> - (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
> - return Success;
> -
> - if ((x1 >= x2) || (y1 >= y2))
> - return Success;
> -
> - 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(screen, width, height, 8, 0);
> - port_priv->src_pix[1] =
> - glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
> - port_priv->src_pix[2] =
> - glamor_create_pixmap(screen, 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 = (y1 >> 16) & ~1;
> - nlines = ((y2 + 0xffff) >> 16) - 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 = (*screen->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_display_textured_video(port_priv);
> - return Success;
> + port_priv->brightness = 0;
> + port_priv->contrast = 0;
> + port_priv->saturation = 0;
> + port_priv->hue = 0;
> + port_priv->gamma = 1000;
> + port_priv->transform_index = 0;
> +
> + REGION_NULL(pScreen, &port_priv->clip);
> }
>
> -static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
> - {
> - 0,
> - "XV_IMAGE",
> - 8192, 8192,
> - {1, 1}
> - }
> -};
> -
> -XF86VideoAdaptorPtr
> -glamor_xv_init(ScreenPtr screen, int num_texture_ports)
> +void
> +glamor_xv_core_init(ScreenPtr screen)
> {
> - glamor_port_private *port_priv;
> - XF86VideoAdaptorPtr adapt;
> - int i;
> -
> - glamor_init_xv_shader(screen);
> -
> - adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
> - (sizeof(glamor_port_private) + sizeof(DevUnion)));
> - if (adapt == NULL)
> - return NULL;
> -
> - xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
> - xvContrast = MAKE_ATOM("XV_CONTRAST");
> - xvSaturation = MAKE_ATOM("XV_SATURATION");
> - xvHue = MAKE_ATOM("XV_HUE");
> - xvGamma = MAKE_ATOM("XV_GAMMA");
> - xvColorspace = MAKE_ATOM("XV_COLORSPACE");
> -
> - adapt->type = XvWindowMask | XvInputMask | XvImageMask;
> - adapt->flags = 0;
> - adapt->name = "GLAMOR Textured Video";
> - adapt->nEncodings = 1;
> - adapt->pEncodings = DummyEncodingGLAMOR;
> -
> - adapt->nFormats = NUM_FORMATS;
> - adapt->pFormats = Formats;
> - adapt->nPorts = num_texture_ports;
> - adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
> -
> - adapt->pAttributes = Attributes_glamor;
> - adapt->nAttributes = NUM_ATTRIBUTES;
> -
> - port_priv =
> - (glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
> - adapt->pImages = Images;
> - adapt->nImages = NUM_IMAGES;
> - adapt->PutVideo = NULL;
> - adapt->PutStill = NULL;
> - adapt->GetVideo = NULL;
> - adapt->GetStill = NULL;
> - adapt->StopVideo = glamor_xv_stop_video;
> - adapt->SetPortAttribute = glamor_xv_set_port_attribute;
> - adapt->GetPortAttribute = glamor_xv_get_port_attribute;
> - adapt->QueryBestSize = glamor_xv_query_best_size;
> - adapt->PutImage = glamor_xv_put_image;
> - adapt->ReputImage = NULL;
> - adapt->QueryImageAttributes = glamor_xv_query_image_attributes;
> -
> - for (i = 0; i < num_texture_ports; i++) {
> - glamor_port_private *pPriv = &port_priv[i];
> -
> - pPriv->brightness = 0;
> - pPriv->contrast = 0;
> - pPriv->saturation = 0;
> - pPriv->hue = 0;
> - pPriv->gamma = 1000;
> - pPriv->transform_index = 0;
> -
> - REGION_NULL(pScreen, &pPriv->clip);
> -
> - adapt->pPortPrivates[i].ptr = (void *) (pPriv);
> - }
> - return adapt;
> + glamorBrightness = MAKE_ATOM("XV_BRIGHTNESS");
> + glamorContrast = MAKE_ATOM("XV_CONTRAST");
> + glamorSaturation = MAKE_ATOM("XV_SATURATION");
> + glamorHue = MAKE_ATOM("XV_HUE");
> + glamorGamma = MAKE_ATOM("XV_GAMMA");
> + glamorColorspace = MAKE_ATOM("XV_COLORSPACE");
> }
> diff --git a/hw/xfree86/glamor_egl/Makefile.am b/hw/xfree86/glamor_egl/Makefile.am
> index 85e1c0c..e697c82 100644
> --- a/hw/xfree86/glamor_egl/Makefile.am
> +++ b/hw/xfree86/glamor_egl/Makefile.am
> @@ -24,7 +24,7 @@ module_LTLIBRARIES = libglamoregl.la
> libglamoregl_la_SOURCES = \
> $(top_srcdir)/glamor/glamor_egl.c \
> $(top_srcdir)/glamor/glamor_eglmodule.c \
> - $(top_srcdir)/glamor/glamor_xv.c \
> + glamor_xf86_xv.c \
> $()
>
> libglamoregl_la_LDFLAGS = \
> @@ -38,6 +38,7 @@ libglamoregl_la_LIBADD = \
>
> AM_CPPFLAGS = $(XORG_INCS) \
> -I$(top_srcdir)/dri3 \
> + -I$(top_srcdir)/glamor \
> $()
>
> AM_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) $(GLAMOR_CFLAGS) $(GBM_CFLAGS)
> diff --git a/hw/xfree86/glamor_egl/glamor_xf86_xv.c b/hw/xfree86/glamor_egl/glamor_xf86_xv.c
> new file mode 100644
> index 0000000..a54c9a9
> --- /dev/null
> +++ b/hw/xfree86/glamor_egl/glamor_xf86_xv.c
> @@ -0,0 +1,287 @@
> +/*
> + * Copyright © 2013 Red Hat
> + *
> + * 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.
> + *
> + * Authors:
> + * Dave Airlie <airlied at redhat.com>
> + *
> + * some code is derived from the xf86-video-ati radeon driver, mainly
> + * the calculations.
> + */
> +
> +/** @file glamor_xf86_xv.c
> + *
> + * This implements the XF86 XV interface, and calls into glamor core
> + * for its support of the suspiciously similar XF86 and Kdrive
> + * device-dependent XV interfaces.
> + */
> +
> +#ifdef HAVE_DIX_CONFIG_H
> +#include <dix-config.h>
> +#endif
> +
> +#define GLAMOR_FOR_XORG
> +#include "glamor_priv.h"
> +
> +#include <X11/extensions/Xv.h>
> +#include "fourcc.h"
> +
> +#define NUM_FORMATS 3
> +
> +static XF86VideoFormatRec Formats[NUM_FORMATS] = {
> + {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
> +};
> +
> +static void
> +glamor_xf86_xv_stop_video(ScrnInfoPtr pScrn, void *data, Bool cleanup)
> +{
> + if (!cleanup)
> + return;
> +
> + glamor_xv_stop_video(data);
> +}
> +
> +static int
> +glamor_xf86_xv_set_port_attribute(ScrnInfoPtr pScrn,
> + Atom attribute, INT32 value, void *data)
> +{
> + return glamor_xv_set_port_attribute(data, attribute, value);
> +}
> +
> +static int
> +glamor_xf86_xv_get_port_attribute(ScrnInfoPtr pScrn,
> + Atom attribute, INT32 *value, void *data)
> +{
> + return glamor_xv_get_port_attribute(data, attribute, value);
> +}
> +
> +static void
> +glamor_xf86_xv_query_best_size(ScrnInfoPtr pScrn,
> + 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
> +glamor_xf86_xv_query_image_attributes(ScrnInfoPtr pScrn,
> + 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
> +glamor_xf86_xv_put_image(ScrnInfoPtr pScrn,
> + 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, DrawablePtr pDrawable)
> +{
> + ScreenPtr screen = pDrawable->pScreen;
> + glamor_port_private *port_priv = (glamor_port_private *) data;
> + INT32 x1, x2, y1, y2;
> + int srcPitch, srcPitch2;
> + BoxRec dstBox;
> + int top, nlines;
> + int s2offset, s3offset, tmp;
> +
> + s2offset = s3offset = srcPitch2 = 0;
> +
> + /* Clip */
> + x1 = src_x;
> + x2 = src_x + src_w;
> + y1 = src_y;
> + y2 = src_y + src_h;
> +
> + dstBox.x1 = drw_x;
> + dstBox.x2 = drw_x + drw_w;
> + dstBox.y1 = drw_y;
> + dstBox.y2 = drw_y + drw_h;
> + if (!xf86XVClipVideoHelper
> + (&dstBox, &x1, &x2, &y1, &y2, clipBoxes, width, height))
> + return Success;
> +
> + if ((x1 >= x2) || (y1 >= y2))
> + return Success;
> +
> + 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(screen, width, height, 8, 0);
> + port_priv->src_pix[1] =
> + glamor_create_pixmap(screen, width >> 1, height >> 1, 8, 0);
> + port_priv->src_pix[2] =
> + glamor_create_pixmap(screen, 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 = (y1 >> 16) & ~1;
> + nlines = ((y2 + 0xffff) >> 16) - 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 = (*screen->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;
> +}
> +
> +static XF86VideoEncodingRec DummyEncodingGLAMOR[1] = {
> + {
> + 0,
> + "XV_IMAGE",
> + 8192, 8192,
> + {1, 1}
> + }
> +};
> +
> +XF86VideoAdaptorPtr
> +glamor_xv_init(ScreenPtr screen, int num_texture_ports)
> +{
> + glamor_port_private *port_priv;
> + XF86VideoAdaptorPtr adapt;
> + int i;
> +
> + glamor_xv_core_init(screen);
> +
> + adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + num_texture_ports *
> + (sizeof(glamor_port_private) + sizeof(DevUnion)));
> + if (adapt == NULL)
> + return NULL;
> +
> + adapt->type = XvWindowMask | XvInputMask | XvImageMask;
> + adapt->flags = 0;
> + adapt->name = "GLAMOR Textured Video";
> + adapt->nEncodings = 1;
> + adapt->pEncodings = DummyEncodingGLAMOR;
> +
> + adapt->nFormats = NUM_FORMATS;
> + adapt->pFormats = Formats;
> + adapt->nPorts = num_texture_ports;
> + adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
> +
> + adapt->pAttributes = glamor_xv_attributes;
> + adapt->nAttributes = glamor_xv_num_attributes;
> +
> + port_priv =
> + (glamor_port_private *) (&adapt->pPortPrivates[num_texture_ports]);
> + adapt->pImages = glamor_xv_images;
> + adapt->nImages = glamor_xv_num_images;
> + adapt->PutVideo = NULL;
> + adapt->PutStill = NULL;
> + adapt->GetVideo = NULL;
> + adapt->GetStill = NULL;
> + adapt->StopVideo = glamor_xf86_xv_stop_video;
> + adapt->SetPortAttribute = glamor_xf86_xv_set_port_attribute;
> + adapt->GetPortAttribute = glamor_xf86_xv_get_port_attribute;
> + adapt->QueryBestSize = glamor_xf86_xv_query_best_size;
> + adapt->PutImage = glamor_xf86_xv_put_image;
> + adapt->ReputImage = NULL;
> + adapt->QueryImageAttributes = glamor_xf86_xv_query_image_attributes;
> +
> + for (i = 0; i < num_texture_ports; i++) {
> + glamor_port_private *pPriv = &port_priv[i];
> +
> + pPriv->brightness = 0;
> + pPriv->contrast = 0;
> + pPriv->saturation = 0;
> + pPriv->hue = 0;
> + pPriv->gamma = 1000;
> + pPriv->transform_index = 0;
> +
> + REGION_NULL(pScreen, &pPriv->clip);
> +
> + adapt->pPortPrivates[i].ptr = (void *) (pPriv);
> + }
> + return adapt;
> +}
More information about the xorg-devel
mailing list