2
* Copyright Ā© 2005 Novell, Inc.
4
* Permission to use, copy, modify, distribute, and sell this software
5
* and its documentation for any purpose is hereby granted without
6
* fee, provided that the above copyright notice appear in all copies
7
* and that both that copyright notice and this permission notice
8
* appear in supporting documentation, and that the name of
9
* Novell, Inc. not be used in advertising or publicity pertaining to
10
* distribution of the software without specific, written prior permission.
11
* Novell, Inc. makes no representations about the suitability of this
12
* software for any purpose. It is provided "as is" without express or
15
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23
* Authors: David Reveman <davidr@novell.com>
24
* Matthias Hopf <mhopf@suse.de>
33
#include "dixstruct.h"
35
#include <X11/extensions/Xv.h>
36
#include <X11/extensions/Xvproto.h>
38
static unsigned int xglXvScreenIndex = 0;
39
static unsigned long portResource = 0;
41
#define XGL_GET_XV_SCREEN(pScreen) \
42
((XvScreenPtr) ((pScreen)->devPrivates[xglXvScreenIndex].ptr))
44
#define XGL_XV_SCREEN(pScreen) \
45
XvScreenPtr pXvScreen = XGL_GET_XV_SCREEN (pScreen)
47
#define XGL_GET_XV_SCREEN_PRIV(pScreen) \
48
((xglXvScreenPtr) (GET_XV_SCREEN (pScreen)->devPriv.ptr))
50
#define XGL_XV_SCREEN_PRIV(pScreen) \
51
xglXvScreenPtr pXvScreenPriv = XGL_GET_XV_SCREEN_PRIV (pScreen)
53
#define XGL_GET_XV_PORT_PRIV(pPort) \
54
((xglXvPortPtr) ((pPort)->devPriv.ptr))
56
#define XGL_XV_PORT_PRIV(pPort) \
57
xglXvPortPtr pPortPriv = XGL_GET_XV_PORT_PRIV (pPort)
59
#define XGL_XV_NUM_PORTS 32
61
#define XGL_XV_IMAGE_MAX_WIDTH 2048
62
#define XGL_XV_IMAGE_MAX_HEIGHT 2048
64
static XvImageRec xvImages[] = {
66
GLITZ_FOURCC_YUY2, XvYUV, BITMAP_BIT_ORDER,
69
0x00, 0x00, 0x00, 0x10, 0x80, 0x00,
70
0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
74
8, 8, 8, 1, 2, 2, 1, 1, 1,
77
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82
GLITZ_FOURCC_YV12, XvYUV, BITMAP_BIT_ORDER,
85
0x00, 0x00, 0x00, 0x10, 0x80, 0x00,
86
0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
90
8, 8, 8, 1, 2, 2, 1, 2, 2,
93
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
94
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
98
GLITZ_FOURCC_RGB, XvRGB, BITMAP_BIT_ORDER,
100
0x03, 0x00, 0x00, 0x00,
101
0x00, 0x00, 0x00, 0x10, 0x80, 0x00,
102
0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
105
24, 0xff0000, 0xff00, 0xff,
106
0, 0, 0, 0, 0, 0, 0, 0, 0,
109
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
116
static struct _xglXvFormat {
118
glitz_fourcc_t fourcc;
119
xglPixelFormatRec pixel;
120
} xglXvFormat[XGL_XV_FORMAT_NUM] = {
164
xglXvQueryAdaptors (ScreenPtr pScreen,
165
XvAdaptorPtr *pAdaptors,
168
XGL_XV_SCREEN (pScreen);
170
*nAdaptors = pXvScreen->nAdaptors;
171
*pAdaptors = pXvScreen->pAdaptors;
177
xglXvAllocatePort (unsigned long port,
187
xglXvFreePort (XvPortPtr pPort)
189
XGL_XV_PORT_PRIV (pPort);
193
FreePicture ((pointer) pPortPriv->pDst, 0);
194
pPortPriv->pDst = (PicturePtr) 0;
199
FreePicture ((pointer) pPortPriv->pSrc, 0);
200
pPortPriv->pSrc = (PicturePtr) 0;
203
if (pPortPriv->pPixmap)
207
pScreen = pPortPriv->pPixmap->drawable.pScreen;
208
(*pScreen->DestroyPixmap) (pPortPriv->pPixmap);
209
pPortPriv->pPixmap = (PixmapPtr) 0;
216
xglXvQueryBestSize (ClientPtr client,
223
unsigned int *pWidth,
224
unsigned int *pHeight)
227
*pHeight = dstHeight;
233
xglXvStopVideo (ClientPtr client,
235
DrawablePtr pDrawable)
237
xglXvFreePort (pPort);
243
xglXvPutImage (ClientPtr client,
244
DrawablePtr pDrawable,
261
ScreenPtr pScreen = pDrawable->pScreen;
262
PictTransform transform;
266
XGL_SCREEN_PRIV (pScreen);
267
XGL_XV_PORT_PRIV (pPort);
268
XGL_DRAWABLE_PIXMAP (pDrawable);
269
XGL_PIXMAP_PRIV (pPixmap);
271
switch (pImage->id) {
272
case GLITZ_FOURCC_YUY2:
276
case GLITZ_FOURCC_YV12:
280
case GLITZ_FOURCC_RGB:
283
format = PICT_x8r8g8b8;
286
return BadImplementation;
289
pPort->pDraw = pDrawable;
291
if (!pPortPriv->pPixmap)
293
pPortPriv->pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth);
294
if (!pPortPriv->pPixmap)
298
(*pScreen->ModifyPixmapHeader) (pPortPriv->pPixmap,
300
depth, bpp, -1, (pointer) data);
302
XGL_GET_PIXMAP_PRIV (pPortPriv->pPixmap)->stride = -srcWidth;
304
pPortPriv->pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
306
if (!pPortPriv->pSrc || pPortPriv->pSrc->format != format)
308
PictFormatPtr pFormat;
310
static XID value = RepeatPad;
312
pFormat = PictureMatchFormat (pScreen, depth, format);
314
return BadImplementation;
317
FreePicture ((pointer) pPortPriv->pSrc, 0);
319
pPortPriv->pSrc = CreatePicture (0, &pPortPriv->pPixmap->drawable,
320
pFormat, CPRepeat, &value,
321
serverClient, &error);
322
if (!pPortPriv->pSrc)
324
xglXvFreePort (pPort);
328
SetPictureFilter (pPortPriv->pSrc,
329
FilterBilinear, strlen (FilterBilinear),
333
if (!pPortPriv->pDst || pPortPriv->pDst->pDrawable != pDrawable)
335
PictFormatPtr pFormat = 0;
338
for (i = 0; i < pScreen->numVisuals; i++)
340
if (pScreen->visuals[i].nplanes == pDrawable->depth)
342
pFormat = PictureMatchVisual (pScreen, pDrawable->depth,
343
&pScreen->visuals[i]);
349
return BadImplementation;
352
FreePicture ((pointer) pPortPriv->pDst, 0);
354
pPortPriv->pDst = CreatePicture (0, pDrawable,
355
pFormat, 0, 0, serverClient,
357
if (!pPortPriv->pDst)
359
xglXvFreePort (pPort);
364
transform.matrix[0][0] = ((srcWidth << 16) + (dstWidth >> 1))
366
transform.matrix[0][1] = 0;
367
transform.matrix[0][2] = 0;
370
transform.matrix[1][0] = 0;
371
transform.matrix[1][1] = -((srcHeight << 16) + (dstHeight >> 1))
373
transform.matrix[1][2] = (srcHeight << 16);
375
transform.matrix[2][0] = 0;
376
transform.matrix[2][1] = 0;
377
transform.matrix[2][2] = 1 << 16;
379
SetPictureTransform (pPortPriv->pSrc, &transform);
381
if (pPixmap != pScreenPriv->pScreenPixmap && !pPixmapPriv->target)
382
xglEnablePixmapAccel (pPixmap, &pScreenPriv->accel.xv);
384
CompositePicture (PictOpSrc,
391
dstWidth, dstHeight);
397
xglXvQueryImageAttributes (ClientPtr client,
405
if (*width > XGL_XV_IMAGE_MAX_WIDTH)
406
*width = XGL_XV_IMAGE_MAX_WIDTH;
408
if (*height > XGL_XV_IMAGE_MAX_HEIGHT)
409
*height = XGL_XV_IMAGE_MAX_HEIGHT;
411
*width = (*width + 7) & ~7;
413
switch (pImage->id) {
414
case GLITZ_FOURCC_YUY2:
419
pitches[0] = *width * 2;
421
return *width * *height * 2;
422
case GLITZ_FOURCC_YV12:
423
*height = (*height + 1) & ~1;
428
offsets[1] = *width * *height;
429
offsets[2] = *width * *height + (*width >> 1) * (*height >> 1);
435
pitches[1] = pitches[2] = *width >> 1;
438
return *width * *height + (*width >> 1) * *height;
439
case GLITZ_FOURCC_RGB:
444
pitches[0] = *width * 4;
446
return *width * *height * 4;
453
xglXvFreeAdaptor (XvAdaptorPtr pAdaptor)
455
xfree (pAdaptor->pEncodings);
456
xfree (pAdaptor->pFormats);
458
if (pAdaptor->pPorts)
459
xfree (pAdaptor->pPorts);
463
xglXvInitAdaptors (ScreenPtr pScreen)
465
XvAdaptorPtr pAdaptor;
466
xglXvPortPtr pPortPriv;
469
XvEncodingPtr pEncoding;
472
XGL_XV_SCREEN (pScreen);
474
pXvScreen->nAdaptors = 0;
475
pXvScreen->pAdaptors = NULL;
477
pAdaptor = xcalloc (1, sizeof (XvAdaptorRec));
481
pAdaptor->type = XvInputMask | XvImageMask;
482
pAdaptor->pScreen = pScreen;
484
pAdaptor->ddAllocatePort = xglXvAllocatePort;
485
pAdaptor->ddFreePort = xglXvFreePort;
486
pAdaptor->ddStopVideo = xglXvStopVideo;
487
pAdaptor->ddPutImage = xglXvPutImage;
488
pAdaptor->ddQueryBestSize = xglXvQueryBestSize;
489
pAdaptor->ddQueryImageAttributes = xglXvQueryImageAttributes;
491
pAdaptor->name = "Xgl Generic Texture Video";
493
pEncoding = xcalloc (1, sizeof (XvEncodingRec));
498
pEncoding->pScreen = pScreen;
499
pEncoding->name = "XV_IMAGE";
501
pEncoding->width = XGL_XV_IMAGE_MAX_WIDTH;
502
pEncoding->height = XGL_XV_IMAGE_MAX_HEIGHT;
504
pEncoding->rate.numerator = 1;
505
pEncoding->rate.denominator = 1;
507
pAdaptor->nEncodings = 1;
508
pAdaptor->pEncodings = pEncoding;
510
pAdaptor->nImages = sizeof (xvImages) / sizeof (XvImageRec);
511
pAdaptor->pImages = xvImages;
513
/* TODO: Currently no attributes */
514
pAdaptor->nAttributes = 0;
515
pAdaptor->pAttributes = 0;
517
pFormat = xcalloc (pScreen->numVisuals, sizeof (XvFormatRec));
521
for (i = 0; i < pScreen->numVisuals; i++)
523
pFormat[i].depth = pScreen->visuals[i].nplanes;
524
pFormat[i].visual = pScreen->visuals[i].vid;
527
/* All visuals allowed */
528
pAdaptor->nFormats = pScreen->numVisuals;
529
pAdaptor->pFormats = pFormat;
531
pPort = xcalloc (XGL_XV_NUM_PORTS,
532
sizeof (XvPortRec) + sizeof (xglXvPortRec));
533
pPortPriv = (xglXvPortPtr) (pPort + XGL_XV_NUM_PORTS);
537
for (i = 0; i < XGL_XV_NUM_PORTS; i++)
539
pPort[i].id = FakeClientID (0);
543
if (!AddResource (pPort[i].id, portResource, &pPort[i]))
546
pPort[i].pAdaptor = pAdaptor;
547
pPort[i].pNotify = (XvPortNotifyPtr) 0;
548
pPort[i].pDraw = (DrawablePtr) 0;
549
pPort[i].client = (ClientPtr) 0;
550
pPort[i].grab.client = (ClientPtr) 0;
551
pPort[i].time = currentTime;
552
pPort[i].devPriv.ptr = pPortPriv + i;
555
pAdaptor->nPorts = XGL_XV_NUM_PORTS;
556
pAdaptor->pPorts = pPort;
557
pAdaptor->base_id = pPort->id;
559
pXvScreen->pAdaptors = pAdaptor;
560
pXvScreen->nAdaptors = 1;
566
xglXvCloseScreen (int i, ScreenPtr pScreen)
570
XGL_XV_SCREEN (pScreen);
572
for (j = 0; j < pXvScreen->nAdaptors; j++)
573
xglXvFreeAdaptor (&pXvScreen->pAdaptors[j]);
575
if (pXvScreen->pAdaptors)
576
xfree (pXvScreen->pAdaptors);
582
xglXvScreenInit (ScreenPtr pScreen)
584
XvScreenPtr pXvScreen;
586
int i, status, vid = 0;
588
XGL_SCREEN_PRIV (pScreen);
590
status = XvScreenInit (pScreen);
591
if (status != Success)
594
xglXvScreenIndex = XvGetScreenIndex ();
595
portResource = XvGetRTPort ();
597
pXvScreen = XGL_GET_XV_SCREEN (pScreen);
599
/* Anyone initializing the Xv layer must provide these two.
600
The Xv di layer calls them without even checking if they exist! */
601
pXvScreen->ddCloseScreen = xglXvCloseScreen;
602
pXvScreen->ddQueryAdaptors = xglXvQueryAdaptors;
604
pXvScreen->devPriv.ptr = (pointer) 0;
606
if (!xglXvInitAdaptors (pScreen))
609
for (v = pScreenPriv->pVisual; v; v = v->next)
615
memset (pScreenPriv->pXvVisual, 0, sizeof (pScreenPriv->pXvVisual));
617
for (i = 0; i < XGL_XV_FORMAT_NUM; i++)
619
glitz_format_t templ;
621
templ.color.fourcc = xglXvFormat[i].fourcc;
623
pScreenPriv->pXvVisual[i].vid = ++vid;
624
pScreenPriv->pXvVisual[i].pPixel = &xglXvFormat[i].pixel;
625
pScreenPriv->pXvVisual[i].format.surface =
626
glitz_find_format (pScreenPriv->drawable,
627
GLITZ_FORMAT_FOURCC_MASK,