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