vmwarevideo.c revision 3bfa90b6
16df26cacSmrg/*
26df26cacSmrg * Copyright 2007 by VMware, Inc.
36df26cacSmrg *
46df26cacSmrg * Permission is hereby granted, free of charge, to any person obtaining a
56df26cacSmrg * copy of this software and associated documentation files (the "Software"),
66df26cacSmrg * to deal in the Software without restriction, including without limitation
76df26cacSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86df26cacSmrg * and/or sell copies of the Software, and to permit persons to whom the
96df26cacSmrg * Software is furnished to do so, subject to the following conditions:
106df26cacSmrg *
116df26cacSmrg * The above copyright notice and this permission notice shall be included in
126df26cacSmrg * all copies or substantial portions of the Software.
136df26cacSmrg *
146df26cacSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
156df26cacSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
166df26cacSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
176df26cacSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
186df26cacSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
196df26cacSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
206df26cacSmrg * OTHER DEALINGS IN THE SOFTWARE.
216df26cacSmrg *
226df26cacSmrg * Except as contained in this notice, the name of the copyright holder(s)
236df26cacSmrg * and author(s) shall not be used in advertising or otherwise to promote
246df26cacSmrg * the sale, use or other dealings in this Software without prior written
256df26cacSmrg * authorization from the copyright holder(s) and author(s).
266df26cacSmrg */
276df26cacSmrg
286df26cacSmrg/*
296df26cacSmrg * vmwarevideo.c --
306df26cacSmrg *
316df26cacSmrg *      Xv extension support.
326df26cacSmrg *      See http://www.xfree86.org/current/DESIGN16.html
336df26cacSmrg *
346df26cacSmrg */
356df26cacSmrg
366df26cacSmrg
376df26cacSmrg#ifdef HAVE_CONFIG_H
386df26cacSmrg#include "config.h"
396df26cacSmrg#endif
406df26cacSmrg
416df26cacSmrg#include "vmware.h"
423bfa90b6Smrg#include "vmware_common.h"
436df26cacSmrg#include "xf86xv.h"
446df26cacSmrg#include "fourcc.h"
456df26cacSmrg#include "svga_escape.h"
466df26cacSmrg#include "svga_overlay.h"
476df26cacSmrg
486df26cacSmrg#include <X11/extensions/Xv.h>
496df26cacSmrg
50a241306cSmrg#ifndef HAVE_XORG_SERVER_1_5_0
51a241306cSmrg#include <xf86_ansic.h>
52a241306cSmrg#include <xf86_libc.h>
53a241306cSmrg#endif
54a241306cSmrg
553bfa90b6Smrg
563bfa90b6Smrg#define HAVE_FILLKEYHELPERDRAWABLE \
573bfa90b6Smrg    ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 2) ||  \
583bfa90b6Smrg     ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) == 1) && \
593bfa90b6Smrg      (GET_ABI_MINOR(ABI_VIDEODRV_VERSION) >= 2)))
603bfa90b6Smrg
616df26cacSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
626df26cacSmrg
636df26cacSmrg/*
646df26cacSmrg * Used to pack structs
656df26cacSmrg */
666df26cacSmrg#define PACKED __attribute__((__packed__))
676df26cacSmrg
686df26cacSmrg/*
696df26cacSmrg * Number of videos that can be played simultaneously
706df26cacSmrg */
716df26cacSmrg#define VMWARE_VID_NUM_PORTS 1
726df26cacSmrg
736df26cacSmrg/*
7416fd1166Smrg * Using a dark shade as the default colorKey
756df26cacSmrg */
7616fd1166Smrg#define VMWARE_VIDEO_COLORKEY 0x100701
776df26cacSmrg
786df26cacSmrg/*
796df26cacSmrg * Maximum dimensions
806df26cacSmrg */
816df26cacSmrg#define VMWARE_VID_MAX_WIDTH    2048
826df26cacSmrg#define VMWARE_VID_MAX_HEIGHT   2048
836df26cacSmrg
846df26cacSmrg#define VMWARE_VID_NUM_ENCODINGS 1
856df26cacSmrgstatic XF86VideoEncodingRec vmwareVideoEncodings[] =
866df26cacSmrg{
876df26cacSmrg    {
886df26cacSmrg       0,
896df26cacSmrg       "XV_IMAGE",
906df26cacSmrg       VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT,
916df26cacSmrg       {1, 1}
926df26cacSmrg    }
936df26cacSmrg};
946df26cacSmrg
956df26cacSmrg#define VMWARE_VID_NUM_FORMATS 2
966df26cacSmrgstatic XF86VideoFormatRec vmwareVideoFormats[] =
976df26cacSmrg{
986df26cacSmrg    { 16, TrueColor},
996df26cacSmrg    { 24, TrueColor}
1006df26cacSmrg};
1016df26cacSmrg
10216fd1166Smrg#define VMWARE_VID_NUM_IMAGES 3
1036df26cacSmrgstatic XF86ImageRec vmwareVideoImages[] =
1046df26cacSmrg{
1056df26cacSmrg    XVIMAGE_YV12,
10616fd1166Smrg    XVIMAGE_YUY2,
10716fd1166Smrg    XVIMAGE_UYVY
1086df26cacSmrg};
1096df26cacSmrg
11016fd1166Smrg#define VMWARE_VID_NUM_ATTRIBUTES 2
1116df26cacSmrgstatic XF86AttributeRec vmwareVideoAttributes[] =
1126df26cacSmrg{
1136df26cacSmrg    {
1146df26cacSmrg        XvGettable | XvSettable,
1156df26cacSmrg        0x000000,
1166df26cacSmrg        0xffffff,
1176df26cacSmrg        "XV_COLORKEY"
11816fd1166Smrg    },
11916fd1166Smrg    {
12016fd1166Smrg        XvGettable | XvSettable,
12116fd1166Smrg        0,
12216fd1166Smrg        1,
12316fd1166Smrg        "XV_AUTOPAINT_COLORKEY"
1246df26cacSmrg    }
1256df26cacSmrg};
1266df26cacSmrg
1276df26cacSmrg/*
1286df26cacSmrg * Video frames are stored in a circular list of buffers.
1296df26cacSmrg */
1306df26cacSmrg#define VMWARE_VID_NUM_BUFFERS 1
1316df26cacSmrg/*
1326df26cacSmrg * Defines the structure used to hold and pass video data to the host
1336df26cacSmrg */
1346df26cacSmrgtypedef struct {
1356df26cacSmrg   uint32  dataOffset;
1366df26cacSmrg   pointer data;
1376df26cacSmrg} VMWAREVideoBuffer;
1386df26cacSmrg
1396df26cacSmrgtypedef struct {
1406df26cacSmrg   uint32 size;
1416df26cacSmrg   uint32 offset;
1426df26cacSmrg} VMWAREOffscreenRec, *VMWAREOffscreenPtr;
1436df26cacSmrg
1446df26cacSmrg/*
1456df26cacSmrg * Trivial offscreen manager that allocates memory from the
1466df26cacSmrg * bottom of the VRAM.
1476df26cacSmrg */
1486df26cacSmrgstatic VMWAREOffscreenRec offscreenMgr;
1496df26cacSmrg
1506df26cacSmrg/*
1516df26cacSmrg * structs that reside in fmt_priv.
1526df26cacSmrg */
1536df26cacSmrgtypedef struct {
1546df26cacSmrg    int pitches[3];
1556df26cacSmrg    int offsets[3];
1566df26cacSmrg} VMWAREVideoFmtData;
1576df26cacSmrg
1586df26cacSmrg/*
1596df26cacSmrg * Structure representing a specific video stream.
1606df26cacSmrg */
1616df26cacSmrgstruct VMWAREVideoRec {
1626df26cacSmrg   uint32             streamId;
1636df26cacSmrg   /*
1646df26cacSmrg    * Function prototype same as XvPutImage.
1656df26cacSmrg    */
1666df26cacSmrg   int                (*play)(ScrnInfoPtr, struct VMWAREVideoRec *,
1676df26cacSmrg                              short, short, short, short, short,
1686df26cacSmrg                              short, short, short, int, unsigned char*,
1693bfa90b6Smrg                              short, short, RegionPtr, DrawablePtr);
1706df26cacSmrg   /*
1716df26cacSmrg    * Offscreen memory region used to pass video data to the host.
1726df26cacSmrg    */
1736df26cacSmrg   VMWAREOffscreenPtr fbarea;
1746df26cacSmrg   VMWAREVideoBuffer  bufs[VMWARE_VID_NUM_BUFFERS];
1756df26cacSmrg   uint8              currBuf;
1766df26cacSmrg   uint32             size;
1776df26cacSmrg   uint32             colorKey;
17816fd1166Smrg   Bool               isAutoPaintColorkey;
1796df26cacSmrg   uint32             flags;
18016fd1166Smrg   RegionRec          clipBoxes;
1816df26cacSmrg   VMWAREVideoFmtData *fmt_priv;
1826df26cacSmrg};
1836df26cacSmrg
1846df26cacSmrgtypedef struct VMWAREVideoRec VMWAREVideoRec;
1856df26cacSmrgtypedef VMWAREVideoRec *VMWAREVideoPtr;
1866df26cacSmrg
1876df26cacSmrg/*
1886df26cacSmrg * Callback functions
1896df26cacSmrg */
1903bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
1916df26cacSmrgstatic int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
1926df26cacSmrg                            short drw_x, short drw_y, short src_w, short src_h,
1936df26cacSmrg                            short drw_w, short drw_h, int image,
1946df26cacSmrg                            unsigned char *buf, short width, short height,
1956df26cacSmrg                            Bool sync, RegionPtr clipBoxes, pointer data,
1966df26cacSmrg                            DrawablePtr dst);
1976df26cacSmrg#else
1986df26cacSmrgstatic int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
1996df26cacSmrg                            short drw_x, short drw_y, short src_w, short src_h,
2006df26cacSmrg                            short drw_w, short drw_h, int image,
2016df26cacSmrg                            unsigned char *buf, short width, short height,
2026df26cacSmrg                            Bool sync, RegionPtr clipBoxes, pointer data);
2036df26cacSmrg#endif
2046df26cacSmrgstatic void vmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup);
2056df26cacSmrgstatic int vmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
2066df26cacSmrg                                      unsigned short *width,
2076df26cacSmrg                                      unsigned short *height, int *pitches,
2086df26cacSmrg                                      int *offsets);
2096df26cacSmrgstatic int vmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
2106df26cacSmrg                                  INT32 value, pointer data);
2116df26cacSmrgstatic int vmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
2126df26cacSmrg                                  INT32 *value, pointer data);
2136df26cacSmrgstatic void vmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
2146df26cacSmrg                                short vid_w, short vid_h, short drw_w,
2156df26cacSmrg                                short drw_h, unsigned int *p_w,
2166df26cacSmrg                                unsigned int *p_h, pointer data);
2176df26cacSmrg
2186df26cacSmrg/*
2196df26cacSmrg * Local functions for video streams
2206df26cacSmrg */
2216df26cacSmrgstatic XF86VideoAdaptorPtr vmwareVideoSetup(ScrnInfoPtr pScrn);
2226df26cacSmrgstatic int vmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2236df26cacSmrg                                 short src_x, short src_y, short drw_x,
2246df26cacSmrg                                 short drw_y, short src_w, short src_h,
2256df26cacSmrg                                 short drw_w, short drw_h, int format,
22616fd1166Smrg                                 unsigned char *buf, short width,
2273bfa90b6Smrg                                 short height, RegionPtr clipBoxes,
2283bfa90b6Smrg				 DrawablePtr draw);
2296df26cacSmrgstatic int vmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2306df26cacSmrg                                     int format, unsigned short width,
2316df26cacSmrg                                     unsigned short height);
2326df26cacSmrgstatic int vmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2336df26cacSmrg                           short src_x, short src_y, short drw_x,
2346df26cacSmrg                           short drw_y, short src_w, short src_h,
2356df26cacSmrg                           short drw_w, short drw_h, int format,
2366df26cacSmrg                           unsigned char *buf, short width,
2373bfa90b6Smrg                           short height, RegionPtr clipBoxes,
2383bfa90b6Smrg			   DrawablePtr draw);
2396df26cacSmrgstatic void vmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId);
2406df26cacSmrgstatic void vmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
2416df26cacSmrg                                 uint32 regId, uint32 value);
2426df26cacSmrgstatic void vmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid);
2436df26cacSmrg
2446df26cacSmrg/*
2456df26cacSmrg * Offscreen memory manager functions
2466df26cacSmrg */
2476df26cacSmrgstatic void vmwareOffscreenInit(void);
2486df26cacSmrgstatic VMWAREOffscreenPtr vmwareOffscreenAllocate(VMWAREPtr pVMWARE,
2496df26cacSmrg                                                  uint32 size);
2506df26cacSmrgstatic void vmwareOffscreenFree(VMWAREOffscreenPtr memptr);
2516df26cacSmrg
2526df26cacSmrg
2536df26cacSmrg/*
2546df26cacSmrg *-----------------------------------------------------------------------------
2556df26cacSmrg *
2566df26cacSmrg * vmwareCheckVideoSanity --
2576df26cacSmrg *
2586df26cacSmrg *    Ensures that on ModeSwitch the offscreen memory used
2596df26cacSmrg *    by the Xv streams doesn't become part of the guest framebuffer.
2606df26cacSmrg *
2616df26cacSmrg * Results:
2626df26cacSmrg *    None
2636df26cacSmrg *
2646df26cacSmrg * Side effects:
2656df26cacSmrg *    If it is found that the offscreen used by video streams  lies
2666df26cacSmrg *    within the range of the framebuffer(after ModeSwitch) then the video
2676df26cacSmrg *    streams will be stopped.
2686df26cacSmrg *
2696df26cacSmrg *-----------------------------------------------------------------------------
2706df26cacSmrg */
2716df26cacSmrg
2726df26cacSmrgvoid
2736df26cacSmrgvmwareCheckVideoSanity(ScrnInfoPtr pScrn)
2746df26cacSmrg{
2756df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
2766df26cacSmrg    VMWAREVideoPtr pVid;
2776df26cacSmrg
2786df26cacSmrg   if (offscreenMgr.size == 0 ||
2796df26cacSmrg       offscreenMgr.offset > pVMWARE->FbSize) {
2806df26cacSmrg       return ;
2816df26cacSmrg   }
2826df26cacSmrg
2836df26cacSmrg   pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
2846df26cacSmrg   vmwareStopVideo(pScrn, pVid, TRUE);
2856df26cacSmrg}
2866df26cacSmrg
2876df26cacSmrg
2886df26cacSmrg/*
2896df26cacSmrg *-----------------------------------------------------------------------------
2906df26cacSmrg *
2916df26cacSmrg * vmwareOffscreenInit --
2926df26cacSmrg *
2936df26cacSmrg *    Initializes the trivial Offscreen memory manager.
2946df26cacSmrg *
2956df26cacSmrg * Results:
2966df26cacSmrg *    None.
2976df26cacSmrg *
2986df26cacSmrg * Side effects:
2996df26cacSmrg *    Initializes the Offscreen manager meta-data structure.
3006df26cacSmrg *
3016df26cacSmrg *-----------------------------------------------------------------------------
3026df26cacSmrg */
3036df26cacSmrg
3046df26cacSmrgstatic void
3056df26cacSmrgvmwareOffscreenInit(void)
3066df26cacSmrg{
3076df26cacSmrg    offscreenMgr.size = 0;
3086df26cacSmrg    offscreenMgr.offset  = 0;
3096df26cacSmrg}
3106df26cacSmrg
3116df26cacSmrg
3126df26cacSmrg/*
3136df26cacSmrg *-----------------------------------------------------------------------------
3146df26cacSmrg *
3156df26cacSmrg * vmwareOffscreenAllocate --
3166df26cacSmrg *
3176df26cacSmrg *    Allocates offscreen memory.
3186df26cacSmrg *    Memory is allocated from the bottom part of the VRAM.
3196df26cacSmrg *    The memory manager is trivial iand can handle only 1 video-stream.
3206df26cacSmrg *    ----------
3216df26cacSmrg *    |        |
3226df26cacSmrg *    |  FB    |
3236df26cacSmrg *    |        |
3246df26cacSmrg *    |---------
3256df26cacSmrg *    |        |
3266df26cacSmrg *    |        |
3276df26cacSmrg *    |--------|
3286df26cacSmrg *    | Offscr |
3296df26cacSmrg *    |--------|
3306df26cacSmrg *
3316df26cacSmrg *      VRAM
3326df26cacSmrg *
3336df26cacSmrg * Results:
3346df26cacSmrg *    Pointer to the allocated Offscreen memory.
3356df26cacSmrg *
3366df26cacSmrg * Side effects:
3376df26cacSmrg *    Updates the Offscreen memory manager meta-data structure.
3386df26cacSmrg *
3396df26cacSmrg *-----------------------------------------------------------------------------
3406df26cacSmrg */
3416df26cacSmrg
3426df26cacSmrgstatic VMWAREOffscreenPtr
3436df26cacSmrgvmwareOffscreenAllocate(VMWAREPtr pVMWARE, uint32 size)
3446df26cacSmrg{
3456df26cacSmrg    VMWAREOffscreenPtr memptr;
3466df26cacSmrg
3476df26cacSmrg    if ((pVMWARE->videoRam - pVMWARE->FbSize - pVMWARE->fbPitch - 7) < size) {
3486df26cacSmrg        return NULL;
3496df26cacSmrg    }
3506df26cacSmrg
351a241306cSmrg    memptr = malloc(sizeof(VMWAREOffscreenRec));
3526df26cacSmrg    if (!memptr) {
3536df26cacSmrg        return NULL;
3546df26cacSmrg    }
3556df26cacSmrg    memptr->size = size;
3566df26cacSmrg    memptr->offset  = (pVMWARE->videoRam - size) & ~7;
3576df26cacSmrg
3586df26cacSmrg    VmwareLog(("vmwareOffscreenAllocate: Offset:%x", memptr->offset));
3596df26cacSmrg
3606df26cacSmrg    offscreenMgr.size = memptr->size;
3616df26cacSmrg    offscreenMgr.offset = memptr->offset;
3626df26cacSmrg    return memptr;
3636df26cacSmrg}
3646df26cacSmrg
3656df26cacSmrg
3666df26cacSmrg/*
3676df26cacSmrg *-----------------------------------------------------------------------------
3686df26cacSmrg *
3696df26cacSmrg * vmwareOffscreenFree --
3706df26cacSmrg *
3716df26cacSmrg *    Frees the allocated offscreen memory.
3726df26cacSmrg *
3736df26cacSmrg * Results:
3746df26cacSmrg *    None.
3756df26cacSmrg *
3766df26cacSmrg * Side effects:
3776df26cacSmrg *    Updates the Offscreen memory manager meta-data structure.
3786df26cacSmrg *
3796df26cacSmrg *-----------------------------------------------------------------------------
3806df26cacSmrg */
3816df26cacSmrg
3826df26cacSmrgstatic void
3836df26cacSmrgvmwareOffscreenFree(VMWAREOffscreenPtr memptr)
3846df26cacSmrg{
3856df26cacSmrg    if (memptr) {
3866df26cacSmrg        free(memptr);
3876df26cacSmrg    }
3886df26cacSmrg
3896df26cacSmrg    offscreenMgr.size = 0;
3906df26cacSmrg    offscreenMgr.offset = 0;
3916df26cacSmrg}
3926df26cacSmrg
3936df26cacSmrg
3946df26cacSmrg/*
3956df26cacSmrg *-----------------------------------------------------------------------------
3966df26cacSmrg *
3976df26cacSmrg * vmwareVideoEnabled --
3986df26cacSmrg *
3996df26cacSmrg *    Checks if Video FIFO and Escape FIFO cap are enabled.
4006df26cacSmrg *
4016df26cacSmrg * Results:
4026df26cacSmrg *    TRUE if required caps are enabled, FALSE otherwise.
4036df26cacSmrg *
4046df26cacSmrg * Side effects:
4056df26cacSmrg *    None.
4066df26cacSmrg *
4076df26cacSmrg *-----------------------------------------------------------------------------
4086df26cacSmrg */
4096df26cacSmrg
41016fd1166SmrgBool
41116fd1166SmrgvmwareVideoEnabled(VMWAREPtr pVMWARE)
4126df26cacSmrg{
4136df26cacSmrg    return ((pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO) &&
4146df26cacSmrg            (pVMWARE->vmwareFIFO[SVGA_FIFO_CAPABILITIES] &
4156df26cacSmrg             (SVGA_FIFO_CAP_VIDEO | SVGA_FIFO_CAP_ESCAPE)));
4166df26cacSmrg}
4176df26cacSmrg
4186df26cacSmrg
4196df26cacSmrg/*
4206df26cacSmrg *-----------------------------------------------------------------------------
4216df26cacSmrg *
4226df26cacSmrg * vmwareVideoInit --
4236df26cacSmrg *
4246df26cacSmrg *    Initializes Xv support.
4256df26cacSmrg *
4266df26cacSmrg * Results:
4276df26cacSmrg *    TRUE on success, FALSE on error.
4286df26cacSmrg *
4296df26cacSmrg * Side effects:
4306df26cacSmrg *    Xv support is initialized. Memory is allocated for all supported
4316df26cacSmrg *    video streams.
4326df26cacSmrg *
4336df26cacSmrg *-----------------------------------------------------------------------------
4346df26cacSmrg */
4356df26cacSmrg
43616fd1166SmrgBool
43716fd1166SmrgvmwareVideoInit(ScreenPtr pScreen)
4386df26cacSmrg{
4393bfa90b6Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
4406df26cacSmrg    XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
4416df26cacSmrg    XF86VideoAdaptorPtr newAdaptor = NULL;
4426df26cacSmrg    int numAdaptors;
4436df26cacSmrg
4446df26cacSmrg    TRACEPOINT
4456df26cacSmrg
4466df26cacSmrg    vmwareOffscreenInit();
4476df26cacSmrg
4486df26cacSmrg    numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors);
4496df26cacSmrg
4506df26cacSmrg    newAdaptor = vmwareVideoSetup(pScrn);
4516df26cacSmrg    if (!newAdaptor) {
4526df26cacSmrg        VmwareLog(("Failed to initialize Xv extension \n"));
4536df26cacSmrg        return FALSE;
4546df26cacSmrg    }
4556df26cacSmrg
4566df26cacSmrg    if (!numAdaptors) {
4576df26cacSmrg        numAdaptors = 1;
4586df26cacSmrg        overlayAdaptors = &newAdaptor;
4596df26cacSmrg    } else {
460a241306cSmrg         newAdaptors = malloc((numAdaptors + 1) *
4616df26cacSmrg                              sizeof(XF86VideoAdaptorPtr*));
4626df26cacSmrg         if (!newAdaptors) {
4636df26cacSmrg            xf86XVFreeVideoAdaptorRec(newAdaptor);
4646df26cacSmrg            return FALSE;
4656df26cacSmrg         }
4666df26cacSmrg
4676df26cacSmrg         memcpy(newAdaptors, overlayAdaptors,
4686df26cacSmrg                numAdaptors * sizeof(XF86VideoAdaptorPtr));
4696df26cacSmrg         newAdaptors[numAdaptors++] = newAdaptor;
4706df26cacSmrg         overlayAdaptors = newAdaptors;
4716df26cacSmrg    }
4726df26cacSmrg
4736df26cacSmrg    if (!xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors)) {
4746df26cacSmrg        VmwareLog(("Failed to initialize Xv extension\n"));
4756df26cacSmrg        xf86XVFreeVideoAdaptorRec(newAdaptor);
4766df26cacSmrg        return FALSE;
4776df26cacSmrg    }
4786df26cacSmrg
4796df26cacSmrg    if (newAdaptors) {
480a241306cSmrg        free(newAdaptors);
4816df26cacSmrg    }
4826df26cacSmrg
4836df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4846df26cacSmrg               "Initialized VMware Xv extension successfully.\n");
4856df26cacSmrg    return TRUE;
4866df26cacSmrg}
4876df26cacSmrg
4886df26cacSmrg
4896df26cacSmrg/*
4906df26cacSmrg *-----------------------------------------------------------------------------
4916df26cacSmrg *
4926df26cacSmrg * vmwareVideoEnd --
4936df26cacSmrg *
4946df26cacSmrg *    Unitializes video.
4956df26cacSmrg *
4966df26cacSmrg * Results:
4976df26cacSmrg *    None.
4986df26cacSmrg *
4996df26cacSmrg * Side effects:
5006df26cacSmrg *    pVMWARE->videoStreams = NULL
5016df26cacSmrg *
5026df26cacSmrg *-----------------------------------------------------------------------------
5036df26cacSmrg */
5046df26cacSmrg
50516fd1166Smrgvoid
50616fd1166SmrgvmwareVideoEnd(ScreenPtr pScreen)
5076df26cacSmrg{
5083bfa90b6Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
5096df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
5106df26cacSmrg    VMWAREVideoPtr pVid;
5116df26cacSmrg    int i;
5126df26cacSmrg
5136df26cacSmrg    TRACEPOINT
5146df26cacSmrg
5156df26cacSmrg    /*
5166df26cacSmrg     * Video streams are allocated after the DevUnion array
5176df26cacSmrg     * (see VideoSetup)
5186df26cacSmrg     */
5196df26cacSmrg    pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
5206df26cacSmrg    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
5216df26cacSmrg        vmwareVideoEndStream(pScrn, &pVid[i]);
522a241306cSmrg	REGION_UNINIT(pScreen, &pVid[i].clipBoxes);
5236df26cacSmrg    }
5246df26cacSmrg
5256df26cacSmrg    free(pVMWARE->videoStreams);
5266df26cacSmrg    pVMWARE->videoStreams = NULL;
5276df26cacSmrg}
5286df26cacSmrg
5296df26cacSmrg
5306df26cacSmrg/*
5316df26cacSmrg *-----------------------------------------------------------------------------
5326df26cacSmrg *
5336df26cacSmrg * vmwareVideoSetup --
5346df26cacSmrg *
5356df26cacSmrg *    Initializes a XF86VideoAdaptor structure with the capabilities and
5366df26cacSmrg *    functions supported by this video driver.
5376df26cacSmrg *
5386df26cacSmrg * Results:
5396df26cacSmrg *    On success initialized XF86VideoAdaptor struct or NULL on error
5406df26cacSmrg *
5416df26cacSmrg * Side effects:
5426df26cacSmrg *    None.
5436df26cacSmrg *
5446df26cacSmrg *-----------------------------------------------------------------------------
5456df26cacSmrg */
5466df26cacSmrg
54716fd1166Smrgstatic XF86VideoAdaptorPtr
54816fd1166SmrgvmwareVideoSetup(ScrnInfoPtr pScrn)
5496df26cacSmrg{
5506df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
5516df26cacSmrg    XF86VideoAdaptorPtr adaptor;
5526df26cacSmrg    VMWAREVideoPtr pPriv;
5536df26cacSmrg    DevUnion *du;
5546df26cacSmrg    int i;
5556df26cacSmrg
5566df26cacSmrg    TRACEPOINT
5576df26cacSmrg
5586df26cacSmrg    adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
5596df26cacSmrg    if (!adaptor) {
5606df26cacSmrg        VmwareLog(("Not enough memory\n"));
5616df26cacSmrg        return NULL;
5626df26cacSmrg    }
563a241306cSmrg    du = calloc(1, VMWARE_VID_NUM_PORTS *
5646df26cacSmrg        (sizeof(DevUnion) + sizeof(VMWAREVideoRec)));
5656df26cacSmrg
5666df26cacSmrg    if (!du) {
5676df26cacSmrg        VmwareLog(("Not enough memory.\n"));
5686df26cacSmrg        xf86XVFreeVideoAdaptorRec(adaptor);
5696df26cacSmrg        return NULL;
5706df26cacSmrg    }
5716df26cacSmrg
5726df26cacSmrg    adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
5736df26cacSmrg    adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
5746df26cacSmrg    adaptor->name = "VMware Video Engine";
5756df26cacSmrg    adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
5766df26cacSmrg    adaptor->pEncodings = vmwareVideoEncodings;
5776df26cacSmrg    adaptor->nFormats = VMWARE_VID_NUM_FORMATS;
5786df26cacSmrg    adaptor->pFormats = vmwareVideoFormats;
5796df26cacSmrg    adaptor->nPorts = VMWARE_VID_NUM_PORTS;
5806df26cacSmrg
5816df26cacSmrg    pPriv = (VMWAREVideoPtr) &du[VMWARE_VID_NUM_PORTS];
5826df26cacSmrg    adaptor->pPortPrivates = du;
5836df26cacSmrg
5846df26cacSmrg    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
5856df26cacSmrg        pPriv[i].streamId = i;
5866df26cacSmrg        pPriv[i].play = vmwareVideoInitStream;
5876df26cacSmrg        pPriv[i].flags = SVGA_VIDEO_FLAG_COLORKEY;
5886df26cacSmrg        pPriv[i].colorKey = VMWARE_VIDEO_COLORKEY;
58916fd1166Smrg        pPriv[i].isAutoPaintColorkey = TRUE;
590a241306cSmrg	REGION_NULL(pScreen, &pPriv[i].clipBoxes);
5916df26cacSmrg        adaptor->pPortPrivates[i].ptr = &pPriv[i];
5926df26cacSmrg    }
5936df26cacSmrg    pVMWARE->videoStreams = du;
5946df26cacSmrg
5956df26cacSmrg    adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES;
5966df26cacSmrg    adaptor->pAttributes = vmwareVideoAttributes;
5976df26cacSmrg
5986df26cacSmrg    adaptor->nImages = VMWARE_VID_NUM_IMAGES;
5996df26cacSmrg    adaptor->pImages = vmwareVideoImages;
6006df26cacSmrg
6016df26cacSmrg    adaptor->PutVideo = NULL;
6026df26cacSmrg    adaptor->PutStill = NULL;
6036df26cacSmrg    adaptor->GetVideo = NULL;
6046df26cacSmrg    adaptor->GetStill = NULL;
6056df26cacSmrg    adaptor->StopVideo = vmwareStopVideo;
6066df26cacSmrg    adaptor->SetPortAttribute = vmwareSetPortAttribute;
6076df26cacSmrg    adaptor->GetPortAttribute = vmwareGetPortAttribute;
6086df26cacSmrg    adaptor->QueryBestSize = vmwareQueryBestSize;
6096df26cacSmrg    adaptor->PutImage = vmwareXvPutImage;
6106df26cacSmrg    adaptor->QueryImageAttributes = vmwareQueryImageAttributes;
6116df26cacSmrg
6126df26cacSmrg    return adaptor;
6136df26cacSmrg}
6146df26cacSmrg
6156df26cacSmrg
6166df26cacSmrg/*
6176df26cacSmrg *-----------------------------------------------------------------------------
6186df26cacSmrg *
6196df26cacSmrg * vmwareVideoInitStream --
6206df26cacSmrg *
6216df26cacSmrg *    Initializes a video stream in response to the first PutImage() on a
6226df26cacSmrg *    video stream. The process goes as follows:
6236df26cacSmrg *    - Figure out characteristics according to format
6246df26cacSmrg *    - Allocate offscreen memory
6256df26cacSmrg *    - Pass on video to Play() functions
6266df26cacSmrg *
6276df26cacSmrg * Results:
6286df26cacSmrg *    Success or XvBadAlloc on failure.
6296df26cacSmrg *
6306df26cacSmrg * Side effects:
6316df26cacSmrg *    Video stream is initialized and its first frame sent to the host
6326df26cacSmrg *    (done by VideoPlay() function called at the end)
6336df26cacSmrg *
6346df26cacSmrg *-----------------------------------------------------------------------------
6356df26cacSmrg */
6366df26cacSmrg
63716fd1166Smrgstatic int
63816fd1166SmrgvmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
63916fd1166Smrg                      short src_x, short src_y, short drw_x,
64016fd1166Smrg                      short drw_y, short src_w, short src_h,
64116fd1166Smrg                      short drw_w, short drw_h, int format,
64216fd1166Smrg                      unsigned char *buf, short width,
6433bfa90b6Smrg                      short height, RegionPtr clipBoxes,
6443bfa90b6Smrg		      DrawablePtr draw)
6456df26cacSmrg{
6466df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
6476df26cacSmrg    int i;
6486df26cacSmrg
6496df26cacSmrg    TRACEPOINT
6506df26cacSmrg
6516df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
6526df26cacSmrg               "Initializing Xv video-stream with id:%d format:%d\n",
6536df26cacSmrg                pVid->streamId, format);
6546df26cacSmrg
6556df26cacSmrg    pVid->size = vmwareVideoInitAttributes(pScrn, pVid, format, width,
6566df26cacSmrg                                           height);
6576df26cacSmrg
6586df26cacSmrg    if (pVid->size == -1) {
6596df26cacSmrg        VmwareLog(("Could not initialize 0x%x video stream\n", format));
6606df26cacSmrg        return XvBadAlloc;
6616df26cacSmrg    }
6626df26cacSmrg
6636df26cacSmrg    pVid->play = vmwareVideoPlay;
6646df26cacSmrg
6656df26cacSmrg    pVid->fbarea = vmwareOffscreenAllocate(pVMWARE,
6666df26cacSmrg                       pVid->size * VMWARE_VID_NUM_BUFFERS);
6676df26cacSmrg
6686df26cacSmrg    if (!pVid->fbarea) {
6696df26cacSmrg       VmwareLog(("Could not allocate offscreen memory\n"));
6706df26cacSmrg       vmwareVideoEndStream(pScrn, pVid);
6716df26cacSmrg       return BadAlloc;
6726df26cacSmrg    }
6736df26cacSmrg
6746df26cacSmrg    pVid->bufs[0].dataOffset = pVid->fbarea->offset;
6756df26cacSmrg    pVid->bufs[0].data = pVMWARE->FbBase + pVid->bufs[0].dataOffset;
6766df26cacSmrg
6776df26cacSmrg    for (i = 1; i < VMWARE_VID_NUM_BUFFERS; ++i) {
6786df26cacSmrg        pVid->bufs[i].dataOffset = pVid->bufs[i-1].dataOffset + pVid->size;
6796df26cacSmrg        pVid->bufs[i].data = pVMWARE->FbBase + pVid->bufs[i].dataOffset;
6806df26cacSmrg    }
6816df26cacSmrg    pVid->currBuf = 0;
6826df26cacSmrg
68316fd1166Smrg    REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
68416fd1166Smrg
68516fd1166Smrg    if (pVid->isAutoPaintColorkey) {
686a241306cSmrg	BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
687a241306cSmrg	int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
688a241306cSmrg
6893bfa90b6Smrg#if HAVE_FILLKEYHELPERDRAWABLE
6903bfa90b6Smrg	xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
6913bfa90b6Smrg#else
69216fd1166Smrg        xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
6933bfa90b6Smrg#endif
694a241306cSmrg	/**
695a241306cSmrg	 * Force update to paint the colorkey before the overlay flush.
696a241306cSmrg	 */
697a241306cSmrg
698a241306cSmrg	while(nBoxes--)
699a241306cSmrg	    vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
70016fd1166Smrg    }
70116fd1166Smrg
7026df26cacSmrg    VmwareLog(("Got offscreen region, offset %d, size %d "
7036df26cacSmrg               "(yuv size in bytes: %d)\n",
7046df26cacSmrg               pVid->fbarea->offset, pVid->fbarea->size, pVid->size));
7056df26cacSmrg
7066df26cacSmrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
7073bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
7083bfa90b6Smrg		      draw);
7096df26cacSmrg}
7106df26cacSmrg
7116df26cacSmrg
7126df26cacSmrg/*
7136df26cacSmrg *-----------------------------------------------------------------------------
7146df26cacSmrg *
7156df26cacSmrg * vmwareVideoInitAttributes --
7166df26cacSmrg *
7176df26cacSmrg *    Fetches the format specific attributes using QueryImageAttributes().
7186df26cacSmrg *
7196df26cacSmrg * Results:
7206df26cacSmrg *    size of the YUV frame on success and -1 on error.
7216df26cacSmrg *
7226df26cacSmrg * Side effects:
7236df26cacSmrg *    The video stream gets the format specific attributes(fmtData).
7246df26cacSmrg *
7256df26cacSmrg *-----------------------------------------------------------------------------
7266df26cacSmrg */
7276df26cacSmrg
72816fd1166Smrgstatic int
72916fd1166SmrgvmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
73016fd1166Smrg                          int format, unsigned short width,
73116fd1166Smrg                          unsigned short height)
7326df26cacSmrg{
7336df26cacSmrg    int size;
7346df26cacSmrg    VMWAREVideoFmtData *fmtData;
7356df26cacSmrg
7366df26cacSmrg    TRACEPOINT
7376df26cacSmrg
738a241306cSmrg    fmtData = calloc(1, sizeof(VMWAREVideoFmtData));
7396df26cacSmrg    if (!fmtData) {
7406df26cacSmrg        return -1;
7416df26cacSmrg    }
7426df26cacSmrg
7436df26cacSmrg    size = vmwareQueryImageAttributes(pScrn, format, &width, &height,
7446df26cacSmrg                                      fmtData->pitches, fmtData->offsets);
7456df26cacSmrg    if (size == -1) {
7466df26cacSmrg        free(fmtData);
7476df26cacSmrg        return -1;
7486df26cacSmrg    }
7496df26cacSmrg
7506df26cacSmrg    pVid->fmt_priv = fmtData;
7516df26cacSmrg    return size;
7526df26cacSmrg}
7536df26cacSmrg
7546df26cacSmrg
7556df26cacSmrg/*
7566df26cacSmrg *-----------------------------------------------------------------------------
7576df26cacSmrg *
7586df26cacSmrg * vmwareVideoPlay --
7596df26cacSmrg *
7606df26cacSmrg *    Sends all the attributes associated with the video frame using the
7616df26cacSmrg *    FIFO ESCAPE mechanism to the host.
7626df26cacSmrg *
7636df26cacSmrg * Results:
7646df26cacSmrg *    Always returns Success.
7656df26cacSmrg *
7666df26cacSmrg * Side effects:
7676df26cacSmrg *    None.
7686df26cacSmrg *
7696df26cacSmrg *-----------------------------------------------------------------------------
7706df26cacSmrg */
7716df26cacSmrg
77216fd1166Smrgstatic int
77316fd1166SmrgvmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
77416fd1166Smrg                short src_x, short src_y, short drw_x,
77516fd1166Smrg                short drw_y, short src_w, short src_h,
77616fd1166Smrg                short drw_w, short drw_h, int format,
77716fd1166Smrg                unsigned char *buf, short width,
7783bfa90b6Smrg                short height, RegionPtr clipBoxes,
7793bfa90b6Smrg		DrawablePtr draw)
7806df26cacSmrg{
7816df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
7826df26cacSmrg    uint32 *fifoItem;
7836df26cacSmrg    int i, regId;
7846df26cacSmrg    struct PACKED _item {
7856df26cacSmrg        uint32 regId;
7866df26cacSmrg        uint32 value;
7876df26cacSmrg    };
7886df26cacSmrg
7896df26cacSmrg    struct PACKED _body {
7906df26cacSmrg        uint32 escape;
7916df26cacSmrg        uint32 streamId;
7926df26cacSmrg        struct _item items[SVGA_VIDEO_NUM_REGS];
7936df26cacSmrg    };
7946df26cacSmrg
7956df26cacSmrg    struct PACKED _cmdSetRegs {
7966df26cacSmrg        uint32 cmd;
7976df26cacSmrg        uint32 nsid;
7986df26cacSmrg        uint32 size;
7996df26cacSmrg        struct _body body;
8006df26cacSmrg    };
8016df26cacSmrg
8026df26cacSmrg    struct _cmdSetRegs cmdSetRegs;
8036df26cacSmrg    struct _item *items;
80416fd1166Smrg    int size;
80516fd1166Smrg    VMWAREVideoFmtData *fmtData;
80616fd1166Smrg    unsigned short w, h;
8076df26cacSmrg
80816fd1166Smrg    w = width;
80916fd1166Smrg    h = height;
81016fd1166Smrg    fmtData = pVid->fmt_priv;
81116fd1166Smrg
81216fd1166Smrg    size = vmwareQueryImageAttributes(pScrn, format, &w, &h,
81316fd1166Smrg                                      fmtData->pitches, fmtData->offsets);
81416fd1166Smrg
81516fd1166Smrg    if (size > pVid->size) {
81616fd1166Smrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Increase in size of Xv video "
81716fd1166Smrg                   "frame streamId:%d.\n", pVid->streamId);
81816fd1166Smrg        vmwareStopVideo(pScrn, pVid, TRUE);
81916fd1166Smrg        return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w,
82016fd1166Smrg                          src_h, drw_w, drw_h, format, buf, width, height,
8213bfa90b6Smrg                          clipBoxes, draw);
82216fd1166Smrg    }
82316fd1166Smrg
82416fd1166Smrg    pVid->size = size;
8256df26cacSmrg    memcpy(pVid->bufs[pVid->currBuf].data, buf, pVid->size);
8266df26cacSmrg
8276df26cacSmrg    cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
8286df26cacSmrg    cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
8296df26cacSmrg    cmdSetRegs.size = sizeof(cmdSetRegs.body);
8306df26cacSmrg    cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
8316df26cacSmrg    cmdSetRegs.body.streamId = pVid->streamId;
8326df26cacSmrg
8336df26cacSmrg    items = cmdSetRegs.body.items;
8346df26cacSmrg    for (i = SVGA_VIDEO_ENABLED; i < SVGA_VIDEO_NUM_REGS; i++) {
8356df26cacSmrg        items[i].regId = i;
8366df26cacSmrg    }
8376df26cacSmrg
8386df26cacSmrg    items[SVGA_VIDEO_ENABLED].value = TRUE;
8396df26cacSmrg    items[SVGA_VIDEO_DATA_OFFSET].value =
8406df26cacSmrg        pVid->bufs[pVid->currBuf].dataOffset;
8416df26cacSmrg    items[SVGA_VIDEO_SIZE].value = pVid->size;
8426df26cacSmrg    items[SVGA_VIDEO_FORMAT].value = format;
84316fd1166Smrg    items[SVGA_VIDEO_WIDTH].value = w;
84416fd1166Smrg    items[SVGA_VIDEO_HEIGHT].value = h;
8456df26cacSmrg    items[SVGA_VIDEO_SRC_X].value = src_x;
8466df26cacSmrg    items[SVGA_VIDEO_SRC_Y].value = src_y;
8476df26cacSmrg    items[SVGA_VIDEO_SRC_WIDTH].value = src_w;
8486df26cacSmrg    items[SVGA_VIDEO_SRC_HEIGHT].value = src_h;
8496df26cacSmrg    items[SVGA_VIDEO_DST_X].value = drw_x;
8506df26cacSmrg    items[SVGA_VIDEO_DST_Y].value = drw_y;
8516df26cacSmrg    items[SVGA_VIDEO_DST_WIDTH]. value = drw_w;
8526df26cacSmrg    items[SVGA_VIDEO_DST_HEIGHT].value = drw_h;
8536df26cacSmrg    items[SVGA_VIDEO_COLORKEY].value = pVid->colorKey;
8546df26cacSmrg    items[SVGA_VIDEO_FLAGS].value = pVid->flags;
8556df26cacSmrg
8566df26cacSmrg    for (i = 0, regId = SVGA_VIDEO_PITCH_1; i < 3; i++, regId++) {
85716fd1166Smrg        items[regId].value = fmtData->pitches[i];
8586df26cacSmrg    }
8596df26cacSmrg
8606df26cacSmrg    fifoItem = (uint32 *) &cmdSetRegs;
8616df26cacSmrg    for (i = 0; i <  sizeof(cmdSetRegs) / sizeof(uint32); i++) {
8626df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
8636df26cacSmrg    }
8646df26cacSmrg
86516fd1166Smrg    /*
86616fd1166Smrg     *  Update the clipList and paint the colorkey, if required.
86716fd1166Smrg     */
86816fd1166Smrg    if (!vmwareIsRegionEqual(&pVid->clipBoxes, clipBoxes)) {
86916fd1166Smrg        REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
87016fd1166Smrg        if (pVid->isAutoPaintColorkey) {
871a241306cSmrg	    BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
872a241306cSmrg	    int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
873a241306cSmrg
8743bfa90b6Smrg#if HAVE_FILLKEYHELPERDRAWABLE
8753bfa90b6Smrg	    xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
8763bfa90b6Smrg#else
8773bfa90b6Smrg	    xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
8783bfa90b6Smrg#endif
879a241306cSmrg	    /**
880a241306cSmrg	     * Force update to paint the colorkey before the overlay flush.
881a241306cSmrg	     */
882a241306cSmrg
883a241306cSmrg	    while(nBoxes--)
884a241306cSmrg		vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
885a241306cSmrg
88616fd1166Smrg        }
88716fd1166Smrg    }
88816fd1166Smrg
8896df26cacSmrg    vmwareVideoFlush(pVMWARE, pVid->streamId);
8906df26cacSmrg
8916df26cacSmrg    pVid->currBuf = ++pVid->currBuf & (VMWARE_VID_NUM_BUFFERS - 1);
89216fd1166Smrg
8936df26cacSmrg    return Success;
8946df26cacSmrg}
8956df26cacSmrg
8966df26cacSmrg
8976df26cacSmrg/*
8986df26cacSmrg *-----------------------------------------------------------------------------
8996df26cacSmrg *
9006df26cacSmrg * vmwareVideoFlush --
9016df26cacSmrg *
9026df26cacSmrg *    Sends the VIDEO_FLUSH command (FIFO ESCAPE mechanism) asking the host
9036df26cacSmrg *    to play the video stream or end it.
9046df26cacSmrg *
9056df26cacSmrg * Results:
9066df26cacSmrg *    None.
9076df26cacSmrg *
9086df26cacSmrg * Side effects:
9096df26cacSmrg *    None.
9106df26cacSmrg *
9116df26cacSmrg *-----------------------------------------------------------------------------
9126df26cacSmrg */
9136df26cacSmrg
91416fd1166Smrgstatic void
91516fd1166SmrgvmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId)
9166df26cacSmrg{
9176df26cacSmrg    struct PACKED _body {
9186df26cacSmrg        uint32 escape;
9196df26cacSmrg        uint32 streamId;
9206df26cacSmrg    };
9216df26cacSmrg
9226df26cacSmrg    struct PACKED _cmdFlush {
9236df26cacSmrg        uint32 cmd;
9246df26cacSmrg        uint32 nsid;
9256df26cacSmrg        uint32 size;
9266df26cacSmrg        struct _body body;
9276df26cacSmrg    };
9286df26cacSmrg
9296df26cacSmrg    struct _cmdFlush cmdFlush;
9306df26cacSmrg    uint32 *fifoItem;
9316df26cacSmrg    int i;
9326df26cacSmrg
9336df26cacSmrg    cmdFlush.cmd = SVGA_CMD_ESCAPE;
9346df26cacSmrg    cmdFlush.nsid = SVGA_ESCAPE_NSID_VMWARE;
9356df26cacSmrg    cmdFlush.size = sizeof(cmdFlush.body);
9366df26cacSmrg    cmdFlush.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
9376df26cacSmrg    cmdFlush.body.streamId = streamId;
9386df26cacSmrg
9396df26cacSmrg    fifoItem = (uint32 *) &cmdFlush;
9406df26cacSmrg    for (i = 0; i < sizeof(cmdFlush) / sizeof(uint32); i++) {
9416df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
9426df26cacSmrg    }
9436df26cacSmrg}
9446df26cacSmrg
9456df26cacSmrg
9466df26cacSmrg/*
9476df26cacSmrg *-----------------------------------------------------------------------------
9486df26cacSmrg *
9496df26cacSmrg * vmwareVideoSetOneReg --
9506df26cacSmrg *
9516df26cacSmrg *    Sets one video register using the FIFO ESCAPE mechanidm.
9526df26cacSmrg *
9536df26cacSmrg * Results:
9546df26cacSmrg *    None.
9556df26cacSmrg *
9566df26cacSmrg * Side effects:
9576df26cacSmrg *    None.
9586df26cacSmrg *-----------------------------------------------------------------------------
9596df26cacSmrg */
9606df26cacSmrg
96116fd1166Smrgstatic void
96216fd1166SmrgvmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
96316fd1166Smrg                     uint32 regId, uint32 value)
9646df26cacSmrg{
9656df26cacSmrg    struct PACKED _item {
9666df26cacSmrg        uint32 regId;
9676df26cacSmrg        uint32 value;
9686df26cacSmrg    };
9696df26cacSmrg
9706df26cacSmrg    struct PACKED _body {
9716df26cacSmrg        uint32 escape;
9726df26cacSmrg        uint32 streamId;
9736df26cacSmrg        struct _item item;
9746df26cacSmrg    };
9756df26cacSmrg
9766df26cacSmrg    struct PACKED _cmdSetRegs {
9776df26cacSmrg        uint32 cmd;
9786df26cacSmrg        uint32 nsid;
9796df26cacSmrg        uint32 size;
9806df26cacSmrg        struct _body body;
9816df26cacSmrg    };
9826df26cacSmrg
9836df26cacSmrg    struct _cmdSetRegs cmdSetRegs;
9846df26cacSmrg    int i;
9856df26cacSmrg    uint32 *fifoItem;
9866df26cacSmrg
9876df26cacSmrg    cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
9886df26cacSmrg    cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
9896df26cacSmrg    cmdSetRegs.size = sizeof(cmdSetRegs.body);
9906df26cacSmrg    cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
9916df26cacSmrg    cmdSetRegs.body.streamId = streamId;
9926df26cacSmrg    cmdSetRegs.body.item.regId = regId;
9936df26cacSmrg    cmdSetRegs.body.item.value = value;
9946df26cacSmrg
9956df26cacSmrg    fifoItem = (uint32 *) &cmdSetRegs;
9966df26cacSmrg    for (i = 0; i < sizeof(cmdSetRegs) / sizeof(uint32); i++) {
9976df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
9986df26cacSmrg    }
9996df26cacSmrg}
10006df26cacSmrg
10016df26cacSmrg
10026df26cacSmrg/*
10036df26cacSmrg *-----------------------------------------------------------------------------
10046df26cacSmrg *
10056df26cacSmrg * vmwareVideoEndStream --
10066df26cacSmrg *
10076df26cacSmrg *    Frees up all resources (if any) taken by a video stream.
10086df26cacSmrg *
10096df26cacSmrg * Results:
10106df26cacSmrg *    None.
10116df26cacSmrg *
10126df26cacSmrg * Side effects:
10136df26cacSmrg *    Same as above.
10146df26cacSmrg *
10156df26cacSmrg *-----------------------------------------------------------------------------
10166df26cacSmrg */
10176df26cacSmrg
101816fd1166Smrgstatic void
101916fd1166SmrgvmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid)
10206df26cacSmrg{
10216df26cacSmrg    uint32 id, colorKey, flags;
102216fd1166Smrg    Bool isAutoPaintColorkey;
10236df26cacSmrg
10246df26cacSmrg    if (pVid->fmt_priv) {
10256df26cacSmrg        free(pVid->fmt_priv);
10266df26cacSmrg    }
10276df26cacSmrg
10286df26cacSmrg    if (pVid->fbarea) {
10296df26cacSmrg        vmwareOffscreenFree(pVid->fbarea);
10306df26cacSmrg        pVid->fbarea =  NULL;
10316df26cacSmrg    }
10326df26cacSmrg
10336df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
10346df26cacSmrg               "Terminating Xv video-stream id:%d\n", pVid->streamId);
10356df26cacSmrg    /*
10366df26cacSmrg     * reset stream for next video
10376df26cacSmrg     */
10386df26cacSmrg    id = pVid->streamId;
10396df26cacSmrg    colorKey = pVid->colorKey;
10406df26cacSmrg    flags = pVid->flags;
104116fd1166Smrg    isAutoPaintColorkey = pVid->isAutoPaintColorkey;
104216fd1166Smrg
10436df26cacSmrg    memset(pVid, 0, sizeof(*pVid));
104416fd1166Smrg
10456df26cacSmrg    pVid->streamId = id;
10466df26cacSmrg    pVid->play = vmwareVideoInitStream;
10476df26cacSmrg    pVid->colorKey = colorKey;
10486df26cacSmrg    pVid->flags = flags;
104916fd1166Smrg    pVid->isAutoPaintColorkey = isAutoPaintColorkey;
10506df26cacSmrg}
10516df26cacSmrg
10526df26cacSmrg
10536df26cacSmrg/*
10546df26cacSmrg *-----------------------------------------------------------------------------
10556df26cacSmrg *
10566df26cacSmrg * vmwareXvPutImage --
10576df26cacSmrg *
10586df26cacSmrg *    Main video playback function. It copies the passed data which is in
10596df26cacSmrg *    the specified format (e.g. FOURCC_YV12) into the overlay.
10606df26cacSmrg *
10616df26cacSmrg *    If sync is TRUE the driver should not return from this
10626df26cacSmrg *    function until it is through reading the data from buf.
10636df26cacSmrg *
10646df26cacSmrg *    There are two function prototypes to cope with the API change in X.org
10656df26cacSmrg *    7.1
10666df26cacSmrg *
10676df26cacSmrg * Results:
10686df26cacSmrg *    Success or XvBadAlloc on failure
10696df26cacSmrg *
10706df26cacSmrg * Side effects:
10716df26cacSmrg *    Video stream will be played(initialized if 1st frame) on success
10726df26cacSmrg *    or will fail on error.
10736df26cacSmrg *
10746df26cacSmrg *-----------------------------------------------------------------------------
10756df26cacSmrg */
10766df26cacSmrg
10773bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
107816fd1166Smrgstatic int
107916fd1166SmrgvmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
108016fd1166Smrg                 short drw_x, short drw_y, short src_w, short src_h,
108116fd1166Smrg                 short drw_w, short drw_h, int format,
108216fd1166Smrg                 unsigned char *buf, short width, short height,
108316fd1166Smrg                 Bool sync, RegionPtr clipBoxes, pointer data,
108416fd1166Smrg                 DrawablePtr dst)
10856df26cacSmrg#else
108616fd1166Smrgstatic int
108716fd1166SmrgvmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
108816fd1166Smrg                 short drw_x, short drw_y, short src_w, short src_h,
108916fd1166Smrg                 short drw_w, short drw_h, int format,
109016fd1166Smrg                 unsigned char *buf, short width, short height,
109116fd1166Smrg                 Bool sync, RegionPtr clipBoxes, pointer data)
10926df26cacSmrg#endif
10936df26cacSmrg{
10946df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
10956df26cacSmrg    VMWAREVideoPtr pVid = data;
10966df26cacSmrg
10976df26cacSmrg    TRACEPOINT
10986df26cacSmrg
10996df26cacSmrg    if (!vmwareVideoEnabled(pVMWARE)) {
11006df26cacSmrg        return XvBadAlloc;
11016df26cacSmrg    }
11026df26cacSmrg
11033bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
11046df26cacSmrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
11053bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
11063bfa90b6Smrg		      dst);
11073bfa90b6Smrg#else
11083bfa90b6Smrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
11093bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
11103bfa90b6Smrg		      NULL);
11113bfa90b6Smrg#endif
11126df26cacSmrg}
11136df26cacSmrg
11146df26cacSmrg
11156df26cacSmrg/*
11166df26cacSmrg *-----------------------------------------------------------------------------
11176df26cacSmrg *
11186df26cacSmrg * vmwareStopVideo --
11196df26cacSmrg *
11206df26cacSmrg *    Called when we should stop playing video for a particular stream. If
11216df26cacSmrg *    Cleanup is FALSE, the "stop" operation is only temporary, and thus we
11226df26cacSmrg *    don't do anything. If Cleanup is TRUE we kill the video stream by
11236df26cacSmrg *    sending a message to the host and freeing up the stream.
11246df26cacSmrg *
11256df26cacSmrg * Results:
11266df26cacSmrg *    None.
11276df26cacSmrg *
11286df26cacSmrg * Side effects:
11296df26cacSmrg *    See above.
11306df26cacSmrg *
11316df26cacSmrg *-----------------------------------------------------------------------------
11326df26cacSmrg */
11336df26cacSmrg
113416fd1166Smrgstatic void
113516fd1166SmrgvmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup)
11366df26cacSmrg{
11376df26cacSmrg    VMWAREVideoPtr pVid = data;
11386df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
11396df26cacSmrg    TRACEPOINT
11406df26cacSmrg
11416df26cacSmrg    if (!vmwareVideoEnabled(pVMWARE)) {
11426df26cacSmrg        return;
11436df26cacSmrg    }
1144a241306cSmrg
1145a241306cSmrg    REGION_EMPTY(pScrn->pScreen, &pVid->clipBoxes);
1146a241306cSmrg
11476df26cacSmrg    if (!Cleanup) {
114816fd1166Smrg        VmwareLog(("vmwareStopVideo: Cleanup is FALSE.\n"));
11496df26cacSmrg        return;
11506df26cacSmrg    }
11516df26cacSmrg    vmwareVideoSetOneReg(pVMWARE, pVid->streamId,
11526df26cacSmrg                         SVGA_VIDEO_ENABLED, FALSE);
11536df26cacSmrg
11546df26cacSmrg    vmwareVideoFlush(pVMWARE, pVid->streamId);
11556df26cacSmrg    vmwareVideoEndStream(pScrn, pVid);
11566df26cacSmrg
11576df26cacSmrg}
11586df26cacSmrg
11596df26cacSmrg
11606df26cacSmrg/*
11616df26cacSmrg *-----------------------------------------------------------------------------
11626df26cacSmrg *
11636df26cacSmrg * vmwareQueryImageAttributes --
11646df26cacSmrg *
11656df26cacSmrg *    From the spec: This function is called to let the driver specify how data
11666df26cacSmrg *    for a particular image of size width by height should be stored.
11676df26cacSmrg *    Sometimes only the size and corrected width and height are needed. In
11686df26cacSmrg *    that case pitches and offsets are NULL.
11696df26cacSmrg *
11706df26cacSmrg * Results:
11716df26cacSmrg *    The size of the memory required for the image, or -1 on error.
11726df26cacSmrg *
11736df26cacSmrg * Side effects:
11746df26cacSmrg *    None.
11756df26cacSmrg *
11766df26cacSmrg *-----------------------------------------------------------------------------
11776df26cacSmrg */
11786df26cacSmrg
117916fd1166Smrgstatic int
118016fd1166SmrgvmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
118116fd1166Smrg                           unsigned short *width, unsigned short *height,
118216fd1166Smrg                           int *pitches, int *offsets)
11836df26cacSmrg{
11846df26cacSmrg    INT32 size, tmp;
11856df26cacSmrg
11866df26cacSmrg    TRACEPOINT
11876df26cacSmrg
11886df26cacSmrg    if (*width > VMWARE_VID_MAX_WIDTH) {
11896df26cacSmrg        *width = VMWARE_VID_MAX_WIDTH;
11906df26cacSmrg    }
11916df26cacSmrg    if (*height > VMWARE_VID_MAX_HEIGHT) {
11926df26cacSmrg        *height = VMWARE_VID_MAX_HEIGHT;
11936df26cacSmrg    }
11946df26cacSmrg
11956df26cacSmrg    *width = (*width + 1) & ~1;
11966df26cacSmrg    if (offsets != NULL) {
11976df26cacSmrg        offsets[0] = 0;
11986df26cacSmrg    }
11996df26cacSmrg
12006df26cacSmrg    switch (format) {
12016df26cacSmrg       case FOURCC_YV12:
12026df26cacSmrg           *height = (*height + 1) & ~1;
12036df26cacSmrg           size = (*width + 3) & ~3;
12046df26cacSmrg           if (pitches) {
12056df26cacSmrg               pitches[0] = size;
12066df26cacSmrg           }
12076df26cacSmrg           size *= *height;
12086df26cacSmrg           if (offsets) {
12096df26cacSmrg               offsets[1] = size;
12106df26cacSmrg           }
12116df26cacSmrg           tmp = ((*width >> 1) + 3) & ~3;
12126df26cacSmrg           if (pitches) {
12136df26cacSmrg                pitches[1] = pitches[2] = tmp;
12146df26cacSmrg           }
12156df26cacSmrg           tmp *= (*height >> 1);
12166df26cacSmrg           size += tmp;
12176df26cacSmrg           if (offsets) {
12186df26cacSmrg               offsets[2] = size;
12196df26cacSmrg           }
12206df26cacSmrg           size += tmp;
12216df26cacSmrg           break;
122216fd1166Smrg       case FOURCC_UYVY:
12236df26cacSmrg       case FOURCC_YUY2:
12246df26cacSmrg           size = *width * 2;
12256df26cacSmrg           if (pitches) {
12266df26cacSmrg               pitches[0] = size;
12276df26cacSmrg           }
12286df26cacSmrg           size *= *height;
12296df26cacSmrg           break;
12306df26cacSmrg       default:
12316df26cacSmrg           VmwareLog(("Query for invalid video format %d\n", format));
12326df26cacSmrg           return -1;
12336df26cacSmrg    }
12346df26cacSmrg    return size;
12356df26cacSmrg}
12366df26cacSmrg
12376df26cacSmrg
12386df26cacSmrg/*
12396df26cacSmrg *-----------------------------------------------------------------------------
12406df26cacSmrg *
12416df26cacSmrg * vmwareSetPortAttribute --
12426df26cacSmrg *
12436df26cacSmrg *    From the spec: A port may have particular attributes such as colorKey, hue,
12446df26cacSmrg *    saturation, brightness or contrast. Xv clients set these
12456df26cacSmrg *    attribute values by sending attribute strings (Atoms) to the server.
12466df26cacSmrg *
12476df26cacSmrg * Results:
12486df26cacSmrg *    Success if the attribute exists and XvBadAlloc otherwise.
12496df26cacSmrg *
12506df26cacSmrg * Side effects:
12516df26cacSmrg *    The respective attribute gets the new value.
12526df26cacSmrg *
12536df26cacSmrg *-----------------------------------------------------------------------------
12546df26cacSmrg */
12556df26cacSmrg
125616fd1166Smrgstatic int
125716fd1166SmrgvmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
125816fd1166Smrg                       INT32 value, pointer data)
12596df26cacSmrg{
12606df26cacSmrg    VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
12616df26cacSmrg    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
126216fd1166Smrg    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
12636df26cacSmrg
12646df26cacSmrg    if (attribute == xvColorKey) {
126516fd1166Smrg        VmwareLog(("Set colorkey:0x%x\n", value));
12666df26cacSmrg        pVid->colorKey = value;
126716fd1166Smrg    } else if (attribute == xvAutoPaint) {
126816fd1166Smrg        VmwareLog(("Set autoPaint: %s\n", value? "TRUE": "FALSE"));
126916fd1166Smrg        pVid->isAutoPaintColorkey = value;
12706df26cacSmrg    } else {
12716df26cacSmrg        return XvBadAlloc;
12726df26cacSmrg    }
127316fd1166Smrg
12746df26cacSmrg    return Success;
12756df26cacSmrg}
12766df26cacSmrg
12776df26cacSmrg
12786df26cacSmrg/*
12796df26cacSmrg *-----------------------------------------------------------------------------
12806df26cacSmrg *
12816df26cacSmrg * vmwareGetPortAttribute --
12826df26cacSmrg *
12836df26cacSmrg *    From the spec: A port may have particular attributes such as hue,
12846df26cacSmrg *    saturation, brightness or contrast. Xv clients get these
12856df26cacSmrg *    attribute values by sending attribute strings (Atoms) to the server
12866df26cacSmrg *
12876df26cacSmrg * Results:
12886df26cacSmrg *    Success if the attribute exists and XvBadAlloc otherwise.
12896df26cacSmrg *
12906df26cacSmrg * Side effects:
12916df26cacSmrg *    "value" contains the requested attribute on success.
12926df26cacSmrg *
12936df26cacSmrg *-----------------------------------------------------------------------------
12946df26cacSmrg */
12956df26cacSmrg
129616fd1166Smrgstatic int
129716fd1166SmrgvmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
129816fd1166Smrg                       INT32 *value, pointer data)
12996df26cacSmrg{
13006df26cacSmrg    VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
13016df26cacSmrg    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
130216fd1166Smrg    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
13036df26cacSmrg
13046df26cacSmrg    if (attribute == xvColorKey) {
13056df26cacSmrg        *value = pVid->colorKey;
130616fd1166Smrg    } else if (attribute == xvAutoPaint) {
130716fd1166Smrg        *value = pVid->isAutoPaintColorkey;
13086df26cacSmrg    } else {
13096df26cacSmrg        return XvBadAlloc;
13106df26cacSmrg    }
131116fd1166Smrg
13126df26cacSmrg    return Success;
13136df26cacSmrg}
13146df26cacSmrg
13156df26cacSmrg
13166df26cacSmrg/*
13176df26cacSmrg *-----------------------------------------------------------------------------
13186df26cacSmrg *
13196df26cacSmrg * vmwareQueryBestSize --
13206df26cacSmrg *
13216df26cacSmrg *    From the spec: QueryBestSize provides the client with a way to query what
13226df26cacSmrg *    the destination dimensions would end up being if they were to request
13236df26cacSmrg *    that an area vid_w by vid_h from the video stream be scaled to rectangle
13246df26cacSmrg *    of drw_w by drw_h on the screen. Since it is not expected that all
13256df26cacSmrg *    hardware will be able to get the target dimensions exactly, it is
13266df26cacSmrg *    important that the driver provide this function.
13276df26cacSmrg *
13286df26cacSmrg *    This function seems to never be called, but to be on the safe side
13296df26cacSmrg *    we apply the same logic that QueryImageAttributes has for width
13306df26cacSmrg *    and height
13316df26cacSmrg *
13326df26cacSmrg * Results:
13336df26cacSmrg *    None.
13346df26cacSmrg *
13356df26cacSmrg * Side effects:
13366df26cacSmrg *    None
13376df26cacSmrg *
13386df26cacSmrg *-----------------------------------------------------------------------------
13396df26cacSmrg */
13406df26cacSmrg
134116fd1166Smrgstatic void
134216fd1166SmrgvmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
134316fd1166Smrg                    short vid_w, short vid_h, short drw_w,
134416fd1166Smrg                    short drw_h, unsigned int *p_w,
134516fd1166Smrg                    unsigned int *p_h, pointer data)
13466df26cacSmrg{
13476df26cacSmrg    *p_w = (drw_w + 1) & ~1;
13486df26cacSmrg    *p_h = drw_h;
13496df26cacSmrg
13506df26cacSmrg    return;
13516df26cacSmrg}
13526df26cacSmrg
1353