2 * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
5 * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
25 * Except as contained in this notice, the name of the copyright holder(s)
26 * and author(s) shall not be used in advertising or otherwise to promote
27 * the sale, use or other dealings in this Software without prior written
28 * authorization from the copyright holder(s) and author(s).
31 #ifdef HAVE_XORG_CONFIG_H
32 #include <xorg-config.h>
37 #include "xf86_OSproc.h"
40 #include <X11/Xproto.h>
41 #include "scrnintstr.h"
42 #include "regionstr.h"
43 #include "windowstr.h"
44 #include "pixmapstr.h"
45 #include "mivalidate.h"
49 #include "dixstruct.h"
51 #include <X11/extensions/Xv.h>
52 #include <X11/extensions/Xvproto.h>
55 #include "xf86xvpriv.h"
57 /* XvScreenRec fields */
59 static Bool
xf86XVCloseScreen(ScreenPtr
);
60 static int xf86XVQueryAdaptors(ScreenPtr
, XvAdaptorPtr
*, int *);
62 /* XvAdaptorRec fields */
64 static int xf86XVAllocatePort(unsigned long, XvPortPtr
, XvPortPtr
*);
65 static int xf86XVFreePort(XvPortPtr
);
66 static int xf86XVPutVideo(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
67 INT16
, INT16
, CARD16
, CARD16
,
68 INT16
, INT16
, CARD16
, CARD16
);
69 static int xf86XVPutStill(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
70 INT16
, INT16
, CARD16
, CARD16
,
71 INT16
, INT16
, CARD16
, CARD16
);
72 static int xf86XVGetVideo(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
73 INT16
, INT16
, CARD16
, CARD16
,
74 INT16
, INT16
, CARD16
, CARD16
);
75 static int xf86XVGetStill(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
76 INT16
, INT16
, CARD16
, CARD16
,
77 INT16
, INT16
, CARD16
, CARD16
);
78 static int xf86XVStopVideo(ClientPtr
, XvPortPtr
, DrawablePtr
);
79 static int xf86XVSetPortAttribute(ClientPtr
, XvPortPtr
, Atom
, INT32
);
80 static int xf86XVGetPortAttribute(ClientPtr
, XvPortPtr
, Atom
, INT32
*);
81 static int xf86XVQueryBestSize(ClientPtr
, XvPortPtr
, CARD8
,
82 CARD16
, CARD16
, CARD16
, CARD16
,
83 unsigned int *, unsigned int *);
84 static int xf86XVPutImage(ClientPtr
, DrawablePtr
, XvPortPtr
, GCPtr
,
85 INT16
, INT16
, CARD16
, CARD16
,
86 INT16
, INT16
, CARD16
, CARD16
,
87 XvImagePtr
, unsigned char *, Bool
, CARD16
, CARD16
);
88 static int xf86XVQueryImageAttributes(ClientPtr
, XvPortPtr
, XvImagePtr
,
89 CARD16
*, CARD16
*, int *, int *);
91 /* ScreenRec fields */
93 static Bool
xf86XVDestroyWindow(WindowPtr pWin
);
94 static void xf86XVWindowExposures(WindowPtr pWin
, RegionPtr r1
, RegionPtr r2
);
95 static void xf86XVPostValidateTree(WindowPtr pWin
, WindowPtr pLayerWin
,
97 static void xf86XVClipNotify(WindowPtr pWin
, int dx
, int dy
);
99 #define PostValidateTreeUndefined ((PostValidateTreeProcPtr)-1)
101 /* ScrnInfoRec functions */
103 static Bool
xf86XVEnterVT(ScrnInfoPtr
);
104 static void xf86XVLeaveVT(ScrnInfoPtr
);
105 static void xf86XVAdjustFrame(ScrnInfoPtr
, int x
, int y
);
106 static void xf86XVModeSet(ScrnInfoPtr pScrn
);
110 static Bool
xf86XVInitAdaptors(ScreenPtr
, XF86VideoAdaptorPtr
*, int);
112 static DevPrivateKeyRec XF86XVWindowKeyRec
;
114 #define XF86XVWindowKey (&XF86XVWindowKeyRec)
116 DevPrivateKey XF86XvScreenKey
;
118 static unsigned long PortResource
= 0;
120 #define GET_XV_SCREEN(pScreen) \
121 ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
123 #define GET_XF86XV_SCREEN(pScreen) \
124 ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
126 #define GET_XF86XV_WINDOW(pWin) \
127 ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
129 static xf86XVInitGenericAdaptorPtr
*GenDrivers
= NULL
;
130 static int NumGenDrivers
= 0;
133 xf86XVRegisterGenericAdaptorDriver(xf86XVInitGenericAdaptorPtr InitFunc
)
135 xf86XVInitGenericAdaptorPtr
*newdrivers
;
137 newdrivers
= realloc(GenDrivers
, sizeof(xf86XVInitGenericAdaptorPtr
) *
138 (1 + NumGenDrivers
));
141 GenDrivers
= newdrivers
;
143 GenDrivers
[NumGenDrivers
++] = InitFunc
;
149 xf86XVListGenericAdaptors(ScrnInfoPtr pScrn
, XF86VideoAdaptorPtr
** adaptors
)
152 XF86VideoAdaptorPtr
*DrivAdap
, *new;
157 * The v4l driver registers itself first, but can use surfaces registered
158 * by other drivers. So, call the v4l driver last.
160 for (i
= NumGenDrivers
; --i
>= 0;) {
162 n
= (*GenDrivers
[i
]) (pScrn
, &DrivAdap
);
165 new = realloc(*adaptors
, sizeof(XF86VideoAdaptorPtr
) * (num
+ n
));
169 for (j
= 0; j
< n
; j
++, num
++)
170 (*adaptors
)[num
] = DrivAdap
[j
];
175 /**************** Offscreen surface stuff *******************/
178 XF86OffscreenImagePtr images
;
182 static DevPrivateKeyRec OffscreenPrivateKeyRec
;
184 #define OffscreenPrivateKey (&OffscreenPrivateKeyRec)
185 #define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
188 xf86XVRegisterOffscreenImages(ScreenPtr pScreen
,
189 XF86OffscreenImagePtr images
, int num
)
191 OffscreenImageRec
*OffscreenImage
;
193 /* This function may be called before xf86XVScreenInit, so there's
194 * no better place than this to call dixRegisterPrivateKey to ensure we
195 * have space reserved. After the first call it is a no-op. */
196 if (!dixRegisterPrivateKey
197 (OffscreenPrivateKey
, PRIVATE_SCREEN
, sizeof(OffscreenImageRec
)) ||
198 !(OffscreenImage
= GetOffscreenImage(pScreen
)))
199 /* Every X.org driver assumes this function always succeeds, so
200 * just die on allocation failure. */
202 ("Could not allocate private storage for XV offscreen images.\n");
204 OffscreenImage
->num
= num
;
205 OffscreenImage
->images
= images
;
209 XF86OffscreenImagePtr
210 xf86XVQueryOffscreenImages(ScreenPtr pScreen
, int *num
)
212 OffscreenImageRec
*OffscreenImage
= GetOffscreenImage(pScreen
);
214 *num
= OffscreenImage
->num
;
215 return OffscreenImage
->images
;
219 xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn
)
221 return calloc(1, sizeof(XF86VideoAdaptorRec
));
225 xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr
)
231 xf86XVScreenInit(ScreenPtr pScreen
, XF86VideoAdaptorPtr
* adaptors
, int num
)
234 XF86XVScreenPtr ScreenPriv
;
237 if (num
<= 0 || noXvExtension
)
240 if (Success
!= XvScreenInit(pScreen
))
243 if (!dixRegisterPrivateKey(&XF86XVWindowKeyRec
, PRIVATE_WINDOW
, 0))
246 XF86XvScreenKey
= XvGetScreenKey();
248 PortResource
= XvGetRTPort();
250 pxvs
= GET_XV_SCREEN(pScreen
);
252 /* Anyone initializing the Xv layer must provide these two.
253 The Xv di layer calls them without even checking if they exist! */
255 pxvs
->ddCloseScreen
= xf86XVCloseScreen
;
256 pxvs
->ddQueryAdaptors
= xf86XVQueryAdaptors
;
258 /* The Xv di layer provides us with a private hook so that we don't
259 have to allocate our own screen private. They also provide
260 a CloseScreen hook so that we don't have to wrap it. I'm not
261 sure that I appreciate that. */
263 ScreenPriv
= malloc(sizeof(XF86XVScreenRec
));
264 pxvs
->devPriv
.ptr
= (pointer
) ScreenPriv
;
269 pScrn
= xf86ScreenToScrn(pScreen
);
271 ScreenPriv
->DestroyWindow
= pScreen
->DestroyWindow
;
272 ScreenPriv
->WindowExposures
= pScreen
->WindowExposures
;
273 ScreenPriv
->PostValidateTree
= PostValidateTreeUndefined
;
274 ScreenPriv
->ClipNotify
= pScreen
->ClipNotify
;
275 ScreenPriv
->EnterVT
= pScrn
->EnterVT
;
276 ScreenPriv
->LeaveVT
= pScrn
->LeaveVT
;
277 ScreenPriv
->AdjustFrame
= pScrn
->AdjustFrame
;
278 ScreenPriv
->ModeSet
= pScrn
->ModeSet
;
280 pScreen
->DestroyWindow
= xf86XVDestroyWindow
;
281 pScreen
->WindowExposures
= xf86XVWindowExposures
;
282 pScreen
->ClipNotify
= xf86XVClipNotify
;
283 pScrn
->EnterVT
= xf86XVEnterVT
;
284 pScrn
->LeaveVT
= xf86XVLeaveVT
;
285 if (pScrn
->AdjustFrame
)
286 pScrn
->AdjustFrame
= xf86XVAdjustFrame
;
287 pScrn
->ModeSet
= xf86XVModeSet
;
289 if (!xf86XVInitAdaptors(pScreen
, adaptors
, num
))
296 xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor
)
300 free(pAdaptor
->name
);
301 pAdaptor
->name
= NULL
;
303 if (pAdaptor
->pEncodings
) {
304 XvEncodingPtr pEncode
= pAdaptor
->pEncodings
;
306 for (i
= 0; i
< pAdaptor
->nEncodings
; i
++, pEncode
++)
308 free(pAdaptor
->pEncodings
);
309 pAdaptor
->pEncodings
= NULL
;
312 free(pAdaptor
->pFormats
);
313 pAdaptor
->pFormats
= NULL
;
315 if (pAdaptor
->pPorts
) {
316 XvPortPtr pPort
= pAdaptor
->pPorts
;
317 XvPortRecPrivatePtr pPriv
;
319 for (i
= 0; i
< pAdaptor
->nPorts
; i
++, pPort
++) {
320 pPriv
= (XvPortRecPrivatePtr
) pPort
->devPriv
.ptr
;
322 if (pPriv
->clientClip
)
323 RegionDestroy(pPriv
->clientClip
);
324 if (pPriv
->pCompositeClip
&& pPriv
->FreeCompositeClip
)
325 RegionDestroy(pPriv
->pCompositeClip
);
326 if (pPriv
->ckeyFilled
)
327 RegionDestroy(pPriv
->ckeyFilled
);
331 free(pAdaptor
->pPorts
);
332 pAdaptor
->pPorts
= NULL
;
335 if (pAdaptor
->pAttributes
) {
336 XvAttributePtr pAttribute
= pAdaptor
->pAttributes
;
338 for (i
= 0; i
< pAdaptor
->nAttributes
; i
++, pAttribute
++)
339 free(pAttribute
->name
);
340 free(pAdaptor
->pAttributes
);
341 pAdaptor
->pAttributes
= NULL
;
344 free(pAdaptor
->pImages
);
345 free(pAdaptor
->devPriv
.ptr
);
346 pAdaptor
->pImages
= NULL
;
347 pAdaptor
->devPriv
.ptr
= NULL
;
351 xf86XVInitAdaptors(ScreenPtr pScreen
, XF86VideoAdaptorPtr
* infoPtr
, int number
)
353 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
354 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
355 XF86VideoAdaptorPtr adaptorPtr
;
356 XvAdaptorPtr pAdaptor
, pa
;
357 XvAdaptorRecPrivatePtr adaptorPriv
;
359 XvPortRecPrivatePtr portPriv
;
362 XF86AttributePtr attributePtr
;
363 XvAttributePtr pAttribute
, pat
;
364 XF86VideoFormatPtr formatPtr
;
365 XvFormatPtr pFormat
, pf
;
366 int numFormat
, totFormat
;
367 XF86VideoEncodingPtr encodingPtr
;
368 XvEncodingPtr pEncode
, pe
;
369 XF86ImagePtr imagePtr
;
370 XvImagePtr pImage
, pi
;
376 pxvs
->pAdaptors
= NULL
;
378 if (!(pAdaptor
= calloc(number
, sizeof(XvAdaptorRec
))))
381 for (pa
= pAdaptor
, na
= 0, numAdaptor
= 0; na
< number
; na
++, adaptorPtr
++) {
382 adaptorPtr
= infoPtr
[na
];
384 if (!adaptorPtr
->StopVideo
|| !adaptorPtr
->SetPortAttribute
||
385 !adaptorPtr
->GetPortAttribute
|| !adaptorPtr
->QueryBestSize
)
388 /* client libs expect at least one encoding */
389 if (!adaptorPtr
->nEncodings
|| !adaptorPtr
->pEncodings
)
392 pa
->type
= adaptorPtr
->type
;
394 if (!adaptorPtr
->PutVideo
&& !adaptorPtr
->GetVideo
)
395 pa
->type
&= ~XvVideoMask
;
397 if (!adaptorPtr
->PutStill
&& !adaptorPtr
->GetStill
)
398 pa
->type
&= ~XvStillMask
;
400 if (!adaptorPtr
->PutImage
|| !adaptorPtr
->QueryImageAttributes
)
401 pa
->type
&= ~XvImageMask
;
403 if (!adaptorPtr
->PutVideo
&& !adaptorPtr
->PutImage
&&
404 !adaptorPtr
->PutStill
)
405 pa
->type
&= ~XvInputMask
;
407 if (!adaptorPtr
->GetVideo
&& !adaptorPtr
->GetStill
)
408 pa
->type
&= ~XvOutputMask
;
410 if (!(adaptorPtr
->type
& (XvPixmapMask
| XvWindowMask
)))
412 if (!(adaptorPtr
->type
& (XvImageMask
| XvVideoMask
| XvStillMask
)))
415 pa
->pScreen
= pScreen
;
416 pa
->ddAllocatePort
= xf86XVAllocatePort
;
417 pa
->ddFreePort
= xf86XVFreePort
;
418 pa
->ddPutVideo
= xf86XVPutVideo
;
419 pa
->ddPutStill
= xf86XVPutStill
;
420 pa
->ddGetVideo
= xf86XVGetVideo
;
421 pa
->ddGetStill
= xf86XVGetStill
;
422 pa
->ddStopVideo
= xf86XVStopVideo
;
423 pa
->ddPutImage
= xf86XVPutImage
;
424 pa
->ddSetPortAttribute
= xf86XVSetPortAttribute
;
425 pa
->ddGetPortAttribute
= xf86XVGetPortAttribute
;
426 pa
->ddQueryBestSize
= xf86XVQueryBestSize
;
427 pa
->ddQueryImageAttributes
= xf86XVQueryImageAttributes
;
428 pa
->name
= strdup(adaptorPtr
->name
);
430 if (adaptorPtr
->nEncodings
&&
431 (pEncode
= calloc(adaptorPtr
->nEncodings
, sizeof(XvEncodingRec
)))) {
433 for (pe
= pEncode
, encodingPtr
= adaptorPtr
->pEncodings
, i
= 0;
434 i
< adaptorPtr
->nEncodings
; pe
++, i
++, encodingPtr
++) {
435 pe
->id
= encodingPtr
->id
;
436 pe
->pScreen
= pScreen
;
437 pe
->name
= strdup(encodingPtr
->name
);
438 pe
->width
= encodingPtr
->width
;
439 pe
->height
= encodingPtr
->height
;
440 pe
->rate
.numerator
= encodingPtr
->rate
.numerator
;
441 pe
->rate
.denominator
= encodingPtr
->rate
.denominator
;
443 pa
->nEncodings
= adaptorPtr
->nEncodings
;
444 pa
->pEncodings
= pEncode
;
447 if (adaptorPtr
->nImages
&&
448 (pImage
= calloc(adaptorPtr
->nImages
, sizeof(XvImageRec
)))) {
450 for (i
= 0, pi
= pImage
, imagePtr
= adaptorPtr
->pImages
;
451 i
< adaptorPtr
->nImages
; i
++, pi
++, imagePtr
++) {
452 pi
->id
= imagePtr
->id
;
453 pi
->type
= imagePtr
->type
;
454 pi
->byte_order
= imagePtr
->byte_order
;
455 memcpy(pi
->guid
, imagePtr
->guid
, 16);
456 pi
->bits_per_pixel
= imagePtr
->bits_per_pixel
;
457 pi
->format
= imagePtr
->format
;
458 pi
->num_planes
= imagePtr
->num_planes
;
459 pi
->depth
= imagePtr
->depth
;
460 pi
->red_mask
= imagePtr
->red_mask
;
461 pi
->green_mask
= imagePtr
->green_mask
;
462 pi
->blue_mask
= imagePtr
->blue_mask
;
463 pi
->y_sample_bits
= imagePtr
->y_sample_bits
;
464 pi
->u_sample_bits
= imagePtr
->u_sample_bits
;
465 pi
->v_sample_bits
= imagePtr
->v_sample_bits
;
466 pi
->horz_y_period
= imagePtr
->horz_y_period
;
467 pi
->horz_u_period
= imagePtr
->horz_u_period
;
468 pi
->horz_v_period
= imagePtr
->horz_v_period
;
469 pi
->vert_y_period
= imagePtr
->vert_y_period
;
470 pi
->vert_u_period
= imagePtr
->vert_u_period
;
471 pi
->vert_v_period
= imagePtr
->vert_v_period
;
472 memcpy(pi
->component_order
, imagePtr
->component_order
, 32);
473 pi
->scanline_order
= imagePtr
->scanline_order
;
475 pa
->nImages
= adaptorPtr
->nImages
;
476 pa
->pImages
= pImage
;
479 if (adaptorPtr
->nAttributes
&&
481 calloc(adaptorPtr
->nAttributes
, sizeof(XvAttributeRec
)))) {
482 for (pat
= pAttribute
, attributePtr
= adaptorPtr
->pAttributes
, i
=
483 0; i
< adaptorPtr
->nAttributes
; pat
++, i
++, attributePtr
++) {
484 pat
->flags
= attributePtr
->flags
;
485 pat
->min_value
= attributePtr
->min_value
;
486 pat
->max_value
= attributePtr
->max_value
;
487 pat
->name
= strdup(attributePtr
->name
);
489 pa
->nAttributes
= adaptorPtr
->nAttributes
;
490 pa
->pAttributes
= pAttribute
;
493 totFormat
= adaptorPtr
->nFormats
;
495 if (!(pFormat
= calloc(totFormat
, sizeof(XvFormatRec
)))) {
496 xf86XVFreeAdaptor(pa
);
499 for (pf
= pFormat
, i
= 0, numFormat
= 0, formatPtr
=
500 adaptorPtr
->pFormats
; i
< adaptorPtr
->nFormats
; i
++, formatPtr
++) {
501 numVisuals
= pScreen
->numVisuals
;
502 pVisual
= pScreen
->visuals
;
504 while (numVisuals
--) {
505 if ((pVisual
->class == formatPtr
->class) &&
506 (pVisual
->nplanes
== formatPtr
->depth
)) {
508 if (numFormat
>= totFormat
) {
512 moreSpace
= realloc(pFormat
,
513 totFormat
* sizeof(XvFormatRec
));
517 pf
= pFormat
+ numFormat
;
520 pf
->visual
= pVisual
->vid
;
521 pf
->depth
= formatPtr
->depth
;
529 pa
->nFormats
= numFormat
;
530 pa
->pFormats
= pFormat
;
532 xf86XVFreeAdaptor(pa
);
536 if (!(adaptorPriv
= calloc(1, sizeof(XvAdaptorRecPrivate
)))) {
537 xf86XVFreeAdaptor(pa
);
541 adaptorPriv
->flags
= adaptorPtr
->flags
;
542 adaptorPriv
->PutVideo
= adaptorPtr
->PutVideo
;
543 adaptorPriv
->PutStill
= adaptorPtr
->PutStill
;
544 adaptorPriv
->GetVideo
= adaptorPtr
->GetVideo
;
545 adaptorPriv
->GetStill
= adaptorPtr
->GetStill
;
546 adaptorPriv
->StopVideo
= adaptorPtr
->StopVideo
;
547 adaptorPriv
->SetPortAttribute
= adaptorPtr
->SetPortAttribute
;
548 adaptorPriv
->GetPortAttribute
= adaptorPtr
->GetPortAttribute
;
549 adaptorPriv
->QueryBestSize
= adaptorPtr
->QueryBestSize
;
550 adaptorPriv
->QueryImageAttributes
= adaptorPtr
->QueryImageAttributes
;
551 adaptorPriv
->PutImage
= adaptorPtr
->PutImage
;
552 adaptorPriv
->ReputImage
= adaptorPtr
->ReputImage
; /* image/still */
554 pa
->devPriv
.ptr
= (pointer
) adaptorPriv
;
556 if (!(pPort
= calloc(adaptorPtr
->nPorts
, sizeof(XvPortRec
)))) {
557 xf86XVFreeAdaptor(pa
);
560 for (pp
= pPort
, i
= 0, numPort
= 0; i
< adaptorPtr
->nPorts
; i
++) {
562 if (!(pp
->id
= FakeClientID(0)))
565 if (!(portPriv
= calloc(1, sizeof(XvPortRecPrivate
))))
568 if (!AddResource(pp
->id
, PortResource
, pp
)) {
574 pp
->pNotify
= (XvPortNotifyPtr
) NULL
;
575 pp
->pDraw
= (DrawablePtr
) NULL
;
576 pp
->client
= (ClientPtr
) NULL
;
577 pp
->grab
.client
= (ClientPtr
) NULL
;
578 pp
->time
= currentTime
;
579 pp
->devPriv
.ptr
= portPriv
;
581 portPriv
->pScrn
= pScrn
;
582 portPriv
->AdaptorRec
= adaptorPriv
;
583 portPriv
->DevPriv
.ptr
= adaptorPtr
->pPortPrivates
[i
].ptr
;
588 pa
->nPorts
= numPort
;
591 xf86XVFreeAdaptor(pa
);
595 pa
->base_id
= pPort
->id
;
602 pxvs
->nAdaptors
= numAdaptor
;
603 pxvs
->pAdaptors
= pAdaptor
;
613 /* Video should be clipped to the intersection of the window cliplist
614 and the client cliplist specified in the GC for which the video was
615 initialized. When we need to reclip a window, the GC that started
616 the video may not even be around anymore. That's why we save the
617 client clip from the GC when the video is initialized. We then
618 use xf86XVUpdateCompositeClip to calculate the new composite clip
619 when we need it. This is different from what DEC did. They saved
620 the GC and used it's clip list when they needed to reclip the window,
621 even if the client clip was different from the one the video was
622 initialized with. If the original GC was destroyed, they had to stop
623 the video. I like the new method better (MArk).
625 This function only works for windows. Will need to rewrite when
626 (if) we support pixmap rendering.
630 xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv
)
632 RegionPtr pregWin
, pCompositeClip
;
634 Bool freeCompClip
= FALSE
;
636 if (portPriv
->pCompositeClip
)
639 pWin
= (WindowPtr
) portPriv
->pDraw
;
641 /* get window clip list */
642 if (portPriv
->subWindowMode
== IncludeInferiors
) {
643 pregWin
= NotClippedByChildren(pWin
);
647 pregWin
= &pWin
->clipList
;
649 if (!portPriv
->clientClip
) {
650 portPriv
->pCompositeClip
= pregWin
;
651 portPriv
->FreeCompositeClip
= freeCompClip
;
655 pCompositeClip
= RegionCreate(NullBox
, 1);
656 RegionCopy(pCompositeClip
, portPriv
->clientClip
);
657 RegionTranslate(pCompositeClip
, portPriv
->pDraw
->x
, portPriv
->pDraw
->y
);
658 RegionIntersect(pCompositeClip
, pregWin
, pCompositeClip
);
660 portPriv
->pCompositeClip
= pCompositeClip
;
661 portPriv
->FreeCompositeClip
= TRUE
;
664 RegionDestroy(pregWin
);
668 /* Save the current clientClip and update the CompositeClip whenever
669 we have a fresh GC */
672 xf86XVCopyClip(XvPortRecPrivatePtr portPriv
, GCPtr pGC
)
674 /* copy the new clip if it exists */
675 if ((pGC
->clientClipType
== CT_REGION
) && pGC
->clientClip
) {
676 if (!portPriv
->clientClip
)
677 portPriv
->clientClip
= RegionCreate(NullBox
, 1);
678 /* Note: this is in window coordinates */
679 RegionCopy(portPriv
->clientClip
, pGC
->clientClip
);
680 RegionTranslate(portPriv
->clientClip
, pGC
->clipOrg
.x
, pGC
->clipOrg
.y
);
682 else if (portPriv
->clientClip
) { /* free the old clientClip */
683 RegionDestroy(portPriv
->clientClip
);
684 portPriv
->clientClip
= NULL
;
687 /* get rid of the old clip list */
688 if (portPriv
->pCompositeClip
&& portPriv
->FreeCompositeClip
) {
689 RegionDestroy(portPriv
->pCompositeClip
);
692 portPriv
->pCompositeClip
= pGC
->pCompositeClip
;
693 portPriv
->FreeCompositeClip
= FALSE
;
694 portPriv
->subWindowMode
= pGC
->subWindowMode
;
698 xf86XVCopyCompositeClip(XvPortRecPrivatePtr portPriv
,
699 GCPtr pGC
, DrawablePtr pDraw
)
701 if (!portPriv
->clientClip
)
702 portPriv
->clientClip
= RegionCreate(NullBox
, 1);
703 /* Keep the original GC composite clip around for ReputImage */
704 RegionCopy(portPriv
->clientClip
, pGC
->pCompositeClip
);
705 RegionTranslate(portPriv
->clientClip
, -pDraw
->x
, -pDraw
->y
);
707 /* get rid of the old clip list */
708 if (portPriv
->pCompositeClip
&& portPriv
->FreeCompositeClip
)
709 RegionDestroy(portPriv
->pCompositeClip
);
711 portPriv
->pCompositeClip
= pGC
->pCompositeClip
;
712 portPriv
->FreeCompositeClip
= FALSE
;
713 portPriv
->subWindowMode
= pGC
->subWindowMode
;
717 xf86XVRegetVideo(XvPortRecPrivatePtr portPriv
)
720 RegionRec ClipRegion
;
723 Bool clippedAway
= FALSE
;
725 xf86XVUpdateCompositeClip(portPriv
);
727 /* translate the video region to the screen */
728 WinBox
.x1
= portPriv
->pDraw
->x
+ portPriv
->drw_x
;
729 WinBox
.y1
= portPriv
->pDraw
->y
+ portPriv
->drw_y
;
730 WinBox
.x2
= WinBox
.x1
+ portPriv
->drw_w
;
731 WinBox
.y2
= WinBox
.y1
+ portPriv
->drw_h
;
733 /* clip to the window composite clip */
734 RegionInit(&WinRegion
, &WinBox
, 1);
735 RegionNull(&ClipRegion
);
736 RegionIntersect(&ClipRegion
, &WinRegion
, portPriv
->pCompositeClip
);
738 /* that's all if it's totally obscured */
739 if (!RegionNotEmpty(&ClipRegion
)) {
741 goto CLIP_VIDEO_BAILOUT
;
744 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
745 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
748 ret
= (*portPriv
->AdaptorRec
->GetVideo
) (portPriv
->pScrn
,
749 portPriv
->vid_x
, portPriv
->vid_y
,
750 WinBox
.x1
, WinBox
.y1
,
751 portPriv
->vid_w
, portPriv
->vid_h
,
752 portPriv
->drw_w
, portPriv
->drw_h
,
753 &ClipRegion
, portPriv
->DevPriv
.ptr
,
757 portPriv
->isOn
= XV_ON
;
761 if ((clippedAway
|| (ret
!= Success
)) && portPriv
->isOn
== XV_ON
) {
762 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
763 portPriv
->DevPriv
.ptr
, FALSE
);
764 portPriv
->isOn
= XV_PENDING
;
767 /* This clip was copied and only good for one shot */
768 if (!portPriv
->FreeCompositeClip
)
769 portPriv
->pCompositeClip
= NULL
;
771 RegionUninit(&WinRegion
);
772 RegionUninit(&ClipRegion
);
778 xf86XVReputVideo(XvPortRecPrivatePtr portPriv
)
781 RegionRec ClipRegion
;
784 Bool clippedAway
= FALSE
;
786 xf86XVUpdateCompositeClip(portPriv
);
788 /* translate the video region to the screen */
789 WinBox
.x1
= portPriv
->pDraw
->x
+ portPriv
->drw_x
;
790 WinBox
.y1
= portPriv
->pDraw
->y
+ portPriv
->drw_y
;
791 WinBox
.x2
= WinBox
.x1
+ portPriv
->drw_w
;
792 WinBox
.y2
= WinBox
.y1
+ portPriv
->drw_h
;
794 /* clip to the window composite clip */
795 RegionInit(&WinRegion
, &WinBox
, 1);
796 RegionNull(&ClipRegion
);
797 RegionIntersect(&ClipRegion
, &WinRegion
, portPriv
->pCompositeClip
);
799 /* clip and translate to the viewport */
800 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
804 VPBox
.x1
= portPriv
->pScrn
->frameX0
;
805 VPBox
.y1
= portPriv
->pScrn
->frameY0
;
806 VPBox
.x2
= portPriv
->pScrn
->frameX1
+ 1;
807 VPBox
.y2
= portPriv
->pScrn
->frameY1
+ 1;
809 RegionInit(&VPReg
, &VPBox
, 1);
810 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
811 RegionUninit(&VPReg
);
814 /* that's all if it's totally obscured */
815 if (!RegionNotEmpty(&ClipRegion
)) {
817 goto CLIP_VIDEO_BAILOUT
;
820 /* bailout if we have to clip but the hardware doesn't support it */
821 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
822 BoxPtr clipBox
= RegionRects(&ClipRegion
);
824 if ((RegionNumRects(&ClipRegion
) != 1) ||
825 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
826 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
828 goto CLIP_VIDEO_BAILOUT
;
832 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
833 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
836 ret
= (*portPriv
->AdaptorRec
->PutVideo
) (portPriv
->pScrn
,
837 portPriv
->vid_x
, portPriv
->vid_y
,
838 WinBox
.x1
, WinBox
.y1
,
839 portPriv
->vid_w
, portPriv
->vid_h
,
840 portPriv
->drw_w
, portPriv
->drw_h
,
841 &ClipRegion
, portPriv
->DevPriv
.ptr
,
845 portPriv
->isOn
= XV_ON
;
849 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
850 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
851 portPriv
->DevPriv
.ptr
, FALSE
);
852 portPriv
->isOn
= XV_PENDING
;
855 /* This clip was copied and only good for one shot */
856 if (!portPriv
->FreeCompositeClip
)
857 portPriv
->pCompositeClip
= NULL
;
859 RegionUninit(&WinRegion
);
860 RegionUninit(&ClipRegion
);
865 /* Reput image/still */
867 xf86XVReputImage(XvPortRecPrivatePtr portPriv
)
870 RegionRec ClipRegion
;
873 Bool clippedAway
= FALSE
;
875 xf86XVUpdateCompositeClip(portPriv
);
877 /* the clip can get smaller over time */
878 RegionCopy(portPriv
->clientClip
, portPriv
->pCompositeClip
);
879 RegionTranslate(portPriv
->clientClip
,
880 -portPriv
->pDraw
->x
, -portPriv
->pDraw
->y
);
882 /* translate the video region to the screen */
883 WinBox
.x1
= portPriv
->pDraw
->x
+ portPriv
->drw_x
;
884 WinBox
.y1
= portPriv
->pDraw
->y
+ portPriv
->drw_y
;
885 WinBox
.x2
= WinBox
.x1
+ portPriv
->drw_w
;
886 WinBox
.y2
= WinBox
.y1
+ portPriv
->drw_h
;
888 /* clip to the window composite clip */
889 RegionInit(&WinRegion
, &WinBox
, 1);
890 RegionNull(&ClipRegion
);
891 RegionIntersect(&ClipRegion
, &WinRegion
, portPriv
->pCompositeClip
);
893 /* clip and translate to the viewport */
894 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
898 VPBox
.x1
= portPriv
->pScrn
->frameX0
;
899 VPBox
.y1
= portPriv
->pScrn
->frameY0
;
900 VPBox
.x2
= portPriv
->pScrn
->frameX1
+ 1;
901 VPBox
.y2
= portPriv
->pScrn
->frameY1
+ 1;
903 RegionInit(&VPReg
, &VPBox
, 1);
904 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
905 RegionUninit(&VPReg
);
908 /* that's all if it's totally obscured */
909 if (!RegionNotEmpty(&ClipRegion
)) {
911 goto CLIP_VIDEO_BAILOUT
;
914 /* bailout if we have to clip but the hardware doesn't support it */
915 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
916 BoxPtr clipBox
= RegionRects(&ClipRegion
);
918 if ((RegionNumRects(&ClipRegion
) != 1) ||
919 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
920 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
922 goto CLIP_VIDEO_BAILOUT
;
926 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
927 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
930 ret
= (*portPriv
->AdaptorRec
->ReputImage
) (portPriv
->pScrn
,
931 portPriv
->vid_x
, portPriv
->vid_y
,
932 WinBox
.x1
, WinBox
.y1
,
933 portPriv
->vid_w
, portPriv
->vid_h
,
934 portPriv
->drw_w
, portPriv
->drw_h
,
936 portPriv
->DevPriv
.ptr
,
939 portPriv
->isOn
= (ret
== Success
) ? XV_ON
: XV_OFF
;
943 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
944 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
945 portPriv
->DevPriv
.ptr
, FALSE
);
946 portPriv
->isOn
= XV_PENDING
;
949 /* This clip was copied and only good for one shot */
950 if (!portPriv
->FreeCompositeClip
)
951 portPriv
->pCompositeClip
= NULL
;
953 RegionUninit(&WinRegion
);
954 RegionUninit(&ClipRegion
);
960 xf86XVReputAllVideo(WindowPtr pWin
, pointer data
)
962 XF86XVWindowPtr WinPriv
= GET_XF86XV_WINDOW(pWin
);
965 if (WinPriv
->PortRec
->type
== XvInputMask
)
966 xf86XVReputVideo(WinPriv
->PortRec
);
968 xf86XVRegetVideo(WinPriv
->PortRec
);
969 WinPriv
= WinPriv
->next
;
972 return WT_WALKCHILDREN
;
976 xf86XVEnlistPortInWindow(WindowPtr pWin
, XvPortRecPrivatePtr portPriv
)
978 XF86XVWindowPtr winPriv
, PrivRoot
;
980 winPriv
= PrivRoot
= GET_XF86XV_WINDOW(pWin
);
982 /* Enlist our port in the window private */
984 if (winPriv
->PortRec
== portPriv
) /* we're already listed */
986 winPriv
= winPriv
->next
;
990 winPriv
= calloc(1, sizeof(XF86XVWindowRec
));
993 winPriv
->PortRec
= portPriv
;
994 winPriv
->next
= PrivRoot
;
995 dixSetPrivate(&pWin
->devPrivates
, XF86XVWindowKey
, winPriv
);
998 portPriv
->pDraw
= (DrawablePtr
) pWin
;
1004 xf86XVRemovePortFromWindow(WindowPtr pWin
, XvPortRecPrivatePtr portPriv
)
1006 XF86XVWindowPtr winPriv
, prevPriv
= NULL
;
1008 winPriv
= GET_XF86XV_WINDOW(pWin
);
1011 if (winPriv
->PortRec
== portPriv
) {
1013 prevPriv
->next
= winPriv
->next
;
1015 dixSetPrivate(&pWin
->devPrivates
, XF86XVWindowKey
,
1021 winPriv
= winPriv
->next
;
1023 portPriv
->pDraw
= NULL
;
1024 if (portPriv
->ckeyFilled
) {
1025 RegionDestroy(portPriv
->ckeyFilled
);
1026 portPriv
->ckeyFilled
= NULL
;
1028 portPriv
->clipChanged
= FALSE
;
1032 xf86XVReputOrStopPort(XvPortRecPrivatePtr pPriv
, WindowPtr pWin
, Bool visible
)
1035 if (pPriv
->isOn
== XV_ON
) {
1036 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->pScrn
, pPriv
->DevPriv
.ptr
,
1038 pPriv
->isOn
= XV_PENDING
;
1041 if (!pPriv
->type
) /* overlaid still/image */
1042 xf86XVRemovePortFromWindow(pWin
, pPriv
);
1047 switch (pPriv
->type
) {
1049 xf86XVReputVideo(pPriv
);
1052 xf86XVRegetVideo(pPriv
);
1054 default: /* overlaid still/image */
1055 if (pPriv
->AdaptorRec
->ReputImage
)
1056 xf86XVReputImage(pPriv
);
1062 xf86XVReputOrStopAllPorts(ScrnInfoPtr pScrn
, Bool onlyChanged
)
1064 ScreenPtr pScreen
= xf86ScrnToScreen(pScrn
);
1065 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
1069 for (c
= pxvs
->nAdaptors
, pa
= pxvs
->pAdaptors
; c
> 0; c
--, pa
++) {
1070 XvPortPtr pPort
= pa
->pPorts
;
1072 for (i
= pa
->nPorts
; i
> 0; i
--, pPort
++) {
1073 XvPortRecPrivatePtr pPriv
=
1074 (XvPortRecPrivatePtr
) pPort
->devPriv
.ptr
;
1075 WindowPtr pWin
= (WindowPtr
) pPriv
->pDraw
;
1078 if (pPriv
->isOn
== XV_OFF
|| !pWin
)
1081 if (onlyChanged
&& !pPriv
->clipChanged
)
1084 visible
= pWin
->visibility
== VisibilityUnobscured
||
1085 pWin
->visibility
== VisibilityPartiallyObscured
;
1088 * Stop and remove still/images if
1089 * ReputImage isn't supported.
1091 if (!pPriv
->type
&& !pPriv
->AdaptorRec
->ReputImage
)
1094 xf86XVReputOrStopPort(pPriv
, pWin
, visible
);
1096 pPriv
->clipChanged
= FALSE
;
1101 /**** ScreenRec fields ****/
1104 xf86XVDestroyWindow(WindowPtr pWin
)
1106 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1107 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1108 XF86XVWindowPtr tmp
, WinPriv
= GET_XF86XV_WINDOW(pWin
);
1112 XvPortRecPrivatePtr pPriv
= WinPriv
->PortRec
;
1114 if (pPriv
->isOn
> XV_OFF
) {
1115 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->pScrn
, pPriv
->DevPriv
.ptr
,
1117 pPriv
->isOn
= XV_OFF
;
1120 pPriv
->pDraw
= NULL
;
1122 WinPriv
= WinPriv
->next
;
1126 dixSetPrivate(&pWin
->devPrivates
, XF86XVWindowKey
, NULL
);
1128 pScreen
->DestroyWindow
= ScreenPriv
->DestroyWindow
;
1129 ret
= (*pScreen
->DestroyWindow
) (pWin
);
1130 pScreen
->DestroyWindow
= xf86XVDestroyWindow
;
1136 xf86XVPostValidateTree(WindowPtr pWin
, WindowPtr pLayerWin
, VTKind kind
)
1139 XF86XVScreenPtr ScreenPriv
;
1143 pScreen
= pWin
->drawable
.pScreen
;
1145 pScreen
= pLayerWin
->drawable
.pScreen
;
1147 ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1148 pScrn
= xf86ScreenToScrn(pScreen
);
1150 xf86XVReputOrStopAllPorts(pScrn
, TRUE
);
1152 pScreen
->PostValidateTree
= ScreenPriv
->PostValidateTree
;
1153 if (pScreen
->PostValidateTree
) {
1154 (*pScreen
->PostValidateTree
) (pWin
, pLayerWin
, kind
);
1156 ScreenPriv
->PostValidateTree
= PostValidateTreeUndefined
;
1160 xf86XVWindowExposures(WindowPtr pWin
, RegionPtr reg1
, RegionPtr reg2
)
1162 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1163 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1164 XF86XVWindowPtr WinPriv
= GET_XF86XV_WINDOW(pWin
);
1165 XvPortRecPrivatePtr pPriv
;
1168 AreasExposed
= (WinPriv
&& reg1
&& RegionNotEmpty(reg1
));
1170 pScreen
->WindowExposures
= ScreenPriv
->WindowExposures
;
1171 (*pScreen
->WindowExposures
) (pWin
, reg1
, reg2
);
1172 pScreen
->WindowExposures
= xf86XVWindowExposures
;
1174 /* filter out XClearWindow/Area */
1179 Bool visible
= TRUE
;
1181 pPriv
= WinPriv
->PortRec
;
1184 * Stop and remove still/images if areas were exposed and
1185 * ReputImage isn't supported.
1187 if (!pPriv
->type
&& !pPriv
->AdaptorRec
->ReputImage
)
1188 visible
= !AreasExposed
;
1191 * Subtract exposed areas from overlaid image to match textured video
1194 if (!pPriv
->type
&& pPriv
->clientClip
)
1195 RegionSubtract(pPriv
->clientClip
, pPriv
->clientClip
, reg1
);
1197 if (visible
&& pPriv
->ckeyFilled
) {
1201 RegionCopy(&tmp
, reg1
);
1202 RegionTranslate(&tmp
, pWin
->drawable
.x
, pWin
->drawable
.y
);
1203 RegionSubtract(pPriv
->ckeyFilled
, pPriv
->ckeyFilled
, &tmp
);
1206 WinPriv
= WinPriv
->next
;
1207 xf86XVReputOrStopPort(pPriv
, pWin
, visible
);
1209 pPriv
->clipChanged
= FALSE
;
1214 xf86XVClipNotify(WindowPtr pWin
, int dx
, int dy
)
1216 ScreenPtr pScreen
= pWin
->drawable
.pScreen
;
1217 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1218 XF86XVWindowPtr WinPriv
= GET_XF86XV_WINDOW(pWin
);
1219 XvPortRecPrivatePtr pPriv
;
1222 pPriv
= WinPriv
->PortRec
;
1224 if (pPriv
->pCompositeClip
&& pPriv
->FreeCompositeClip
)
1225 RegionDestroy(pPriv
->pCompositeClip
);
1227 pPriv
->pCompositeClip
= NULL
;
1229 if (pPriv
->AdaptorRec
->ClipNotify
)
1230 (*pPriv
->AdaptorRec
->ClipNotify
) (pPriv
->pScrn
, pPriv
->DevPriv
.ptr
,
1233 pPriv
->clipChanged
= TRUE
;
1235 if (ScreenPriv
->PostValidateTree
== PostValidateTreeUndefined
) {
1236 ScreenPriv
->PostValidateTree
= pScreen
->PostValidateTree
;
1237 pScreen
->PostValidateTree
= xf86XVPostValidateTree
;
1240 WinPriv
= WinPriv
->next
;
1243 if (ScreenPriv
->ClipNotify
) {
1244 pScreen
->ClipNotify
= ScreenPriv
->ClipNotify
;
1245 (*pScreen
->ClipNotify
) (pWin
, dx
, dy
);
1246 pScreen
->ClipNotify
= xf86XVClipNotify
;
1250 /**** Required XvScreenRec fields ****/
1253 xf86XVCloseScreen(ScreenPtr pScreen
)
1255 ScrnInfoPtr pScrn
= xf86ScreenToScrn(pScreen
);
1256 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
1257 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1264 pScreen
->DestroyWindow
= ScreenPriv
->DestroyWindow
;
1265 pScreen
->WindowExposures
= ScreenPriv
->WindowExposures
;
1266 pScreen
->ClipNotify
= ScreenPriv
->ClipNotify
;
1268 pScrn
->EnterVT
= ScreenPriv
->EnterVT
;
1269 pScrn
->LeaveVT
= ScreenPriv
->LeaveVT
;
1270 pScrn
->AdjustFrame
= ScreenPriv
->AdjustFrame
;
1271 pScrn
->ModeSet
= ScreenPriv
->ModeSet
;
1273 for (c
= 0, pa
= pxvs
->pAdaptors
; c
< pxvs
->nAdaptors
; c
++, pa
++) {
1274 xf86XVFreeAdaptor(pa
);
1277 free(pxvs
->pAdaptors
);
1283 xf86XVQueryAdaptors(ScreenPtr pScreen
,
1284 XvAdaptorPtr
* p_pAdaptors
, int *p_nAdaptors
)
1286 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
1288 *p_nAdaptors
= pxvs
->nAdaptors
;
1289 *p_pAdaptors
= pxvs
->pAdaptors
;
1294 /**** ScrnInfoRec fields ****/
1297 xf86XVEnterVT(ScrnInfoPtr pScrn
)
1299 ScreenPtr pScreen
= xf86ScrnToScreen(pScrn
);
1300 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1303 pScrn
->EnterVT
= ScreenPriv
->EnterVT
;
1304 ret
= (*ScreenPriv
->EnterVT
) (pScrn
);
1305 ScreenPriv
->EnterVT
= pScrn
->EnterVT
;
1306 pScrn
->EnterVT
= xf86XVEnterVT
;
1309 WalkTree(pScreen
, xf86XVReputAllVideo
, 0);
1315 xf86XVLeaveVT(ScrnInfoPtr pScrn
)
1317 ScreenPtr pScreen
= xf86ScrnToScreen(pScrn
);
1318 XvScreenPtr pxvs
= GET_XV_SCREEN(pScreen
);
1319 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1320 XvAdaptorPtr pAdaptor
;
1322 XvPortRecPrivatePtr pPriv
;
1325 for (i
= 0; i
< pxvs
->nAdaptors
; i
++) {
1326 pAdaptor
= &pxvs
->pAdaptors
[i
];
1327 for (j
= 0; j
< pAdaptor
->nPorts
; j
++) {
1328 pPort
= &pAdaptor
->pPorts
[j
];
1329 pPriv
= (XvPortRecPrivatePtr
) pPort
->devPriv
.ptr
;
1330 if (pPriv
->isOn
> XV_OFF
) {
1332 (*pPriv
->AdaptorRec
->StopVideo
) (pPriv
->pScrn
,
1333 pPriv
->DevPriv
.ptr
, TRUE
);
1334 pPriv
->isOn
= XV_OFF
;
1336 if (pPriv
->pCompositeClip
&& pPriv
->FreeCompositeClip
)
1337 RegionDestroy(pPriv
->pCompositeClip
);
1339 pPriv
->pCompositeClip
= NULL
;
1341 if (!pPriv
->type
&& pPriv
->pDraw
) { /* still */
1342 xf86XVRemovePortFromWindow((WindowPtr
) pPriv
->pDraw
, pPriv
);
1348 pScrn
->LeaveVT
= ScreenPriv
->LeaveVT
;
1349 (*ScreenPriv
->LeaveVT
) (pScrn
);
1350 ScreenPriv
->LeaveVT
= pScrn
->LeaveVT
;
1351 pScrn
->LeaveVT
= xf86XVLeaveVT
;
1355 xf86XVAdjustFrame(ScrnInfoPtr pScrn
, int x
, int y
)
1357 ScreenPtr pScreen
= xf86ScrnToScreen(pScrn
);
1358 XF86XVScreenPtr ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1360 if (ScreenPriv
->AdjustFrame
) {
1361 pScrn
->AdjustFrame
= ScreenPriv
->AdjustFrame
;
1362 (*pScrn
->AdjustFrame
) (pScrn
, x
, y
);
1363 pScrn
->AdjustFrame
= xf86XVAdjustFrame
;
1366 xf86XVReputOrStopAllPorts(pScrn
, FALSE
);
1370 xf86XVModeSet(ScrnInfoPtr pScrn
)
1372 ScreenPtr pScreen
= xf86ScrnToScreen(pScrn
);
1373 XF86XVScreenPtr ScreenPriv
;
1375 /* Can be called before pScrn->pScreen is set */
1379 ScreenPriv
= GET_XF86XV_SCREEN(pScreen
);
1381 if (ScreenPriv
->ModeSet
) {
1382 pScrn
->ModeSet
= ScreenPriv
->ModeSet
;
1383 (*pScrn
->ModeSet
) (pScrn
);
1384 pScrn
->ModeSet
= xf86XVModeSet
;
1387 xf86XVReputOrStopAllPorts(pScrn
, FALSE
);
1390 /**** XvAdaptorRec fields ****/
1393 xf86XVAllocatePort(unsigned long port
, XvPortPtr pPort
, XvPortPtr
* ppPort
)
1400 xf86XVFreePort(XvPortPtr pPort
)
1406 xf86XVPutVideo(ClientPtr client
,
1410 INT16 vid_x
, INT16 vid_y
,
1411 CARD16 vid_w
, CARD16 vid_h
,
1412 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1414 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1417 /* No dumping video to pixmaps... For now anyhow */
1418 if (pDraw
->type
!= DRAWABLE_WINDOW
) {
1419 pPort
->pDraw
= (DrawablePtr
) NULL
;
1423 /* If we are changing windows, unregister our port in the old window */
1424 if (portPriv
->pDraw
&& (portPriv
->pDraw
!= pDraw
))
1425 xf86XVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1427 /* Register our port with the new window */
1428 result
= xf86XVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1429 if (result
!= Success
)
1432 portPriv
->type
= XvInputMask
;
1434 /* save a copy of these parameters */
1435 portPriv
->vid_x
= vid_x
;
1436 portPriv
->vid_y
= vid_y
;
1437 portPriv
->vid_w
= vid_w
;
1438 portPriv
->vid_h
= vid_h
;
1439 portPriv
->drw_x
= drw_x
;
1440 portPriv
->drw_y
= drw_y
;
1441 portPriv
->drw_w
= drw_w
;
1442 portPriv
->drw_h
= drw_h
;
1444 /* make sure we have the most recent copy of the clientClip */
1445 xf86XVCopyClip(portPriv
, pGC
);
1447 /* To indicate to the DI layer that we were successful */
1448 pPort
->pDraw
= pDraw
;
1450 if (!portPriv
->pScrn
->vtSema
)
1451 return Success
; /* Success ? */
1453 return (xf86XVReputVideo(portPriv
));
1457 xf86XVPutStill(ClientPtr client
,
1461 INT16 vid_x
, INT16 vid_y
,
1462 CARD16 vid_w
, CARD16 vid_h
,
1463 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1465 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1466 RegionRec WinRegion
;
1467 RegionRec ClipRegion
;
1470 Bool clippedAway
= FALSE
;
1472 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1475 if (!portPriv
->pScrn
->vtSema
)
1476 return Success
; /* Success ? */
1478 WinBox
.x1
= pDraw
->x
+ drw_x
;
1479 WinBox
.y1
= pDraw
->y
+ drw_y
;
1480 WinBox
.x2
= WinBox
.x1
+ drw_w
;
1481 WinBox
.y2
= WinBox
.y1
+ drw_h
;
1483 xf86XVCopyCompositeClip(portPriv
, pGC
, pDraw
);
1485 RegionInit(&WinRegion
, &WinBox
, 1);
1486 RegionNull(&ClipRegion
);
1487 RegionIntersect(&ClipRegion
, &WinRegion
, pGC
->pCompositeClip
);
1489 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
1493 VPBox
.x1
= portPriv
->pScrn
->frameX0
;
1494 VPBox
.y1
= portPriv
->pScrn
->frameY0
;
1495 VPBox
.x2
= portPriv
->pScrn
->frameX1
+ 1;
1496 VPBox
.y2
= portPriv
->pScrn
->frameY1
+ 1;
1498 RegionInit(&VPReg
, &VPBox
, 1);
1499 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
1500 RegionUninit(&VPReg
);
1503 if (portPriv
->pDraw
) {
1504 xf86XVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1507 if (!RegionNotEmpty(&ClipRegion
)) {
1509 goto PUT_STILL_BAILOUT
;
1512 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
1513 BoxPtr clipBox
= RegionRects(&ClipRegion
);
1515 if ((RegionNumRects(&ClipRegion
) != 1) ||
1516 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
1517 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
1519 goto PUT_STILL_BAILOUT
;
1523 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
1524 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
1527 ret
= (*portPriv
->AdaptorRec
->PutStill
) (portPriv
->pScrn
,
1528 vid_x
, vid_y
, WinBox
.x1
, WinBox
.y1
,
1529 vid_w
, vid_h
, drw_w
, drw_h
,
1530 &ClipRegion
, portPriv
->DevPriv
.ptr
,
1533 if ((ret
== Success
) &&
1534 (portPriv
->AdaptorRec
->flags
& VIDEO_OVERLAID_STILLS
)) {
1536 xf86XVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1537 portPriv
->isOn
= XV_ON
;
1538 portPriv
->vid_x
= vid_x
;
1539 portPriv
->vid_y
= vid_y
;
1540 portPriv
->vid_w
= vid_w
;
1541 portPriv
->vid_h
= vid_h
;
1542 portPriv
->drw_x
= drw_x
;
1543 portPriv
->drw_y
= drw_y
;
1544 portPriv
->drw_w
= drw_w
;
1545 portPriv
->drw_h
= drw_h
;
1546 portPriv
->type
= 0; /* no mask means it's transient and should
1547 not be reput once it's removed */
1548 pPort
->pDraw
= pDraw
; /* make sure we can get stop requests */
1553 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
1554 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
1555 portPriv
->DevPriv
.ptr
, FALSE
);
1556 portPriv
->isOn
= XV_PENDING
;
1559 /* This clip was copied and only good for one shot */
1560 if (!portPriv
->FreeCompositeClip
)
1561 portPriv
->pCompositeClip
= NULL
;
1563 RegionUninit(&WinRegion
);
1564 RegionUninit(&ClipRegion
);
1570 xf86XVGetVideo(ClientPtr client
,
1574 INT16 vid_x
, INT16 vid_y
,
1575 CARD16 vid_w
, CARD16 vid_h
,
1576 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1578 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1581 /* No pixmaps... For now anyhow */
1582 if (pDraw
->type
!= DRAWABLE_WINDOW
) {
1583 pPort
->pDraw
= (DrawablePtr
) NULL
;
1587 /* If we are changing windows, unregister our port in the old window */
1588 if (portPriv
->pDraw
&& (portPriv
->pDraw
!= pDraw
))
1589 xf86XVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1591 /* Register our port with the new window */
1592 result
= xf86XVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1593 if (result
!= Success
)
1596 portPriv
->type
= XvOutputMask
;
1598 /* save a copy of these parameters */
1599 portPriv
->vid_x
= vid_x
;
1600 portPriv
->vid_y
= vid_y
;
1601 portPriv
->vid_w
= vid_w
;
1602 portPriv
->vid_h
= vid_h
;
1603 portPriv
->drw_x
= drw_x
;
1604 portPriv
->drw_y
= drw_y
;
1605 portPriv
->drw_w
= drw_w
;
1606 portPriv
->drw_h
= drw_h
;
1608 /* make sure we have the most recent copy of the clientClip */
1609 xf86XVCopyClip(portPriv
, pGC
);
1611 /* To indicate to the DI layer that we were successful */
1612 pPort
->pDraw
= pDraw
;
1614 if (!portPriv
->pScrn
->vtSema
)
1615 return Success
; /* Success ? */
1617 return (xf86XVRegetVideo(portPriv
));
1621 xf86XVGetStill(ClientPtr client
,
1625 INT16 vid_x
, INT16 vid_y
,
1626 CARD16 vid_w
, CARD16 vid_h
,
1627 INT16 drw_x
, INT16 drw_y
, CARD16 drw_w
, CARD16 drw_h
)
1629 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1630 RegionRec WinRegion
;
1631 RegionRec ClipRegion
;
1634 Bool clippedAway
= FALSE
;
1636 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1639 if (!portPriv
->pScrn
->vtSema
)
1640 return Success
; /* Success ? */
1642 WinBox
.x1
= pDraw
->x
+ drw_x
;
1643 WinBox
.y1
= pDraw
->y
+ drw_y
;
1644 WinBox
.x2
= WinBox
.x1
+ drw_w
;
1645 WinBox
.y2
= WinBox
.y1
+ drw_h
;
1647 RegionInit(&WinRegion
, &WinBox
, 1);
1648 RegionNull(&ClipRegion
);
1649 RegionIntersect(&ClipRegion
, &WinRegion
, pGC
->pCompositeClip
);
1651 if (portPriv
->pDraw
) {
1652 xf86XVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1655 if (!RegionNotEmpty(&ClipRegion
)) {
1657 goto GET_STILL_BAILOUT
;
1660 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
1661 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
1664 ret
= (*portPriv
->AdaptorRec
->GetStill
) (portPriv
->pScrn
,
1665 vid_x
, vid_y
, WinBox
.x1
, WinBox
.y1
,
1666 vid_w
, vid_h
, drw_w
, drw_h
,
1667 &ClipRegion
, portPriv
->DevPriv
.ptr
,
1672 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
1673 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
1674 portPriv
->DevPriv
.ptr
, FALSE
);
1675 portPriv
->isOn
= XV_PENDING
;
1678 RegionUninit(&WinRegion
);
1679 RegionUninit(&ClipRegion
);
1685 xf86XVStopVideo(ClientPtr client
, XvPortPtr pPort
, DrawablePtr pDraw
)
1687 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1689 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1692 xf86XVRemovePortFromWindow((WindowPtr
) pDraw
, portPriv
);
1694 if (!portPriv
->pScrn
->vtSema
)
1695 return Success
; /* Success ? */
1697 /* Must free resources. */
1699 if (portPriv
->isOn
> XV_OFF
) {
1700 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
1701 portPriv
->DevPriv
.ptr
, TRUE
);
1702 portPriv
->isOn
= XV_OFF
;
1709 xf86XVSetPortAttribute(ClientPtr client
,
1710 XvPortPtr pPort
, Atom attribute
, INT32 value
)
1712 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1714 return ((*portPriv
->AdaptorRec
->SetPortAttribute
) (portPriv
->pScrn
,
1716 portPriv
->DevPriv
.ptr
));
1720 xf86XVGetPortAttribute(ClientPtr client
,
1721 XvPortPtr pPort
, Atom attribute
, INT32
*p_value
)
1723 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1725 return ((*portPriv
->AdaptorRec
->GetPortAttribute
) (portPriv
->pScrn
,
1727 portPriv
->DevPriv
.ptr
));
1731 xf86XVQueryBestSize(ClientPtr client
,
1734 CARD16 vid_w
, CARD16 vid_h
,
1735 CARD16 drw_w
, CARD16 drw_h
,
1736 unsigned int *p_w
, unsigned int *p_h
)
1738 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1740 (*portPriv
->AdaptorRec
->QueryBestSize
) (portPriv
->pScrn
,
1741 (Bool
) motion
, vid_w
, vid_h
, drw_w
,
1743 portPriv
->DevPriv
.ptr
);
1749 xf86XVPutImage(ClientPtr client
,
1753 INT16 src_x
, INT16 src_y
,
1754 CARD16 src_w
, CARD16 src_h
,
1755 INT16 drw_x
, INT16 drw_y
,
1756 CARD16 drw_w
, CARD16 drw_h
,
1758 unsigned char *data
, Bool sync
, CARD16 width
, CARD16 height
)
1760 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1761 RegionRec WinRegion
;
1762 RegionRec ClipRegion
;
1765 Bool clippedAway
= FALSE
;
1767 if (pDraw
->type
!= DRAWABLE_WINDOW
)
1770 if (!portPriv
->pScrn
->vtSema
)
1771 return Success
; /* Success ? */
1773 xf86XVCopyCompositeClip(portPriv
, pGC
, pDraw
);
1775 WinBox
.x1
= pDraw
->x
+ drw_x
;
1776 WinBox
.y1
= pDraw
->y
+ drw_y
;
1777 WinBox
.x2
= WinBox
.x1
+ drw_w
;
1778 WinBox
.y2
= WinBox
.y1
+ drw_h
;
1780 RegionInit(&WinRegion
, &WinBox
, 1);
1781 RegionNull(&ClipRegion
);
1782 RegionIntersect(&ClipRegion
, &WinRegion
, pGC
->pCompositeClip
);
1784 if (portPriv
->AdaptorRec
->flags
& VIDEO_CLIP_TO_VIEWPORT
) {
1788 VPBox
.x1
= portPriv
->pScrn
->frameX0
;
1789 VPBox
.y1
= portPriv
->pScrn
->frameY0
;
1790 VPBox
.x2
= portPriv
->pScrn
->frameX1
+ 1;
1791 VPBox
.y2
= portPriv
->pScrn
->frameY1
+ 1;
1793 RegionInit(&VPReg
, &VPBox
, 1);
1794 RegionIntersect(&ClipRegion
, &ClipRegion
, &VPReg
);
1795 RegionUninit(&VPReg
);
1798 /* If we are changing windows, unregister our port in the old window */
1799 if (portPriv
->pDraw
&& (portPriv
->pDraw
!= pDraw
))
1800 xf86XVRemovePortFromWindow((WindowPtr
) (portPriv
->pDraw
), portPriv
);
1802 /* Register our port with the new window */
1803 ret
= xf86XVEnlistPortInWindow((WindowPtr
) pDraw
, portPriv
);
1805 goto PUT_IMAGE_BAILOUT
;
1807 if (!RegionNotEmpty(&ClipRegion
)) {
1809 goto PUT_IMAGE_BAILOUT
;
1812 if (portPriv
->AdaptorRec
->flags
& VIDEO_NO_CLIPPING
) {
1813 BoxPtr clipBox
= RegionRects(&ClipRegion
);
1815 if ((RegionNumRects(&ClipRegion
) != 1) ||
1816 (clipBox
->x1
!= WinBox
.x1
) || (clipBox
->x2
!= WinBox
.x2
) ||
1817 (clipBox
->y1
!= WinBox
.y1
) || (clipBox
->y2
!= WinBox
.y2
)) {
1819 goto PUT_IMAGE_BAILOUT
;
1823 if (portPriv
->AdaptorRec
->flags
& VIDEO_INVERT_CLIPLIST
) {
1824 RegionSubtract(&ClipRegion
, &WinRegion
, &ClipRegion
);
1827 ret
= (*portPriv
->AdaptorRec
->PutImage
) (portPriv
->pScrn
,
1828 src_x
, src_y
, WinBox
.x1
, WinBox
.y1
,
1829 src_w
, src_h
, drw_w
, drw_h
,
1830 format
->id
, data
, width
, height
,
1832 portPriv
->DevPriv
.ptr
, pDraw
);
1834 if ((ret
== Success
) &&
1835 (portPriv
->AdaptorRec
->flags
& VIDEO_OVERLAID_IMAGES
)) {
1837 portPriv
->isOn
= XV_ON
;
1838 portPriv
->vid_x
= src_x
;
1839 portPriv
->vid_y
= src_y
;
1840 portPriv
->vid_w
= src_w
;
1841 portPriv
->vid_h
= src_h
;
1842 portPriv
->drw_x
= drw_x
;
1843 portPriv
->drw_y
= drw_y
;
1844 portPriv
->drw_w
= drw_w
;
1845 portPriv
->drw_h
= drw_h
;
1846 portPriv
->type
= 0; /* no mask means it's transient and should
1847 not be reput once it's removed */
1848 pPort
->pDraw
= pDraw
; /* make sure we can get stop requests */
1853 if ((clippedAway
|| (ret
!= Success
)) && (portPriv
->isOn
== XV_ON
)) {
1854 (*portPriv
->AdaptorRec
->StopVideo
) (portPriv
->pScrn
,
1855 portPriv
->DevPriv
.ptr
, FALSE
);
1856 portPriv
->isOn
= XV_PENDING
;
1859 /* This clip was copied and only good for one shot */
1860 if (!portPriv
->FreeCompositeClip
)
1861 portPriv
->pCompositeClip
= NULL
;
1863 RegionUninit(&WinRegion
);
1864 RegionUninit(&ClipRegion
);
1870 xf86XVQueryImageAttributes(ClientPtr client
,
1874 CARD16
*height
, int *pitches
, int *offsets
)
1876 XvPortRecPrivatePtr portPriv
= (XvPortRecPrivatePtr
) (pPort
->devPriv
.ptr
);
1878 return (*portPriv
->AdaptorRec
->QueryImageAttributes
) (portPriv
->pScrn
,
1885 xf86XVFillKeyHelperDrawable(DrawablePtr pDraw
, CARD32 key
, RegionPtr fillboxes
)
1887 ScreenPtr pScreen
= pDraw
->pScreen
;
1888 ChangeGCVal pval
[2];
1889 BoxPtr pbox
= RegionRects(fillboxes
);
1890 int i
, nbox
= RegionNumRects(fillboxes
);
1894 if (!xf86ScreenToScrn(pScreen
)->vtSema
)
1897 gc
= GetScratchGC(pDraw
->depth
, pScreen
);
1899 pval
[1].val
= IncludeInferiors
;
1900 (void) ChangeGC(NullClient
, gc
, GCForeground
| GCSubwindowMode
, pval
);
1901 ValidateGC(pDraw
, gc
);
1903 rects
= malloc(nbox
* sizeof(xRectangle
));
1905 for (i
= 0; i
< nbox
; i
++, pbox
++) {
1906 rects
[i
].x
= pbox
->x1
- pDraw
->x
;
1907 rects
[i
].y
= pbox
->y1
- pDraw
->y
;
1908 rects
[i
].width
= pbox
->x2
- pbox
->x1
;
1909 rects
[i
].height
= pbox
->y2
- pbox
->y1
;
1912 (*gc
->ops
->PolyFillRect
) (pDraw
, gc
, nbox
, rects
);
1919 xf86XVFillKeyHelper(ScreenPtr pScreen
, CARD32 key
, RegionPtr fillboxes
)
1921 xf86XVFillKeyHelperDrawable(&pScreen
->root
->drawable
, key
, fillboxes
);
1925 xf86XVFillKeyHelperPort(DrawablePtr pDraw
, pointer data
, CARD32 key
,
1926 RegionPtr clipboxes
, Bool fillEverything
)
1928 WindowPtr pWin
= (WindowPtr
) pDraw
;
1929 XF86XVWindowPtr WinPriv
= GET_XF86XV_WINDOW(pWin
);
1930 XvPortRecPrivatePtr portPriv
= NULL
;
1932 RegionPtr fillboxes
;
1935 XvPortRecPrivatePtr pPriv
= WinPriv
->PortRec
;
1937 if (data
== pPriv
->DevPriv
.ptr
) {
1942 WinPriv
= WinPriv
->next
;
1948 if (!portPriv
->ckeyFilled
)
1949 portPriv
->ckeyFilled
= RegionCreate(NULL
, 0);
1951 if (!fillEverything
) {
1954 RegionSubtract(fillboxes
, clipboxes
, portPriv
->ckeyFilled
);
1956 if (!RegionNotEmpty(fillboxes
))
1960 fillboxes
= clipboxes
;
1962 RegionCopy(portPriv
->ckeyFilled
, clipboxes
);
1964 xf86XVFillKeyHelperDrawable(pDraw
, key
, fillboxes
);
1966 if (!fillEverything
)
1970 /* xf86XVClipVideoHelper -
1972 Takes the dst box in standard X BoxRec form (top and left
1973 edges inclusive, bottom and right exclusive). The new dst
1974 box is returned. The source boundaries are given (x1, y1
1975 inclusive, x2, y2 exclusive) and returned are the new source
1976 boundaries in 16.16 fixed point.
1980 xf86XVClipVideoHelper(BoxPtr dst
,
1984 INT32
*yb
, RegionPtr reg
, INT32 width
, INT32 height
)
1986 double xsw
, xdw
, ysw
, ydw
;
1988 BoxPtr extents
= RegionExtents(reg
);
1991 xsw
= (*xb
- *xa
) << 16;
1992 xdw
= dst
->x2
- dst
->x1
;
1993 ysw
= (*yb
- *ya
) << 16;
1994 ydw
= dst
->y2
- dst
->y1
;
2001 diff
= extents
->x1
- dst
->x1
;
2003 dst
->x1
= extents
->x1
;
2004 *xa
+= (diff
* xsw
) / xdw
;
2006 diff
= dst
->x2
- extents
->x2
;
2008 dst
->x2
= extents
->x2
;
2009 *xb
-= (diff
* xsw
) / xdw
;
2011 diff
= extents
->y1
- dst
->y1
;
2013 dst
->y1
= extents
->y1
;
2014 *ya
+= (diff
* ysw
) / ydw
;
2016 diff
= dst
->y2
- extents
->y2
;
2018 dst
->y2
= extents
->y2
;
2019 *yb
-= (diff
* ysw
) / ydw
;
2023 diff
= (((-*xa
) * xdw
) + xsw
- 1) / xsw
;
2025 *xa
+= (diff
* xsw
) / xdw
;
2027 delta
= *xb
- (width
<< 16);
2029 diff
= ((delta
* xdw
) + xsw
- 1) / xsw
;
2031 *xb
-= (diff
* xsw
) / xdw
;
2037 diff
= (((-*ya
) * ydw
) + ysw
- 1) / ysw
;
2039 *ya
+= (diff
* ysw
) / ydw
;
2041 delta
= *yb
- (height
<< 16);
2043 diff
= ((delta
* ydw
) + ysw
- 1) / ysw
;
2045 *yb
-= (diff
* ysw
) / ydw
;
2050 if ((dst
->x1
> extents
->x1
) || (dst
->x2
< extents
->x2
) ||
2051 (dst
->y1
> extents
->y1
) || (dst
->y2
< extents
->y2
)) {
2054 RegionInit(&clipReg
, dst
, 1);
2055 RegionIntersect(reg
, reg
, &clipReg
);
2056 RegionUninit(&clipReg
);
2062 xf86XVCopyYUV12ToPacked(const void *srcy
,
2067 int srcPitchuv
, int dstPitch
, int h
, int w
)
2070 const CARD8
*Y
, *U
, *V
;
2075 for (j
= 0; j
< h
; j
++) {
2082 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
2083 Dst
[0] = Y
[0] | (Y
[1] << 16) | (U
[0] << 8) | (V
[0] << 24);
2084 Dst
[1] = Y
[2] | (Y
[3] << 16) | (U
[1] << 8) | (V
[1] << 24);
2085 Dst
[2] = Y
[4] | (Y
[5] << 16) | (U
[2] << 8) | (V
[2] << 24);
2086 Dst
[3] = Y
[6] | (Y
[7] << 16) | (U
[3] << 8) | (V
[3] << 24);
2088 /* This assumes a little-endian framebuffer */
2089 Dst
[0] = (Y
[0] << 24) | (Y
[1] << 8) | (U
[0] << 16) | V
[0];
2090 Dst
[1] = (Y
[2] << 24) | (Y
[3] << 8) | (U
[1] << 16) | V
[1];
2091 Dst
[2] = (Y
[4] << 24) | (Y
[5] << 8) | (U
[2] << 16) | V
[2];
2092 Dst
[3] = (Y
[6] << 24) | (Y
[7] << 8) | (U
[3] << 16) | V
[3];
2102 #if X_BYTE_ORDER == X_LITTLE_ENDIAN
2103 Dst
[0] = Y
[0] | (Y
[1] << 16) | (U
[0] << 8) | (V
[0] << 24);
2105 /* This assumes a little-endian framebuffer */
2106 Dst
[0] = (Y
[0] << 24) | (Y
[1] << 8) | (U
[0] << 16) | V
[0];
2114 dst
= (CARD8
*) dst
+ dstPitch
;
2115 srcy
= (const CARD8
*) srcy
+ srcPitchy
;
2117 srcu
= (const CARD8
*) srcu
+ srcPitchuv
;
2118 srcv
= (const CARD8
*) srcv
+ srcPitchuv
;
2124 xf86XVCopyPacked(const void *src
,
2125 void *dst
, int srcPitch
, int dstPitch
, int h
, int w
)
2157 src
= (const CARD8
*) src
+ srcPitch
;
2158 dst
= (CARD8
*) dst
+ dstPitch
;