2 * Copyright 2007 by VMware, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 * Except as contained in this notice, the name of the copyright holder(s)
23 * and author(s) shall not be used in advertising or otherwise to promote
24 * the sale, use or other dealings in this Software without prior written
25 * authorization from the copyright holder(s) and author(s).
31 * Xv extension support.
32 * See http://www.xfree86.org/current/DESIGN16.html
40 #include "pipe/p_compiler.h"
42 * We can't incude svga_types.h due to conflicting types for Bool.
44 typedef int64_t int64
;
45 typedef uint64_t uint64
;
47 typedef int32_t int32
;
48 typedef uint32_t uint32
;
50 typedef int16_t int16
;
51 typedef uint16_t uint16
;
54 typedef uint8_t uint8
;
56 #include "svga/include/svga_reg.h"
57 #include "svga/include/svga_escape.h"
58 #include "svga/include/svga_overlay.h"
60 #include "vmw_driver.h"
62 #include <X11/extensions/Xv.h>
65 #include "../../winsys/svga/drm/vmwgfx_drm.h"
67 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
70 * Number of videos that can be played simultaneously
72 #define VMWARE_VID_NUM_PORTS 1
75 * Using a dark shade as the default colorKey
77 #define VMWARE_VIDEO_COLORKEY 0x100701
82 #define VMWARE_VID_MAX_WIDTH 2048
83 #define VMWARE_VID_MAX_HEIGHT 2048
85 #define VMWARE_VID_NUM_ENCODINGS 1
86 static XF86VideoEncodingRec vmwareVideoEncodings
[] =
91 VMWARE_VID_MAX_WIDTH
, VMWARE_VID_MAX_HEIGHT
,
96 #define VMWARE_VID_NUM_FORMATS 2
97 static XF86VideoFormatRec vmwareVideoFormats
[] =
103 #define VMWARE_VID_NUM_IMAGES 3
104 static XF86ImageRec vmwareVideoImages
[] =
111 #define VMWARE_VID_NUM_ATTRIBUTES 2
112 static XF86AttributeRec vmwareVideoAttributes
[] =
115 XvGettable
| XvSettable
,
121 XvGettable
| XvSettable
,
124 "XV_AUTOPAINT_COLORKEY"
129 * Video frames are stored in a circular list of buffers.
130 * Must be power or two, See vmw_video_port_play.
132 #define VMWARE_VID_NUM_BUFFERS 1
135 * Defines the structure used to hold and pass video data to the host
137 struct vmw_video_buffer
143 struct vmw_dma_buffer
*buf
;
148 * Structure representing a single video stream, aka port.
150 * Ports maps one to one to a SVGA stream. Port is just
151 * what Xv calls a SVGA stream.
153 struct vmw_video_port
156 * Function prototype same as XvPutImage.
158 * This is either set to vmw_video_port_init or vmw_video_port_play.
159 * At init this function is set to port_init. In port_init we set it
160 * to port_play and call it, after initializing the struct.
162 int (*play
)(ScrnInfoPtr
, struct vmw_video_port
*,
163 short, short, short, short, short,
164 short, short, short, int, unsigned char*,
165 short, short, RegionPtr
);
167 /* values to go into the SVGAOverlayUnit */
172 /* round robin of buffers */
174 struct vmw_video_buffer bufs
[VMWARE_VID_NUM_BUFFERS
];
176 /* properties that applies to all buffers */
183 Bool isAutoPaintColorkey
;
188 * Structure holding all the infromation for video.
190 struct vmw_video_private
195 struct vmw_video_port port
[VMWARE_VID_NUM_PORTS
];
197 /** Used to store port pointers pointers */
198 DevUnion port_ptr
[VMWARE_VID_NUM_PORTS
];
203 * Callback functions exported to Xv, prefixed with vmw_xv_*.
205 static int vmw_xv_put_image(ScrnInfoPtr pScrn
, short src_x
, short src_y
,
206 short drw_x
, short drw_y
, short src_w
, short src_h
,
207 short drw_w
, short drw_h
, int image
,
208 unsigned char *buf
, short width
, short height
,
209 Bool sync
, RegionPtr clipBoxes
, pointer data
,
211 static void vmw_xv_stop_video(ScrnInfoPtr pScrn
, pointer data
, Bool Cleanup
);
212 static int vmw_xv_query_image_attributes(ScrnInfoPtr pScrn
, int format
,
213 unsigned short *width
,
214 unsigned short *height
, int *pitches
,
216 static int vmw_xv_set_port_attribute(ScrnInfoPtr pScrn
, Atom attribute
,
217 INT32 value
, pointer data
);
218 static int vmw_xv_get_port_attribute(ScrnInfoPtr pScrn
, Atom attribute
,
219 INT32
*value
, pointer data
);
220 static void vmw_xv_query_best_size(ScrnInfoPtr pScrn
, Bool motion
,
221 short vid_w
, short vid_h
, short drw_w
,
222 short drw_h
, unsigned int *p_w
,
223 unsigned int *p_h
, pointer data
);
229 static XF86VideoAdaptorPtr
vmw_video_init_adaptor(ScrnInfoPtr pScrn
, struct vmw_customizer
*vmw
);
231 static int vmw_video_port_init(ScrnInfoPtr pScrn
,
232 struct vmw_video_port
*port
,
233 short src_x
, short src_y
, short drw_x
,
234 short drw_y
, short src_w
, short src_h
,
235 short drw_w
, short drw_h
, int format
,
236 unsigned char *buf
, short width
,
237 short height
, RegionPtr clipBoxes
);
238 static int vmw_video_port_play(ScrnInfoPtr pScrn
, struct vmw_video_port
*port
,
239 short src_x
, short src_y
, short drw_x
,
240 short drw_y
, short src_w
, short src_h
,
241 short drw_w
, short drw_h
, int format
,
242 unsigned char *buf
, short width
,
243 short height
, RegionPtr clipBoxes
);
244 static void vmw_video_port_cleanup(ScrnInfoPtr pScrn
, struct vmw_video_port
*port
);
246 static int vmw_video_buffer_alloc(struct vmw_customizer
*vmw
, int size
,
247 struct vmw_video_buffer
*out
);
248 static int vmw_video_buffer_free(struct vmw_customizer
*vmw
,
249 struct vmw_video_buffer
*out
);
253 *-----------------------------------------------------------------------------
257 * Initializes Xv support.
260 * TRUE on success, FALSE on error.
263 * Xv support is initialized. Memory is allocated for all supported
266 *-----------------------------------------------------------------------------
270 vmw_video_init(struct vmw_customizer
*vmw
)
272 ScrnInfoPtr pScrn
= vmw
->pScrn
;
273 ScreenPtr pScreen
= pScrn
->pScreen
;
274 XF86VideoAdaptorPtr
*overlayAdaptors
, *newAdaptors
= NULL
;
275 XF86VideoAdaptorPtr newAdaptor
= NULL
;
277 unsigned int ntot
, nfree
;
279 debug_printf("%s: enter\n", __func__
);
281 if (vmw_ioctl_num_streams(vmw
, &ntot
, &nfree
) != 0) {
282 debug_printf("No stream ioctl support\n");
287 debug_printf("No free streams\n");
291 numAdaptors
= xf86XVListGenericAdaptors(pScrn
, &overlayAdaptors
);
293 newAdaptor
= vmw_video_init_adaptor(pScrn
, vmw
);
295 debug_printf("Failed to initialize Xv extension\n");
301 overlayAdaptors
= &newAdaptor
;
303 newAdaptors
= malloc((numAdaptors
+ 1) *
304 sizeof(XF86VideoAdaptorPtr
*));
306 xf86XVFreeVideoAdaptorRec(newAdaptor
);
310 memcpy(newAdaptors
, overlayAdaptors
,
311 numAdaptors
* sizeof(XF86VideoAdaptorPtr
));
312 newAdaptors
[numAdaptors
++] = newAdaptor
;
313 overlayAdaptors
= newAdaptors
;
316 if (!xf86XVScreenInit(pScreen
, overlayAdaptors
, numAdaptors
)) {
317 debug_printf("Failed to initialize Xv extension\n");
318 xf86XVFreeVideoAdaptorRec(newAdaptor
);
326 debug_printf("Initialized VMware Xv extension successfully\n");
333 *-----------------------------------------------------------------------------
343 * vmw->video_priv = NULL
345 *-----------------------------------------------------------------------------
349 vmw_video_close(struct vmw_customizer
*vmw
)
351 ScrnInfoPtr pScrn
= vmw
->pScrn
;
352 struct vmw_video_private
*video
;
355 debug_printf("%s: enter\n", __func__
);
357 video
= vmw
->video_priv
;
361 for (i
= 0; i
< VMWARE_VID_NUM_PORTS
; ++i
) {
362 /* make sure the port is stoped as well */
363 vmw_xv_stop_video(pScrn
, &video
->port
[i
], TRUE
);
364 vmw_ioctl_unref_stream(vmw
, video
->port
[i
].streamId
);
365 REGION_UNINIT(pScreen
, &video
->port
[i
].clipBoxes
);
369 /* XXX: I'm sure this function is missing code for turning off Xv */
371 free(vmw
->video_priv
);
372 vmw
->video_priv
= NULL
;
379 *-----------------------------------------------------------------------------
381 * vmw_video_stop_all --
383 * Stop all video streams from playing.
389 * All buffers are freed.
391 *-----------------------------------------------------------------------------
394 void vmw_video_stop_all(struct vmw_customizer
*vmw
)
396 ScrnInfoPtr pScrn
= vmw
->pScrn
;
397 struct vmw_video_private
*video
= vmw
->video_priv
;
400 debug_printf("%s: enter\n", __func__
);
405 for (i
= 0; i
< VMWARE_VID_NUM_PORTS
; ++i
) {
406 vmw_xv_stop_video(pScrn
, &video
->port
[i
], TRUE
);
412 *-----------------------------------------------------------------------------
414 * vmw_video_init_adaptor --
416 * Initializes a XF86VideoAdaptor structure with the capabilities and
417 * functions supported by this video driver.
420 * On success initialized XF86VideoAdaptor struct or NULL on error
425 *-----------------------------------------------------------------------------
428 static XF86VideoAdaptorPtr
429 vmw_video_init_adaptor(ScrnInfoPtr pScrn
, struct vmw_customizer
*vmw
)
431 XF86VideoAdaptorPtr adaptor
;
432 struct vmw_video_private
*video
;
435 debug_printf("%s: enter \n", __func__
);
437 adaptor
= xf86XVAllocateVideoAdaptorRec(pScrn
);
439 debug_printf("Not enough memory\n");
443 video
= calloc(1, sizeof(*video
));
445 debug_printf("Not enough memory.\n");
446 xf86XVFreeVideoAdaptorRec(adaptor
);
450 vmw
->video_priv
= video
;
452 adaptor
->type
= XvInputMask
| XvImageMask
| XvWindowMask
;
453 adaptor
->flags
= VIDEO_OVERLAID_IMAGES
| VIDEO_CLIP_TO_VIEWPORT
;
454 adaptor
->name
= "VMware Video Engine";
455 adaptor
->nEncodings
= VMWARE_VID_NUM_ENCODINGS
;
456 adaptor
->pEncodings
= vmwareVideoEncodings
;
457 adaptor
->nFormats
= VMWARE_VID_NUM_FORMATS
;
458 adaptor
->pFormats
= vmwareVideoFormats
;
459 adaptor
->nPorts
= VMWARE_VID_NUM_PORTS
;
460 adaptor
->pPortPrivates
= video
->port_ptr
;
462 for (i
= 0; i
< VMWARE_VID_NUM_PORTS
; ++i
) {
463 vmw_ioctl_claim_stream(vmw
, &video
->port
[i
].streamId
);
464 video
->port
[i
].play
= vmw_video_port_init
;
465 video
->port
[i
].flags
= SVGA_VIDEO_FLAG_COLORKEY
;
466 video
->port
[i
].colorKey
= VMWARE_VIDEO_COLORKEY
;
467 video
->port
[i
].isAutoPaintColorkey
= TRUE
;
468 REGION_NULL(pScrn
->pScreen
, &video
->port
[i
].clipBoxes
);
469 adaptor
->pPortPrivates
[i
].ptr
= &video
->port
[i
];
472 adaptor
->nAttributes
= VMWARE_VID_NUM_ATTRIBUTES
;
473 adaptor
->pAttributes
= vmwareVideoAttributes
;
475 adaptor
->nImages
= VMWARE_VID_NUM_IMAGES
;
476 adaptor
->pImages
= vmwareVideoImages
;
478 adaptor
->PutVideo
= NULL
;
479 adaptor
->PutStill
= NULL
;
480 adaptor
->GetVideo
= NULL
;
481 adaptor
->GetStill
= NULL
;
482 adaptor
->StopVideo
= vmw_xv_stop_video
;
483 adaptor
->SetPortAttribute
= vmw_xv_set_port_attribute
;
484 adaptor
->GetPortAttribute
= vmw_xv_get_port_attribute
;
485 adaptor
->QueryBestSize
= vmw_xv_query_best_size
;
486 adaptor
->PutImage
= vmw_xv_put_image
;
487 adaptor
->QueryImageAttributes
= vmw_xv_query_image_attributes
;
489 debug_printf("%s: done %p\n", __func__
, adaptor
);
496 *-----------------------------------------------------------------------------
498 * vmw_video_port_init --
500 * Initializes a video stream in response to the first PutImage() on a
501 * video stream. The process goes as follows:
502 * - Figure out characteristics according to format
503 * - Allocate offscreen memory
504 * - Pass on video to Play() functions
507 * Success or XvBadAlloc on failure.
510 * Video stream is initialized and its first frame sent to the host
511 * (done by VideoPlay() function called at the end)
513 *-----------------------------------------------------------------------------
517 vmw_video_port_init(ScrnInfoPtr pScrn
, struct vmw_video_port
*port
,
518 short src_x
, short src_y
, short drw_x
,
519 short drw_y
, short src_w
, short src_h
,
520 short drw_w
, short drw_h
, int format
,
521 unsigned char *buf
, short width
,
522 short height
, RegionPtr clipBoxes
)
524 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
528 debug_printf("\t%s: id %d, format %d\n", __func__
, port
->streamId
, format
);
532 /* init all the format attributes, used for buffers */
533 port
->size
= vmw_xv_query_image_attributes(pScrn
, format
, &w
, &h
,
534 port
->pitches
, port
->offsets
);
536 if (port
->size
== -1)
539 port
->play
= vmw_video_port_play
;
541 for (i
= 0; i
< VMWARE_VID_NUM_BUFFERS
; ++i
) {
542 ret
= vmw_video_buffer_alloc(vmw
, port
->size
, &port
->bufs
[i
]);
547 /* Free all allocated buffers on failure */
548 if (ret
!= Success
) {
549 for (--i
; i
>= 0; --i
) {
550 vmw_video_buffer_free(vmw
, &port
->bufs
[i
]);
557 REGION_COPY(pScrn
->pScreen
, &port
->clipBoxes
, clipBoxes
);
559 if (port
->isAutoPaintColorkey
)
560 xf86XVFillKeyHelper(pScrn
->pScreen
, port
->colorKey
, clipBoxes
);
562 xorg_flush(pScrn
->pScreen
);
564 return port
->play(pScrn
, port
, src_x
, src_y
, drw_x
, drw_y
, src_w
, src_h
,
565 drw_w
, drw_h
, format
, buf
, width
, height
, clipBoxes
);
570 *-----------------------------------------------------------------------------
572 * vmw_video_port_play --
574 * Sends all the attributes associated with the video frame using the
575 * FIFO ESCAPE mechanism to the host.
578 * Always returns Success.
583 *-----------------------------------------------------------------------------
587 vmw_video_port_play(ScrnInfoPtr pScrn
, struct vmw_video_port
*port
,
588 short src_x
, short src_y
, short drw_x
,
589 short drw_y
, short src_w
, short src_h
,
590 short drw_w
, short drw_h
, int format
,
591 unsigned char *buf
, short width
,
592 short height
, RegionPtr clipBoxes
)
594 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
595 struct drm_vmw_control_stream_arg arg
;
600 debug_printf("\t%s: enter\n", __func__
);
605 /* we don't update the ports size */
606 size
= vmw_xv_query_image_attributes(pScrn
, format
, &w
, &h
,
607 port
->pitches
, port
->offsets
);
609 if (size
> port
->size
) {
610 debug_printf("\t%s: Increase in size of Xv video frame streamId:%d.\n",
611 __func__
, port
->streamId
);
612 vmw_xv_stop_video(pScrn
, port
, TRUE
);
613 return port
->play(pScrn
, port
, src_x
, src_y
, drw_x
, drw_y
, src_w
,
614 src_h
, drw_w
, drw_h
, format
, buf
, width
, height
,
618 memcpy(port
->bufs
[port
->currBuf
].data
, buf
, port
->size
);
620 memset(&arg
, 0, sizeof(arg
));
622 arg
.stream_id
= port
->streamId
;
624 arg
.flags
= port
->flags
;
625 arg
.color_key
= port
->colorKey
;
626 arg
.handle
= port
->bufs
[port
->currBuf
].handle
;
628 arg
.size
= port
->size
;
639 arg
.pitch
[0] = port
->pitches
[0];
640 arg
.pitch
[1] = port
->pitches
[1];
641 arg
.pitch
[2] = port
->pitches
[2];
645 * Update the clipList and paint the colorkey, if required.
647 if (!REGION_EQUAL(pScrn
->pScreen
, &port
->clipBoxes
, clipBoxes
)) {
648 REGION_COPY(pScrn
->pScreen
, &port
->clipBoxes
, clipBoxes
);
649 if (port
->isAutoPaintColorkey
)
650 xf86XVFillKeyHelper(pScrn
->pScreen
, port
->colorKey
, clipBoxes
);
653 xorg_flush(pScrn
->pScreen
);
655 ret
= drmCommandWrite(vmw
->fd
, DRM_VMW_CONTROL_STREAM
, &arg
, sizeof(arg
));
657 vmw_video_port_cleanup(pScrn
, port
);
661 if (++(port
->currBuf
) >= VMWARE_VID_NUM_BUFFERS
)
669 *-----------------------------------------------------------------------------
671 * vmw_video_port_cleanup --
673 * Frees up all resources (if any) taken by a video stream.
681 *-----------------------------------------------------------------------------
685 vmw_video_port_cleanup(ScrnInfoPtr pScrn
, struct vmw_video_port
*port
)
687 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
688 uint32 id
, colorKey
, flags
;
689 Bool isAutoPaintColorkey
;
692 debug_printf("\t%s: enter\n", __func__
);
694 for (i
= 0; i
< VMWARE_VID_NUM_BUFFERS
; i
++) {
695 vmw_video_buffer_free(vmw
, &port
->bufs
[i
]);
699 * reset stream for next video
702 colorKey
= port
->colorKey
;
704 isAutoPaintColorkey
= port
->isAutoPaintColorkey
;
706 memset(port
, 0, sizeof(*port
));
709 port
->play
= vmw_video_port_init
;
710 port
->colorKey
= colorKey
;
712 port
->isAutoPaintColorkey
= isAutoPaintColorkey
;
717 *-----------------------------------------------------------------------------
719 * vmw_video_buffer_alloc --
721 * Allocates and map a kernel buffer to be used as data storage.
724 * XvBadAlloc on failure, otherwise Success.
727 * Calls into the kernel, sets members of out.
729 *-----------------------------------------------------------------------------
733 vmw_video_buffer_alloc(struct vmw_customizer
*vmw
, int size
,
734 struct vmw_video_buffer
*out
)
736 out
->buf
= vmw_ioctl_buffer_create(vmw
, size
, &out
->handle
);
740 out
->data
= vmw_ioctl_buffer_map(vmw
, out
->buf
);
742 vmw_ioctl_buffer_destroy(vmw
, out
->buf
);
751 out
->extra_data
= calloc(1, size
);
753 debug_printf("\t\t%s: allocated buffer %p of size %i\n", __func__
, out
, size
);
760 *-----------------------------------------------------------------------------
762 * vmw_video_buffer_free --
764 * Frees and unmaps an allocated kernel buffer.
770 * Calls into the kernel, sets members of out to 0.
772 *-----------------------------------------------------------------------------
776 vmw_video_buffer_free(struct vmw_customizer
*vmw
,
777 struct vmw_video_buffer
*out
)
782 free(out
->extra_data
);
783 vmw_ioctl_buffer_unmap(vmw
, out
->buf
);
784 vmw_ioctl_buffer_destroy(vmw
, out
->buf
);
791 debug_printf("\t\t%s: freed buffer %p\n", __func__
, out
);
798 *-----------------------------------------------------------------------------
800 * vmw_xv_put_image --
802 * Main video playback function. It copies the passed data which is in
803 * the specified format (e.g. FOURCC_YV12) into the overlay.
805 * If sync is TRUE the driver should not return from this
806 * function until it is through reading the data from buf.
809 * Success or XvBadAlloc on failure
812 * Video port will be played(initialized if 1st frame) on success
813 * or will fail on error.
815 *-----------------------------------------------------------------------------
819 vmw_xv_put_image(ScrnInfoPtr pScrn
, short src_x
, short src_y
,
820 short drw_x
, short drw_y
, short src_w
, short src_h
,
821 short drw_w
, short drw_h
, int format
,
822 unsigned char *buf
, short width
, short height
,
823 Bool sync
, RegionPtr clipBoxes
, pointer data
,
826 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
827 struct vmw_video_port
*port
= data
;
829 debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__
,
830 src_x
, src_y
, src_w
, src_h
,
831 drw_x
, drw_y
, drw_w
, drw_h
,
834 if (!vmw
->video_priv
)
837 return port
->play(pScrn
, port
, src_x
, src_y
, drw_x
, drw_y
, src_w
, src_h
,
838 drw_w
, drw_h
, format
, buf
, width
, height
, clipBoxes
);
843 *-----------------------------------------------------------------------------
845 * vmw_xv_stop_video --
847 * Called when we should stop playing video for a particular stream. If
848 * Cleanup is FALSE, the "stop" operation is only temporary, and thus we
849 * don't do anything. If Cleanup is TRUE we kill the video port by
850 * sending a message to the host and freeing up the stream.
858 *-----------------------------------------------------------------------------
862 vmw_xv_stop_video(ScrnInfoPtr pScrn
, pointer data
, Bool cleanup
)
864 struct vmw_customizer
*vmw
= vmw_customizer(xorg_customizer(pScrn
));
865 struct vmw_video_port
*port
= data
;
866 struct drm_vmw_control_stream_arg arg
;
869 debug_printf("%s: cleanup is %s\n", __func__
, cleanup
? "TRUE" : "FALSE");
871 if (!vmw
->video_priv
)
874 REGION_EMPTY(pScrn
->pScreen
, &port
->clipBoxes
);
880 memset(&arg
, 0, sizeof(arg
));
881 arg
.stream_id
= port
->streamId
;
884 ret
= drmCommandWrite(vmw
->fd
, DRM_VMW_CONTROL_STREAM
, &arg
, sizeof(arg
));
887 vmw_video_port_cleanup(pScrn
, port
);
892 *-----------------------------------------------------------------------------
894 * vmw_xv_query_image_attributes --
896 * From the spec: This function is called to let the driver specify how data
897 * for a particular image of size width by height should be stored.
898 * Sometimes only the size and corrected width and height are needed. In
899 * that case pitches and offsets are NULL.
902 * The size of the memory required for the image, or -1 on error.
907 *-----------------------------------------------------------------------------
911 vmw_xv_query_image_attributes(ScrnInfoPtr pScrn
, int format
,
912 unsigned short *width
, unsigned short *height
,
913 int *pitches
, int *offsets
)
917 if (*width
> VMWARE_VID_MAX_WIDTH
) {
918 *width
= VMWARE_VID_MAX_WIDTH
;
920 if (*height
> VMWARE_VID_MAX_HEIGHT
) {
921 *height
= VMWARE_VID_MAX_HEIGHT
;
924 *width
= (*width
+ 1) & ~1;
925 if (offsets
!= NULL
) {
931 *height
= (*height
+ 1) & ~1;
932 size
= (*width
+ 3) & ~3;
940 tmp
= ((*width
>> 1) + 3) & ~3;
942 pitches
[1] = pitches
[2] = tmp
;
944 tmp
*= (*height
>> 1);
960 debug_printf("Query for invalid video format %d\n", format
);
968 *-----------------------------------------------------------------------------
970 * vmw_xv_set_port_attribute --
972 * From the spec: A port may have particular attributes such as colorKey, hue,
973 * saturation, brightness or contrast. Xv clients set these
974 * attribute values by sending attribute strings (Atoms) to the server.
977 * Success if the attribute exists and XvBadAlloc otherwise.
980 * The respective attribute gets the new value.
982 *-----------------------------------------------------------------------------
986 vmw_xv_set_port_attribute(ScrnInfoPtr pScrn
, Atom attribute
,
987 INT32 value
, pointer data
)
989 struct vmw_video_port
*port
= data
;
990 Atom xvColorKey
= MAKE_ATOM("XV_COLORKEY");
991 Atom xvAutoPaint
= MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
993 if (attribute
== xvColorKey
) {
994 debug_printf("%s: Set colorkey:0x%x\n", __func__
, (unsigned)value
);
995 port
->colorKey
= value
;
996 } else if (attribute
== xvAutoPaint
) {
997 debug_printf("%s: Set autoPaint: %s\n", __func__
, value
? "TRUE": "FALSE");
998 port
->isAutoPaintColorkey
= value
;
1008 *-----------------------------------------------------------------------------
1010 * vmw_xv_get_port_attribute --
1012 * From the spec: A port may have particular attributes such as hue,
1013 * saturation, brightness or contrast. Xv clients get these
1014 * attribute values by sending attribute strings (Atoms) to the server
1017 * Success if the attribute exists and XvBadAlloc otherwise.
1020 * "value" contains the requested attribute on success.
1022 *-----------------------------------------------------------------------------
1026 vmw_xv_get_port_attribute(ScrnInfoPtr pScrn
, Atom attribute
,
1027 INT32
*value
, pointer data
)
1029 struct vmw_video_port
*port
= data
;
1030 Atom xvColorKey
= MAKE_ATOM("XV_COLORKEY");
1031 Atom xvAutoPaint
= MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
1033 if (attribute
== xvColorKey
) {
1034 *value
= port
->colorKey
;
1035 } else if (attribute
== xvAutoPaint
) {
1036 *value
= port
->isAutoPaintColorkey
;
1046 *-----------------------------------------------------------------------------
1048 * vmw_xv_query_best_size --
1050 * From the spec: QueryBestSize provides the client with a way to query what
1051 * the destination dimensions would end up being if they were to request
1052 * that an area vid_w by vid_h from the video stream be scaled to rectangle
1053 * of drw_w by drw_h on the screen. Since it is not expected that all
1054 * hardware will be able to get the target dimensions exactly, it is
1055 * important that the driver provide this function.
1057 * This function seems to never be called, but to be on the safe side
1058 * we apply the same logic that QueryImageAttributes has for width
1067 *-----------------------------------------------------------------------------
1071 vmw_xv_query_best_size(ScrnInfoPtr pScrn
, Bool motion
,
1072 short vid_w
, short vid_h
, short drw_w
,
1073 short drw_h
, unsigned int *p_w
,
1074 unsigned int *p_h
, pointer data
)
1076 *p_w
= (drw_w
+ 1) & ~1;