summaryrefslogtreecommitdiff
path: root/vmwgfx/vmwgfx_overlay.c
diff options
context:
space:
mode:
Diffstat (limited to 'vmwgfx/vmwgfx_overlay.c')
-rw-r--r--vmwgfx/vmwgfx_overlay.c893
1 files changed, 893 insertions, 0 deletions
diff --git a/vmwgfx/vmwgfx_overlay.c b/vmwgfx/vmwgfx_overlay.c
new file mode 100644
index 0000000..6624a10
--- /dev/null
+++ b/vmwgfx/vmwgfx_overlay.c
@@ -0,0 +1,893 @@
1/*
2 * Copyright 2007-2011 by VMware, Inc.
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
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.
21 *
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).
26 *
27 */
28
29/*
30 * vmwarevideo.c --
31 *
32 * Xv extension support.
33 * See http://www.xfree86.org/current/DESIGN16.html
34 *
35 */
36
37
38#include "xf86xv.h"
39#include "fourcc.h"
40#define debug_printf(...)
41
42/*
43 * We can't incude svga_types.h due to conflicting types for Bool.
44 */
45typedef int64_t int64;
46typedef uint64_t uint64;
47
48typedef int32_t int32;
49typedef uint32_t uint32;
50
51typedef int16_t int16;
52typedef uint16_t uint16;
53
54typedef int8_t int8;
55typedef uint8_t uint8;
56
57#include "../src/svga_reg.h"
58#include "../src/svga_escape.h"
59#include "../src/svga_overlay.h"
60
61#include <X11/extensions/Xv.h>
62
63#include "xf86drm.h"
64#include "vmwgfx_drm.h"
65#include "vmwgfx_drmi.h"
66#include "vmwgfx_driver.h"
67
68#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
69
70/*
71 * Number of videos that can be played simultaneously
72 */
73#define VMWARE_VID_NUM_PORTS 1
74
75/*
76 * Using a dark shade as the default colorKey
77 */
78#define VMWARE_VIDEO_COLORKEY 0x100701
79
80/*
81 * Maximum dimensions
82 */
83#define VMWARE_VID_MAX_WIDTH 2048
84#define VMWARE_VID_MAX_HEIGHT 2048
85
86#define VMWARE_VID_NUM_ENCODINGS 1
87static XF86VideoEncodingRec vmwareVideoEncodings[] =
88{
89 {
90 0,
91 "XV_IMAGE",
92 VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT,
93 {1, 1}
94 }
95};
96
97#define VMWARE_VID_NUM_FORMATS 2
98static XF86VideoFormatRec vmwareVideoFormats[] =
99{
100 { 16, TrueColor},
101 { 24, TrueColor}
102};
103
104#define VMWARE_VID_NUM_IMAGES 3
105static XF86ImageRec vmwareVideoImages[] =
106{
107 XVIMAGE_YV12,
108 XVIMAGE_YUY2,
109 XVIMAGE_UYVY
110};
111
112#define VMWARE_VID_NUM_ATTRIBUTES 2
113static XF86AttributeRec vmwareVideoAttributes[] =
114{
115 {
116 XvGettable | XvSettable,
117 0x000000,
118 0xffffff,
119 "XV_COLORKEY"
120 },
121 {
122 XvGettable | XvSettable,
123 0,
124 1,
125 "XV_AUTOPAINT_COLORKEY"
126 }
127};
128
129/*
130 * Video frames are stored in a circular list of buffers.
131 * Must be power or two, See vmw_video_port_play.
132 */
133#define VMWARE_VID_NUM_BUFFERS 1
134
135/*
136 * Defines the structure used to hold and pass video data to the host
137 */
138struct vmw_video_buffer
139{
140 int size;
141 void *data;
142 struct vmwgfx_dmabuf *buf;
143};
144
145
146/**
147 * Structure representing a single video stream, aka port.
148 *
149 * Ports maps one to one to a SVGA stream. Port is just
150 * what Xv calls a SVGA stream.
151 */
152struct vmwgfx_overlay_port
153{
154 /*
155 * Function prototype same as XvPutImage.
156 *
157 * This is either set to vmw_video_port_init or vmw_video_port_play.
158 * At init this function is set to port_init. In port_init we set it
159 * to port_play and call it, after initializing the struct.
160 */
161 int (*play)(ScrnInfoPtr, struct vmwgfx_overlay_port *,
162 short, short, short, short, short,
163 short, short, short, int, unsigned char*,
164 short, short, RegionPtr);
165
166 /* values to go into the SVGAOverlayUnit */
167 uint32 streamId;
168 uint32 colorKey;
169 uint32 flags;
170
171 /* round robin of buffers */
172 unsigned currBuf;
173 struct vmw_video_buffer bufs[VMWARE_VID_NUM_BUFFERS];
174
175 /* properties that applies to all buffers */
176 int size;
177 int pitches[3];
178 int offsets[3];
179
180 /* things for X */
181 RegionRec clipBoxes;
182 Bool isAutoPaintColorkey;
183 int drm_fd;
184};
185
186/*
187 * Callback functions exported to Xv, prefixed with vmw_xv_*.
188 */
189static int vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
190 short drw_x, short drw_y, short src_w, short src_h,
191 short drw_w, short drw_h, int image,
192 unsigned char *buf, short width, short height,
193 Bool sync, RegionPtr clipBoxes, pointer data,
194 DrawablePtr dst);
195static void vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool Cleanup);
196static int vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format,
197 unsigned short *width,
198 unsigned short *height, int *pitches,
199 int *offsets);
200static int vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
201 INT32 value, pointer data);
202static int vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
203 INT32 *value, pointer data);
204static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
205 short vid_w, short vid_h, short drw_w,
206 short drw_h, unsigned int *p_w,
207 unsigned int *p_h, pointer data);
208
209
210/*
211 * Local functions.
212 */
213static int vmw_video_port_init(ScrnInfoPtr pScrn,
214 struct vmwgfx_overlay_port *port,
215 short src_x, short src_y, short drw_x,
216 short drw_y, short src_w, short src_h,
217 short drw_w, short drw_h, int format,
218 unsigned char *buf, short width,
219 short height, RegionPtr clipBoxes);
220static int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port,
221 short src_x, short src_y, short drw_x,
222 short drw_y, short src_w, short src_h,
223 short drw_w, short drw_h, int format,
224 unsigned char *buf, short width,
225 short height, RegionPtr clipBoxes);
226static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port);
227
228static int vmw_video_buffer_alloc(int drm_fd, int size,
229 struct vmw_video_buffer *out);
230static int vmw_video_buffer_free(struct vmw_video_buffer *out);
231
232
233static struct vmwgfx_overlay_port *
234vmwgfx_overlay_port_create(int drm_fd, ScreenPtr pScreen)
235{
236 struct vmwgfx_overlay_port *port = calloc(1, sizeof(*port));
237
238 if (!port)
239 return NULL;
240
241 port->drm_fd = drm_fd;
242 port->play = vmw_video_port_init;
243 port->flags = SVGA_VIDEO_FLAG_COLORKEY;
244 port->colorKey = VMWARE_VIDEO_COLORKEY;
245 port->isAutoPaintColorkey = TRUE;
246 return port;
247}
248
249void
250vmw_video_free_adaptor(XF86VideoAdaptorPtr adaptor, Bool free_ports)
251{
252 if (free_ports) {
253 int i;
254
255 for(i=0; i<adaptor->nPorts; ++i) {
256 free(adaptor->pPortPrivates[i].ptr);
257 }
258 }
259
260 free(adaptor->pPortPrivates);
261 xf86XVFreeVideoAdaptorRec(adaptor);
262}
263
264/*
265 *-----------------------------------------------------------------------------
266 *
267 * vmw_video_init_adaptor --
268 *
269 * Initializes a XF86VideoAdaptor structure with the capabilities and
270 * functions supported by this video driver.
271 *
272 * Results:
273 * On success initialized XF86VideoAdaptor struct or NULL on error
274 *
275 * Side effects:
276 * None.
277 *
278 *-----------------------------------------------------------------------------
279 */
280
281XF86VideoAdaptorPtr
282vmw_video_init_adaptor(ScrnInfoPtr pScrn)
283{
284 XF86VideoAdaptorPtr adaptor;
285 modesettingPtr ms = modesettingPTR(pScrn);
286 int i;
287 DevUnion *dev_unions;
288 uint32_t ntot, nfree;
289
290 if (vmwgfx_num_streams(ms->fd, &ntot, &nfree) != 0) {
291 debug_printf("No stream ioctl support\n");
292 return NULL;
293 }
294 if (nfree == 0) {
295 debug_printf("No free streams\n");
296 return NULL;
297 }
298 adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
299 dev_unions = calloc(VMWARE_VID_NUM_PORTS, sizeof(DevUnion));
300 if (adaptor == NULL || dev_unions == NULL) {
301 xf86XVFreeVideoAdaptorRec(adaptor);
302 free(dev_unions);
303 return NULL;
304 }
305
306 adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
307
308 /**
309 * Note: CLIP_TO_VIEWPORT was removed from the flags, since with the
310 * crtc/output based modesetting, the viewport is not updated on
311 * RandR modeswitches. Hence the video may incorrectly be clipped away.
312 * The correct approach, (if needed) would be to clip against the
313 * scanout area union of all active crtcs. Revisit if needed.
314 */
315
316 adaptor->flags = VIDEO_OVERLAID_IMAGES;
317 adaptor->name = "VMware Overlay Video Engine";
318 adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
319 adaptor->pEncodings = vmwareVideoEncodings;
320 adaptor->nFormats = VMWARE_VID_NUM_FORMATS;
321 adaptor->pFormats = vmwareVideoFormats;
322 adaptor->nPorts = VMWARE_VID_NUM_PORTS;
323 adaptor->pPortPrivates = dev_unions;
324
325 for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
326 struct vmwgfx_overlay_port *priv =
327 vmwgfx_overlay_port_create(ms->fd, pScrn->pScreen);
328
329 adaptor->pPortPrivates[i].ptr = (pointer) priv;
330 }
331
332 adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES;
333 adaptor->pAttributes = vmwareVideoAttributes;
334 adaptor->nImages = VMWARE_VID_NUM_IMAGES;
335 adaptor->pImages = vmwareVideoImages;
336
337 adaptor->PutVideo = NULL;
338 adaptor->PutStill = NULL;
339 adaptor->GetVideo = NULL;
340 adaptor->GetStill = NULL;
341 adaptor->StopVideo = vmw_xv_stop_video;
342 adaptor->SetPortAttribute = vmw_xv_set_port_attribute;
343 adaptor->GetPortAttribute = vmw_xv_get_port_attribute;
344 adaptor->QueryBestSize = vmw_xv_query_best_size;
345 adaptor->PutImage = vmw_xv_put_image;
346 adaptor->QueryImageAttributes = vmw_xv_query_image_attributes;
347
348 return adaptor;
349}
350
351
352/*
353 *-----------------------------------------------------------------------------
354 *
355 * vmw_video_port_init --
356 *
357 * Initializes a video stream in response to the first PutImage() on a
358 * video stream. The process goes as follows:
359 * - Figure out characteristics according to format
360 * - Allocate offscreen memory
361 * - Pass on video to Play() functions
362 *
363 * Results:
364 * Success or XvBadAlloc on failure.
365 *
366 * Side effects:
367 * Video stream is initialized and its first frame sent to the host
368 * (done by VideoPlay() function called at the end)
369 *
370 *-----------------------------------------------------------------------------
371 */
372
373static int
374vmw_video_port_init(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port,
375 short src_x, short src_y, short drw_x,
376 short drw_y, short src_w, short src_h,
377 short drw_w, short drw_h, int format,
378 unsigned char *buf, short width,
379 short height, RegionPtr clipBoxes)
380{
381 unsigned short w, h;
382 int i, ret;
383
384 debug_printf("\t%s: id %d, format %d\n", __func__, port->streamId, format);
385
386 ret = vmwgfx_claim_stream(port->drm_fd, &port->streamId);
387 if (ret != 0)
388 return XvBadAlloc;
389
390 w = width;
391 h = height;
392 /* init all the format attributes, used for buffers */
393 port->size = vmw_xv_query_image_attributes(pScrn, format, &w, &h,
394 port->pitches, port->offsets);
395
396 if (port->size == -1) {
397 ret = XvBadAlloc;
398 goto out_bad_size;
399 }
400
401 for (i = 0; i < VMWARE_VID_NUM_BUFFERS; ++i) {
402 ret = vmw_video_buffer_alloc(port->drm_fd, port->size, &port->bufs[i]);
403 if (ret != Success)
404 goto out_no_buffer;
405 }
406
407 port->currBuf = 0;
408 REGION_NULL(pScrn->pScreen, &port->clipBoxes);
409 port->play = vmw_video_port_play;
410 return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h,
411 drw_w, drw_h, format, buf, width, height, clipBoxes);
412
413 out_no_buffer:
414 while(i-- != 0) {
415 vmw_video_buffer_free(&port->bufs[i]);
416 }
417 out_bad_size:
418 (void) vmwgfx_unref_stream(port->drm_fd, port->streamId);
419
420 return ret;
421}
422
423
424/*
425 *-----------------------------------------------------------------------------
426 *
427 * vmw_video_port_play --
428 *
429 * Sends all the attributes associated with the video frame using the
430 * FIFO ESCAPE mechanism to the host.
431 *
432 * Results:
433 * Always returns Success.
434 *
435 * Side effects:
436 * None.
437 *
438 *-----------------------------------------------------------------------------
439 */
440
441static int
442vmw_video_port_play(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port,
443 short src_x, short src_y, short drw_x,
444 short drw_y, short src_w, short src_h,
445 short drw_w, short drw_h, int format,
446 unsigned char *buf, short width,
447 short height, RegionPtr clipBoxes)
448{
449 struct drm_vmw_control_stream_arg arg;
450 unsigned short w, h;
451 int size;
452 int ret;
453
454 debug_printf("\t%s: enter\n", __func__);
455
456 w = width;
457 h = height;
458
459 /* we don't update the ports size */
460 size = vmw_xv_query_image_attributes(pScrn, format, &w, &h,
461 port->pitches, port->offsets);
462
463 if (size != port->size) {
464 vmw_xv_stop_video(pScrn, port, TRUE);
465 return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w,
466 src_h, drw_w, drw_h, format, buf, width, height,
467 clipBoxes);
468 }
469
470 memcpy(port->bufs[port->currBuf].data, buf, port->size);
471
472 memset(&arg, 0, sizeof(arg));
473
474 arg.stream_id = port->streamId;
475 arg.enabled = TRUE;
476 arg.flags = port->flags;
477 arg.color_key = port->colorKey;
478 arg.handle = port->bufs[port->currBuf].buf->handle;
479 arg.format = format;
480 arg.size = port->size;
481 arg.width = w;
482 arg.height = h;
483 arg.src.x = src_x;
484 arg.src.y = src_y;
485 arg.src.w = src_w;
486 arg.src.h = src_h;
487 arg.dst.x = drw_x;
488 arg.dst.y = drw_y;
489 arg.dst.w = drw_w;
490 arg.dst.h = drw_h;
491 arg.pitch[0] = port->pitches[0];
492 arg.pitch[1] = port->pitches[1];
493 arg.pitch[2] = port->pitches[2];
494 arg.offset = 0;
495
496 /*
497 * Update the clipList and paint the colorkey, if required.
498 */
499 if (!REGION_EQUAL(pScrn->pScreen, &port->clipBoxes, clipBoxes)) {
500 REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes);
501 if (port->isAutoPaintColorkey)
502 xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes);
503 }
504
505 xorg_flush(pScrn->pScreen);
506 ret = drmCommandWrite(port->drm_fd, DRM_VMW_CONTROL_STREAM, &arg, sizeof(arg));
507 if (ret) {
508 vmw_video_port_cleanup(pScrn, port);
509 return XvBadAlloc;
510 }
511
512 if (++(port->currBuf) >= VMWARE_VID_NUM_BUFFERS)
513 port->currBuf = 0;
514
515 return Success;
516}
517
518
519/*
520 *-----------------------------------------------------------------------------
521 *
522 * vmw_video_port_cleanup --
523 *
524 * Frees up all resources (if any) taken by a video stream.
525 *
526 * Results:
527 * None.
528 *
529 * Side effects:
530 * Same as above.
531 *
532 *-----------------------------------------------------------------------------
533 */
534
535static void
536vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port)
537{
538 int i;
539
540 debug_printf("\t%s: enter\n", __func__);
541
542 if (port->play == vmw_video_port_init)
543 return;
544
545 port->play = vmw_video_port_init;
546 (void) vmwgfx_unref_stream(port->drm_fd, port->streamId);
547
548 for (i = 0; i < VMWARE_VID_NUM_BUFFERS; i++) {
549 vmw_video_buffer_free(&port->bufs[i]);
550 }
551
552 REGION_UNINIT(pScreen->pScreen, &port->clipBoxes);
553}
554
555
556/*
557 *-----------------------------------------------------------------------------
558 *
559 * vmw_video_buffer_alloc --
560 *
561 * Allocates and map a kernel buffer to be used as data storage.
562 *
563 * Results:
564 * XvBadAlloc on failure, otherwise Success.
565 *
566 * Side effects:
567 * Calls into the kernel, sets members of out.
568 *
569 *-----------------------------------------------------------------------------
570 */
571
572static int
573vmw_video_buffer_alloc(int drm_fd, int size,
574 struct vmw_video_buffer *out)
575{
576 out->buf = vmwgfx_dmabuf_alloc(drm_fd, size);
577 if (!out->buf)
578 return XvBadAlloc;
579
580 out->data = vmwgfx_dmabuf_map(out->buf);
581 if (!out->data) {
582 vmwgfx_dmabuf_destroy(out->buf);
583 out->buf = NULL;
584 return XvBadAlloc;
585 }
586
587 out->size = size;
588 debug_printf("\t\t%s: allocated buffer %p of size %i\n", __func__, out, size);
589
590 return Success;
591}
592
593
594/*
595 *-----------------------------------------------------------------------------
596 *
597 * vmw_video_buffer_free --
598 *
599 * Frees and unmaps an allocated kernel buffer.
600 *
601 * Results:
602 * Success.
603 *
604 * Side effects:
605 * Calls into the kernel, sets members of out to 0.
606 *
607 *-----------------------------------------------------------------------------
608 */
609
610static int
611vmw_video_buffer_free(struct vmw_video_buffer *out)
612{
613 if (out->size == 0)
614 return Success;
615
616 vmwgfx_dmabuf_unmap(out->buf);
617 vmwgfx_dmabuf_destroy(out->buf);
618
619 out->buf = NULL;
620 out->data = NULL;
621 out->size = 0;
622
623 debug_printf("\t\t%s: freed buffer %p\n", __func__, out);
624
625 return Success;
626}
627
628
629/*
630 *-----------------------------------------------------------------------------
631 *
632 * vmw_xv_put_image --
633 *
634 * Main video playback function. It copies the passed data which is in
635 * the specified format (e.g. FOURCC_YV12) into the overlay.
636 *
637 * If sync is TRUE the driver should not return from this
638 * function until it is through reading the data from buf.
639 *
640 * Results:
641 * Success or XvBadAlloc on failure
642 *
643 * Side effects:
644 * Video port will be played(initialized if 1st frame) on success
645 * or will fail on error.
646 *
647 *-----------------------------------------------------------------------------
648 */
649
650static int
651vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
652 short drw_x, short drw_y, short src_w, short src_h,
653 short drw_w, short drw_h, int format,
654 unsigned char *buf, short width, short height,
655 Bool sync, RegionPtr clipBoxes, pointer data,
656 DrawablePtr dst)
657{
658 struct vmwgfx_overlay_port *port = data;
659
660 debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__,
661 src_x, src_y, src_w, src_h,
662 drw_x, drw_y, drw_w, drw_h,
663 width, height);
664
665 return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h,
666 drw_w, drw_h, format, buf, width, height, clipBoxes);
667}
668
669
670/*
671 *-----------------------------------------------------------------------------
672 *
673 * vmw_xv_stop_video --
674 *
675 * Called when we should stop playing video for a particular stream. If
676 * Cleanup is FALSE, the "stop" operation is only temporary, and thus we
677 * don't do anything. If Cleanup is TRUE we kill the video port by
678 * sending a message to the host and freeing up the stream.
679 *
680 * Results:
681 * None.
682 *
683 * Side effects:
684 * See above.
685 *
686 *-----------------------------------------------------------------------------
687 */
688
689static void
690vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
691{
692 struct vmwgfx_overlay_port *port = data;
693
694 debug_printf("%s: cleanup is %s\n", __func__, cleanup ? "TRUE" : "FALSE");
695 REGION_EMPTY(pScrn->pScreen, &port->clipBoxes);
696
697 if (!cleanup)
698 return;
699
700 vmw_video_port_cleanup(pScrn, port);
701}
702
703
704/*
705 *-----------------------------------------------------------------------------
706 *
707 * vmw_xv_query_image_attributes --
708 *
709 * From the spec: This function is called to let the driver specify how data
710 * for a particular image of size width by height should be stored.
711 * Sometimes only the size and corrected width and height are needed. In
712 * that case pitches and offsets are NULL.
713 *
714 * Results:
715 * The size of the memory required for the image, or -1 on error.
716 *
717 * Side effects:
718 * None.
719 *
720 *-----------------------------------------------------------------------------
721 */
722
723static int
724vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format,
725 unsigned short *width, unsigned short *height,
726 int *pitches, int *offsets)
727{
728 INT32 size, tmp;
729
730 if (*width > VMWARE_VID_MAX_WIDTH) {
731 *width = VMWARE_VID_MAX_WIDTH;
732 }
733 if (*height > VMWARE_VID_MAX_HEIGHT) {
734 *height = VMWARE_VID_MAX_HEIGHT;
735 }
736
737 *width = (*width + 1) & ~1;
738 if (offsets != NULL) {
739 offsets[0] = 0;
740 }
741
742 switch (format) {
743 case FOURCC_YV12:
744 *height = (*height + 1) & ~1;
745 size = (*width + 3) & ~3;
746 if (pitches) {
747 pitches[0] = size;
748 }
749 size *= *height;
750 if (offsets) {
751 offsets[1] = size;
752 }
753 tmp = ((*width >> 1) + 3) & ~3;
754 if (pitches) {
755 pitches[1] = pitches[2] = tmp;
756 }
757 tmp *= (*height >> 1);
758 size += tmp;
759 if (offsets) {
760 offsets[2] = size;
761 }
762 size += tmp;
763 break;
764 case FOURCC_UYVY:
765 case FOURCC_YUY2:
766 size = *width * 2;
767 if (pitches) {
768 pitches[0] = size;
769 }
770 size *= *height;
771 break;
772 default:
773 debug_printf("Query for invalid video format %d\n", format);
774 return -1;
775 }
776 return size;
777}
778
779
780/*
781 *-----------------------------------------------------------------------------
782 *
783 * vmw_xv_set_port_attribute --
784 *
785 * From the spec: A port may have particular attributes such as colorKey, hue,
786 * saturation, brightness or contrast. Xv clients set these
787 * attribute values by sending attribute strings (Atoms) to the server.
788 *
789 * Results:
790 * Success if the attribute exists and XvBadAlloc otherwise.
791 *
792 * Side effects:
793 * The respective attribute gets the new value.
794 *
795 *-----------------------------------------------------------------------------
796 */
797
798static int
799vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
800 INT32 value, pointer data)
801{
802 struct vmwgfx_overlay_port *port = data;
803 Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
804 Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
805
806 if (attribute == xvColorKey) {
807 debug_printf("%s: Set colorkey:0x%x\n", __func__, (unsigned)value);
808 port->colorKey = value;
809 } else if (attribute == xvAutoPaint) {
810 debug_printf("%s: Set autoPaint: %s\n", __func__, value? "TRUE": "FALSE");
811 port->isAutoPaintColorkey = value;
812 } else {
813 return XvBadAlloc;
814 }
815
816 return Success;
817}
818
819
820/*
821 *-----------------------------------------------------------------------------
822 *
823 * vmw_xv_get_port_attribute --
824 *
825 * From the spec: A port may have particular attributes such as hue,
826 * saturation, brightness or contrast. Xv clients get these
827 * attribute values by sending attribute strings (Atoms) to the server
828 *
829 * Results:
830 * Success if the attribute exists and XvBadAlloc otherwise.
831 *
832 * Side effects:
833 * "value" contains the requested attribute on success.
834 *
835 *-----------------------------------------------------------------------------
836 */
837
838static int
839vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute,
840 INT32 *value, pointer data)
841{
842 struct vmwgfx_overlay_port *port = data;
843 Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
844 Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
845
846 if (attribute == xvColorKey) {
847 *value = port->colorKey;
848 } else if (attribute == xvAutoPaint) {
849 *value = port->isAutoPaintColorkey;
850 } else {
851 return XvBadAlloc;
852 }
853
854 return Success;
855}
856
857
858/*
859 *-----------------------------------------------------------------------------
860 *
861 * vmw_xv_query_best_size --
862 *
863 * From the spec: QueryBestSize provides the client with a way to query what
864 * the destination dimensions would end up being if they were to request
865 * that an area vid_w by vid_h from the video stream be scaled to rectangle
866 * of drw_w by drw_h on the screen. Since it is not expected that all
867 * hardware will be able to get the target dimensions exactly, it is
868 * important that the driver provide this function.
869 *
870 * This function seems to never be called, but to be on the safe side
871 * we apply the same logic that QueryImageAttributes has for width
872 * and height.
873 *
874 * Results:
875 * None.
876 *
877 * Side effects:
878 * None.
879 *
880 *-----------------------------------------------------------------------------
881 */
882
883static void
884vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
885 short vid_w, short vid_h, short drw_w,
886 short drw_h, unsigned int *p_w,
887 unsigned int *p_h, pointer data)
888{
889 *p_w = (drw_w + 1) & ~1;
890 *p_h = drw_h;
891
892 return;
893}