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