vmwarevideo.c revision 25dbecb6
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"
4725dbecb6Smrg#include "common_compat.h"
486df26cacSmrg
496df26cacSmrg#include <X11/extensions/Xv.h>
506df26cacSmrg
51a241306cSmrg#ifndef HAVE_XORG_SERVER_1_5_0
52a241306cSmrg#include <xf86_ansic.h>
53a241306cSmrg#include <xf86_libc.h>
54a241306cSmrg#endif
55a241306cSmrg
5625dbecb6Smrgstatic CONST_ABI_16_0 char xv_adapt_name[] = "VMWare Overlay Video Engine";
5725dbecb6Smrgstatic CONST_ABI_16_0 char xv_image_name[] = "XV_IMAGE";
583bfa90b6Smrg
593bfa90b6Smrg#define HAVE_FILLKEYHELPERDRAWABLE \
603bfa90b6Smrg    ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 2) ||  \
613bfa90b6Smrg     ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) == 1) && \
623bfa90b6Smrg      (GET_ABI_MINOR(ABI_VIDEODRV_VERSION) >= 2)))
633bfa90b6Smrg
64591e32d7Ssnj#if HAVE_FILLKEYHELPERDRAWABLE
65591e32d7Ssnj#include <damage.h>
66591e32d7Ssnj#endif
67591e32d7Ssnj
686df26cacSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
696df26cacSmrg
706df26cacSmrg/*
716df26cacSmrg * Used to pack structs
726df26cacSmrg */
736df26cacSmrg#define PACKED __attribute__((__packed__))
746df26cacSmrg
756df26cacSmrg/*
766df26cacSmrg * Number of videos that can be played simultaneously
776df26cacSmrg */
786df26cacSmrg#define VMWARE_VID_NUM_PORTS 1
796df26cacSmrg
806df26cacSmrg/*
8116fd1166Smrg * Using a dark shade as the default colorKey
826df26cacSmrg */
8316fd1166Smrg#define VMWARE_VIDEO_COLORKEY 0x100701
846df26cacSmrg
856df26cacSmrg/*
866df26cacSmrg * Maximum dimensions
876df26cacSmrg */
886df26cacSmrg#define VMWARE_VID_MAX_WIDTH    2048
896df26cacSmrg#define VMWARE_VID_MAX_HEIGHT   2048
906df26cacSmrg
916df26cacSmrg#define VMWARE_VID_NUM_ENCODINGS 1
926df26cacSmrgstatic XF86VideoEncodingRec vmwareVideoEncodings[] =
936df26cacSmrg{
946df26cacSmrg    {
956df26cacSmrg       0,
9625dbecb6Smrg       xv_image_name,
976df26cacSmrg       VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT,
986df26cacSmrg       {1, 1}
996df26cacSmrg    }
1006df26cacSmrg};
1016df26cacSmrg
1026df26cacSmrg#define VMWARE_VID_NUM_FORMATS 2
1036df26cacSmrgstatic XF86VideoFormatRec vmwareVideoFormats[] =
1046df26cacSmrg{
1056df26cacSmrg    { 16, TrueColor},
1066df26cacSmrg    { 24, TrueColor}
1076df26cacSmrg};
1086df26cacSmrg
10916fd1166Smrg#define VMWARE_VID_NUM_IMAGES 3
1106df26cacSmrgstatic XF86ImageRec vmwareVideoImages[] =
1116df26cacSmrg{
1126df26cacSmrg    XVIMAGE_YV12,
11316fd1166Smrg    XVIMAGE_YUY2,
11416fd1166Smrg    XVIMAGE_UYVY
1156df26cacSmrg};
1166df26cacSmrg
11725dbecb6Smrgstatic CONST_ABI_16_TO_19 char xv_colorkey_name[] = "XV_COLORKEY";
11825dbecb6Smrgstatic CONST_ABI_16_TO_19 char xv_autopaint_name[] = "XV_AUTOPAINT_COLORKEY";
11925dbecb6Smrg
12016fd1166Smrg#define VMWARE_VID_NUM_ATTRIBUTES 2
1216df26cacSmrgstatic XF86AttributeRec vmwareVideoAttributes[] =
1226df26cacSmrg{
1236df26cacSmrg    {
1246df26cacSmrg        XvGettable | XvSettable,
1256df26cacSmrg        0x000000,
1266df26cacSmrg        0xffffff,
12725dbecb6Smrg        xv_colorkey_name,
12816fd1166Smrg    },
12916fd1166Smrg    {
13016fd1166Smrg        XvGettable | XvSettable,
13116fd1166Smrg        0,
13216fd1166Smrg        1,
13325dbecb6Smrg        xv_autopaint_name,
1346df26cacSmrg    }
1356df26cacSmrg};
1366df26cacSmrg
1376df26cacSmrg/*
1386df26cacSmrg * Video frames are stored in a circular list of buffers.
1396df26cacSmrg */
1406df26cacSmrg#define VMWARE_VID_NUM_BUFFERS 1
1416df26cacSmrg/*
1426df26cacSmrg * Defines the structure used to hold and pass video data to the host
1436df26cacSmrg */
1446df26cacSmrgtypedef struct {
1456df26cacSmrg   uint32  dataOffset;
1466df26cacSmrg   pointer data;
1476df26cacSmrg} VMWAREVideoBuffer;
1486df26cacSmrg
1496df26cacSmrgtypedef struct {
1506df26cacSmrg   uint32 size;
1516df26cacSmrg   uint32 offset;
1526df26cacSmrg} VMWAREOffscreenRec, *VMWAREOffscreenPtr;
1536df26cacSmrg
1546df26cacSmrg/*
1556df26cacSmrg * Trivial offscreen manager that allocates memory from the
1566df26cacSmrg * bottom of the VRAM.
1576df26cacSmrg */
1586df26cacSmrgstatic VMWAREOffscreenRec offscreenMgr;
1596df26cacSmrg
1606df26cacSmrg/*
1616df26cacSmrg * structs that reside in fmt_priv.
1626df26cacSmrg */
1636df26cacSmrgtypedef struct {
1646df26cacSmrg    int pitches[3];
1656df26cacSmrg    int offsets[3];
1666df26cacSmrg} VMWAREVideoFmtData;
1676df26cacSmrg
1686df26cacSmrg/*
1696df26cacSmrg * Structure representing a specific video stream.
1706df26cacSmrg */
1716df26cacSmrgstruct VMWAREVideoRec {
1726df26cacSmrg   uint32             streamId;
1736df26cacSmrg   /*
1746df26cacSmrg    * Function prototype same as XvPutImage.
1756df26cacSmrg    */
1766df26cacSmrg   int                (*play)(ScrnInfoPtr, struct VMWAREVideoRec *,
1776df26cacSmrg                              short, short, short, short, short,
1786df26cacSmrg                              short, short, short, int, unsigned char*,
1793bfa90b6Smrg                              short, short, RegionPtr, DrawablePtr);
1806df26cacSmrg   /*
1816df26cacSmrg    * Offscreen memory region used to pass video data to the host.
1826df26cacSmrg    */
1836df26cacSmrg   VMWAREOffscreenPtr fbarea;
1846df26cacSmrg   VMWAREVideoBuffer  bufs[VMWARE_VID_NUM_BUFFERS];
1856df26cacSmrg   uint8              currBuf;
1866df26cacSmrg   uint32             size;
1876df26cacSmrg   uint32             colorKey;
18816fd1166Smrg   Bool               isAutoPaintColorkey;
1896df26cacSmrg   uint32             flags;
19016fd1166Smrg   RegionRec          clipBoxes;
1916df26cacSmrg   VMWAREVideoFmtData *fmt_priv;
1926df26cacSmrg};
1936df26cacSmrg
1946df26cacSmrgtypedef struct VMWAREVideoRec VMWAREVideoRec;
1956df26cacSmrgtypedef VMWAREVideoRec *VMWAREVideoPtr;
1966df26cacSmrg
1976df26cacSmrg/*
1986df26cacSmrg * Callback functions
1996df26cacSmrg */
2003bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
2016df26cacSmrgstatic int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
2026df26cacSmrg                            short drw_x, short drw_y, short src_w, short src_h,
2036df26cacSmrg                            short drw_w, short drw_h, int image,
2046df26cacSmrg                            unsigned char *buf, short width, short height,
2056df26cacSmrg                            Bool sync, RegionPtr clipBoxes, pointer data,
2066df26cacSmrg                            DrawablePtr dst);
2076df26cacSmrg#else
2086df26cacSmrgstatic int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
2096df26cacSmrg                            short drw_x, short drw_y, short src_w, short src_h,
2106df26cacSmrg                            short drw_w, short drw_h, int image,
2116df26cacSmrg                            unsigned char *buf, short width, short height,
2126df26cacSmrg                            Bool sync, RegionPtr clipBoxes, pointer data);
2136df26cacSmrg#endif
2146df26cacSmrgstatic void vmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup);
2156df26cacSmrgstatic int vmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
2166df26cacSmrg                                      unsigned short *width,
2176df26cacSmrg                                      unsigned short *height, int *pitches,
2186df26cacSmrg                                      int *offsets);
2196df26cacSmrgstatic int vmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
2206df26cacSmrg                                  INT32 value, pointer data);
2216df26cacSmrgstatic int vmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
2226df26cacSmrg                                  INT32 *value, pointer data);
2236df26cacSmrgstatic void vmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
2246df26cacSmrg                                short vid_w, short vid_h, short drw_w,
2256df26cacSmrg                                short drw_h, unsigned int *p_w,
2266df26cacSmrg                                unsigned int *p_h, pointer data);
2276df26cacSmrg
2286df26cacSmrg/*
2296df26cacSmrg * Local functions for video streams
2306df26cacSmrg */
2316df26cacSmrgstatic XF86VideoAdaptorPtr vmwareVideoSetup(ScrnInfoPtr pScrn);
2326df26cacSmrgstatic int vmwareVideoInitStream(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,
23616fd1166Smrg                                 unsigned char *buf, short width,
2373bfa90b6Smrg                                 short height, RegionPtr clipBoxes,
2383bfa90b6Smrg				 DrawablePtr draw);
2396df26cacSmrgstatic int vmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2406df26cacSmrg                                     int format, unsigned short width,
2416df26cacSmrg                                     unsigned short height);
2426df26cacSmrgstatic int vmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2436df26cacSmrg                           short src_x, short src_y, short drw_x,
2446df26cacSmrg                           short drw_y, short src_w, short src_h,
2456df26cacSmrg                           short drw_w, short drw_h, int format,
2466df26cacSmrg                           unsigned char *buf, short width,
2473bfa90b6Smrg                           short height, RegionPtr clipBoxes,
2483bfa90b6Smrg			   DrawablePtr draw);
2496df26cacSmrgstatic void vmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId);
2506df26cacSmrgstatic void vmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
2516df26cacSmrg                                 uint32 regId, uint32 value);
2526df26cacSmrgstatic void vmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid);
2536df26cacSmrg
2546df26cacSmrg/*
2556df26cacSmrg * Offscreen memory manager functions
2566df26cacSmrg */
2576df26cacSmrgstatic void vmwareOffscreenInit(void);
2586df26cacSmrgstatic VMWAREOffscreenPtr vmwareOffscreenAllocate(VMWAREPtr pVMWARE,
2596df26cacSmrg                                                  uint32 size);
2606df26cacSmrgstatic void vmwareOffscreenFree(VMWAREOffscreenPtr memptr);
2616df26cacSmrg
2626df26cacSmrg
2636df26cacSmrg/*
2646df26cacSmrg *-----------------------------------------------------------------------------
2656df26cacSmrg *
2666df26cacSmrg * vmwareCheckVideoSanity --
2676df26cacSmrg *
2686df26cacSmrg *    Ensures that on ModeSwitch the offscreen memory used
2696df26cacSmrg *    by the Xv streams doesn't become part of the guest framebuffer.
2706df26cacSmrg *
2716df26cacSmrg * Results:
2726df26cacSmrg *    None
2736df26cacSmrg *
2746df26cacSmrg * Side effects:
2756df26cacSmrg *    If it is found that the offscreen used by video streams  lies
2766df26cacSmrg *    within the range of the framebuffer(after ModeSwitch) then the video
2776df26cacSmrg *    streams will be stopped.
2786df26cacSmrg *
2796df26cacSmrg *-----------------------------------------------------------------------------
2806df26cacSmrg */
2816df26cacSmrg
2826df26cacSmrgvoid
2836df26cacSmrgvmwareCheckVideoSanity(ScrnInfoPtr pScrn)
2846df26cacSmrg{
2856df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
2866df26cacSmrg    VMWAREVideoPtr pVid;
2876df26cacSmrg
2886df26cacSmrg   if (offscreenMgr.size == 0 ||
2896df26cacSmrg       offscreenMgr.offset > pVMWARE->FbSize) {
2906df26cacSmrg       return ;
2916df26cacSmrg   }
2926df26cacSmrg
2936df26cacSmrg   pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
2946df26cacSmrg   vmwareStopVideo(pScrn, pVid, TRUE);
2956df26cacSmrg}
2966df26cacSmrg
2976df26cacSmrg
2986df26cacSmrg/*
2996df26cacSmrg *-----------------------------------------------------------------------------
3006df26cacSmrg *
3016df26cacSmrg * vmwareOffscreenInit --
3026df26cacSmrg *
3036df26cacSmrg *    Initializes the trivial Offscreen memory manager.
3046df26cacSmrg *
3056df26cacSmrg * Results:
3066df26cacSmrg *    None.
3076df26cacSmrg *
3086df26cacSmrg * Side effects:
3096df26cacSmrg *    Initializes the Offscreen manager meta-data structure.
3106df26cacSmrg *
3116df26cacSmrg *-----------------------------------------------------------------------------
3126df26cacSmrg */
3136df26cacSmrg
3146df26cacSmrgstatic void
3156df26cacSmrgvmwareOffscreenInit(void)
3166df26cacSmrg{
3176df26cacSmrg    offscreenMgr.size = 0;
3186df26cacSmrg    offscreenMgr.offset  = 0;
3196df26cacSmrg}
3206df26cacSmrg
3216df26cacSmrg
3226df26cacSmrg/*
3236df26cacSmrg *-----------------------------------------------------------------------------
3246df26cacSmrg *
3256df26cacSmrg * vmwareOffscreenAllocate --
3266df26cacSmrg *
3276df26cacSmrg *    Allocates offscreen memory.
3286df26cacSmrg *    Memory is allocated from the bottom part of the VRAM.
3296df26cacSmrg *    The memory manager is trivial iand can handle only 1 video-stream.
3306df26cacSmrg *    ----------
3316df26cacSmrg *    |        |
3326df26cacSmrg *    |  FB    |
3336df26cacSmrg *    |        |
3346df26cacSmrg *    |---------
3356df26cacSmrg *    |        |
3366df26cacSmrg *    |        |
3376df26cacSmrg *    |--------|
3386df26cacSmrg *    | Offscr |
3396df26cacSmrg *    |--------|
3406df26cacSmrg *
3416df26cacSmrg *      VRAM
3426df26cacSmrg *
3436df26cacSmrg * Results:
3446df26cacSmrg *    Pointer to the allocated Offscreen memory.
3456df26cacSmrg *
3466df26cacSmrg * Side effects:
3476df26cacSmrg *    Updates the Offscreen memory manager meta-data structure.
3486df26cacSmrg *
3496df26cacSmrg *-----------------------------------------------------------------------------
3506df26cacSmrg */
3516df26cacSmrg
3526df26cacSmrgstatic VMWAREOffscreenPtr
3536df26cacSmrgvmwareOffscreenAllocate(VMWAREPtr pVMWARE, uint32 size)
3546df26cacSmrg{
3556df26cacSmrg    VMWAREOffscreenPtr memptr;
3566df26cacSmrg
3576df26cacSmrg    if ((pVMWARE->videoRam - pVMWARE->FbSize - pVMWARE->fbPitch - 7) < size) {
3586df26cacSmrg        return NULL;
3596df26cacSmrg    }
3606df26cacSmrg
361a241306cSmrg    memptr = malloc(sizeof(VMWAREOffscreenRec));
3626df26cacSmrg    if (!memptr) {
3636df26cacSmrg        return NULL;
3646df26cacSmrg    }
3656df26cacSmrg    memptr->size = size;
3666df26cacSmrg    memptr->offset  = (pVMWARE->videoRam - size) & ~7;
3676df26cacSmrg
3686df26cacSmrg    VmwareLog(("vmwareOffscreenAllocate: Offset:%x", memptr->offset));
3696df26cacSmrg
3706df26cacSmrg    offscreenMgr.size = memptr->size;
3716df26cacSmrg    offscreenMgr.offset = memptr->offset;
3726df26cacSmrg    return memptr;
3736df26cacSmrg}
3746df26cacSmrg
3756df26cacSmrg
3766df26cacSmrg/*
3776df26cacSmrg *-----------------------------------------------------------------------------
3786df26cacSmrg *
3796df26cacSmrg * vmwareOffscreenFree --
3806df26cacSmrg *
3816df26cacSmrg *    Frees the allocated offscreen memory.
3826df26cacSmrg *
3836df26cacSmrg * Results:
3846df26cacSmrg *    None.
3856df26cacSmrg *
3866df26cacSmrg * Side effects:
3876df26cacSmrg *    Updates the Offscreen memory manager meta-data structure.
3886df26cacSmrg *
3896df26cacSmrg *-----------------------------------------------------------------------------
3906df26cacSmrg */
3916df26cacSmrg
3926df26cacSmrgstatic void
3936df26cacSmrgvmwareOffscreenFree(VMWAREOffscreenPtr memptr)
3946df26cacSmrg{
3956df26cacSmrg    if (memptr) {
3966df26cacSmrg        free(memptr);
3976df26cacSmrg    }
3986df26cacSmrg
3996df26cacSmrg    offscreenMgr.size = 0;
4006df26cacSmrg    offscreenMgr.offset = 0;
4016df26cacSmrg}
4026df26cacSmrg
4036df26cacSmrg
4046df26cacSmrg/*
4056df26cacSmrg *-----------------------------------------------------------------------------
4066df26cacSmrg *
4076df26cacSmrg * vmwareVideoEnabled --
4086df26cacSmrg *
4096df26cacSmrg *    Checks if Video FIFO and Escape FIFO cap are enabled.
4106df26cacSmrg *
4116df26cacSmrg * Results:
4126df26cacSmrg *    TRUE if required caps are enabled, FALSE otherwise.
4136df26cacSmrg *
4146df26cacSmrg * Side effects:
4156df26cacSmrg *    None.
4166df26cacSmrg *
4176df26cacSmrg *-----------------------------------------------------------------------------
4186df26cacSmrg */
4196df26cacSmrg
42016fd1166SmrgBool
42116fd1166SmrgvmwareVideoEnabled(VMWAREPtr pVMWARE)
4226df26cacSmrg{
4236df26cacSmrg    return ((pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO) &&
4246df26cacSmrg            (pVMWARE->vmwareFIFO[SVGA_FIFO_CAPABILITIES] &
4256df26cacSmrg             (SVGA_FIFO_CAP_VIDEO | SVGA_FIFO_CAP_ESCAPE)));
4266df26cacSmrg}
4276df26cacSmrg
4286df26cacSmrg
4296df26cacSmrg/*
4306df26cacSmrg *-----------------------------------------------------------------------------
4316df26cacSmrg *
4326df26cacSmrg * vmwareVideoInit --
4336df26cacSmrg *
4346df26cacSmrg *    Initializes Xv support.
4356df26cacSmrg *
4366df26cacSmrg * Results:
4376df26cacSmrg *    TRUE on success, FALSE on error.
4386df26cacSmrg *
4396df26cacSmrg * Side effects:
4406df26cacSmrg *    Xv support is initialized. Memory is allocated for all supported
4416df26cacSmrg *    video streams.
4426df26cacSmrg *
4436df26cacSmrg *-----------------------------------------------------------------------------
4446df26cacSmrg */
4456df26cacSmrg
44616fd1166SmrgBool
44716fd1166SmrgvmwareVideoInit(ScreenPtr pScreen)
4486df26cacSmrg{
4493bfa90b6Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
4506df26cacSmrg    XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
4516df26cacSmrg    XF86VideoAdaptorPtr newAdaptor = NULL;
4526df26cacSmrg    int numAdaptors;
4536df26cacSmrg
4546df26cacSmrg    TRACEPOINT
4556df26cacSmrg
4566df26cacSmrg    vmwareOffscreenInit();
4576df26cacSmrg
4586df26cacSmrg    numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors);
4596df26cacSmrg
4606df26cacSmrg    newAdaptor = vmwareVideoSetup(pScrn);
4616df26cacSmrg    if (!newAdaptor) {
4626df26cacSmrg        VmwareLog(("Failed to initialize Xv extension \n"));
4636df26cacSmrg        return FALSE;
4646df26cacSmrg    }
4656df26cacSmrg
4666df26cacSmrg    if (!numAdaptors) {
4676df26cacSmrg        numAdaptors = 1;
4686df26cacSmrg        overlayAdaptors = &newAdaptor;
4696df26cacSmrg    } else {
470a241306cSmrg         newAdaptors = malloc((numAdaptors + 1) *
4716df26cacSmrg                              sizeof(XF86VideoAdaptorPtr*));
4726df26cacSmrg         if (!newAdaptors) {
4736df26cacSmrg            xf86XVFreeVideoAdaptorRec(newAdaptor);
4746df26cacSmrg            return FALSE;
4756df26cacSmrg         }
4766df26cacSmrg
4776df26cacSmrg         memcpy(newAdaptors, overlayAdaptors,
4786df26cacSmrg                numAdaptors * sizeof(XF86VideoAdaptorPtr));
4796df26cacSmrg         newAdaptors[numAdaptors++] = newAdaptor;
4806df26cacSmrg         overlayAdaptors = newAdaptors;
4816df26cacSmrg    }
4826df26cacSmrg
4836df26cacSmrg    if (!xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors)) {
4846df26cacSmrg        VmwareLog(("Failed to initialize Xv extension\n"));
4856df26cacSmrg        xf86XVFreeVideoAdaptorRec(newAdaptor);
4866df26cacSmrg        return FALSE;
4876df26cacSmrg    }
4886df26cacSmrg
4896df26cacSmrg    if (newAdaptors) {
490a241306cSmrg        free(newAdaptors);
4916df26cacSmrg    }
4926df26cacSmrg
4936df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4946df26cacSmrg               "Initialized VMware Xv extension successfully.\n");
4956df26cacSmrg    return TRUE;
4966df26cacSmrg}
4976df26cacSmrg
4986df26cacSmrg
4996df26cacSmrg/*
5006df26cacSmrg *-----------------------------------------------------------------------------
5016df26cacSmrg *
5026df26cacSmrg * vmwareVideoEnd --
5036df26cacSmrg *
5046df26cacSmrg *    Unitializes video.
5056df26cacSmrg *
5066df26cacSmrg * Results:
5076df26cacSmrg *    None.
5086df26cacSmrg *
5096df26cacSmrg * Side effects:
5106df26cacSmrg *    pVMWARE->videoStreams = NULL
5116df26cacSmrg *
5126df26cacSmrg *-----------------------------------------------------------------------------
5136df26cacSmrg */
5146df26cacSmrg
51516fd1166Smrgvoid
51616fd1166SmrgvmwareVideoEnd(ScreenPtr pScreen)
5176df26cacSmrg{
5183bfa90b6Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
5196df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
5206df26cacSmrg    VMWAREVideoPtr pVid;
5216df26cacSmrg    int i;
5226df26cacSmrg
5236df26cacSmrg    TRACEPOINT
5246df26cacSmrg
5256df26cacSmrg    /*
5266df26cacSmrg     * Video streams are allocated after the DevUnion array
5276df26cacSmrg     * (see VideoSetup)
5286df26cacSmrg     */
5296df26cacSmrg    pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
5306df26cacSmrg    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
5316df26cacSmrg        vmwareVideoEndStream(pScrn, &pVid[i]);
532a241306cSmrg	REGION_UNINIT(pScreen, &pVid[i].clipBoxes);
5336df26cacSmrg    }
5346df26cacSmrg
5356df26cacSmrg    free(pVMWARE->videoStreams);
5366df26cacSmrg    pVMWARE->videoStreams = NULL;
5376df26cacSmrg}
5386df26cacSmrg
5396df26cacSmrg
5406df26cacSmrg/*
5416df26cacSmrg *-----------------------------------------------------------------------------
5426df26cacSmrg *
5436df26cacSmrg * vmwareVideoSetup --
5446df26cacSmrg *
5456df26cacSmrg *    Initializes a XF86VideoAdaptor structure with the capabilities and
5466df26cacSmrg *    functions supported by this video driver.
5476df26cacSmrg *
5486df26cacSmrg * Results:
5496df26cacSmrg *    On success initialized XF86VideoAdaptor struct or NULL on error
5506df26cacSmrg *
5516df26cacSmrg * Side effects:
5526df26cacSmrg *    None.
5536df26cacSmrg *
5546df26cacSmrg *-----------------------------------------------------------------------------
5556df26cacSmrg */
5566df26cacSmrg
55716fd1166Smrgstatic XF86VideoAdaptorPtr
55816fd1166SmrgvmwareVideoSetup(ScrnInfoPtr pScrn)
5596df26cacSmrg{
5606df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
5616df26cacSmrg    XF86VideoAdaptorPtr adaptor;
5626df26cacSmrg    VMWAREVideoPtr pPriv;
5636df26cacSmrg    DevUnion *du;
5646df26cacSmrg    int i;
5656df26cacSmrg
5666df26cacSmrg    TRACEPOINT
5676df26cacSmrg
5686df26cacSmrg    adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
5696df26cacSmrg    if (!adaptor) {
5706df26cacSmrg        VmwareLog(("Not enough memory\n"));
5716df26cacSmrg        return NULL;
5726df26cacSmrg    }
573a241306cSmrg    du = calloc(1, VMWARE_VID_NUM_PORTS *
5746df26cacSmrg        (sizeof(DevUnion) + sizeof(VMWAREVideoRec)));
5756df26cacSmrg
5766df26cacSmrg    if (!du) {
5776df26cacSmrg        VmwareLog(("Not enough memory.\n"));
5786df26cacSmrg        xf86XVFreeVideoAdaptorRec(adaptor);
5796df26cacSmrg        return NULL;
5806df26cacSmrg    }
5816df26cacSmrg
5826df26cacSmrg    adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
5836df26cacSmrg    adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
58425dbecb6Smrg    adaptor->name = xv_adapt_name;
5856df26cacSmrg    adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
5866df26cacSmrg    adaptor->pEncodings = vmwareVideoEncodings;
5876df26cacSmrg    adaptor->nFormats = VMWARE_VID_NUM_FORMATS;
5886df26cacSmrg    adaptor->pFormats = vmwareVideoFormats;
5896df26cacSmrg    adaptor->nPorts = VMWARE_VID_NUM_PORTS;
5906df26cacSmrg
5916df26cacSmrg    pPriv = (VMWAREVideoPtr) &du[VMWARE_VID_NUM_PORTS];
5926df26cacSmrg    adaptor->pPortPrivates = du;
5936df26cacSmrg
5946df26cacSmrg    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
5956df26cacSmrg        pPriv[i].streamId = i;
5966df26cacSmrg        pPriv[i].play = vmwareVideoInitStream;
5976df26cacSmrg        pPriv[i].flags = SVGA_VIDEO_FLAG_COLORKEY;
5986df26cacSmrg        pPriv[i].colorKey = VMWARE_VIDEO_COLORKEY;
59916fd1166Smrg        pPriv[i].isAutoPaintColorkey = TRUE;
600a241306cSmrg	REGION_NULL(pScreen, &pPriv[i].clipBoxes);
6016df26cacSmrg        adaptor->pPortPrivates[i].ptr = &pPriv[i];
6026df26cacSmrg    }
6036df26cacSmrg    pVMWARE->videoStreams = du;
6046df26cacSmrg
6056df26cacSmrg    adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES;
6066df26cacSmrg    adaptor->pAttributes = vmwareVideoAttributes;
6076df26cacSmrg
6086df26cacSmrg    adaptor->nImages = VMWARE_VID_NUM_IMAGES;
6096df26cacSmrg    adaptor->pImages = vmwareVideoImages;
6106df26cacSmrg
6116df26cacSmrg    adaptor->PutVideo = NULL;
6126df26cacSmrg    adaptor->PutStill = NULL;
6136df26cacSmrg    adaptor->GetVideo = NULL;
6146df26cacSmrg    adaptor->GetStill = NULL;
6156df26cacSmrg    adaptor->StopVideo = vmwareStopVideo;
6166df26cacSmrg    adaptor->SetPortAttribute = vmwareSetPortAttribute;
6176df26cacSmrg    adaptor->GetPortAttribute = vmwareGetPortAttribute;
6186df26cacSmrg    adaptor->QueryBestSize = vmwareQueryBestSize;
6196df26cacSmrg    adaptor->PutImage = vmwareXvPutImage;
6206df26cacSmrg    adaptor->QueryImageAttributes = vmwareQueryImageAttributes;
6216df26cacSmrg
6226df26cacSmrg    return adaptor;
6236df26cacSmrg}
6246df26cacSmrg
6256df26cacSmrg
6266df26cacSmrg/*
6276df26cacSmrg *-----------------------------------------------------------------------------
6286df26cacSmrg *
6296df26cacSmrg * vmwareVideoInitStream --
6306df26cacSmrg *
6316df26cacSmrg *    Initializes a video stream in response to the first PutImage() on a
6326df26cacSmrg *    video stream. The process goes as follows:
6336df26cacSmrg *    - Figure out characteristics according to format
6346df26cacSmrg *    - Allocate offscreen memory
6356df26cacSmrg *    - Pass on video to Play() functions
6366df26cacSmrg *
6376df26cacSmrg * Results:
6386df26cacSmrg *    Success or XvBadAlloc on failure.
6396df26cacSmrg *
6406df26cacSmrg * Side effects:
6416df26cacSmrg *    Video stream is initialized and its first frame sent to the host
6426df26cacSmrg *    (done by VideoPlay() function called at the end)
6436df26cacSmrg *
6446df26cacSmrg *-----------------------------------------------------------------------------
6456df26cacSmrg */
6466df26cacSmrg
64716fd1166Smrgstatic int
64816fd1166SmrgvmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
64916fd1166Smrg                      short src_x, short src_y, short drw_x,
65016fd1166Smrg                      short drw_y, short src_w, short src_h,
65116fd1166Smrg                      short drw_w, short drw_h, int format,
65216fd1166Smrg                      unsigned char *buf, short width,
6533bfa90b6Smrg                      short height, RegionPtr clipBoxes,
6543bfa90b6Smrg		      DrawablePtr draw)
6556df26cacSmrg{
6566df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
6576df26cacSmrg    int i;
6586df26cacSmrg
6596df26cacSmrg    TRACEPOINT
6606df26cacSmrg
6616df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
6626df26cacSmrg               "Initializing Xv video-stream with id:%d format:%d\n",
6636df26cacSmrg                pVid->streamId, format);
6646df26cacSmrg
6656df26cacSmrg    pVid->size = vmwareVideoInitAttributes(pScrn, pVid, format, width,
6666df26cacSmrg                                           height);
6676df26cacSmrg
6686df26cacSmrg    if (pVid->size == -1) {
6696df26cacSmrg        VmwareLog(("Could not initialize 0x%x video stream\n", format));
6706df26cacSmrg        return XvBadAlloc;
6716df26cacSmrg    }
6726df26cacSmrg
6736df26cacSmrg    pVid->play = vmwareVideoPlay;
6746df26cacSmrg
6756df26cacSmrg    pVid->fbarea = vmwareOffscreenAllocate(pVMWARE,
6766df26cacSmrg                       pVid->size * VMWARE_VID_NUM_BUFFERS);
6776df26cacSmrg
6786df26cacSmrg    if (!pVid->fbarea) {
6796df26cacSmrg       VmwareLog(("Could not allocate offscreen memory\n"));
6806df26cacSmrg       vmwareVideoEndStream(pScrn, pVid);
6816df26cacSmrg       return BadAlloc;
6826df26cacSmrg    }
6836df26cacSmrg
6846df26cacSmrg    pVid->bufs[0].dataOffset = pVid->fbarea->offset;
6856df26cacSmrg    pVid->bufs[0].data = pVMWARE->FbBase + pVid->bufs[0].dataOffset;
6866df26cacSmrg
6876df26cacSmrg    for (i = 1; i < VMWARE_VID_NUM_BUFFERS; ++i) {
6886df26cacSmrg        pVid->bufs[i].dataOffset = pVid->bufs[i-1].dataOffset + pVid->size;
6896df26cacSmrg        pVid->bufs[i].data = pVMWARE->FbBase + pVid->bufs[i].dataOffset;
6906df26cacSmrg    }
6916df26cacSmrg    pVid->currBuf = 0;
6926df26cacSmrg
69316fd1166Smrg    REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
69416fd1166Smrg
69516fd1166Smrg    if (pVid->isAutoPaintColorkey) {
696a241306cSmrg	BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
697a241306cSmrg	int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
698a241306cSmrg
6993bfa90b6Smrg#if HAVE_FILLKEYHELPERDRAWABLE
700591e32d7Ssnj	if (draw->type == DRAWABLE_WINDOW) {
701591e32d7Ssnj	    xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
702591e32d7Ssnj	    DamageDamageRegion(draw, clipBoxes);
703591e32d7Ssnj	} else {
704591e32d7Ssnj	    xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
705591e32d7Ssnj        }
7063bfa90b6Smrg#else
70716fd1166Smrg        xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
7083bfa90b6Smrg#endif
709a241306cSmrg	/**
710a241306cSmrg	 * Force update to paint the colorkey before the overlay flush.
711a241306cSmrg	 */
712a241306cSmrg
713a241306cSmrg	while(nBoxes--)
714a241306cSmrg	    vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
71516fd1166Smrg    }
71616fd1166Smrg
7176df26cacSmrg    VmwareLog(("Got offscreen region, offset %d, size %d "
7186df26cacSmrg               "(yuv size in bytes: %d)\n",
7196df26cacSmrg               pVid->fbarea->offset, pVid->fbarea->size, pVid->size));
7206df26cacSmrg
7216df26cacSmrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
7223bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
7233bfa90b6Smrg		      draw);
7246df26cacSmrg}
7256df26cacSmrg
7266df26cacSmrg
7276df26cacSmrg/*
7286df26cacSmrg *-----------------------------------------------------------------------------
7296df26cacSmrg *
7306df26cacSmrg * vmwareVideoInitAttributes --
7316df26cacSmrg *
7326df26cacSmrg *    Fetches the format specific attributes using QueryImageAttributes().
7336df26cacSmrg *
7346df26cacSmrg * Results:
7356df26cacSmrg *    size of the YUV frame on success and -1 on error.
7366df26cacSmrg *
7376df26cacSmrg * Side effects:
7386df26cacSmrg *    The video stream gets the format specific attributes(fmtData).
7396df26cacSmrg *
7406df26cacSmrg *-----------------------------------------------------------------------------
7416df26cacSmrg */
7426df26cacSmrg
74316fd1166Smrgstatic int
74416fd1166SmrgvmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
74516fd1166Smrg                          int format, unsigned short width,
74616fd1166Smrg                          unsigned short height)
7476df26cacSmrg{
7486df26cacSmrg    int size;
7496df26cacSmrg    VMWAREVideoFmtData *fmtData;
7506df26cacSmrg
7516df26cacSmrg    TRACEPOINT
7526df26cacSmrg
753a241306cSmrg    fmtData = calloc(1, sizeof(VMWAREVideoFmtData));
7546df26cacSmrg    if (!fmtData) {
7556df26cacSmrg        return -1;
7566df26cacSmrg    }
7576df26cacSmrg
7586df26cacSmrg    size = vmwareQueryImageAttributes(pScrn, format, &width, &height,
7596df26cacSmrg                                      fmtData->pitches, fmtData->offsets);
7606df26cacSmrg    if (size == -1) {
7616df26cacSmrg        free(fmtData);
7626df26cacSmrg        return -1;
7636df26cacSmrg    }
7646df26cacSmrg
7656df26cacSmrg    pVid->fmt_priv = fmtData;
7666df26cacSmrg    return size;
7676df26cacSmrg}
7686df26cacSmrg
7696df26cacSmrg
7706df26cacSmrg/*
7716df26cacSmrg *-----------------------------------------------------------------------------
7726df26cacSmrg *
7736df26cacSmrg * vmwareVideoPlay --
7746df26cacSmrg *
7756df26cacSmrg *    Sends all the attributes associated with the video frame using the
7766df26cacSmrg *    FIFO ESCAPE mechanism to the host.
7776df26cacSmrg *
7786df26cacSmrg * Results:
7796df26cacSmrg *    Always returns Success.
7806df26cacSmrg *
7816df26cacSmrg * Side effects:
7826df26cacSmrg *    None.
7836df26cacSmrg *
7846df26cacSmrg *-----------------------------------------------------------------------------
7856df26cacSmrg */
7866df26cacSmrg
78716fd1166Smrgstatic int
78816fd1166SmrgvmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
78916fd1166Smrg                short src_x, short src_y, short drw_x,
79016fd1166Smrg                short drw_y, short src_w, short src_h,
79116fd1166Smrg                short drw_w, short drw_h, int format,
79216fd1166Smrg                unsigned char *buf, short width,
7933bfa90b6Smrg                short height, RegionPtr clipBoxes,
7943bfa90b6Smrg		DrawablePtr draw)
7956df26cacSmrg{
7966df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
7976df26cacSmrg    uint32 *fifoItem;
7986df26cacSmrg    int i, regId;
7996df26cacSmrg    struct PACKED _item {
8006df26cacSmrg        uint32 regId;
8016df26cacSmrg        uint32 value;
8026df26cacSmrg    };
8036df26cacSmrg
8046df26cacSmrg    struct PACKED _body {
8056df26cacSmrg        uint32 escape;
8066df26cacSmrg        uint32 streamId;
807591e32d7Ssnj        /* Old hosts can not handle more then these regs */
808591e32d7Ssnj        struct _item items[SVGA_VIDEO_DATA_GMRID];
8096df26cacSmrg    };
8106df26cacSmrg
8116df26cacSmrg    struct PACKED _cmdSetRegs {
8126df26cacSmrg        uint32 cmd;
8136df26cacSmrg        uint32 nsid;
8146df26cacSmrg        uint32 size;
8156df26cacSmrg        struct _body body;
8166df26cacSmrg    };
8176df26cacSmrg
8186df26cacSmrg    struct _cmdSetRegs cmdSetRegs;
8196df26cacSmrg    struct _item *items;
82016fd1166Smrg    int size;
82116fd1166Smrg    VMWAREVideoFmtData *fmtData;
82216fd1166Smrg    unsigned short w, h;
8236df26cacSmrg
82416fd1166Smrg    w = width;
82516fd1166Smrg    h = height;
82616fd1166Smrg    fmtData = pVid->fmt_priv;
82716fd1166Smrg
82816fd1166Smrg    size = vmwareQueryImageAttributes(pScrn, format, &w, &h,
82916fd1166Smrg                                      fmtData->pitches, fmtData->offsets);
83016fd1166Smrg
83116fd1166Smrg    if (size > pVid->size) {
83216fd1166Smrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Increase in size of Xv video "
83316fd1166Smrg                   "frame streamId:%d.\n", pVid->streamId);
83416fd1166Smrg        vmwareStopVideo(pScrn, pVid, TRUE);
83516fd1166Smrg        return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w,
83616fd1166Smrg                          src_h, drw_w, drw_h, format, buf, width, height,
8373bfa90b6Smrg                          clipBoxes, draw);
83816fd1166Smrg    }
83916fd1166Smrg
84016fd1166Smrg    pVid->size = size;
8416df26cacSmrg    memcpy(pVid->bufs[pVid->currBuf].data, buf, pVid->size);
8426df26cacSmrg
8436df26cacSmrg    cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
8446df26cacSmrg    cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
8456df26cacSmrg    cmdSetRegs.size = sizeof(cmdSetRegs.body);
8466df26cacSmrg    cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
8476df26cacSmrg    cmdSetRegs.body.streamId = pVid->streamId;
8486df26cacSmrg
8496df26cacSmrg    items = cmdSetRegs.body.items;
850591e32d7Ssnj    for (i = SVGA_VIDEO_ENABLED; i < SVGA_VIDEO_DATA_GMRID; i++) {
8516df26cacSmrg        items[i].regId = i;
8526df26cacSmrg    }
8536df26cacSmrg
8546df26cacSmrg    items[SVGA_VIDEO_ENABLED].value = TRUE;
8556df26cacSmrg    items[SVGA_VIDEO_DATA_OFFSET].value =
8566df26cacSmrg        pVid->bufs[pVid->currBuf].dataOffset;
8576df26cacSmrg    items[SVGA_VIDEO_SIZE].value = pVid->size;
8586df26cacSmrg    items[SVGA_VIDEO_FORMAT].value = format;
85916fd1166Smrg    items[SVGA_VIDEO_WIDTH].value = w;
86016fd1166Smrg    items[SVGA_VIDEO_HEIGHT].value = h;
8616df26cacSmrg    items[SVGA_VIDEO_SRC_X].value = src_x;
8626df26cacSmrg    items[SVGA_VIDEO_SRC_Y].value = src_y;
8636df26cacSmrg    items[SVGA_VIDEO_SRC_WIDTH].value = src_w;
8646df26cacSmrg    items[SVGA_VIDEO_SRC_HEIGHT].value = src_h;
8656df26cacSmrg    items[SVGA_VIDEO_DST_X].value = drw_x;
8666df26cacSmrg    items[SVGA_VIDEO_DST_Y].value = drw_y;
8676df26cacSmrg    items[SVGA_VIDEO_DST_WIDTH]. value = drw_w;
8686df26cacSmrg    items[SVGA_VIDEO_DST_HEIGHT].value = drw_h;
8696df26cacSmrg    items[SVGA_VIDEO_COLORKEY].value = pVid->colorKey;
8706df26cacSmrg    items[SVGA_VIDEO_FLAGS].value = pVid->flags;
8716df26cacSmrg
8726df26cacSmrg    for (i = 0, regId = SVGA_VIDEO_PITCH_1; i < 3; i++, regId++) {
87316fd1166Smrg        items[regId].value = fmtData->pitches[i];
8746df26cacSmrg    }
8756df26cacSmrg
8766df26cacSmrg    fifoItem = (uint32 *) &cmdSetRegs;
8776df26cacSmrg    for (i = 0; i <  sizeof(cmdSetRegs) / sizeof(uint32); i++) {
8786df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
8796df26cacSmrg    }
8806df26cacSmrg
88116fd1166Smrg    /*
88216fd1166Smrg     *  Update the clipList and paint the colorkey, if required.
88316fd1166Smrg     */
88416fd1166Smrg    if (!vmwareIsRegionEqual(&pVid->clipBoxes, clipBoxes)) {
88516fd1166Smrg        REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
88616fd1166Smrg        if (pVid->isAutoPaintColorkey) {
887a241306cSmrg	    BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
888a241306cSmrg	    int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
889a241306cSmrg
8903bfa90b6Smrg#if HAVE_FILLKEYHELPERDRAWABLE
8913bfa90b6Smrg	    xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
8923bfa90b6Smrg#else
8933bfa90b6Smrg	    xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
8943bfa90b6Smrg#endif
895a241306cSmrg	    /**
896a241306cSmrg	     * Force update to paint the colorkey before the overlay flush.
897a241306cSmrg	     */
898a241306cSmrg
899a241306cSmrg	    while(nBoxes--)
900a241306cSmrg		vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
901a241306cSmrg
90216fd1166Smrg        }
90316fd1166Smrg    }
90416fd1166Smrg
9056df26cacSmrg    vmwareVideoFlush(pVMWARE, pVid->streamId);
9066df26cacSmrg
9076df26cacSmrg    pVid->currBuf = ++pVid->currBuf & (VMWARE_VID_NUM_BUFFERS - 1);
90816fd1166Smrg
9096df26cacSmrg    return Success;
9106df26cacSmrg}
9116df26cacSmrg
9126df26cacSmrg
9136df26cacSmrg/*
9146df26cacSmrg *-----------------------------------------------------------------------------
9156df26cacSmrg *
9166df26cacSmrg * vmwareVideoFlush --
9176df26cacSmrg *
9186df26cacSmrg *    Sends the VIDEO_FLUSH command (FIFO ESCAPE mechanism) asking the host
9196df26cacSmrg *    to play the video stream or end it.
9206df26cacSmrg *
9216df26cacSmrg * Results:
9226df26cacSmrg *    None.
9236df26cacSmrg *
9246df26cacSmrg * Side effects:
9256df26cacSmrg *    None.
9266df26cacSmrg *
9276df26cacSmrg *-----------------------------------------------------------------------------
9286df26cacSmrg */
9296df26cacSmrg
93016fd1166Smrgstatic void
93116fd1166SmrgvmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId)
9326df26cacSmrg{
9336df26cacSmrg    struct PACKED _body {
9346df26cacSmrg        uint32 escape;
9356df26cacSmrg        uint32 streamId;
9366df26cacSmrg    };
9376df26cacSmrg
9386df26cacSmrg    struct PACKED _cmdFlush {
9396df26cacSmrg        uint32 cmd;
9406df26cacSmrg        uint32 nsid;
9416df26cacSmrg        uint32 size;
9426df26cacSmrg        struct _body body;
9436df26cacSmrg    };
9446df26cacSmrg
9456df26cacSmrg    struct _cmdFlush cmdFlush;
9466df26cacSmrg    uint32 *fifoItem;
9476df26cacSmrg    int i;
9486df26cacSmrg
9496df26cacSmrg    cmdFlush.cmd = SVGA_CMD_ESCAPE;
9506df26cacSmrg    cmdFlush.nsid = SVGA_ESCAPE_NSID_VMWARE;
9516df26cacSmrg    cmdFlush.size = sizeof(cmdFlush.body);
9526df26cacSmrg    cmdFlush.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
9536df26cacSmrg    cmdFlush.body.streamId = streamId;
9546df26cacSmrg
9556df26cacSmrg    fifoItem = (uint32 *) &cmdFlush;
9566df26cacSmrg    for (i = 0; i < sizeof(cmdFlush) / sizeof(uint32); i++) {
9576df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
9586df26cacSmrg    }
9596df26cacSmrg}
9606df26cacSmrg
9616df26cacSmrg
9626df26cacSmrg/*
9636df26cacSmrg *-----------------------------------------------------------------------------
9646df26cacSmrg *
9656df26cacSmrg * vmwareVideoSetOneReg --
9666df26cacSmrg *
9676df26cacSmrg *    Sets one video register using the FIFO ESCAPE mechanidm.
9686df26cacSmrg *
9696df26cacSmrg * Results:
9706df26cacSmrg *    None.
9716df26cacSmrg *
9726df26cacSmrg * Side effects:
9736df26cacSmrg *    None.
9746df26cacSmrg *-----------------------------------------------------------------------------
9756df26cacSmrg */
9766df26cacSmrg
97716fd1166Smrgstatic void
97816fd1166SmrgvmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
97916fd1166Smrg                     uint32 regId, uint32 value)
9806df26cacSmrg{
9816df26cacSmrg    struct PACKED _item {
9826df26cacSmrg        uint32 regId;
9836df26cacSmrg        uint32 value;
9846df26cacSmrg    };
9856df26cacSmrg
9866df26cacSmrg    struct PACKED _body {
9876df26cacSmrg        uint32 escape;
9886df26cacSmrg        uint32 streamId;
9896df26cacSmrg        struct _item item;
9906df26cacSmrg    };
9916df26cacSmrg
9926df26cacSmrg    struct PACKED _cmdSetRegs {
9936df26cacSmrg        uint32 cmd;
9946df26cacSmrg        uint32 nsid;
9956df26cacSmrg        uint32 size;
9966df26cacSmrg        struct _body body;
9976df26cacSmrg    };
9986df26cacSmrg
9996df26cacSmrg    struct _cmdSetRegs cmdSetRegs;
10006df26cacSmrg    int i;
10016df26cacSmrg    uint32 *fifoItem;
10026df26cacSmrg
10036df26cacSmrg    cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
10046df26cacSmrg    cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
10056df26cacSmrg    cmdSetRegs.size = sizeof(cmdSetRegs.body);
10066df26cacSmrg    cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
10076df26cacSmrg    cmdSetRegs.body.streamId = streamId;
10086df26cacSmrg    cmdSetRegs.body.item.regId = regId;
10096df26cacSmrg    cmdSetRegs.body.item.value = value;
10106df26cacSmrg
10116df26cacSmrg    fifoItem = (uint32 *) &cmdSetRegs;
10126df26cacSmrg    for (i = 0; i < sizeof(cmdSetRegs) / sizeof(uint32); i++) {
10136df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
10146df26cacSmrg    }
10156df26cacSmrg}
10166df26cacSmrg
10176df26cacSmrg
10186df26cacSmrg/*
10196df26cacSmrg *-----------------------------------------------------------------------------
10206df26cacSmrg *
10216df26cacSmrg * vmwareVideoEndStream --
10226df26cacSmrg *
10236df26cacSmrg *    Frees up all resources (if any) taken by a video stream.
10246df26cacSmrg *
10256df26cacSmrg * Results:
10266df26cacSmrg *    None.
10276df26cacSmrg *
10286df26cacSmrg * Side effects:
10296df26cacSmrg *    Same as above.
10306df26cacSmrg *
10316df26cacSmrg *-----------------------------------------------------------------------------
10326df26cacSmrg */
10336df26cacSmrg
103416fd1166Smrgstatic void
103516fd1166SmrgvmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid)
10366df26cacSmrg{
10376df26cacSmrg    uint32 id, colorKey, flags;
103816fd1166Smrg    Bool isAutoPaintColorkey;
10396df26cacSmrg
10406df26cacSmrg    if (pVid->fmt_priv) {
10416df26cacSmrg        free(pVid->fmt_priv);
10426df26cacSmrg    }
10436df26cacSmrg
10446df26cacSmrg    if (pVid->fbarea) {
10456df26cacSmrg        vmwareOffscreenFree(pVid->fbarea);
10466df26cacSmrg        pVid->fbarea =  NULL;
10476df26cacSmrg    }
10486df26cacSmrg
10496df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
10506df26cacSmrg               "Terminating Xv video-stream id:%d\n", pVid->streamId);
10516df26cacSmrg    /*
10526df26cacSmrg     * reset stream for next video
10536df26cacSmrg     */
10546df26cacSmrg    id = pVid->streamId;
10556df26cacSmrg    colorKey = pVid->colorKey;
10566df26cacSmrg    flags = pVid->flags;
105716fd1166Smrg    isAutoPaintColorkey = pVid->isAutoPaintColorkey;
105816fd1166Smrg
10596df26cacSmrg    memset(pVid, 0, sizeof(*pVid));
106016fd1166Smrg
10616df26cacSmrg    pVid->streamId = id;
10626df26cacSmrg    pVid->play = vmwareVideoInitStream;
10636df26cacSmrg    pVid->colorKey = colorKey;
10646df26cacSmrg    pVid->flags = flags;
106516fd1166Smrg    pVid->isAutoPaintColorkey = isAutoPaintColorkey;
10666df26cacSmrg}
10676df26cacSmrg
10686df26cacSmrg
10696df26cacSmrg/*
10706df26cacSmrg *-----------------------------------------------------------------------------
10716df26cacSmrg *
10726df26cacSmrg * vmwareXvPutImage --
10736df26cacSmrg *
10746df26cacSmrg *    Main video playback function. It copies the passed data which is in
10756df26cacSmrg *    the specified format (e.g. FOURCC_YV12) into the overlay.
10766df26cacSmrg *
10776df26cacSmrg *    If sync is TRUE the driver should not return from this
10786df26cacSmrg *    function until it is through reading the data from buf.
10796df26cacSmrg *
10806df26cacSmrg *    There are two function prototypes to cope with the API change in X.org
10816df26cacSmrg *    7.1
10826df26cacSmrg *
10836df26cacSmrg * Results:
10846df26cacSmrg *    Success or XvBadAlloc on failure
10856df26cacSmrg *
10866df26cacSmrg * Side effects:
10876df26cacSmrg *    Video stream will be played(initialized if 1st frame) on success
10886df26cacSmrg *    or will fail on error.
10896df26cacSmrg *
10906df26cacSmrg *-----------------------------------------------------------------------------
10916df26cacSmrg */
10926df26cacSmrg
10933bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
109416fd1166Smrgstatic int
109516fd1166SmrgvmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
109616fd1166Smrg                 short drw_x, short drw_y, short src_w, short src_h,
109716fd1166Smrg                 short drw_w, short drw_h, int format,
109816fd1166Smrg                 unsigned char *buf, short width, short height,
109916fd1166Smrg                 Bool sync, RegionPtr clipBoxes, pointer data,
110016fd1166Smrg                 DrawablePtr dst)
11016df26cacSmrg#else
110216fd1166Smrgstatic int
110316fd1166SmrgvmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
110416fd1166Smrg                 short drw_x, short drw_y, short src_w, short src_h,
110516fd1166Smrg                 short drw_w, short drw_h, int format,
110616fd1166Smrg                 unsigned char *buf, short width, short height,
110716fd1166Smrg                 Bool sync, RegionPtr clipBoxes, pointer data)
11086df26cacSmrg#endif
11096df26cacSmrg{
11106df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
11116df26cacSmrg    VMWAREVideoPtr pVid = data;
11126df26cacSmrg
11136df26cacSmrg    TRACEPOINT
11146df26cacSmrg
11156df26cacSmrg    if (!vmwareVideoEnabled(pVMWARE)) {
11166df26cacSmrg        return XvBadAlloc;
11176df26cacSmrg    }
11186df26cacSmrg
11193bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
11206df26cacSmrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
11213bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
11223bfa90b6Smrg		      dst);
11233bfa90b6Smrg#else
11243bfa90b6Smrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
11253bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
11263bfa90b6Smrg		      NULL);
11273bfa90b6Smrg#endif
11286df26cacSmrg}
11296df26cacSmrg
11306df26cacSmrg
11316df26cacSmrg/*
11326df26cacSmrg *-----------------------------------------------------------------------------
11336df26cacSmrg *
11346df26cacSmrg * vmwareStopVideo --
11356df26cacSmrg *
11366df26cacSmrg *    Called when we should stop playing video for a particular stream. If
11376df26cacSmrg *    Cleanup is FALSE, the "stop" operation is only temporary, and thus we
11386df26cacSmrg *    don't do anything. If Cleanup is TRUE we kill the video stream by
11396df26cacSmrg *    sending a message to the host and freeing up the stream.
11406df26cacSmrg *
11416df26cacSmrg * Results:
11426df26cacSmrg *    None.
11436df26cacSmrg *
11446df26cacSmrg * Side effects:
11456df26cacSmrg *    See above.
11466df26cacSmrg *
11476df26cacSmrg *-----------------------------------------------------------------------------
11486df26cacSmrg */
11496df26cacSmrg
115016fd1166Smrgstatic void
115116fd1166SmrgvmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup)
11526df26cacSmrg{
11536df26cacSmrg    VMWAREVideoPtr pVid = data;
11546df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
11556df26cacSmrg    TRACEPOINT
11566df26cacSmrg
11576df26cacSmrg    if (!vmwareVideoEnabled(pVMWARE)) {
11586df26cacSmrg        return;
11596df26cacSmrg    }
1160a241306cSmrg
1161a241306cSmrg    REGION_EMPTY(pScrn->pScreen, &pVid->clipBoxes);
1162a241306cSmrg
11636df26cacSmrg    if (!Cleanup) {
116416fd1166Smrg        VmwareLog(("vmwareStopVideo: Cleanup is FALSE.\n"));
11656df26cacSmrg        return;
11666df26cacSmrg    }
11676df26cacSmrg    vmwareVideoSetOneReg(pVMWARE, pVid->streamId,
11686df26cacSmrg                         SVGA_VIDEO_ENABLED, FALSE);
11696df26cacSmrg
11706df26cacSmrg    vmwareVideoFlush(pVMWARE, pVid->streamId);
11716df26cacSmrg    vmwareVideoEndStream(pScrn, pVid);
11726df26cacSmrg
11736df26cacSmrg}
11746df26cacSmrg
11756df26cacSmrg
11766df26cacSmrg/*
11776df26cacSmrg *-----------------------------------------------------------------------------
11786df26cacSmrg *
11796df26cacSmrg * vmwareQueryImageAttributes --
11806df26cacSmrg *
11816df26cacSmrg *    From the spec: This function is called to let the driver specify how data
11826df26cacSmrg *    for a particular image of size width by height should be stored.
11836df26cacSmrg *    Sometimes only the size and corrected width and height are needed. In
11846df26cacSmrg *    that case pitches and offsets are NULL.
11856df26cacSmrg *
11866df26cacSmrg * Results:
11876df26cacSmrg *    The size of the memory required for the image, or -1 on error.
11886df26cacSmrg *
11896df26cacSmrg * Side effects:
11906df26cacSmrg *    None.
11916df26cacSmrg *
11926df26cacSmrg *-----------------------------------------------------------------------------
11936df26cacSmrg */
11946df26cacSmrg
119516fd1166Smrgstatic int
119616fd1166SmrgvmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
119716fd1166Smrg                           unsigned short *width, unsigned short *height,
119816fd1166Smrg                           int *pitches, int *offsets)
11996df26cacSmrg{
12006df26cacSmrg    INT32 size, tmp;
12016df26cacSmrg
12026df26cacSmrg    TRACEPOINT
12036df26cacSmrg
12046df26cacSmrg    if (*width > VMWARE_VID_MAX_WIDTH) {
12056df26cacSmrg        *width = VMWARE_VID_MAX_WIDTH;
12066df26cacSmrg    }
12076df26cacSmrg    if (*height > VMWARE_VID_MAX_HEIGHT) {
12086df26cacSmrg        *height = VMWARE_VID_MAX_HEIGHT;
12096df26cacSmrg    }
12106df26cacSmrg
12116df26cacSmrg    *width = (*width + 1) & ~1;
12126df26cacSmrg    if (offsets != NULL) {
12136df26cacSmrg        offsets[0] = 0;
12146df26cacSmrg    }
12156df26cacSmrg
12166df26cacSmrg    switch (format) {
12176df26cacSmrg       case FOURCC_YV12:
12186df26cacSmrg           *height = (*height + 1) & ~1;
12196df26cacSmrg           size = (*width + 3) & ~3;
12206df26cacSmrg           if (pitches) {
12216df26cacSmrg               pitches[0] = size;
12226df26cacSmrg           }
12236df26cacSmrg           size *= *height;
12246df26cacSmrg           if (offsets) {
12256df26cacSmrg               offsets[1] = size;
12266df26cacSmrg           }
12276df26cacSmrg           tmp = ((*width >> 1) + 3) & ~3;
12286df26cacSmrg           if (pitches) {
12296df26cacSmrg                pitches[1] = pitches[2] = tmp;
12306df26cacSmrg           }
12316df26cacSmrg           tmp *= (*height >> 1);
12326df26cacSmrg           size += tmp;
12336df26cacSmrg           if (offsets) {
12346df26cacSmrg               offsets[2] = size;
12356df26cacSmrg           }
12366df26cacSmrg           size += tmp;
12376df26cacSmrg           break;
123816fd1166Smrg       case FOURCC_UYVY:
12396df26cacSmrg       case FOURCC_YUY2:
12406df26cacSmrg           size = *width * 2;
12416df26cacSmrg           if (pitches) {
12426df26cacSmrg               pitches[0] = size;
12436df26cacSmrg           }
12446df26cacSmrg           size *= *height;
12456df26cacSmrg           break;
12466df26cacSmrg       default:
12476df26cacSmrg           VmwareLog(("Query for invalid video format %d\n", format));
12486df26cacSmrg           return -1;
12496df26cacSmrg    }
12506df26cacSmrg    return size;
12516df26cacSmrg}
12526df26cacSmrg
12536df26cacSmrg
12546df26cacSmrg/*
12556df26cacSmrg *-----------------------------------------------------------------------------
12566df26cacSmrg *
12576df26cacSmrg * vmwareSetPortAttribute --
12586df26cacSmrg *
12596df26cacSmrg *    From the spec: A port may have particular attributes such as colorKey, hue,
12606df26cacSmrg *    saturation, brightness or contrast. Xv clients set these
12616df26cacSmrg *    attribute values by sending attribute strings (Atoms) to the server.
12626df26cacSmrg *
12636df26cacSmrg * Results:
12646df26cacSmrg *    Success if the attribute exists and XvBadAlloc otherwise.
12656df26cacSmrg *
12666df26cacSmrg * Side effects:
12676df26cacSmrg *    The respective attribute gets the new value.
12686df26cacSmrg *
12696df26cacSmrg *-----------------------------------------------------------------------------
12706df26cacSmrg */
12716df26cacSmrg
127216fd1166Smrgstatic int
127316fd1166SmrgvmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
127416fd1166Smrg                       INT32 value, pointer data)
12756df26cacSmrg{
12766df26cacSmrg    VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
12776df26cacSmrg    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
127816fd1166Smrg    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
12796df26cacSmrg
12806df26cacSmrg    if (attribute == xvColorKey) {
128116fd1166Smrg        VmwareLog(("Set colorkey:0x%x\n", value));
12826df26cacSmrg        pVid->colorKey = value;
128316fd1166Smrg    } else if (attribute == xvAutoPaint) {
128416fd1166Smrg        VmwareLog(("Set autoPaint: %s\n", value? "TRUE": "FALSE"));
128516fd1166Smrg        pVid->isAutoPaintColorkey = value;
12866df26cacSmrg    } else {
12876df26cacSmrg        return XvBadAlloc;
12886df26cacSmrg    }
128916fd1166Smrg
12906df26cacSmrg    return Success;
12916df26cacSmrg}
12926df26cacSmrg
12936df26cacSmrg
12946df26cacSmrg/*
12956df26cacSmrg *-----------------------------------------------------------------------------
12966df26cacSmrg *
12976df26cacSmrg * vmwareGetPortAttribute --
12986df26cacSmrg *
12996df26cacSmrg *    From the spec: A port may have particular attributes such as hue,
13006df26cacSmrg *    saturation, brightness or contrast. Xv clients get these
13016df26cacSmrg *    attribute values by sending attribute strings (Atoms) to the server
13026df26cacSmrg *
13036df26cacSmrg * Results:
13046df26cacSmrg *    Success if the attribute exists and XvBadAlloc otherwise.
13056df26cacSmrg *
13066df26cacSmrg * Side effects:
13076df26cacSmrg *    "value" contains the requested attribute on success.
13086df26cacSmrg *
13096df26cacSmrg *-----------------------------------------------------------------------------
13106df26cacSmrg */
13116df26cacSmrg
131216fd1166Smrgstatic int
131316fd1166SmrgvmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
131416fd1166Smrg                       INT32 *value, pointer data)
13156df26cacSmrg{
13166df26cacSmrg    VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
13176df26cacSmrg    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
131816fd1166Smrg    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
13196df26cacSmrg
13206df26cacSmrg    if (attribute == xvColorKey) {
13216df26cacSmrg        *value = pVid->colorKey;
132216fd1166Smrg    } else if (attribute == xvAutoPaint) {
132316fd1166Smrg        *value = pVid->isAutoPaintColorkey;
13246df26cacSmrg    } else {
13256df26cacSmrg        return XvBadAlloc;
13266df26cacSmrg    }
132716fd1166Smrg
13286df26cacSmrg    return Success;
13296df26cacSmrg}
13306df26cacSmrg
13316df26cacSmrg
13326df26cacSmrg/*
13336df26cacSmrg *-----------------------------------------------------------------------------
13346df26cacSmrg *
13356df26cacSmrg * vmwareQueryBestSize --
13366df26cacSmrg *
13376df26cacSmrg *    From the spec: QueryBestSize provides the client with a way to query what
13386df26cacSmrg *    the destination dimensions would end up being if they were to request
13396df26cacSmrg *    that an area vid_w by vid_h from the video stream be scaled to rectangle
13406df26cacSmrg *    of drw_w by drw_h on the screen. Since it is not expected that all
13416df26cacSmrg *    hardware will be able to get the target dimensions exactly, it is
13426df26cacSmrg *    important that the driver provide this function.
13436df26cacSmrg *
13446df26cacSmrg *    This function seems to never be called, but to be on the safe side
13456df26cacSmrg *    we apply the same logic that QueryImageAttributes has for width
13466df26cacSmrg *    and height
13476df26cacSmrg *
13486df26cacSmrg * Results:
13496df26cacSmrg *    None.
13506df26cacSmrg *
13516df26cacSmrg * Side effects:
13526df26cacSmrg *    None
13536df26cacSmrg *
13546df26cacSmrg *-----------------------------------------------------------------------------
13556df26cacSmrg */
13566df26cacSmrg
135716fd1166Smrgstatic void
135816fd1166SmrgvmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
135916fd1166Smrg                    short vid_w, short vid_h, short drw_w,
136016fd1166Smrg                    short drw_h, unsigned int *p_w,
136116fd1166Smrg                    unsigned int *p_h, pointer data)
13626df26cacSmrg{
13636df26cacSmrg    *p_w = (drw_w + 1) & ~1;
13646df26cacSmrg    *p_h = drw_h;
13656df26cacSmrg
13666df26cacSmrg    return;
13676df26cacSmrg}
13686df26cacSmrg
1369