xwayland: add glamor Xv adaptor
This adds an Xv adaptor using glamor. Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
This commit is contained in:
parent
d11fdff50c
commit
da7724d3d2
|
@ -32,7 +32,12 @@ Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
|
|||
|
||||
|
||||
if GLAMOR_EGL
|
||||
Xwayland_SOURCES += xwayland-glamor.c
|
||||
Xwayland_SOURCES += \
|
||||
xwayland-glamor.c
|
||||
if XV
|
||||
Xwayland_SOURCES += \
|
||||
xwayland-glamor-xv.c
|
||||
endif
|
||||
|
||||
nodist_Xwayland_SOURCES = \
|
||||
drm-client-protocol.h \
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* 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 <ofourdan@redhat.com>
|
||||
*
|
||||
* 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 = (unsigned int) (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);
|
||||
}
|
|
@ -569,5 +569,10 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
|
|||
screen->CreatePixmap = xwl_glamor_create_pixmap;
|
||||
screen->DestroyPixmap = xwl_glamor_destroy_pixmap;
|
||||
|
||||
#ifdef XV
|
||||
if (!xwl_glamor_xv_init(screen))
|
||||
ErrorF("Failed to initialize glamor Xv extension\n");
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -190,6 +190,11 @@ 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);
|
||||
|
||||
#ifdef XV
|
||||
/* glamor Xv Adaptor */
|
||||
Bool xwl_glamor_xv_init(ScreenPtr pScreen);
|
||||
#endif
|
||||
|
||||
#ifdef XF86VIDMODE
|
||||
void xwlVidModeExtensionInit(void);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue