[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