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