vmwgfx_overlay.c revision 22f7e8e5
13bfa90b6Smrg/* 23bfa90b6Smrg * Copyright 2007-2011 by VMware, Inc. 33bfa90b6Smrg * 43bfa90b6Smrg * Permission is hereby granted, free of charge, to any person obtaining a 53bfa90b6Smrg * copy of this software and associated documentation files (the "Software"), 63bfa90b6Smrg * to deal in the Software without restriction, including without limitation 73bfa90b6Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83bfa90b6Smrg * and/or sell copies of the Software, and to permit persons to whom the 93bfa90b6Smrg * Software is furnished to do so, subject to the following conditions: 103bfa90b6Smrg * 113bfa90b6Smrg * The above copyright notice and this permission notice shall be included in 123bfa90b6Smrg * all copies or substantial portions of the Software. 133bfa90b6Smrg * 143bfa90b6Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 153bfa90b6Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 163bfa90b6Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 173bfa90b6Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 183bfa90b6Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 193bfa90b6Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 203bfa90b6Smrg * OTHER DEALINGS IN THE SOFTWARE. 213bfa90b6Smrg * 223bfa90b6Smrg * Except as contained in this notice, the name of the copyright holder(s) 233bfa90b6Smrg * and author(s) shall not be used in advertising or otherwise to promote 243bfa90b6Smrg * the sale, use or other dealings in this Software without prior written 253bfa90b6Smrg * authorization from the copyright holder(s) and author(s). 263bfa90b6Smrg * 273bfa90b6Smrg */ 283bfa90b6Smrg 293bfa90b6Smrg/* 303bfa90b6Smrg * vmwarevideo.c -- 313bfa90b6Smrg * 323bfa90b6Smrg * Xv extension support. 333bfa90b6Smrg * See http://www.xfree86.org/current/DESIGN16.html 343bfa90b6Smrg * 353bfa90b6Smrg */ 363bfa90b6Smrg 373bfa90b6Smrg 383bfa90b6Smrg#include "xf86xv.h" 393bfa90b6Smrg#include "fourcc.h" 403bfa90b6Smrg#define debug_printf(...) 413bfa90b6Smrg 423bfa90b6Smrg/* 433bfa90b6Smrg * We can't incude svga_types.h due to conflicting types for Bool. 443bfa90b6Smrg */ 453bfa90b6Smrgtypedef int64_t int64; 463bfa90b6Smrgtypedef uint64_t uint64; 473bfa90b6Smrg 483bfa90b6Smrgtypedef int32_t int32; 493bfa90b6Smrgtypedef uint32_t uint32; 503bfa90b6Smrg 513bfa90b6Smrgtypedef int16_t int16; 523bfa90b6Smrgtypedef uint16_t uint16; 533bfa90b6Smrg 543bfa90b6Smrgtypedef int8_t int8; 553bfa90b6Smrgtypedef uint8_t uint8; 563bfa90b6Smrg 573bfa90b6Smrg#include "../src/svga_reg.h" 583bfa90b6Smrg#include "../src/svga_escape.h" 593bfa90b6Smrg#include "../src/svga_overlay.h" 603bfa90b6Smrg 613bfa90b6Smrg#include <X11/extensions/Xv.h> 623bfa90b6Smrg 633bfa90b6Smrg#include "xf86drm.h" 643bfa90b6Smrg#include "vmwgfx_drm.h" 653bfa90b6Smrg#include "vmwgfx_drmi.h" 663bfa90b6Smrg#include "vmwgfx_driver.h" 6722f7e8e5Smrg#include "vmwgfx_hosted.h" 683bfa90b6Smrg 693bfa90b6Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 703bfa90b6Smrg 713bfa90b6Smrg/* 723bfa90b6Smrg * Number of videos that can be played simultaneously 733bfa90b6Smrg */ 743bfa90b6Smrg#define VMWARE_VID_NUM_PORTS 1 753bfa90b6Smrg 763bfa90b6Smrg/* 773bfa90b6Smrg * Using a dark shade as the default colorKey 783bfa90b6Smrg */ 793bfa90b6Smrg#define VMWARE_VIDEO_COLORKEY 0x100701 803bfa90b6Smrg 813bfa90b6Smrg/* 823bfa90b6Smrg * Maximum dimensions 833bfa90b6Smrg */ 843bfa90b6Smrg#define VMWARE_VID_MAX_WIDTH 2048 853bfa90b6Smrg#define VMWARE_VID_MAX_HEIGHT 2048 863bfa90b6Smrg 873bfa90b6Smrg#define VMWARE_VID_NUM_ENCODINGS 1 883bfa90b6Smrgstatic XF86VideoEncodingRec vmwareVideoEncodings[] = 893bfa90b6Smrg{ 903bfa90b6Smrg { 913bfa90b6Smrg 0, 923bfa90b6Smrg "XV_IMAGE", 933bfa90b6Smrg VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT, 943bfa90b6Smrg {1, 1} 953bfa90b6Smrg } 963bfa90b6Smrg}; 973bfa90b6Smrg 983bfa90b6Smrg#define VMWARE_VID_NUM_FORMATS 2 993bfa90b6Smrgstatic XF86VideoFormatRec vmwareVideoFormats[] = 1003bfa90b6Smrg{ 1013bfa90b6Smrg { 16, TrueColor}, 1023bfa90b6Smrg { 24, TrueColor} 1033bfa90b6Smrg}; 1043bfa90b6Smrg 1053bfa90b6Smrg#define VMWARE_VID_NUM_IMAGES 3 1063bfa90b6Smrgstatic XF86ImageRec vmwareVideoImages[] = 1073bfa90b6Smrg{ 1083bfa90b6Smrg XVIMAGE_YV12, 1093bfa90b6Smrg XVIMAGE_YUY2, 1103bfa90b6Smrg XVIMAGE_UYVY 1113bfa90b6Smrg}; 1123bfa90b6Smrg 1133bfa90b6Smrg#define VMWARE_VID_NUM_ATTRIBUTES 2 1143bfa90b6Smrgstatic XF86AttributeRec vmwareVideoAttributes[] = 1153bfa90b6Smrg{ 1163bfa90b6Smrg { 1173bfa90b6Smrg XvGettable | XvSettable, 1183bfa90b6Smrg 0x000000, 1193bfa90b6Smrg 0xffffff, 1203bfa90b6Smrg "XV_COLORKEY" 1213bfa90b6Smrg }, 1223bfa90b6Smrg { 1233bfa90b6Smrg XvGettable | XvSettable, 1243bfa90b6Smrg 0, 1253bfa90b6Smrg 1, 1263bfa90b6Smrg "XV_AUTOPAINT_COLORKEY" 1273bfa90b6Smrg } 1283bfa90b6Smrg}; 1293bfa90b6Smrg 1303bfa90b6Smrg/* 1313bfa90b6Smrg * Video frames are stored in a circular list of buffers. 1323bfa90b6Smrg * Must be power or two, See vmw_video_port_play. 1333bfa90b6Smrg */ 1343bfa90b6Smrg#define VMWARE_VID_NUM_BUFFERS 1 1353bfa90b6Smrg 1363bfa90b6Smrg/* 1373bfa90b6Smrg * Defines the structure used to hold and pass video data to the host 1383bfa90b6Smrg */ 1393bfa90b6Smrgstruct vmw_video_buffer 1403bfa90b6Smrg{ 1413bfa90b6Smrg int size; 1423bfa90b6Smrg void *data; 1433bfa90b6Smrg struct vmwgfx_dmabuf *buf; 1443bfa90b6Smrg}; 1453bfa90b6Smrg 1463bfa90b6Smrg 1473bfa90b6Smrg/** 1483bfa90b6Smrg * Structure representing a single video stream, aka port. 1493bfa90b6Smrg * 1503bfa90b6Smrg * Ports maps one to one to a SVGA stream. Port is just 1513bfa90b6Smrg * what Xv calls a SVGA stream. 1523bfa90b6Smrg */ 1533bfa90b6Smrgstruct vmwgfx_overlay_port 1543bfa90b6Smrg{ 1553bfa90b6Smrg /* 1563bfa90b6Smrg * Function prototype same as XvPutImage. 1573bfa90b6Smrg * 1583bfa90b6Smrg * This is either set to vmw_video_port_init or vmw_video_port_play. 1593bfa90b6Smrg * At init this function is set to port_init. In port_init we set it 1603bfa90b6Smrg * to port_play and call it, after initializing the struct. 1613bfa90b6Smrg */ 1623bfa90b6Smrg int (*play)(ScrnInfoPtr, struct vmwgfx_overlay_port *, 1633bfa90b6Smrg short, short, short, short, short, 1643bfa90b6Smrg short, short, short, int, unsigned char*, 1653bfa90b6Smrg short, short, RegionPtr); 1663bfa90b6Smrg 1673bfa90b6Smrg /* values to go into the SVGAOverlayUnit */ 1683bfa90b6Smrg uint32 streamId; 1693bfa90b6Smrg uint32 colorKey; 1703bfa90b6Smrg uint32 flags; 1713bfa90b6Smrg 1723bfa90b6Smrg /* round robin of buffers */ 1733bfa90b6Smrg unsigned currBuf; 1743bfa90b6Smrg struct vmw_video_buffer bufs[VMWARE_VID_NUM_BUFFERS]; 1753bfa90b6Smrg 1763bfa90b6Smrg /* properties that applies to all buffers */ 1773bfa90b6Smrg int size; 1783bfa90b6Smrg int pitches[3]; 1793bfa90b6Smrg int offsets[3]; 1803bfa90b6Smrg 1813bfa90b6Smrg /* things for X */ 1823bfa90b6Smrg RegionRec clipBoxes; 1833bfa90b6Smrg Bool isAutoPaintColorkey; 1843bfa90b6Smrg int drm_fd; 1853bfa90b6Smrg}; 1863bfa90b6Smrg 1873bfa90b6Smrg/* 1883bfa90b6Smrg * Callback functions exported to Xv, prefixed with vmw_xv_*. 1893bfa90b6Smrg */ 1903bfa90b6Smrgstatic int vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y, 1913bfa90b6Smrg short drw_x, short drw_y, short src_w, short src_h, 1923bfa90b6Smrg short drw_w, short drw_h, int image, 1933bfa90b6Smrg unsigned char *buf, short width, short height, 1943bfa90b6Smrg Bool sync, RegionPtr clipBoxes, pointer data, 1953bfa90b6Smrg DrawablePtr dst); 1963bfa90b6Smrgstatic void vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool Cleanup); 1973bfa90b6Smrgstatic int vmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format, 1983bfa90b6Smrg unsigned short *width, 1993bfa90b6Smrg unsigned short *height, int *pitches, 2003bfa90b6Smrg int *offsets); 2013bfa90b6Smrgstatic int vmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute, 2023bfa90b6Smrg INT32 value, pointer data); 2033bfa90b6Smrgstatic int vmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute, 2043bfa90b6Smrg INT32 *value, pointer data); 2053bfa90b6Smrgstatic void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion, 2063bfa90b6Smrg short vid_w, short vid_h, short drw_w, 2073bfa90b6Smrg short drw_h, unsigned int *p_w, 2083bfa90b6Smrg unsigned int *p_h, pointer data); 2093bfa90b6Smrg 2103bfa90b6Smrg 2113bfa90b6Smrg/* 2123bfa90b6Smrg * Local functions. 2133bfa90b6Smrg */ 2143bfa90b6Smrgstatic int vmw_video_port_init(ScrnInfoPtr pScrn, 2153bfa90b6Smrg struct vmwgfx_overlay_port *port, 2163bfa90b6Smrg short src_x, short src_y, short drw_x, 2173bfa90b6Smrg short drw_y, short src_w, short src_h, 2183bfa90b6Smrg short drw_w, short drw_h, int format, 2193bfa90b6Smrg unsigned char *buf, short width, 2203bfa90b6Smrg short height, RegionPtr clipBoxes); 2213bfa90b6Smrgstatic int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port, 2223bfa90b6Smrg short src_x, short src_y, short drw_x, 2233bfa90b6Smrg short drw_y, short src_w, short src_h, 2243bfa90b6Smrg short drw_w, short drw_h, int format, 2253bfa90b6Smrg unsigned char *buf, short width, 2263bfa90b6Smrg short height, RegionPtr clipBoxes); 2273bfa90b6Smrgstatic void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port); 2283bfa90b6Smrg 2293bfa90b6Smrgstatic int vmw_video_buffer_alloc(int drm_fd, int size, 2303bfa90b6Smrg struct vmw_video_buffer *out); 2313bfa90b6Smrgstatic int vmw_video_buffer_free(struct vmw_video_buffer *out); 2323bfa90b6Smrg 2333bfa90b6Smrg 2343bfa90b6Smrgstatic struct vmwgfx_overlay_port * 2353bfa90b6Smrgvmwgfx_overlay_port_create(int drm_fd, ScreenPtr pScreen) 2363bfa90b6Smrg{ 2373bfa90b6Smrg struct vmwgfx_overlay_port *port = calloc(1, sizeof(*port)); 2383bfa90b6Smrg 2393bfa90b6Smrg if (!port) 2403bfa90b6Smrg return NULL; 2413bfa90b6Smrg 2423bfa90b6Smrg port->drm_fd = drm_fd; 2433bfa90b6Smrg port->play = vmw_video_port_init; 2443bfa90b6Smrg port->flags = SVGA_VIDEO_FLAG_COLORKEY; 2453bfa90b6Smrg port->colorKey = VMWARE_VIDEO_COLORKEY; 2463bfa90b6Smrg port->isAutoPaintColorkey = TRUE; 2473bfa90b6Smrg return port; 2483bfa90b6Smrg} 2493bfa90b6Smrg 2503bfa90b6Smrgvoid 2513bfa90b6Smrgvmw_video_free_adaptor(XF86VideoAdaptorPtr adaptor, Bool free_ports) 2523bfa90b6Smrg{ 2533bfa90b6Smrg if (free_ports) { 2543bfa90b6Smrg int i; 2553bfa90b6Smrg 2563bfa90b6Smrg for(i=0; i<adaptor->nPorts; ++i) { 2573bfa90b6Smrg free(adaptor->pPortPrivates[i].ptr); 2583bfa90b6Smrg } 2593bfa90b6Smrg } 2603bfa90b6Smrg 2613bfa90b6Smrg free(adaptor->pPortPrivates); 2623bfa90b6Smrg xf86XVFreeVideoAdaptorRec(adaptor); 2633bfa90b6Smrg} 2643bfa90b6Smrg 2653bfa90b6Smrg/* 2663bfa90b6Smrg *----------------------------------------------------------------------------- 2673bfa90b6Smrg * 2683bfa90b6Smrg * vmw_video_init_adaptor -- 2693bfa90b6Smrg * 2703bfa90b6Smrg * Initializes a XF86VideoAdaptor structure with the capabilities and 2713bfa90b6Smrg * functions supported by this video driver. 2723bfa90b6Smrg * 2733bfa90b6Smrg * Results: 2743bfa90b6Smrg * On success initialized XF86VideoAdaptor struct or NULL on error 2753bfa90b6Smrg * 2763bfa90b6Smrg * Side effects: 2773bfa90b6Smrg * None. 2783bfa90b6Smrg * 2793bfa90b6Smrg *----------------------------------------------------------------------------- 2803bfa90b6Smrg */ 2813bfa90b6Smrg 2823bfa90b6SmrgXF86VideoAdaptorPtr 2833bfa90b6Smrgvmw_video_init_adaptor(ScrnInfoPtr pScrn) 2843bfa90b6Smrg{ 2853bfa90b6Smrg XF86VideoAdaptorPtr adaptor; 2863bfa90b6Smrg modesettingPtr ms = modesettingPTR(pScrn); 2873bfa90b6Smrg int i; 2883bfa90b6Smrg DevUnion *dev_unions; 2893bfa90b6Smrg uint32_t ntot, nfree; 2903bfa90b6Smrg 29122f7e8e5Smrg if (vmwgfx_is_hosted(ms->hdriver)) 29222f7e8e5Smrg return NULL; 29322f7e8e5Smrg 2943bfa90b6Smrg if (vmwgfx_num_streams(ms->fd, &ntot, &nfree) != 0) { 2953bfa90b6Smrg debug_printf("No stream ioctl support\n"); 2963bfa90b6Smrg return NULL; 2973bfa90b6Smrg } 2983bfa90b6Smrg if (nfree == 0) { 2993bfa90b6Smrg debug_printf("No free streams\n"); 3003bfa90b6Smrg return NULL; 3013bfa90b6Smrg } 3023bfa90b6Smrg adaptor = xf86XVAllocateVideoAdaptorRec(pScrn); 3033bfa90b6Smrg dev_unions = calloc(VMWARE_VID_NUM_PORTS, sizeof(DevUnion)); 3043bfa90b6Smrg if (adaptor == NULL || dev_unions == NULL) { 3053bfa90b6Smrg xf86XVFreeVideoAdaptorRec(adaptor); 3063bfa90b6Smrg free(dev_unions); 3073bfa90b6Smrg return NULL; 3083bfa90b6Smrg } 3093bfa90b6Smrg 3103bfa90b6Smrg adaptor->type = XvInputMask | XvImageMask | XvWindowMask; 3113bfa90b6Smrg 3123bfa90b6Smrg /** 3133bfa90b6Smrg * Note: CLIP_TO_VIEWPORT was removed from the flags, since with the 3143bfa90b6Smrg * crtc/output based modesetting, the viewport is not updated on 3153bfa90b6Smrg * RandR modeswitches. Hence the video may incorrectly be clipped away. 3163bfa90b6Smrg * The correct approach, (if needed) would be to clip against the 3173bfa90b6Smrg * scanout area union of all active crtcs. Revisit if needed. 3183bfa90b6Smrg */ 3193bfa90b6Smrg 3203bfa90b6Smrg adaptor->flags = VIDEO_OVERLAID_IMAGES; 3213bfa90b6Smrg adaptor->name = "VMware Overlay Video Engine"; 3223bfa90b6Smrg adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS; 3233bfa90b6Smrg adaptor->pEncodings = vmwareVideoEncodings; 3243bfa90b6Smrg adaptor->nFormats = VMWARE_VID_NUM_FORMATS; 3253bfa90b6Smrg adaptor->pFormats = vmwareVideoFormats; 3263bfa90b6Smrg adaptor->nPorts = VMWARE_VID_NUM_PORTS; 3273bfa90b6Smrg adaptor->pPortPrivates = dev_unions; 3283bfa90b6Smrg 3293bfa90b6Smrg for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) { 3303bfa90b6Smrg struct vmwgfx_overlay_port *priv = 3313bfa90b6Smrg vmwgfx_overlay_port_create(ms->fd, pScrn->pScreen); 3323bfa90b6Smrg 3333bfa90b6Smrg adaptor->pPortPrivates[i].ptr = (pointer) priv; 3343bfa90b6Smrg } 3353bfa90b6Smrg 3363bfa90b6Smrg adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES; 3373bfa90b6Smrg adaptor->pAttributes = vmwareVideoAttributes; 3383bfa90b6Smrg adaptor->nImages = VMWARE_VID_NUM_IMAGES; 3393bfa90b6Smrg adaptor->pImages = vmwareVideoImages; 3403bfa90b6Smrg 3413bfa90b6Smrg adaptor->PutVideo = NULL; 3423bfa90b6Smrg adaptor->PutStill = NULL; 3433bfa90b6Smrg adaptor->GetVideo = NULL; 3443bfa90b6Smrg adaptor->GetStill = NULL; 3453bfa90b6Smrg adaptor->StopVideo = vmw_xv_stop_video; 3463bfa90b6Smrg adaptor->SetPortAttribute = vmw_xv_set_port_attribute; 3473bfa90b6Smrg adaptor->GetPortAttribute = vmw_xv_get_port_attribute; 3483bfa90b6Smrg adaptor->QueryBestSize = vmw_xv_query_best_size; 3493bfa90b6Smrg adaptor->PutImage = vmw_xv_put_image; 3503bfa90b6Smrg adaptor->QueryImageAttributes = vmw_xv_query_image_attributes; 3513bfa90b6Smrg 3523bfa90b6Smrg return adaptor; 3533bfa90b6Smrg} 3543bfa90b6Smrg 3553bfa90b6Smrg 3563bfa90b6Smrg/* 3573bfa90b6Smrg *----------------------------------------------------------------------------- 3583bfa90b6Smrg * 3593bfa90b6Smrg * vmw_video_port_init -- 3603bfa90b6Smrg * 3613bfa90b6Smrg * Initializes a video stream in response to the first PutImage() on a 3623bfa90b6Smrg * video stream. The process goes as follows: 3633bfa90b6Smrg * - Figure out characteristics according to format 3643bfa90b6Smrg * - Allocate offscreen memory 3653bfa90b6Smrg * - Pass on video to Play() functions 3663bfa90b6Smrg * 3673bfa90b6Smrg * Results: 3683bfa90b6Smrg * Success or XvBadAlloc on failure. 3693bfa90b6Smrg * 3703bfa90b6Smrg * Side effects: 3713bfa90b6Smrg * Video stream is initialized and its first frame sent to the host 3723bfa90b6Smrg * (done by VideoPlay() function called at the end) 3733bfa90b6Smrg * 3743bfa90b6Smrg *----------------------------------------------------------------------------- 3753bfa90b6Smrg */ 3763bfa90b6Smrg 3773bfa90b6Smrgstatic int 3783bfa90b6Smrgvmw_video_port_init(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port, 3793bfa90b6Smrg short src_x, short src_y, short drw_x, 3803bfa90b6Smrg short drw_y, short src_w, short src_h, 3813bfa90b6Smrg short drw_w, short drw_h, int format, 3823bfa90b6Smrg unsigned char *buf, short width, 3833bfa90b6Smrg short height, RegionPtr clipBoxes) 3843bfa90b6Smrg{ 3853bfa90b6Smrg unsigned short w, h; 3863bfa90b6Smrg int i, ret; 3873bfa90b6Smrg 3883bfa90b6Smrg debug_printf("\t%s: id %d, format %d\n", __func__, port->streamId, format); 3893bfa90b6Smrg 3903bfa90b6Smrg ret = vmwgfx_claim_stream(port->drm_fd, &port->streamId); 3913bfa90b6Smrg if (ret != 0) 3923bfa90b6Smrg return XvBadAlloc; 3933bfa90b6Smrg 3943bfa90b6Smrg w = width; 3953bfa90b6Smrg h = height; 3963bfa90b6Smrg /* init all the format attributes, used for buffers */ 3973bfa90b6Smrg port->size = vmw_xv_query_image_attributes(pScrn, format, &w, &h, 3983bfa90b6Smrg port->pitches, port->offsets); 3993bfa90b6Smrg 4003bfa90b6Smrg if (port->size == -1) { 4013bfa90b6Smrg ret = XvBadAlloc; 4023bfa90b6Smrg goto out_bad_size; 4033bfa90b6Smrg } 4043bfa90b6Smrg 4053bfa90b6Smrg for (i = 0; i < VMWARE_VID_NUM_BUFFERS; ++i) { 4063bfa90b6Smrg ret = vmw_video_buffer_alloc(port->drm_fd, port->size, &port->bufs[i]); 4073bfa90b6Smrg if (ret != Success) 4083bfa90b6Smrg goto out_no_buffer; 4093bfa90b6Smrg } 4103bfa90b6Smrg 4113bfa90b6Smrg port->currBuf = 0; 4123bfa90b6Smrg REGION_NULL(pScrn->pScreen, &port->clipBoxes); 4133bfa90b6Smrg port->play = vmw_video_port_play; 4143bfa90b6Smrg return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h, 4153bfa90b6Smrg drw_w, drw_h, format, buf, width, height, clipBoxes); 4163bfa90b6Smrg 4173bfa90b6Smrg out_no_buffer: 4183bfa90b6Smrg while(i-- != 0) { 4193bfa90b6Smrg vmw_video_buffer_free(&port->bufs[i]); 4203bfa90b6Smrg } 4213bfa90b6Smrg out_bad_size: 4223bfa90b6Smrg (void) vmwgfx_unref_stream(port->drm_fd, port->streamId); 4233bfa90b6Smrg 4243bfa90b6Smrg return ret; 4253bfa90b6Smrg} 4263bfa90b6Smrg 4273bfa90b6Smrg 4283bfa90b6Smrg/* 4293bfa90b6Smrg *----------------------------------------------------------------------------- 4303bfa90b6Smrg * 4313bfa90b6Smrg * vmw_video_port_play -- 4323bfa90b6Smrg * 4333bfa90b6Smrg * Sends all the attributes associated with the video frame using the 4343bfa90b6Smrg * FIFO ESCAPE mechanism to the host. 4353bfa90b6Smrg * 4363bfa90b6Smrg * Results: 4373bfa90b6Smrg * Always returns Success. 4383bfa90b6Smrg * 4393bfa90b6Smrg * Side effects: 4403bfa90b6Smrg * None. 4413bfa90b6Smrg * 4423bfa90b6Smrg *----------------------------------------------------------------------------- 4433bfa90b6Smrg */ 4443bfa90b6Smrg 4453bfa90b6Smrgstatic int 4463bfa90b6Smrgvmw_video_port_play(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port, 4473bfa90b6Smrg short src_x, short src_y, short drw_x, 4483bfa90b6Smrg short drw_y, short src_w, short src_h, 4493bfa90b6Smrg short drw_w, short drw_h, int format, 4503bfa90b6Smrg unsigned char *buf, short width, 4513bfa90b6Smrg short height, RegionPtr clipBoxes) 4523bfa90b6Smrg{ 4533bfa90b6Smrg struct drm_vmw_control_stream_arg arg; 4543bfa90b6Smrg unsigned short w, h; 4553bfa90b6Smrg int size; 4563bfa90b6Smrg int ret; 4573bfa90b6Smrg 4583bfa90b6Smrg debug_printf("\t%s: enter\n", __func__); 4593bfa90b6Smrg 4603bfa90b6Smrg w = width; 4613bfa90b6Smrg h = height; 4623bfa90b6Smrg 4633bfa90b6Smrg /* we don't update the ports size */ 4643bfa90b6Smrg size = vmw_xv_query_image_attributes(pScrn, format, &w, &h, 4653bfa90b6Smrg port->pitches, port->offsets); 4663bfa90b6Smrg 4673bfa90b6Smrg if (size != port->size) { 4683bfa90b6Smrg vmw_xv_stop_video(pScrn, port, TRUE); 4693bfa90b6Smrg return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, 4703bfa90b6Smrg src_h, drw_w, drw_h, format, buf, width, height, 4713bfa90b6Smrg clipBoxes); 4723bfa90b6Smrg } 4733bfa90b6Smrg 4743bfa90b6Smrg memcpy(port->bufs[port->currBuf].data, buf, port->size); 4753bfa90b6Smrg 4763bfa90b6Smrg memset(&arg, 0, sizeof(arg)); 4773bfa90b6Smrg 4783bfa90b6Smrg arg.stream_id = port->streamId; 4793bfa90b6Smrg arg.enabled = TRUE; 4803bfa90b6Smrg arg.flags = port->flags; 4813bfa90b6Smrg arg.color_key = port->colorKey; 4823bfa90b6Smrg arg.handle = port->bufs[port->currBuf].buf->handle; 4833bfa90b6Smrg arg.format = format; 4843bfa90b6Smrg arg.size = port->size; 4853bfa90b6Smrg arg.width = w; 4863bfa90b6Smrg arg.height = h; 4873bfa90b6Smrg arg.src.x = src_x; 4883bfa90b6Smrg arg.src.y = src_y; 4893bfa90b6Smrg arg.src.w = src_w; 4903bfa90b6Smrg arg.src.h = src_h; 4913bfa90b6Smrg arg.dst.x = drw_x; 4923bfa90b6Smrg arg.dst.y = drw_y; 4933bfa90b6Smrg arg.dst.w = drw_w; 4943bfa90b6Smrg arg.dst.h = drw_h; 4953bfa90b6Smrg arg.pitch[0] = port->pitches[0]; 4963bfa90b6Smrg arg.pitch[1] = port->pitches[1]; 4973bfa90b6Smrg arg.pitch[2] = port->pitches[2]; 4983bfa90b6Smrg arg.offset = 0; 4993bfa90b6Smrg 5003bfa90b6Smrg /* 5013bfa90b6Smrg * Update the clipList and paint the colorkey, if required. 5023bfa90b6Smrg */ 5033bfa90b6Smrg if (!REGION_EQUAL(pScrn->pScreen, &port->clipBoxes, clipBoxes)) { 5043bfa90b6Smrg REGION_COPY(pScrn->pScreen, &port->clipBoxes, clipBoxes); 5053bfa90b6Smrg if (port->isAutoPaintColorkey) 5063bfa90b6Smrg xf86XVFillKeyHelper(pScrn->pScreen, port->colorKey, clipBoxes); 5073bfa90b6Smrg } 5083bfa90b6Smrg 5093bfa90b6Smrg xorg_flush(pScrn->pScreen); 5103bfa90b6Smrg ret = drmCommandWrite(port->drm_fd, DRM_VMW_CONTROL_STREAM, &arg, sizeof(arg)); 5113bfa90b6Smrg if (ret) { 5123bfa90b6Smrg vmw_video_port_cleanup(pScrn, port); 5133bfa90b6Smrg return XvBadAlloc; 5143bfa90b6Smrg } 5153bfa90b6Smrg 5163bfa90b6Smrg if (++(port->currBuf) >= VMWARE_VID_NUM_BUFFERS) 5173bfa90b6Smrg port->currBuf = 0; 5183bfa90b6Smrg 5193bfa90b6Smrg return Success; 5203bfa90b6Smrg} 5213bfa90b6Smrg 5223bfa90b6Smrg 5233bfa90b6Smrg/* 5243bfa90b6Smrg *----------------------------------------------------------------------------- 5253bfa90b6Smrg * 5263bfa90b6Smrg * vmw_video_port_cleanup -- 5273bfa90b6Smrg * 5283bfa90b6Smrg * Frees up all resources (if any) taken by a video stream. 5293bfa90b6Smrg * 5303bfa90b6Smrg * Results: 5313bfa90b6Smrg * None. 5323bfa90b6Smrg * 5333bfa90b6Smrg * Side effects: 5343bfa90b6Smrg * Same as above. 5353bfa90b6Smrg * 5363bfa90b6Smrg *----------------------------------------------------------------------------- 5373bfa90b6Smrg */ 5383bfa90b6Smrg 5393bfa90b6Smrgstatic void 5403bfa90b6Smrgvmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmwgfx_overlay_port *port) 5413bfa90b6Smrg{ 5423bfa90b6Smrg int i; 5433bfa90b6Smrg 5443bfa90b6Smrg debug_printf("\t%s: enter\n", __func__); 5453bfa90b6Smrg 5463bfa90b6Smrg if (port->play == vmw_video_port_init) 5473bfa90b6Smrg return; 5483bfa90b6Smrg 5493bfa90b6Smrg port->play = vmw_video_port_init; 5503bfa90b6Smrg (void) vmwgfx_unref_stream(port->drm_fd, port->streamId); 5513bfa90b6Smrg 5523bfa90b6Smrg for (i = 0; i < VMWARE_VID_NUM_BUFFERS; i++) { 5533bfa90b6Smrg vmw_video_buffer_free(&port->bufs[i]); 5543bfa90b6Smrg } 5553bfa90b6Smrg 5563bfa90b6Smrg REGION_UNINIT(pScreen->pScreen, &port->clipBoxes); 5573bfa90b6Smrg} 5583bfa90b6Smrg 5593bfa90b6Smrg 5603bfa90b6Smrg/* 5613bfa90b6Smrg *----------------------------------------------------------------------------- 5623bfa90b6Smrg * 5633bfa90b6Smrg * vmw_video_buffer_alloc -- 5643bfa90b6Smrg * 5653bfa90b6Smrg * Allocates and map a kernel buffer to be used as data storage. 5663bfa90b6Smrg * 5673bfa90b6Smrg * Results: 5683bfa90b6Smrg * XvBadAlloc on failure, otherwise Success. 5693bfa90b6Smrg * 5703bfa90b6Smrg * Side effects: 5713bfa90b6Smrg * Calls into the kernel, sets members of out. 5723bfa90b6Smrg * 5733bfa90b6Smrg *----------------------------------------------------------------------------- 5743bfa90b6Smrg */ 5753bfa90b6Smrg 5763bfa90b6Smrgstatic int 5773bfa90b6Smrgvmw_video_buffer_alloc(int drm_fd, int size, 5783bfa90b6Smrg struct vmw_video_buffer *out) 5793bfa90b6Smrg{ 5803bfa90b6Smrg out->buf = vmwgfx_dmabuf_alloc(drm_fd, size); 5813bfa90b6Smrg if (!out->buf) 5823bfa90b6Smrg return XvBadAlloc; 5833bfa90b6Smrg 5843bfa90b6Smrg out->data = vmwgfx_dmabuf_map(out->buf); 5853bfa90b6Smrg if (!out->data) { 5863bfa90b6Smrg vmwgfx_dmabuf_destroy(out->buf); 5873bfa90b6Smrg out->buf = NULL; 5883bfa90b6Smrg return XvBadAlloc; 5893bfa90b6Smrg } 5903bfa90b6Smrg 5913bfa90b6Smrg out->size = size; 5923bfa90b6Smrg debug_printf("\t\t%s: allocated buffer %p of size %i\n", __func__, out, size); 5933bfa90b6Smrg 5943bfa90b6Smrg return Success; 5953bfa90b6Smrg} 5963bfa90b6Smrg 5973bfa90b6Smrg 5983bfa90b6Smrg/* 5993bfa90b6Smrg *----------------------------------------------------------------------------- 6003bfa90b6Smrg * 6013bfa90b6Smrg * vmw_video_buffer_free -- 6023bfa90b6Smrg * 6033bfa90b6Smrg * Frees and unmaps an allocated kernel buffer. 6043bfa90b6Smrg * 6053bfa90b6Smrg * Results: 6063bfa90b6Smrg * Success. 6073bfa90b6Smrg * 6083bfa90b6Smrg * Side effects: 6093bfa90b6Smrg * Calls into the kernel, sets members of out to 0. 6103bfa90b6Smrg * 6113bfa90b6Smrg *----------------------------------------------------------------------------- 6123bfa90b6Smrg */ 6133bfa90b6Smrg 6143bfa90b6Smrgstatic int 6153bfa90b6Smrgvmw_video_buffer_free(struct vmw_video_buffer *out) 6163bfa90b6Smrg{ 6173bfa90b6Smrg if (out->size == 0) 6183bfa90b6Smrg return Success; 6193bfa90b6Smrg 6203bfa90b6Smrg vmwgfx_dmabuf_unmap(out->buf); 6213bfa90b6Smrg vmwgfx_dmabuf_destroy(out->buf); 6223bfa90b6Smrg 6233bfa90b6Smrg out->buf = NULL; 6243bfa90b6Smrg out->data = NULL; 6253bfa90b6Smrg out->size = 0; 6263bfa90b6Smrg 6273bfa90b6Smrg debug_printf("\t\t%s: freed buffer %p\n", __func__, out); 6283bfa90b6Smrg 6293bfa90b6Smrg return Success; 6303bfa90b6Smrg} 6313bfa90b6Smrg 6323bfa90b6Smrg 6333bfa90b6Smrg/* 6343bfa90b6Smrg *----------------------------------------------------------------------------- 6353bfa90b6Smrg * 6363bfa90b6Smrg * vmw_xv_put_image -- 6373bfa90b6Smrg * 6383bfa90b6Smrg * Main video playback function. It copies the passed data which is in 6393bfa90b6Smrg * the specified format (e.g. FOURCC_YV12) into the overlay. 6403bfa90b6Smrg * 6413bfa90b6Smrg * If sync is TRUE the driver should not return from this 6423bfa90b6Smrg * function until it is through reading the data from buf. 6433bfa90b6Smrg * 6443bfa90b6Smrg * Results: 6453bfa90b6Smrg * Success or XvBadAlloc on failure 6463bfa90b6Smrg * 6473bfa90b6Smrg * Side effects: 6483bfa90b6Smrg * Video port will be played(initialized if 1st frame) on success 6493bfa90b6Smrg * or will fail on error. 6503bfa90b6Smrg * 6513bfa90b6Smrg *----------------------------------------------------------------------------- 6523bfa90b6Smrg */ 6533bfa90b6Smrg 6543bfa90b6Smrgstatic int 6553bfa90b6Smrgvmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y, 6563bfa90b6Smrg short drw_x, short drw_y, short src_w, short src_h, 6573bfa90b6Smrg short drw_w, short drw_h, int format, 6583bfa90b6Smrg unsigned char *buf, short width, short height, 6593bfa90b6Smrg Bool sync, RegionPtr clipBoxes, pointer data, 6603bfa90b6Smrg DrawablePtr dst) 6613bfa90b6Smrg{ 6623bfa90b6Smrg struct vmwgfx_overlay_port *port = data; 6633bfa90b6Smrg 6643bfa90b6Smrg debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__, 6653bfa90b6Smrg src_x, src_y, src_w, src_h, 6663bfa90b6Smrg drw_x, drw_y, drw_w, drw_h, 6673bfa90b6Smrg width, height); 6683bfa90b6Smrg 6693bfa90b6Smrg return port->play(pScrn, port, src_x, src_y, drw_x, drw_y, src_w, src_h, 6703bfa90b6Smrg drw_w, drw_h, format, buf, width, height, clipBoxes); 6713bfa90b6Smrg} 6723bfa90b6Smrg 6733bfa90b6Smrg 6743bfa90b6Smrg/* 6753bfa90b6Smrg *----------------------------------------------------------------------------- 6763bfa90b6Smrg * 6773bfa90b6Smrg * vmw_xv_stop_video -- 6783bfa90b6Smrg * 6793bfa90b6Smrg * Called when we should stop playing video for a particular stream. If 6803bfa90b6Smrg * Cleanup is FALSE, the "stop" operation is only temporary, and thus we 6813bfa90b6Smrg * don't do anything. If Cleanup is TRUE we kill the video port by 6823bfa90b6Smrg * sending a message to the host and freeing up the stream. 6833bfa90b6Smrg * 6843bfa90b6Smrg * Results: 6853bfa90b6Smrg * None. 6863bfa90b6Smrg * 6873bfa90b6Smrg * Side effects: 6883bfa90b6Smrg * See above. 6893bfa90b6Smrg * 6903bfa90b6Smrg *----------------------------------------------------------------------------- 6913bfa90b6Smrg */ 6923bfa90b6Smrg 6933bfa90b6Smrgstatic void 6943bfa90b6Smrgvmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup) 6953bfa90b6Smrg{ 6963bfa90b6Smrg struct vmwgfx_overlay_port *port = data; 6973bfa90b6Smrg 6983bfa90b6Smrg debug_printf("%s: cleanup is %s\n", __func__, cleanup ? "TRUE" : "FALSE"); 6993bfa90b6Smrg REGION_EMPTY(pScrn->pScreen, &port->clipBoxes); 7003bfa90b6Smrg 7013bfa90b6Smrg if (!cleanup) 7023bfa90b6Smrg return; 7033bfa90b6Smrg 7043bfa90b6Smrg vmw_video_port_cleanup(pScrn, port); 7053bfa90b6Smrg} 7063bfa90b6Smrg 7073bfa90b6Smrg 7083bfa90b6Smrg/* 7093bfa90b6Smrg *----------------------------------------------------------------------------- 7103bfa90b6Smrg * 7113bfa90b6Smrg * vmw_xv_query_image_attributes -- 7123bfa90b6Smrg * 7133bfa90b6Smrg * From the spec: This function is called to let the driver specify how data 7143bfa90b6Smrg * for a particular image of size width by height should be stored. 7153bfa90b6Smrg * Sometimes only the size and corrected width and height are needed. In 7163bfa90b6Smrg * that case pitches and offsets are NULL. 7173bfa90b6Smrg * 7183bfa90b6Smrg * Results: 7193bfa90b6Smrg * The size of the memory required for the image, or -1 on error. 7203bfa90b6Smrg * 7213bfa90b6Smrg * Side effects: 7223bfa90b6Smrg * None. 7233bfa90b6Smrg * 7243bfa90b6Smrg *----------------------------------------------------------------------------- 7253bfa90b6Smrg */ 7263bfa90b6Smrg 7273bfa90b6Smrgstatic int 7283bfa90b6Smrgvmw_xv_query_image_attributes(ScrnInfoPtr pScrn, int format, 7293bfa90b6Smrg unsigned short *width, unsigned short *height, 7303bfa90b6Smrg int *pitches, int *offsets) 7313bfa90b6Smrg{ 7323bfa90b6Smrg INT32 size, tmp; 7333bfa90b6Smrg 7343bfa90b6Smrg if (*width > VMWARE_VID_MAX_WIDTH) { 7353bfa90b6Smrg *width = VMWARE_VID_MAX_WIDTH; 7363bfa90b6Smrg } 7373bfa90b6Smrg if (*height > VMWARE_VID_MAX_HEIGHT) { 7383bfa90b6Smrg *height = VMWARE_VID_MAX_HEIGHT; 7393bfa90b6Smrg } 7403bfa90b6Smrg 7413bfa90b6Smrg *width = (*width + 1) & ~1; 7423bfa90b6Smrg if (offsets != NULL) { 7433bfa90b6Smrg offsets[0] = 0; 7443bfa90b6Smrg } 7453bfa90b6Smrg 7463bfa90b6Smrg switch (format) { 7473bfa90b6Smrg case FOURCC_YV12: 7483bfa90b6Smrg *height = (*height + 1) & ~1; 7493bfa90b6Smrg size = (*width + 3) & ~3; 7503bfa90b6Smrg if (pitches) { 7513bfa90b6Smrg pitches[0] = size; 7523bfa90b6Smrg } 7533bfa90b6Smrg size *= *height; 7543bfa90b6Smrg if (offsets) { 7553bfa90b6Smrg offsets[1] = size; 7563bfa90b6Smrg } 7573bfa90b6Smrg tmp = ((*width >> 1) + 3) & ~3; 7583bfa90b6Smrg if (pitches) { 7593bfa90b6Smrg pitches[1] = pitches[2] = tmp; 7603bfa90b6Smrg } 7613bfa90b6Smrg tmp *= (*height >> 1); 7623bfa90b6Smrg size += tmp; 7633bfa90b6Smrg if (offsets) { 7643bfa90b6Smrg offsets[2] = size; 7653bfa90b6Smrg } 7663bfa90b6Smrg size += tmp; 7673bfa90b6Smrg break; 7683bfa90b6Smrg case FOURCC_UYVY: 7693bfa90b6Smrg case FOURCC_YUY2: 7703bfa90b6Smrg size = *width * 2; 7713bfa90b6Smrg if (pitches) { 7723bfa90b6Smrg pitches[0] = size; 7733bfa90b6Smrg } 7743bfa90b6Smrg size *= *height; 7753bfa90b6Smrg break; 7763bfa90b6Smrg default: 7773bfa90b6Smrg debug_printf("Query for invalid video format %d\n", format); 7783bfa90b6Smrg return -1; 7793bfa90b6Smrg } 7803bfa90b6Smrg return size; 7813bfa90b6Smrg} 7823bfa90b6Smrg 7833bfa90b6Smrg 7843bfa90b6Smrg/* 7853bfa90b6Smrg *----------------------------------------------------------------------------- 7863bfa90b6Smrg * 7873bfa90b6Smrg * vmw_xv_set_port_attribute -- 7883bfa90b6Smrg * 7893bfa90b6Smrg * From the spec: A port may have particular attributes such as colorKey, hue, 7903bfa90b6Smrg * saturation, brightness or contrast. Xv clients set these 7913bfa90b6Smrg * attribute values by sending attribute strings (Atoms) to the server. 7923bfa90b6Smrg * 7933bfa90b6Smrg * Results: 7943bfa90b6Smrg * Success if the attribute exists and XvBadAlloc otherwise. 7953bfa90b6Smrg * 7963bfa90b6Smrg * Side effects: 7973bfa90b6Smrg * The respective attribute gets the new value. 7983bfa90b6Smrg * 7993bfa90b6Smrg *----------------------------------------------------------------------------- 8003bfa90b6Smrg */ 8013bfa90b6Smrg 8023bfa90b6Smrgstatic int 8033bfa90b6Smrgvmw_xv_set_port_attribute(ScrnInfoPtr pScrn, Atom attribute, 8043bfa90b6Smrg INT32 value, pointer data) 8053bfa90b6Smrg{ 8063bfa90b6Smrg struct vmwgfx_overlay_port *port = data; 8073bfa90b6Smrg Atom xvColorKey = MAKE_ATOM("XV_COLORKEY"); 8083bfa90b6Smrg Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 8093bfa90b6Smrg 8103bfa90b6Smrg if (attribute == xvColorKey) { 8113bfa90b6Smrg debug_printf("%s: Set colorkey:0x%x\n", __func__, (unsigned)value); 8123bfa90b6Smrg port->colorKey = value; 8133bfa90b6Smrg } else if (attribute == xvAutoPaint) { 8143bfa90b6Smrg debug_printf("%s: Set autoPaint: %s\n", __func__, value? "TRUE": "FALSE"); 8153bfa90b6Smrg port->isAutoPaintColorkey = value; 8163bfa90b6Smrg } else { 8173bfa90b6Smrg return XvBadAlloc; 8183bfa90b6Smrg } 8193bfa90b6Smrg 8203bfa90b6Smrg return Success; 8213bfa90b6Smrg} 8223bfa90b6Smrg 8233bfa90b6Smrg 8243bfa90b6Smrg/* 8253bfa90b6Smrg *----------------------------------------------------------------------------- 8263bfa90b6Smrg * 8273bfa90b6Smrg * vmw_xv_get_port_attribute -- 8283bfa90b6Smrg * 8293bfa90b6Smrg * From the spec: A port may have particular attributes such as hue, 8303bfa90b6Smrg * saturation, brightness or contrast. Xv clients get these 8313bfa90b6Smrg * attribute values by sending attribute strings (Atoms) to the server 8323bfa90b6Smrg * 8333bfa90b6Smrg * Results: 8343bfa90b6Smrg * Success if the attribute exists and XvBadAlloc otherwise. 8353bfa90b6Smrg * 8363bfa90b6Smrg * Side effects: 8373bfa90b6Smrg * "value" contains the requested attribute on success. 8383bfa90b6Smrg * 8393bfa90b6Smrg *----------------------------------------------------------------------------- 8403bfa90b6Smrg */ 8413bfa90b6Smrg 8423bfa90b6Smrgstatic int 8433bfa90b6Smrgvmw_xv_get_port_attribute(ScrnInfoPtr pScrn, Atom attribute, 8443bfa90b6Smrg INT32 *value, pointer data) 8453bfa90b6Smrg{ 8463bfa90b6Smrg struct vmwgfx_overlay_port *port = data; 8473bfa90b6Smrg Atom xvColorKey = MAKE_ATOM("XV_COLORKEY"); 8483bfa90b6Smrg Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 8493bfa90b6Smrg 8503bfa90b6Smrg if (attribute == xvColorKey) { 8513bfa90b6Smrg *value = port->colorKey; 8523bfa90b6Smrg } else if (attribute == xvAutoPaint) { 8533bfa90b6Smrg *value = port->isAutoPaintColorkey; 8543bfa90b6Smrg } else { 8553bfa90b6Smrg return XvBadAlloc; 8563bfa90b6Smrg } 8573bfa90b6Smrg 8583bfa90b6Smrg return Success; 8593bfa90b6Smrg} 8603bfa90b6Smrg 8613bfa90b6Smrg 8623bfa90b6Smrg/* 8633bfa90b6Smrg *----------------------------------------------------------------------------- 8643bfa90b6Smrg * 8653bfa90b6Smrg * vmw_xv_query_best_size -- 8663bfa90b6Smrg * 8673bfa90b6Smrg * From the spec: QueryBestSize provides the client with a way to query what 8683bfa90b6Smrg * the destination dimensions would end up being if they were to request 8693bfa90b6Smrg * that an area vid_w by vid_h from the video stream be scaled to rectangle 8703bfa90b6Smrg * of drw_w by drw_h on the screen. Since it is not expected that all 8713bfa90b6Smrg * hardware will be able to get the target dimensions exactly, it is 8723bfa90b6Smrg * important that the driver provide this function. 8733bfa90b6Smrg * 8743bfa90b6Smrg * This function seems to never be called, but to be on the safe side 8753bfa90b6Smrg * we apply the same logic that QueryImageAttributes has for width 8763bfa90b6Smrg * and height. 8773bfa90b6Smrg * 8783bfa90b6Smrg * Results: 8793bfa90b6Smrg * None. 8803bfa90b6Smrg * 8813bfa90b6Smrg * Side effects: 8823bfa90b6Smrg * None. 8833bfa90b6Smrg * 8843bfa90b6Smrg *----------------------------------------------------------------------------- 8853bfa90b6Smrg */ 8863bfa90b6Smrg 8873bfa90b6Smrgstatic void 8883bfa90b6Smrgvmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion, 8893bfa90b6Smrg short vid_w, short vid_h, short drw_w, 8903bfa90b6Smrg short drw_h, unsigned int *p_w, 8913bfa90b6Smrg unsigned int *p_h, pointer data) 8923bfa90b6Smrg{ 8933bfa90b6Smrg *p_w = (drw_w + 1) & ~1; 8943bfa90b6Smrg *p_h = drw_h; 8953bfa90b6Smrg 8963bfa90b6Smrg return; 8973bfa90b6Smrg} 898