Hi Adam, I had posted a revisited version using GL_MAX_TEXTURE_SIZE to determine the encoder size as per your review last week, is there anything else that needs rework?
Cheers, Olivier ----- Original Message ----- > This adds an Xv adaptor using glamor. > > Signed-off-by: Olivier Fourdan <[email protected]> > --- > v2: Plug leak of Xv adaptor and glamor private ports array on closure > v3: Get the adaptor size from the GL_MAX_TEXTURE_SIZE > > hw/xwayland/Makefile.am | 4 +- > hw/xwayland/xwayland-glamor-xv.c | 413 > +++++++++++++++++++++++++++++++++++++++ > hw/xwayland/xwayland-glamor.c | 3 + > hw/xwayland/xwayland.h | 2 + > 4 files changed, 421 insertions(+), 1 deletion(-) > create mode 100644 hw/xwayland/xwayland-glamor-xv.c > > diff --git a/hw/xwayland/Makefile.am b/hw/xwayland/Makefile.am > index 0905082..26fdba7 100644 > --- a/hw/xwayland/Makefile.am > +++ b/hw/xwayland/Makefile.am > @@ -32,7 +32,9 @@ Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) > > > if GLAMOR_EGL > -Xwayland_SOURCES += xwayland-glamor.c > +Xwayland_SOURCES += \ > + xwayland-glamor.c \ > + xwayland-glamor-xv.c > > nodist_Xwayland_SOURCES = \ > drm-client-protocol.h \ > diff --git a/hw/xwayland/xwayland-glamor-xv.c > b/hw/xwayland/xwayland-glamor-xv.c > new file mode 100644 > index 0000000..5fa1c69 > --- /dev/null > +++ b/hw/xwayland/xwayland-glamor-xv.c > @@ -0,0 +1,413 @@ > +/* > + * Copyright (c) 1998-2003 by The XFree86 Project, Inc. > + * Copyright © 2013 Red Hat > + * Copyright © 2014 Intel Corporation > + * Copyright © 2016 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: > + * Olivier Fourdan <[email protected]> > + * > + * Derived from the glamor_xf86_xv, ephyr_glamor_xv and xf86xv > + * implementations > + */ > + > +#include "xwayland.h" > +#include "glamor_priv.h" > + > +#include <X11/extensions/Xv.h> > + > +#define NUM_FORMATS 3 > +#define NUM_PORTS 16 > +#define ADAPTOR_NAME "glamor textured video" > +#define ENCODER_NAME "XV_IMAGE" > + > +static DevPrivateKeyRec xwlXvScreenPrivateKeyRec; > +#define xwlXvScreenPrivateKey (&xwlXvScreenPrivateKeyRec) > + > +typedef struct { > + XvAdaptorPtr glxv_adaptor; /* We have only one adaptor, glamor Xv */ > + glamor_port_private *port_privates; > + > + CloseScreenProcPtr CloseScreen; > +} xwlXvScreenRec, *xwlXvScreenPtr; > + > +typedef struct { > + char depth; > + short class; > +} xwlVideoFormatRec, *xwlVideoFormatPtr; > + > +static xwlVideoFormatRec Formats[NUM_FORMATS] = { > + {15, TrueColor}, > + {16, TrueColor}, > + {24, TrueColor} > +}; > + > +static int > +xwl_glamor_xv_stop_video(XvPortPtr pPort, > + DrawablePtr pDraw) > +{ > + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); > + > + if (pDraw->type != DRAWABLE_WINDOW) > + return BadAlloc; > + > + glamor_xv_stop_video(gpp); > + > + return Success; > +} > + > +static int > +xwl_glamor_xv_set_port_attribute(XvPortPtr pPort, > + Atom attribute, > + INT32 value) > +{ > + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); > + > + return glamor_xv_set_port_attribute(gpp, attribute, value); > +} > + > +static int > +xwl_glamor_xv_get_port_attribute(XvPortPtr pPort, > + Atom attribute, > + INT32 *pValue) > +{ > + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); > + > + return glamor_xv_get_port_attribute(gpp, attribute, pValue); > +} > + > +static int > +xwl_glamor_xv_query_best_size(XvPortPtr pPort, > + CARD8 motion, > + CARD16 vid_w, > + CARD16 vid_h, > + CARD16 drw_w, > + CARD16 drw_h, > + unsigned int *p_w, > + unsigned int *p_h) > +{ > + *p_w = drw_w; > + *p_h = drw_h; > + > + return Success; > +} > + > +static int > +xwl_glamor_xv_query_image_attributes(XvPortPtr pPort, > + XvImagePtr format, > + CARD16 *width, > + CARD16 *height, > + int *pitches, > + int *offsets) > +{ > + return glamor_xv_query_image_attributes(format->id, > + width, > + height, > + pitches, > + offsets); > +} > + > +static int > +xwl_glamor_xv_put_image(DrawablePtr pDrawable, > + XvPortPtr pPort, > + GCPtr pGC, > + INT16 src_x, > + INT16 src_y, > + CARD16 src_w, > + CARD16 src_h, > + INT16 drw_x, > + INT16 drw_y, > + CARD16 drw_w, > + CARD16 drw_h, > + XvImagePtr format, > + unsigned char *data, > + Bool sync, > + CARD16 width, > + CARD16 height) > +{ > + glamor_port_private *gpp = (glamor_port_private *) (pPort->devPriv.ptr); > + > + RegionRec WinRegion; > + RegionRec ClipRegion; > + BoxRec WinBox; > + int ret = Success; > + > + if (pDrawable->type != DRAWABLE_WINDOW) > + return BadWindow; > + > + WinBox.x1 = pDrawable->x + drw_x; > + WinBox.y1 = pDrawable->y + drw_y; > + WinBox.x2 = WinBox.x1 + drw_w; > + WinBox.y2 = WinBox.y1 + drw_h; > + > + RegionInit(&WinRegion, &WinBox, 1); > + RegionInit(&ClipRegion, NullBox, 1); > + RegionIntersect(&ClipRegion, &WinRegion, pGC->pCompositeClip); > + > + if (RegionNotEmpty(&ClipRegion)) > + ret = glamor_xv_put_image(gpp, > + pDrawable, > + src_x, > + src_y, > + pDrawable->x + drw_x, > + pDrawable->y + drw_y, > + src_w, > + src_h, > + drw_w, > + drw_h, > + format->id, > + data, > + width, > + height, > + sync, > + &ClipRegion); > + > + RegionUninit(&WinRegion); > + RegionUninit(&ClipRegion); > + > + return ret; > + > +} > + > +static Bool > +xwl_glamor_xv_add_formats(XvAdaptorPtr pa) > +{ > + ScreenPtr pScreen; > + XvFormatPtr pFormat, pf; > + VisualPtr pVisual; > + int numFormat; > + int totFormat; > + int numVisuals; > + int i; > + > + totFormat = NUM_FORMATS; > + pFormat = xnfcalloc(totFormat, sizeof(XvFormatRec)); > + pScreen = pa->pScreen; > + for (pf = pFormat, i = 0, numFormat = 0; i < NUM_FORMATS; i++) { > + numVisuals = pScreen->numVisuals; > + pVisual = pScreen->visuals; > + > + while (numVisuals--) { > + if ((pVisual->class == Formats[i].class) && > + (pVisual->nplanes == Formats[i].depth)) { > + if (numFormat >= totFormat) { > + void *moreSpace; > + > + totFormat *= 2; > + moreSpace = XNFreallocarray(pFormat, totFormat, > + sizeof(XvFormatRec)); > + pFormat = moreSpace; > + pf = pFormat + numFormat; > + } > + > + pf->visual = pVisual->vid; > + pf->depth = Formats[i].depth; > + > + pf++; > + numFormat++; > + } > + pVisual++; > + } > + } > + pa->nFormats = numFormat; > + pa->pFormats = pFormat; > + > + return numFormat != 0; > +} > + > +static Bool > +xwl_glamor_xv_add_ports(XvAdaptorPtr pa) > +{ > + XvPortPtr pPorts, pp; > + xwlXvScreenPtr xwlXvScreen; > + unsigned long PortResource = 0; > + int nPorts; > + int i; > + > + pPorts = xnfcalloc(NUM_PORTS, sizeof(XvPortRec)); > + xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates, > + xwlXvScreenPrivateKey); > + xwlXvScreen->port_privates = xnfcalloc(NUM_PORTS, > + sizeof(glamor_port_private)); > + > + PortResource = XvGetRTPort(); > + for (pp = pPorts, i = 0, nPorts = 0; i < NUM_PORTS; i++) { > + if (!(pp->id = FakeClientID(0))) > + continue; > + > + pp->pAdaptor = pa; > + > + glamor_xv_init_port(&xwlXvScreen->port_privates[i]); > + pp->devPriv.ptr = &xwlXvScreen->port_privates[i]; > + > + if (AddResource(pp->id, PortResource, pp)) { > + pp++; > + nPorts++; > + } > + } > + > + pa->base_id = pPorts->id; > + pa->nPorts = nPorts; > + pa->pPorts = pPorts; > + > + return nPorts != 0; > +} > + > +static void > +xwl_glamor_xv_add_attributes(XvAdaptorPtr pa) > +{ > + int i; > + > + pa->pAttributes = xnfcalloc(glamor_xv_num_attributes, > sizeof(XvAttributeRec)); > + memcpy(pa->pAttributes, glamor_xv_attributes, > + glamor_xv_num_attributes * sizeof(XvAttributeRec)); > + > + for (i = 0; i < glamor_xv_num_attributes; i++) > + pa->pAttributes[i].name = strdup(glamor_xv_attributes[i].name); > + > + pa->nAttributes = glamor_xv_num_attributes; > +} > + > +static void > +xwl_glamor_xv_add_images(XvAdaptorPtr pa) > +{ > + pa->pImages = xnfcalloc(glamor_xv_num_images, sizeof(XvImageRec)); > + memcpy(pa->pImages, glamor_xv_images, glamor_xv_num_images * > sizeof(XvImageRec)); > + > + pa->nImages = glamor_xv_num_images; > +} > + > +static void > +xwl_glamor_xv_add_encodings(XvAdaptorPtr pa) > +{ > + XvEncodingPtr pe; > + GLint texsize; > + > + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize); > + > + pe = xnfcalloc(1, sizeof(XvEncodingRec)); > + pe->id = 0; > + pe->pScreen = pa->pScreen; > + pe->name = strdup(ENCODER_NAME); > + pe->width = texsize; > + pe->height = texsize; > + pe->rate.numerator = 1; > + pe->rate.denominator = 1; > + > + pa->pEncodings = pe; > + pa->nEncodings = 1; > +} > + > +static Bool > +xwl_glamor_xv_add_adaptors(ScreenPtr pScreen) > +{ > + DevPrivateKey XvScreenKey; > + XvScreenPtr XvScreen; > + xwlXvScreenPtr xwlXvScreen; > + XvAdaptorPtr pa; > + > + if (XvScreenInit(pScreen) != Success) > + return FALSE; > + > + XvScreenKey = XvGetScreenKey(); > + XvScreen = dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey); > + > + XvScreen->nAdaptors = 0; > + XvScreen->pAdaptors = NULL; > + > + pa = xnfcalloc(1, sizeof(XvAdaptorRec)); > + pa->pScreen = pScreen; > + pa->type = XvWindowMask | XvInputMask | XvImageMask;; > + pa->ddStopVideo = xwl_glamor_xv_stop_video; > + pa->ddPutImage = xwl_glamor_xv_put_image; > + pa->ddSetPortAttribute = xwl_glamor_xv_set_port_attribute; > + pa->ddGetPortAttribute = xwl_glamor_xv_get_port_attribute; > + pa->ddQueryBestSize = xwl_glamor_xv_query_best_size; > + pa->ddQueryImageAttributes = xwl_glamor_xv_query_image_attributes; > + pa->name = strdup(ADAPTOR_NAME); > + > + xwl_glamor_xv_add_encodings(pa); > + xwl_glamor_xv_add_images(pa); > + xwl_glamor_xv_add_attributes(pa); > + if (!xwl_glamor_xv_add_formats(pa)) > + goto failed; > + if (!xwl_glamor_xv_add_ports(pa)) > + goto failed; > + > + /* We're good now with out Xv adaptor */ > + XvScreen->nAdaptors = 1; > + XvScreen->pAdaptors = pa; > + > + xwlXvScreen = dixLookupPrivate(&(pa->pScreen)->devPrivates, > + xwlXvScreenPrivateKey); > + xwlXvScreen->glxv_adaptor = pa; > + > + return TRUE; > + > +failed: > + XvFreeAdaptor(pa); > + free(pa); > + > + return FALSE; > +} > + > +static Bool > +xwl_glamor_xv_close_screen(ScreenPtr pScreen) > +{ > + xwlXvScreenPtr xwlXvScreen; > + > + xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates, > + xwlXvScreenPrivateKey); > + > + if (xwlXvScreen->glxv_adaptor) { > + XvFreeAdaptor(xwlXvScreen->glxv_adaptor); > + free(xwlXvScreen->glxv_adaptor); > + } > + free(xwlXvScreen->port_privates); > + > + pScreen->CloseScreen = xwlXvScreen->CloseScreen; > + > + return pScreen->CloseScreen(pScreen); > +} > + > +Bool > +xwl_glamor_xv_init(ScreenPtr pScreen) > +{ > + xwlXvScreenPtr xwlXvScreen; > + > + if (!dixRegisterPrivateKey(xwlXvScreenPrivateKey, PRIVATE_SCREEN, > + sizeof(xwlXvScreenRec))) > + return FALSE; > + > + xwlXvScreen = dixLookupPrivate(&(pScreen)->devPrivates, > + xwlXvScreenPrivateKey); > + > + xwlXvScreen->port_privates = NULL; > + xwlXvScreen->glxv_adaptor = NULL; > + xwlXvScreen->CloseScreen = pScreen->CloseScreen; > + pScreen->CloseScreen = xwl_glamor_xv_close_screen; > + > + glamor_xv_core_init(pScreen); > + > + return xwl_glamor_xv_add_adaptors(pScreen); > +} > + > diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c > index 8e77a84..9acbf3a 100644 > --- a/hw/xwayland/xwayland-glamor.c > +++ b/hw/xwayland/xwayland-glamor.c > @@ -569,5 +569,8 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) > screen->CreatePixmap = xwl_glamor_create_pixmap; > screen->DestroyPixmap = xwl_glamor_destroy_pixmap; > > + if (!xwl_glamor_xv_init(screen)) > + ErrorF("Failed to initialize glamor Xv extension\n"); > + > return TRUE; > } > diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h > index 4b150ed..2a54183 100644 > --- a/hw/xwayland/xwayland.h > +++ b/hw/xwayland/xwayland.h > @@ -189,6 +189,8 @@ Bool xwl_glamor_init(struct xwl_screen *xwl_screen); > Bool xwl_screen_init_glamor(struct xwl_screen *xwl_screen, > uint32_t id, uint32_t version); > struct wl_buffer *xwl_glamor_pixmap_get_wl_buffer(PixmapPtr pixmap); > +/* glamor Xv Adaptor */ > +Bool xwl_glamor_xv_init(ScreenPtr pScreen); > > #ifdef XF86VIDMODE > void xwlVidModeExtensionInit(void); > -- > 2.5.0 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: https://lists.x.org/mailman/listinfo/xorg-devel _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
