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