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