vmwarevideo.c revision 591e32d7
16df26cacSmrg/*
26df26cacSmrg * Copyright 2007 by VMware, Inc.
36df26cacSmrg *
46df26cacSmrg * Permission is hereby granted, free of charge, to any person obtaining a
56df26cacSmrg * copy of this software and associated documentation files (the "Software"),
66df26cacSmrg * to deal in the Software without restriction, including without limitation
76df26cacSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
86df26cacSmrg * and/or sell copies of the Software, and to permit persons to whom the
96df26cacSmrg * Software is furnished to do so, subject to the following conditions:
106df26cacSmrg *
116df26cacSmrg * The above copyright notice and this permission notice shall be included in
126df26cacSmrg * all copies or substantial portions of the Software.
136df26cacSmrg *
146df26cacSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
156df26cacSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
166df26cacSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
176df26cacSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
186df26cacSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
196df26cacSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
206df26cacSmrg * OTHER DEALINGS IN THE SOFTWARE.
216df26cacSmrg *
226df26cacSmrg * Except as contained in this notice, the name of the copyright holder(s)
236df26cacSmrg * and author(s) shall not be used in advertising or otherwise to promote
246df26cacSmrg * the sale, use or other dealings in this Software without prior written
256df26cacSmrg * authorization from the copyright holder(s) and author(s).
266df26cacSmrg */
276df26cacSmrg
286df26cacSmrg/*
296df26cacSmrg * vmwarevideo.c --
306df26cacSmrg *
316df26cacSmrg *      Xv extension support.
326df26cacSmrg *      See http://www.xfree86.org/current/DESIGN16.html
336df26cacSmrg *
346df26cacSmrg */
356df26cacSmrg
366df26cacSmrg
376df26cacSmrg#ifdef HAVE_CONFIG_H
386df26cacSmrg#include "config.h"
396df26cacSmrg#endif
406df26cacSmrg
416df26cacSmrg#include "vmware.h"
423bfa90b6Smrg#include "vmware_common.h"
436df26cacSmrg#include "xf86xv.h"
446df26cacSmrg#include "fourcc.h"
456df26cacSmrg#include "svga_escape.h"
466df26cacSmrg#include "svga_overlay.h"
476df26cacSmrg
486df26cacSmrg#include <X11/extensions/Xv.h>
496df26cacSmrg
50a241306cSmrg#ifndef HAVE_XORG_SERVER_1_5_0
51a241306cSmrg#include <xf86_ansic.h>
52a241306cSmrg#include <xf86_libc.h>
53a241306cSmrg#endif
54a241306cSmrg
553bfa90b6Smrg
563bfa90b6Smrg#define HAVE_FILLKEYHELPERDRAWABLE \
573bfa90b6Smrg    ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 2) ||  \
583bfa90b6Smrg     ((GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) == 1) && \
593bfa90b6Smrg      (GET_ABI_MINOR(ABI_VIDEODRV_VERSION) >= 2)))
603bfa90b6Smrg
61591e32d7Ssnj#if HAVE_FILLKEYHELPERDRAWABLE
62591e32d7Ssnj#include <damage.h>
63591e32d7Ssnj#endif
64591e32d7Ssnj
656df26cacSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
666df26cacSmrg
676df26cacSmrg/*
686df26cacSmrg * Used to pack structs
696df26cacSmrg */
706df26cacSmrg#define PACKED __attribute__((__packed__))
716df26cacSmrg
726df26cacSmrg/*
736df26cacSmrg * Number of videos that can be played simultaneously
746df26cacSmrg */
756df26cacSmrg#define VMWARE_VID_NUM_PORTS 1
766df26cacSmrg
776df26cacSmrg/*
7816fd1166Smrg * Using a dark shade as the default colorKey
796df26cacSmrg */
8016fd1166Smrg#define VMWARE_VIDEO_COLORKEY 0x100701
816df26cacSmrg
826df26cacSmrg/*
836df26cacSmrg * Maximum dimensions
846df26cacSmrg */
856df26cacSmrg#define VMWARE_VID_MAX_WIDTH    2048
866df26cacSmrg#define VMWARE_VID_MAX_HEIGHT   2048
876df26cacSmrg
886df26cacSmrg#define VMWARE_VID_NUM_ENCODINGS 1
896df26cacSmrgstatic XF86VideoEncodingRec vmwareVideoEncodings[] =
906df26cacSmrg{
916df26cacSmrg    {
926df26cacSmrg       0,
936df26cacSmrg       "XV_IMAGE",
946df26cacSmrg       VMWARE_VID_MAX_WIDTH, VMWARE_VID_MAX_HEIGHT,
956df26cacSmrg       {1, 1}
966df26cacSmrg    }
976df26cacSmrg};
986df26cacSmrg
996df26cacSmrg#define VMWARE_VID_NUM_FORMATS 2
1006df26cacSmrgstatic XF86VideoFormatRec vmwareVideoFormats[] =
1016df26cacSmrg{
1026df26cacSmrg    { 16, TrueColor},
1036df26cacSmrg    { 24, TrueColor}
1046df26cacSmrg};
1056df26cacSmrg
10616fd1166Smrg#define VMWARE_VID_NUM_IMAGES 3
1076df26cacSmrgstatic XF86ImageRec vmwareVideoImages[] =
1086df26cacSmrg{
1096df26cacSmrg    XVIMAGE_YV12,
11016fd1166Smrg    XVIMAGE_YUY2,
11116fd1166Smrg    XVIMAGE_UYVY
1126df26cacSmrg};
1136df26cacSmrg
11416fd1166Smrg#define VMWARE_VID_NUM_ATTRIBUTES 2
1156df26cacSmrgstatic XF86AttributeRec vmwareVideoAttributes[] =
1166df26cacSmrg{
1176df26cacSmrg    {
1186df26cacSmrg        XvGettable | XvSettable,
1196df26cacSmrg        0x000000,
1206df26cacSmrg        0xffffff,
1216df26cacSmrg        "XV_COLORKEY"
12216fd1166Smrg    },
12316fd1166Smrg    {
12416fd1166Smrg        XvGettable | XvSettable,
12516fd1166Smrg        0,
12616fd1166Smrg        1,
12716fd1166Smrg        "XV_AUTOPAINT_COLORKEY"
1286df26cacSmrg    }
1296df26cacSmrg};
1306df26cacSmrg
1316df26cacSmrg/*
1326df26cacSmrg * Video frames are stored in a circular list of buffers.
1336df26cacSmrg */
1346df26cacSmrg#define VMWARE_VID_NUM_BUFFERS 1
1356df26cacSmrg/*
1366df26cacSmrg * Defines the structure used to hold and pass video data to the host
1376df26cacSmrg */
1386df26cacSmrgtypedef struct {
1396df26cacSmrg   uint32  dataOffset;
1406df26cacSmrg   pointer data;
1416df26cacSmrg} VMWAREVideoBuffer;
1426df26cacSmrg
1436df26cacSmrgtypedef struct {
1446df26cacSmrg   uint32 size;
1456df26cacSmrg   uint32 offset;
1466df26cacSmrg} VMWAREOffscreenRec, *VMWAREOffscreenPtr;
1476df26cacSmrg
1486df26cacSmrg/*
1496df26cacSmrg * Trivial offscreen manager that allocates memory from the
1506df26cacSmrg * bottom of the VRAM.
1516df26cacSmrg */
1526df26cacSmrgstatic VMWAREOffscreenRec offscreenMgr;
1536df26cacSmrg
1546df26cacSmrg/*
1556df26cacSmrg * structs that reside in fmt_priv.
1566df26cacSmrg */
1576df26cacSmrgtypedef struct {
1586df26cacSmrg    int pitches[3];
1596df26cacSmrg    int offsets[3];
1606df26cacSmrg} VMWAREVideoFmtData;
1616df26cacSmrg
1626df26cacSmrg/*
1636df26cacSmrg * Structure representing a specific video stream.
1646df26cacSmrg */
1656df26cacSmrgstruct VMWAREVideoRec {
1666df26cacSmrg   uint32             streamId;
1676df26cacSmrg   /*
1686df26cacSmrg    * Function prototype same as XvPutImage.
1696df26cacSmrg    */
1706df26cacSmrg   int                (*play)(ScrnInfoPtr, struct VMWAREVideoRec *,
1716df26cacSmrg                              short, short, short, short, short,
1726df26cacSmrg                              short, short, short, int, unsigned char*,
1733bfa90b6Smrg                              short, short, RegionPtr, DrawablePtr);
1746df26cacSmrg   /*
1756df26cacSmrg    * Offscreen memory region used to pass video data to the host.
1766df26cacSmrg    */
1776df26cacSmrg   VMWAREOffscreenPtr fbarea;
1786df26cacSmrg   VMWAREVideoBuffer  bufs[VMWARE_VID_NUM_BUFFERS];
1796df26cacSmrg   uint8              currBuf;
1806df26cacSmrg   uint32             size;
1816df26cacSmrg   uint32             colorKey;
18216fd1166Smrg   Bool               isAutoPaintColorkey;
1836df26cacSmrg   uint32             flags;
18416fd1166Smrg   RegionRec          clipBoxes;
1856df26cacSmrg   VMWAREVideoFmtData *fmt_priv;
1866df26cacSmrg};
1876df26cacSmrg
1886df26cacSmrgtypedef struct VMWAREVideoRec VMWAREVideoRec;
1896df26cacSmrgtypedef VMWAREVideoRec *VMWAREVideoPtr;
1906df26cacSmrg
1916df26cacSmrg/*
1926df26cacSmrg * Callback functions
1936df26cacSmrg */
1943bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
1956df26cacSmrgstatic int vmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
1966df26cacSmrg                            short drw_x, short drw_y, short src_w, short src_h,
1976df26cacSmrg                            short drw_w, short drw_h, int image,
1986df26cacSmrg                            unsigned char *buf, short width, short height,
1996df26cacSmrg                            Bool sync, RegionPtr clipBoxes, pointer data,
2006df26cacSmrg                            DrawablePtr dst);
2016df26cacSmrg#else
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#endif
2086df26cacSmrgstatic void vmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup);
2096df26cacSmrgstatic int vmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
2106df26cacSmrg                                      unsigned short *width,
2116df26cacSmrg                                      unsigned short *height, int *pitches,
2126df26cacSmrg                                      int *offsets);
2136df26cacSmrgstatic int vmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
2146df26cacSmrg                                  INT32 value, pointer data);
2156df26cacSmrgstatic int vmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
2166df26cacSmrg                                  INT32 *value, pointer data);
2176df26cacSmrgstatic void vmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
2186df26cacSmrg                                short vid_w, short vid_h, short drw_w,
2196df26cacSmrg                                short drw_h, unsigned int *p_w,
2206df26cacSmrg                                unsigned int *p_h, pointer data);
2216df26cacSmrg
2226df26cacSmrg/*
2236df26cacSmrg * Local functions for video streams
2246df26cacSmrg */
2256df26cacSmrgstatic XF86VideoAdaptorPtr vmwareVideoSetup(ScrnInfoPtr pScrn);
2266df26cacSmrgstatic int vmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2276df26cacSmrg                                 short src_x, short src_y, short drw_x,
2286df26cacSmrg                                 short drw_y, short src_w, short src_h,
2296df26cacSmrg                                 short drw_w, short drw_h, int format,
23016fd1166Smrg                                 unsigned char *buf, short width,
2313bfa90b6Smrg                                 short height, RegionPtr clipBoxes,
2323bfa90b6Smrg				 DrawablePtr draw);
2336df26cacSmrgstatic int vmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2346df26cacSmrg                                     int format, unsigned short width,
2356df26cacSmrg                                     unsigned short height);
2366df26cacSmrgstatic int vmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
2376df26cacSmrg                           short src_x, short src_y, short drw_x,
2386df26cacSmrg                           short drw_y, short src_w, short src_h,
2396df26cacSmrg                           short drw_w, short drw_h, int format,
2406df26cacSmrg                           unsigned char *buf, short width,
2413bfa90b6Smrg                           short height, RegionPtr clipBoxes,
2423bfa90b6Smrg			   DrawablePtr draw);
2436df26cacSmrgstatic void vmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId);
2446df26cacSmrgstatic void vmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
2456df26cacSmrg                                 uint32 regId, uint32 value);
2466df26cacSmrgstatic void vmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid);
2476df26cacSmrg
2486df26cacSmrg/*
2496df26cacSmrg * Offscreen memory manager functions
2506df26cacSmrg */
2516df26cacSmrgstatic void vmwareOffscreenInit(void);
2526df26cacSmrgstatic VMWAREOffscreenPtr vmwareOffscreenAllocate(VMWAREPtr pVMWARE,
2536df26cacSmrg                                                  uint32 size);
2546df26cacSmrgstatic void vmwareOffscreenFree(VMWAREOffscreenPtr memptr);
2556df26cacSmrg
2566df26cacSmrg
2576df26cacSmrg/*
2586df26cacSmrg *-----------------------------------------------------------------------------
2596df26cacSmrg *
2606df26cacSmrg * vmwareCheckVideoSanity --
2616df26cacSmrg *
2626df26cacSmrg *    Ensures that on ModeSwitch the offscreen memory used
2636df26cacSmrg *    by the Xv streams doesn't become part of the guest framebuffer.
2646df26cacSmrg *
2656df26cacSmrg * Results:
2666df26cacSmrg *    None
2676df26cacSmrg *
2686df26cacSmrg * Side effects:
2696df26cacSmrg *    If it is found that the offscreen used by video streams  lies
2706df26cacSmrg *    within the range of the framebuffer(after ModeSwitch) then the video
2716df26cacSmrg *    streams will be stopped.
2726df26cacSmrg *
2736df26cacSmrg *-----------------------------------------------------------------------------
2746df26cacSmrg */
2756df26cacSmrg
2766df26cacSmrgvoid
2776df26cacSmrgvmwareCheckVideoSanity(ScrnInfoPtr pScrn)
2786df26cacSmrg{
2796df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
2806df26cacSmrg    VMWAREVideoPtr pVid;
2816df26cacSmrg
2826df26cacSmrg   if (offscreenMgr.size == 0 ||
2836df26cacSmrg       offscreenMgr.offset > pVMWARE->FbSize) {
2846df26cacSmrg       return ;
2856df26cacSmrg   }
2866df26cacSmrg
2876df26cacSmrg   pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
2886df26cacSmrg   vmwareStopVideo(pScrn, pVid, TRUE);
2896df26cacSmrg}
2906df26cacSmrg
2916df26cacSmrg
2926df26cacSmrg/*
2936df26cacSmrg *-----------------------------------------------------------------------------
2946df26cacSmrg *
2956df26cacSmrg * vmwareOffscreenInit --
2966df26cacSmrg *
2976df26cacSmrg *    Initializes the trivial Offscreen memory manager.
2986df26cacSmrg *
2996df26cacSmrg * Results:
3006df26cacSmrg *    None.
3016df26cacSmrg *
3026df26cacSmrg * Side effects:
3036df26cacSmrg *    Initializes the Offscreen manager meta-data structure.
3046df26cacSmrg *
3056df26cacSmrg *-----------------------------------------------------------------------------
3066df26cacSmrg */
3076df26cacSmrg
3086df26cacSmrgstatic void
3096df26cacSmrgvmwareOffscreenInit(void)
3106df26cacSmrg{
3116df26cacSmrg    offscreenMgr.size = 0;
3126df26cacSmrg    offscreenMgr.offset  = 0;
3136df26cacSmrg}
3146df26cacSmrg
3156df26cacSmrg
3166df26cacSmrg/*
3176df26cacSmrg *-----------------------------------------------------------------------------
3186df26cacSmrg *
3196df26cacSmrg * vmwareOffscreenAllocate --
3206df26cacSmrg *
3216df26cacSmrg *    Allocates offscreen memory.
3226df26cacSmrg *    Memory is allocated from the bottom part of the VRAM.
3236df26cacSmrg *    The memory manager is trivial iand can handle only 1 video-stream.
3246df26cacSmrg *    ----------
3256df26cacSmrg *    |        |
3266df26cacSmrg *    |  FB    |
3276df26cacSmrg *    |        |
3286df26cacSmrg *    |---------
3296df26cacSmrg *    |        |
3306df26cacSmrg *    |        |
3316df26cacSmrg *    |--------|
3326df26cacSmrg *    | Offscr |
3336df26cacSmrg *    |--------|
3346df26cacSmrg *
3356df26cacSmrg *      VRAM
3366df26cacSmrg *
3376df26cacSmrg * Results:
3386df26cacSmrg *    Pointer to the allocated Offscreen memory.
3396df26cacSmrg *
3406df26cacSmrg * Side effects:
3416df26cacSmrg *    Updates the Offscreen memory manager meta-data structure.
3426df26cacSmrg *
3436df26cacSmrg *-----------------------------------------------------------------------------
3446df26cacSmrg */
3456df26cacSmrg
3466df26cacSmrgstatic VMWAREOffscreenPtr
3476df26cacSmrgvmwareOffscreenAllocate(VMWAREPtr pVMWARE, uint32 size)
3486df26cacSmrg{
3496df26cacSmrg    VMWAREOffscreenPtr memptr;
3506df26cacSmrg
3516df26cacSmrg    if ((pVMWARE->videoRam - pVMWARE->FbSize - pVMWARE->fbPitch - 7) < size) {
3526df26cacSmrg        return NULL;
3536df26cacSmrg    }
3546df26cacSmrg
355a241306cSmrg    memptr = malloc(sizeof(VMWAREOffscreenRec));
3566df26cacSmrg    if (!memptr) {
3576df26cacSmrg        return NULL;
3586df26cacSmrg    }
3596df26cacSmrg    memptr->size = size;
3606df26cacSmrg    memptr->offset  = (pVMWARE->videoRam - size) & ~7;
3616df26cacSmrg
3626df26cacSmrg    VmwareLog(("vmwareOffscreenAllocate: Offset:%x", memptr->offset));
3636df26cacSmrg
3646df26cacSmrg    offscreenMgr.size = memptr->size;
3656df26cacSmrg    offscreenMgr.offset = memptr->offset;
3666df26cacSmrg    return memptr;
3676df26cacSmrg}
3686df26cacSmrg
3696df26cacSmrg
3706df26cacSmrg/*
3716df26cacSmrg *-----------------------------------------------------------------------------
3726df26cacSmrg *
3736df26cacSmrg * vmwareOffscreenFree --
3746df26cacSmrg *
3756df26cacSmrg *    Frees the allocated offscreen memory.
3766df26cacSmrg *
3776df26cacSmrg * Results:
3786df26cacSmrg *    None.
3796df26cacSmrg *
3806df26cacSmrg * Side effects:
3816df26cacSmrg *    Updates the Offscreen memory manager meta-data structure.
3826df26cacSmrg *
3836df26cacSmrg *-----------------------------------------------------------------------------
3846df26cacSmrg */
3856df26cacSmrg
3866df26cacSmrgstatic void
3876df26cacSmrgvmwareOffscreenFree(VMWAREOffscreenPtr memptr)
3886df26cacSmrg{
3896df26cacSmrg    if (memptr) {
3906df26cacSmrg        free(memptr);
3916df26cacSmrg    }
3926df26cacSmrg
3936df26cacSmrg    offscreenMgr.size = 0;
3946df26cacSmrg    offscreenMgr.offset = 0;
3956df26cacSmrg}
3966df26cacSmrg
3976df26cacSmrg
3986df26cacSmrg/*
3996df26cacSmrg *-----------------------------------------------------------------------------
4006df26cacSmrg *
4016df26cacSmrg * vmwareVideoEnabled --
4026df26cacSmrg *
4036df26cacSmrg *    Checks if Video FIFO and Escape FIFO cap are enabled.
4046df26cacSmrg *
4056df26cacSmrg * Results:
4066df26cacSmrg *    TRUE if required caps are enabled, FALSE otherwise.
4076df26cacSmrg *
4086df26cacSmrg * Side effects:
4096df26cacSmrg *    None.
4106df26cacSmrg *
4116df26cacSmrg *-----------------------------------------------------------------------------
4126df26cacSmrg */
4136df26cacSmrg
41416fd1166SmrgBool
41516fd1166SmrgvmwareVideoEnabled(VMWAREPtr pVMWARE)
4166df26cacSmrg{
4176df26cacSmrg    return ((pVMWARE->vmwareCapability & SVGA_CAP_EXTENDED_FIFO) &&
4186df26cacSmrg            (pVMWARE->vmwareFIFO[SVGA_FIFO_CAPABILITIES] &
4196df26cacSmrg             (SVGA_FIFO_CAP_VIDEO | SVGA_FIFO_CAP_ESCAPE)));
4206df26cacSmrg}
4216df26cacSmrg
4226df26cacSmrg
4236df26cacSmrg/*
4246df26cacSmrg *-----------------------------------------------------------------------------
4256df26cacSmrg *
4266df26cacSmrg * vmwareVideoInit --
4276df26cacSmrg *
4286df26cacSmrg *    Initializes Xv support.
4296df26cacSmrg *
4306df26cacSmrg * Results:
4316df26cacSmrg *    TRUE on success, FALSE on error.
4326df26cacSmrg *
4336df26cacSmrg * Side effects:
4346df26cacSmrg *    Xv support is initialized. Memory is allocated for all supported
4356df26cacSmrg *    video streams.
4366df26cacSmrg *
4376df26cacSmrg *-----------------------------------------------------------------------------
4386df26cacSmrg */
4396df26cacSmrg
44016fd1166SmrgBool
44116fd1166SmrgvmwareVideoInit(ScreenPtr pScreen)
4426df26cacSmrg{
4433bfa90b6Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
4446df26cacSmrg    XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
4456df26cacSmrg    XF86VideoAdaptorPtr newAdaptor = NULL;
4466df26cacSmrg    int numAdaptors;
4476df26cacSmrg
4486df26cacSmrg    TRACEPOINT
4496df26cacSmrg
4506df26cacSmrg    vmwareOffscreenInit();
4516df26cacSmrg
4526df26cacSmrg    numAdaptors = xf86XVListGenericAdaptors(pScrn, &overlayAdaptors);
4536df26cacSmrg
4546df26cacSmrg    newAdaptor = vmwareVideoSetup(pScrn);
4556df26cacSmrg    if (!newAdaptor) {
4566df26cacSmrg        VmwareLog(("Failed to initialize Xv extension \n"));
4576df26cacSmrg        return FALSE;
4586df26cacSmrg    }
4596df26cacSmrg
4606df26cacSmrg    if (!numAdaptors) {
4616df26cacSmrg        numAdaptors = 1;
4626df26cacSmrg        overlayAdaptors = &newAdaptor;
4636df26cacSmrg    } else {
464a241306cSmrg         newAdaptors = malloc((numAdaptors + 1) *
4656df26cacSmrg                              sizeof(XF86VideoAdaptorPtr*));
4666df26cacSmrg         if (!newAdaptors) {
4676df26cacSmrg            xf86XVFreeVideoAdaptorRec(newAdaptor);
4686df26cacSmrg            return FALSE;
4696df26cacSmrg         }
4706df26cacSmrg
4716df26cacSmrg         memcpy(newAdaptors, overlayAdaptors,
4726df26cacSmrg                numAdaptors * sizeof(XF86VideoAdaptorPtr));
4736df26cacSmrg         newAdaptors[numAdaptors++] = newAdaptor;
4746df26cacSmrg         overlayAdaptors = newAdaptors;
4756df26cacSmrg    }
4766df26cacSmrg
4776df26cacSmrg    if (!xf86XVScreenInit(pScreen, overlayAdaptors, numAdaptors)) {
4786df26cacSmrg        VmwareLog(("Failed to initialize Xv extension\n"));
4796df26cacSmrg        xf86XVFreeVideoAdaptorRec(newAdaptor);
4806df26cacSmrg        return FALSE;
4816df26cacSmrg    }
4826df26cacSmrg
4836df26cacSmrg    if (newAdaptors) {
484a241306cSmrg        free(newAdaptors);
4856df26cacSmrg    }
4866df26cacSmrg
4876df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
4886df26cacSmrg               "Initialized VMware Xv extension successfully.\n");
4896df26cacSmrg    return TRUE;
4906df26cacSmrg}
4916df26cacSmrg
4926df26cacSmrg
4936df26cacSmrg/*
4946df26cacSmrg *-----------------------------------------------------------------------------
4956df26cacSmrg *
4966df26cacSmrg * vmwareVideoEnd --
4976df26cacSmrg *
4986df26cacSmrg *    Unitializes video.
4996df26cacSmrg *
5006df26cacSmrg * Results:
5016df26cacSmrg *    None.
5026df26cacSmrg *
5036df26cacSmrg * Side effects:
5046df26cacSmrg *    pVMWARE->videoStreams = NULL
5056df26cacSmrg *
5066df26cacSmrg *-----------------------------------------------------------------------------
5076df26cacSmrg */
5086df26cacSmrg
50916fd1166Smrgvoid
51016fd1166SmrgvmwareVideoEnd(ScreenPtr pScreen)
5116df26cacSmrg{
5123bfa90b6Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
5136df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
5146df26cacSmrg    VMWAREVideoPtr pVid;
5156df26cacSmrg    int i;
5166df26cacSmrg
5176df26cacSmrg    TRACEPOINT
5186df26cacSmrg
5196df26cacSmrg    /*
5206df26cacSmrg     * Video streams are allocated after the DevUnion array
5216df26cacSmrg     * (see VideoSetup)
5226df26cacSmrg     */
5236df26cacSmrg    pVid = (VMWAREVideoPtr) &pVMWARE->videoStreams[VMWARE_VID_NUM_PORTS];
5246df26cacSmrg    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
5256df26cacSmrg        vmwareVideoEndStream(pScrn, &pVid[i]);
526a241306cSmrg	REGION_UNINIT(pScreen, &pVid[i].clipBoxes);
5276df26cacSmrg    }
5286df26cacSmrg
5296df26cacSmrg    free(pVMWARE->videoStreams);
5306df26cacSmrg    pVMWARE->videoStreams = NULL;
5316df26cacSmrg}
5326df26cacSmrg
5336df26cacSmrg
5346df26cacSmrg/*
5356df26cacSmrg *-----------------------------------------------------------------------------
5366df26cacSmrg *
5376df26cacSmrg * vmwareVideoSetup --
5386df26cacSmrg *
5396df26cacSmrg *    Initializes a XF86VideoAdaptor structure with the capabilities and
5406df26cacSmrg *    functions supported by this video driver.
5416df26cacSmrg *
5426df26cacSmrg * Results:
5436df26cacSmrg *    On success initialized XF86VideoAdaptor struct or NULL on error
5446df26cacSmrg *
5456df26cacSmrg * Side effects:
5466df26cacSmrg *    None.
5476df26cacSmrg *
5486df26cacSmrg *-----------------------------------------------------------------------------
5496df26cacSmrg */
5506df26cacSmrg
55116fd1166Smrgstatic XF86VideoAdaptorPtr
55216fd1166SmrgvmwareVideoSetup(ScrnInfoPtr pScrn)
5536df26cacSmrg{
5546df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
5556df26cacSmrg    XF86VideoAdaptorPtr adaptor;
5566df26cacSmrg    VMWAREVideoPtr pPriv;
5576df26cacSmrg    DevUnion *du;
5586df26cacSmrg    int i;
5596df26cacSmrg
5606df26cacSmrg    TRACEPOINT
5616df26cacSmrg
5626df26cacSmrg    adaptor = xf86XVAllocateVideoAdaptorRec(pScrn);
5636df26cacSmrg    if (!adaptor) {
5646df26cacSmrg        VmwareLog(("Not enough memory\n"));
5656df26cacSmrg        return NULL;
5666df26cacSmrg    }
567a241306cSmrg    du = calloc(1, VMWARE_VID_NUM_PORTS *
5686df26cacSmrg        (sizeof(DevUnion) + sizeof(VMWAREVideoRec)));
5696df26cacSmrg
5706df26cacSmrg    if (!du) {
5716df26cacSmrg        VmwareLog(("Not enough memory.\n"));
5726df26cacSmrg        xf86XVFreeVideoAdaptorRec(adaptor);
5736df26cacSmrg        return NULL;
5746df26cacSmrg    }
5756df26cacSmrg
5766df26cacSmrg    adaptor->type = XvInputMask | XvImageMask | XvWindowMask;
5776df26cacSmrg    adaptor->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
5786df26cacSmrg    adaptor->name = "VMware Video Engine";
5796df26cacSmrg    adaptor->nEncodings = VMWARE_VID_NUM_ENCODINGS;
5806df26cacSmrg    adaptor->pEncodings = vmwareVideoEncodings;
5816df26cacSmrg    adaptor->nFormats = VMWARE_VID_NUM_FORMATS;
5826df26cacSmrg    adaptor->pFormats = vmwareVideoFormats;
5836df26cacSmrg    adaptor->nPorts = VMWARE_VID_NUM_PORTS;
5846df26cacSmrg
5856df26cacSmrg    pPriv = (VMWAREVideoPtr) &du[VMWARE_VID_NUM_PORTS];
5866df26cacSmrg    adaptor->pPortPrivates = du;
5876df26cacSmrg
5886df26cacSmrg    for (i = 0; i < VMWARE_VID_NUM_PORTS; ++i) {
5896df26cacSmrg        pPriv[i].streamId = i;
5906df26cacSmrg        pPriv[i].play = vmwareVideoInitStream;
5916df26cacSmrg        pPriv[i].flags = SVGA_VIDEO_FLAG_COLORKEY;
5926df26cacSmrg        pPriv[i].colorKey = VMWARE_VIDEO_COLORKEY;
59316fd1166Smrg        pPriv[i].isAutoPaintColorkey = TRUE;
594a241306cSmrg	REGION_NULL(pScreen, &pPriv[i].clipBoxes);
5956df26cacSmrg        adaptor->pPortPrivates[i].ptr = &pPriv[i];
5966df26cacSmrg    }
5976df26cacSmrg    pVMWARE->videoStreams = du;
5986df26cacSmrg
5996df26cacSmrg    adaptor->nAttributes = VMWARE_VID_NUM_ATTRIBUTES;
6006df26cacSmrg    adaptor->pAttributes = vmwareVideoAttributes;
6016df26cacSmrg
6026df26cacSmrg    adaptor->nImages = VMWARE_VID_NUM_IMAGES;
6036df26cacSmrg    adaptor->pImages = vmwareVideoImages;
6046df26cacSmrg
6056df26cacSmrg    adaptor->PutVideo = NULL;
6066df26cacSmrg    adaptor->PutStill = NULL;
6076df26cacSmrg    adaptor->GetVideo = NULL;
6086df26cacSmrg    adaptor->GetStill = NULL;
6096df26cacSmrg    adaptor->StopVideo = vmwareStopVideo;
6106df26cacSmrg    adaptor->SetPortAttribute = vmwareSetPortAttribute;
6116df26cacSmrg    adaptor->GetPortAttribute = vmwareGetPortAttribute;
6126df26cacSmrg    adaptor->QueryBestSize = vmwareQueryBestSize;
6136df26cacSmrg    adaptor->PutImage = vmwareXvPutImage;
6146df26cacSmrg    adaptor->QueryImageAttributes = vmwareQueryImageAttributes;
6156df26cacSmrg
6166df26cacSmrg    return adaptor;
6176df26cacSmrg}
6186df26cacSmrg
6196df26cacSmrg
6206df26cacSmrg/*
6216df26cacSmrg *-----------------------------------------------------------------------------
6226df26cacSmrg *
6236df26cacSmrg * vmwareVideoInitStream --
6246df26cacSmrg *
6256df26cacSmrg *    Initializes a video stream in response to the first PutImage() on a
6266df26cacSmrg *    video stream. The process goes as follows:
6276df26cacSmrg *    - Figure out characteristics according to format
6286df26cacSmrg *    - Allocate offscreen memory
6296df26cacSmrg *    - Pass on video to Play() functions
6306df26cacSmrg *
6316df26cacSmrg * Results:
6326df26cacSmrg *    Success or XvBadAlloc on failure.
6336df26cacSmrg *
6346df26cacSmrg * Side effects:
6356df26cacSmrg *    Video stream is initialized and its first frame sent to the host
6366df26cacSmrg *    (done by VideoPlay() function called at the end)
6376df26cacSmrg *
6386df26cacSmrg *-----------------------------------------------------------------------------
6396df26cacSmrg */
6406df26cacSmrg
64116fd1166Smrgstatic int
64216fd1166SmrgvmwareVideoInitStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
64316fd1166Smrg                      short src_x, short src_y, short drw_x,
64416fd1166Smrg                      short drw_y, short src_w, short src_h,
64516fd1166Smrg                      short drw_w, short drw_h, int format,
64616fd1166Smrg                      unsigned char *buf, short width,
6473bfa90b6Smrg                      short height, RegionPtr clipBoxes,
6483bfa90b6Smrg		      DrawablePtr draw)
6496df26cacSmrg{
6506df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
6516df26cacSmrg    int i;
6526df26cacSmrg
6536df26cacSmrg    TRACEPOINT
6546df26cacSmrg
6556df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
6566df26cacSmrg               "Initializing Xv video-stream with id:%d format:%d\n",
6576df26cacSmrg                pVid->streamId, format);
6586df26cacSmrg
6596df26cacSmrg    pVid->size = vmwareVideoInitAttributes(pScrn, pVid, format, width,
6606df26cacSmrg                                           height);
6616df26cacSmrg
6626df26cacSmrg    if (pVid->size == -1) {
6636df26cacSmrg        VmwareLog(("Could not initialize 0x%x video stream\n", format));
6646df26cacSmrg        return XvBadAlloc;
6656df26cacSmrg    }
6666df26cacSmrg
6676df26cacSmrg    pVid->play = vmwareVideoPlay;
6686df26cacSmrg
6696df26cacSmrg    pVid->fbarea = vmwareOffscreenAllocate(pVMWARE,
6706df26cacSmrg                       pVid->size * VMWARE_VID_NUM_BUFFERS);
6716df26cacSmrg
6726df26cacSmrg    if (!pVid->fbarea) {
6736df26cacSmrg       VmwareLog(("Could not allocate offscreen memory\n"));
6746df26cacSmrg       vmwareVideoEndStream(pScrn, pVid);
6756df26cacSmrg       return BadAlloc;
6766df26cacSmrg    }
6776df26cacSmrg
6786df26cacSmrg    pVid->bufs[0].dataOffset = pVid->fbarea->offset;
6796df26cacSmrg    pVid->bufs[0].data = pVMWARE->FbBase + pVid->bufs[0].dataOffset;
6806df26cacSmrg
6816df26cacSmrg    for (i = 1; i < VMWARE_VID_NUM_BUFFERS; ++i) {
6826df26cacSmrg        pVid->bufs[i].dataOffset = pVid->bufs[i-1].dataOffset + pVid->size;
6836df26cacSmrg        pVid->bufs[i].data = pVMWARE->FbBase + pVid->bufs[i].dataOffset;
6846df26cacSmrg    }
6856df26cacSmrg    pVid->currBuf = 0;
6866df26cacSmrg
68716fd1166Smrg    REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
68816fd1166Smrg
68916fd1166Smrg    if (pVid->isAutoPaintColorkey) {
690a241306cSmrg	BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
691a241306cSmrg	int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
692a241306cSmrg
6933bfa90b6Smrg#if HAVE_FILLKEYHELPERDRAWABLE
694591e32d7Ssnj	if (draw->type == DRAWABLE_WINDOW) {
695591e32d7Ssnj	    xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
696591e32d7Ssnj	    DamageDamageRegion(draw, clipBoxes);
697591e32d7Ssnj	} else {
698591e32d7Ssnj	    xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
699591e32d7Ssnj        }
7003bfa90b6Smrg#else
70116fd1166Smrg        xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
7023bfa90b6Smrg#endif
703a241306cSmrg	/**
704a241306cSmrg	 * Force update to paint the colorkey before the overlay flush.
705a241306cSmrg	 */
706a241306cSmrg
707a241306cSmrg	while(nBoxes--)
708a241306cSmrg	    vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
70916fd1166Smrg    }
71016fd1166Smrg
7116df26cacSmrg    VmwareLog(("Got offscreen region, offset %d, size %d "
7126df26cacSmrg               "(yuv size in bytes: %d)\n",
7136df26cacSmrg               pVid->fbarea->offset, pVid->fbarea->size, pVid->size));
7146df26cacSmrg
7156df26cacSmrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
7163bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
7173bfa90b6Smrg		      draw);
7186df26cacSmrg}
7196df26cacSmrg
7206df26cacSmrg
7216df26cacSmrg/*
7226df26cacSmrg *-----------------------------------------------------------------------------
7236df26cacSmrg *
7246df26cacSmrg * vmwareVideoInitAttributes --
7256df26cacSmrg *
7266df26cacSmrg *    Fetches the format specific attributes using QueryImageAttributes().
7276df26cacSmrg *
7286df26cacSmrg * Results:
7296df26cacSmrg *    size of the YUV frame on success and -1 on error.
7306df26cacSmrg *
7316df26cacSmrg * Side effects:
7326df26cacSmrg *    The video stream gets the format specific attributes(fmtData).
7336df26cacSmrg *
7346df26cacSmrg *-----------------------------------------------------------------------------
7356df26cacSmrg */
7366df26cacSmrg
73716fd1166Smrgstatic int
73816fd1166SmrgvmwareVideoInitAttributes(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
73916fd1166Smrg                          int format, unsigned short width,
74016fd1166Smrg                          unsigned short height)
7416df26cacSmrg{
7426df26cacSmrg    int size;
7436df26cacSmrg    VMWAREVideoFmtData *fmtData;
7446df26cacSmrg
7456df26cacSmrg    TRACEPOINT
7466df26cacSmrg
747a241306cSmrg    fmtData = calloc(1, sizeof(VMWAREVideoFmtData));
7486df26cacSmrg    if (!fmtData) {
7496df26cacSmrg        return -1;
7506df26cacSmrg    }
7516df26cacSmrg
7526df26cacSmrg    size = vmwareQueryImageAttributes(pScrn, format, &width, &height,
7536df26cacSmrg                                      fmtData->pitches, fmtData->offsets);
7546df26cacSmrg    if (size == -1) {
7556df26cacSmrg        free(fmtData);
7566df26cacSmrg        return -1;
7576df26cacSmrg    }
7586df26cacSmrg
7596df26cacSmrg    pVid->fmt_priv = fmtData;
7606df26cacSmrg    return size;
7616df26cacSmrg}
7626df26cacSmrg
7636df26cacSmrg
7646df26cacSmrg/*
7656df26cacSmrg *-----------------------------------------------------------------------------
7666df26cacSmrg *
7676df26cacSmrg * vmwareVideoPlay --
7686df26cacSmrg *
7696df26cacSmrg *    Sends all the attributes associated with the video frame using the
7706df26cacSmrg *    FIFO ESCAPE mechanism to the host.
7716df26cacSmrg *
7726df26cacSmrg * Results:
7736df26cacSmrg *    Always returns Success.
7746df26cacSmrg *
7756df26cacSmrg * Side effects:
7766df26cacSmrg *    None.
7776df26cacSmrg *
7786df26cacSmrg *-----------------------------------------------------------------------------
7796df26cacSmrg */
7806df26cacSmrg
78116fd1166Smrgstatic int
78216fd1166SmrgvmwareVideoPlay(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid,
78316fd1166Smrg                short src_x, short src_y, short drw_x,
78416fd1166Smrg                short drw_y, short src_w, short src_h,
78516fd1166Smrg                short drw_w, short drw_h, int format,
78616fd1166Smrg                unsigned char *buf, short width,
7873bfa90b6Smrg                short height, RegionPtr clipBoxes,
7883bfa90b6Smrg		DrawablePtr draw)
7896df26cacSmrg{
7906df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
7916df26cacSmrg    uint32 *fifoItem;
7926df26cacSmrg    int i, regId;
7936df26cacSmrg    struct PACKED _item {
7946df26cacSmrg        uint32 regId;
7956df26cacSmrg        uint32 value;
7966df26cacSmrg    };
7976df26cacSmrg
7986df26cacSmrg    struct PACKED _body {
7996df26cacSmrg        uint32 escape;
8006df26cacSmrg        uint32 streamId;
801591e32d7Ssnj        /* Old hosts can not handle more then these regs */
802591e32d7Ssnj        struct _item items[SVGA_VIDEO_DATA_GMRID];
8036df26cacSmrg    };
8046df26cacSmrg
8056df26cacSmrg    struct PACKED _cmdSetRegs {
8066df26cacSmrg        uint32 cmd;
8076df26cacSmrg        uint32 nsid;
8086df26cacSmrg        uint32 size;
8096df26cacSmrg        struct _body body;
8106df26cacSmrg    };
8116df26cacSmrg
8126df26cacSmrg    struct _cmdSetRegs cmdSetRegs;
8136df26cacSmrg    struct _item *items;
81416fd1166Smrg    int size;
81516fd1166Smrg    VMWAREVideoFmtData *fmtData;
81616fd1166Smrg    unsigned short w, h;
8176df26cacSmrg
81816fd1166Smrg    w = width;
81916fd1166Smrg    h = height;
82016fd1166Smrg    fmtData = pVid->fmt_priv;
82116fd1166Smrg
82216fd1166Smrg    size = vmwareQueryImageAttributes(pScrn, format, &w, &h,
82316fd1166Smrg                                      fmtData->pitches, fmtData->offsets);
82416fd1166Smrg
82516fd1166Smrg    if (size > pVid->size) {
82616fd1166Smrg        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Increase in size of Xv video "
82716fd1166Smrg                   "frame streamId:%d.\n", pVid->streamId);
82816fd1166Smrg        vmwareStopVideo(pScrn, pVid, TRUE);
82916fd1166Smrg        return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w,
83016fd1166Smrg                          src_h, drw_w, drw_h, format, buf, width, height,
8313bfa90b6Smrg                          clipBoxes, draw);
83216fd1166Smrg    }
83316fd1166Smrg
83416fd1166Smrg    pVid->size = size;
8356df26cacSmrg    memcpy(pVid->bufs[pVid->currBuf].data, buf, pVid->size);
8366df26cacSmrg
8376df26cacSmrg    cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
8386df26cacSmrg    cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
8396df26cacSmrg    cmdSetRegs.size = sizeof(cmdSetRegs.body);
8406df26cacSmrg    cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
8416df26cacSmrg    cmdSetRegs.body.streamId = pVid->streamId;
8426df26cacSmrg
8436df26cacSmrg    items = cmdSetRegs.body.items;
844591e32d7Ssnj    for (i = SVGA_VIDEO_ENABLED; i < SVGA_VIDEO_DATA_GMRID; i++) {
8456df26cacSmrg        items[i].regId = i;
8466df26cacSmrg    }
8476df26cacSmrg
8486df26cacSmrg    items[SVGA_VIDEO_ENABLED].value = TRUE;
8496df26cacSmrg    items[SVGA_VIDEO_DATA_OFFSET].value =
8506df26cacSmrg        pVid->bufs[pVid->currBuf].dataOffset;
8516df26cacSmrg    items[SVGA_VIDEO_SIZE].value = pVid->size;
8526df26cacSmrg    items[SVGA_VIDEO_FORMAT].value = format;
85316fd1166Smrg    items[SVGA_VIDEO_WIDTH].value = w;
85416fd1166Smrg    items[SVGA_VIDEO_HEIGHT].value = h;
8556df26cacSmrg    items[SVGA_VIDEO_SRC_X].value = src_x;
8566df26cacSmrg    items[SVGA_VIDEO_SRC_Y].value = src_y;
8576df26cacSmrg    items[SVGA_VIDEO_SRC_WIDTH].value = src_w;
8586df26cacSmrg    items[SVGA_VIDEO_SRC_HEIGHT].value = src_h;
8596df26cacSmrg    items[SVGA_VIDEO_DST_X].value = drw_x;
8606df26cacSmrg    items[SVGA_VIDEO_DST_Y].value = drw_y;
8616df26cacSmrg    items[SVGA_VIDEO_DST_WIDTH]. value = drw_w;
8626df26cacSmrg    items[SVGA_VIDEO_DST_HEIGHT].value = drw_h;
8636df26cacSmrg    items[SVGA_VIDEO_COLORKEY].value = pVid->colorKey;
8646df26cacSmrg    items[SVGA_VIDEO_FLAGS].value = pVid->flags;
8656df26cacSmrg
8666df26cacSmrg    for (i = 0, regId = SVGA_VIDEO_PITCH_1; i < 3; i++, regId++) {
86716fd1166Smrg        items[regId].value = fmtData->pitches[i];
8686df26cacSmrg    }
8696df26cacSmrg
8706df26cacSmrg    fifoItem = (uint32 *) &cmdSetRegs;
8716df26cacSmrg    for (i = 0; i <  sizeof(cmdSetRegs) / sizeof(uint32); i++) {
8726df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
8736df26cacSmrg    }
8746df26cacSmrg
87516fd1166Smrg    /*
87616fd1166Smrg     *  Update the clipList and paint the colorkey, if required.
87716fd1166Smrg     */
87816fd1166Smrg    if (!vmwareIsRegionEqual(&pVid->clipBoxes, clipBoxes)) {
87916fd1166Smrg        REGION_COPY(pScrn->pScreen, &pVid->clipBoxes, clipBoxes);
88016fd1166Smrg        if (pVid->isAutoPaintColorkey) {
881a241306cSmrg	    BoxPtr boxes = REGION_RECTS(&pVid->clipBoxes);
882a241306cSmrg	    int nBoxes = REGION_NUM_RECTS(&pVid->clipBoxes);
883a241306cSmrg
8843bfa90b6Smrg#if HAVE_FILLKEYHELPERDRAWABLE
8853bfa90b6Smrg	    xf86XVFillKeyHelperDrawable(draw, pVid->colorKey, clipBoxes);
8863bfa90b6Smrg#else
8873bfa90b6Smrg	    xf86XVFillKeyHelper(pScrn->pScreen, pVid->colorKey, clipBoxes);
8883bfa90b6Smrg#endif
889a241306cSmrg	    /**
890a241306cSmrg	     * Force update to paint the colorkey before the overlay flush.
891a241306cSmrg	     */
892a241306cSmrg
893a241306cSmrg	    while(nBoxes--)
894a241306cSmrg		vmwareSendSVGACmdUpdate(pVMWARE, boxes++);
895a241306cSmrg
89616fd1166Smrg        }
89716fd1166Smrg    }
89816fd1166Smrg
8996df26cacSmrg    vmwareVideoFlush(pVMWARE, pVid->streamId);
9006df26cacSmrg
9016df26cacSmrg    pVid->currBuf = ++pVid->currBuf & (VMWARE_VID_NUM_BUFFERS - 1);
90216fd1166Smrg
9036df26cacSmrg    return Success;
9046df26cacSmrg}
9056df26cacSmrg
9066df26cacSmrg
9076df26cacSmrg/*
9086df26cacSmrg *-----------------------------------------------------------------------------
9096df26cacSmrg *
9106df26cacSmrg * vmwareVideoFlush --
9116df26cacSmrg *
9126df26cacSmrg *    Sends the VIDEO_FLUSH command (FIFO ESCAPE mechanism) asking the host
9136df26cacSmrg *    to play the video stream or end it.
9146df26cacSmrg *
9156df26cacSmrg * Results:
9166df26cacSmrg *    None.
9176df26cacSmrg *
9186df26cacSmrg * Side effects:
9196df26cacSmrg *    None.
9206df26cacSmrg *
9216df26cacSmrg *-----------------------------------------------------------------------------
9226df26cacSmrg */
9236df26cacSmrg
92416fd1166Smrgstatic void
92516fd1166SmrgvmwareVideoFlush(VMWAREPtr pVMWARE, uint32 streamId)
9266df26cacSmrg{
9276df26cacSmrg    struct PACKED _body {
9286df26cacSmrg        uint32 escape;
9296df26cacSmrg        uint32 streamId;
9306df26cacSmrg    };
9316df26cacSmrg
9326df26cacSmrg    struct PACKED _cmdFlush {
9336df26cacSmrg        uint32 cmd;
9346df26cacSmrg        uint32 nsid;
9356df26cacSmrg        uint32 size;
9366df26cacSmrg        struct _body body;
9376df26cacSmrg    };
9386df26cacSmrg
9396df26cacSmrg    struct _cmdFlush cmdFlush;
9406df26cacSmrg    uint32 *fifoItem;
9416df26cacSmrg    int i;
9426df26cacSmrg
9436df26cacSmrg    cmdFlush.cmd = SVGA_CMD_ESCAPE;
9446df26cacSmrg    cmdFlush.nsid = SVGA_ESCAPE_NSID_VMWARE;
9456df26cacSmrg    cmdFlush.size = sizeof(cmdFlush.body);
9466df26cacSmrg    cmdFlush.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
9476df26cacSmrg    cmdFlush.body.streamId = streamId;
9486df26cacSmrg
9496df26cacSmrg    fifoItem = (uint32 *) &cmdFlush;
9506df26cacSmrg    for (i = 0; i < sizeof(cmdFlush) / sizeof(uint32); i++) {
9516df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
9526df26cacSmrg    }
9536df26cacSmrg}
9546df26cacSmrg
9556df26cacSmrg
9566df26cacSmrg/*
9576df26cacSmrg *-----------------------------------------------------------------------------
9586df26cacSmrg *
9596df26cacSmrg * vmwareVideoSetOneReg --
9606df26cacSmrg *
9616df26cacSmrg *    Sets one video register using the FIFO ESCAPE mechanidm.
9626df26cacSmrg *
9636df26cacSmrg * Results:
9646df26cacSmrg *    None.
9656df26cacSmrg *
9666df26cacSmrg * Side effects:
9676df26cacSmrg *    None.
9686df26cacSmrg *-----------------------------------------------------------------------------
9696df26cacSmrg */
9706df26cacSmrg
97116fd1166Smrgstatic void
97216fd1166SmrgvmwareVideoSetOneReg(VMWAREPtr pVMWARE, uint32 streamId,
97316fd1166Smrg                     uint32 regId, uint32 value)
9746df26cacSmrg{
9756df26cacSmrg    struct PACKED _item {
9766df26cacSmrg        uint32 regId;
9776df26cacSmrg        uint32 value;
9786df26cacSmrg    };
9796df26cacSmrg
9806df26cacSmrg    struct PACKED _body {
9816df26cacSmrg        uint32 escape;
9826df26cacSmrg        uint32 streamId;
9836df26cacSmrg        struct _item item;
9846df26cacSmrg    };
9856df26cacSmrg
9866df26cacSmrg    struct PACKED _cmdSetRegs {
9876df26cacSmrg        uint32 cmd;
9886df26cacSmrg        uint32 nsid;
9896df26cacSmrg        uint32 size;
9906df26cacSmrg        struct _body body;
9916df26cacSmrg    };
9926df26cacSmrg
9936df26cacSmrg    struct _cmdSetRegs cmdSetRegs;
9946df26cacSmrg    int i;
9956df26cacSmrg    uint32 *fifoItem;
9966df26cacSmrg
9976df26cacSmrg    cmdSetRegs.cmd = SVGA_CMD_ESCAPE;
9986df26cacSmrg    cmdSetRegs.nsid = SVGA_ESCAPE_NSID_VMWARE;
9996df26cacSmrg    cmdSetRegs.size = sizeof(cmdSetRegs.body);
10006df26cacSmrg    cmdSetRegs.body.escape = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
10016df26cacSmrg    cmdSetRegs.body.streamId = streamId;
10026df26cacSmrg    cmdSetRegs.body.item.regId = regId;
10036df26cacSmrg    cmdSetRegs.body.item.value = value;
10046df26cacSmrg
10056df26cacSmrg    fifoItem = (uint32 *) &cmdSetRegs;
10066df26cacSmrg    for (i = 0; i < sizeof(cmdSetRegs) / sizeof(uint32); i++) {
10076df26cacSmrg        vmwareWriteWordToFIFO(pVMWARE, fifoItem[i]);
10086df26cacSmrg    }
10096df26cacSmrg}
10106df26cacSmrg
10116df26cacSmrg
10126df26cacSmrg/*
10136df26cacSmrg *-----------------------------------------------------------------------------
10146df26cacSmrg *
10156df26cacSmrg * vmwareVideoEndStream --
10166df26cacSmrg *
10176df26cacSmrg *    Frees up all resources (if any) taken by a video stream.
10186df26cacSmrg *
10196df26cacSmrg * Results:
10206df26cacSmrg *    None.
10216df26cacSmrg *
10226df26cacSmrg * Side effects:
10236df26cacSmrg *    Same as above.
10246df26cacSmrg *
10256df26cacSmrg *-----------------------------------------------------------------------------
10266df26cacSmrg */
10276df26cacSmrg
102816fd1166Smrgstatic void
102916fd1166SmrgvmwareVideoEndStream(ScrnInfoPtr pScrn, VMWAREVideoPtr pVid)
10306df26cacSmrg{
10316df26cacSmrg    uint32 id, colorKey, flags;
103216fd1166Smrg    Bool isAutoPaintColorkey;
10336df26cacSmrg
10346df26cacSmrg    if (pVid->fmt_priv) {
10356df26cacSmrg        free(pVid->fmt_priv);
10366df26cacSmrg    }
10376df26cacSmrg
10386df26cacSmrg    if (pVid->fbarea) {
10396df26cacSmrg        vmwareOffscreenFree(pVid->fbarea);
10406df26cacSmrg        pVid->fbarea =  NULL;
10416df26cacSmrg    }
10426df26cacSmrg
10436df26cacSmrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
10446df26cacSmrg               "Terminating Xv video-stream id:%d\n", pVid->streamId);
10456df26cacSmrg    /*
10466df26cacSmrg     * reset stream for next video
10476df26cacSmrg     */
10486df26cacSmrg    id = pVid->streamId;
10496df26cacSmrg    colorKey = pVid->colorKey;
10506df26cacSmrg    flags = pVid->flags;
105116fd1166Smrg    isAutoPaintColorkey = pVid->isAutoPaintColorkey;
105216fd1166Smrg
10536df26cacSmrg    memset(pVid, 0, sizeof(*pVid));
105416fd1166Smrg
10556df26cacSmrg    pVid->streamId = id;
10566df26cacSmrg    pVid->play = vmwareVideoInitStream;
10576df26cacSmrg    pVid->colorKey = colorKey;
10586df26cacSmrg    pVid->flags = flags;
105916fd1166Smrg    pVid->isAutoPaintColorkey = isAutoPaintColorkey;
10606df26cacSmrg}
10616df26cacSmrg
10626df26cacSmrg
10636df26cacSmrg/*
10646df26cacSmrg *-----------------------------------------------------------------------------
10656df26cacSmrg *
10666df26cacSmrg * vmwareXvPutImage --
10676df26cacSmrg *
10686df26cacSmrg *    Main video playback function. It copies the passed data which is in
10696df26cacSmrg *    the specified format (e.g. FOURCC_YV12) into the overlay.
10706df26cacSmrg *
10716df26cacSmrg *    If sync is TRUE the driver should not return from this
10726df26cacSmrg *    function until it is through reading the data from buf.
10736df26cacSmrg *
10746df26cacSmrg *    There are two function prototypes to cope with the API change in X.org
10756df26cacSmrg *    7.1
10766df26cacSmrg *
10776df26cacSmrg * Results:
10786df26cacSmrg *    Success or XvBadAlloc on failure
10796df26cacSmrg *
10806df26cacSmrg * Side effects:
10816df26cacSmrg *    Video stream will be played(initialized if 1st frame) on success
10826df26cacSmrg *    or will fail on error.
10836df26cacSmrg *
10846df26cacSmrg *-----------------------------------------------------------------------------
10856df26cacSmrg */
10866df26cacSmrg
10873bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
108816fd1166Smrgstatic int
108916fd1166SmrgvmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
109016fd1166Smrg                 short drw_x, short drw_y, short src_w, short src_h,
109116fd1166Smrg                 short drw_w, short drw_h, int format,
109216fd1166Smrg                 unsigned char *buf, short width, short height,
109316fd1166Smrg                 Bool sync, RegionPtr clipBoxes, pointer data,
109416fd1166Smrg                 DrawablePtr dst)
10956df26cacSmrg#else
109616fd1166Smrgstatic int
109716fd1166SmrgvmwareXvPutImage(ScrnInfoPtr pScrn, short src_x, short src_y,
109816fd1166Smrg                 short drw_x, short drw_y, short src_w, short src_h,
109916fd1166Smrg                 short drw_w, short drw_h, int format,
110016fd1166Smrg                 unsigned char *buf, short width, short height,
110116fd1166Smrg                 Bool sync, RegionPtr clipBoxes, pointer data)
11026df26cacSmrg#endif
11036df26cacSmrg{
11046df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
11056df26cacSmrg    VMWAREVideoPtr pVid = data;
11066df26cacSmrg
11076df26cacSmrg    TRACEPOINT
11086df26cacSmrg
11096df26cacSmrg    if (!vmwareVideoEnabled(pVMWARE)) {
11106df26cacSmrg        return XvBadAlloc;
11116df26cacSmrg    }
11126df26cacSmrg
11133bfa90b6Smrg#if (GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 1)
11146df26cacSmrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
11153bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
11163bfa90b6Smrg		      dst);
11173bfa90b6Smrg#else
11183bfa90b6Smrg    return pVid->play(pScrn, pVid, src_x, src_y, drw_x, drw_y, src_w, src_h,
11193bfa90b6Smrg                      drw_w, drw_h, format, buf, width, height, clipBoxes,
11203bfa90b6Smrg		      NULL);
11213bfa90b6Smrg#endif
11226df26cacSmrg}
11236df26cacSmrg
11246df26cacSmrg
11256df26cacSmrg/*
11266df26cacSmrg *-----------------------------------------------------------------------------
11276df26cacSmrg *
11286df26cacSmrg * vmwareStopVideo --
11296df26cacSmrg *
11306df26cacSmrg *    Called when we should stop playing video for a particular stream. If
11316df26cacSmrg *    Cleanup is FALSE, the "stop" operation is only temporary, and thus we
11326df26cacSmrg *    don't do anything. If Cleanup is TRUE we kill the video stream by
11336df26cacSmrg *    sending a message to the host and freeing up the stream.
11346df26cacSmrg *
11356df26cacSmrg * Results:
11366df26cacSmrg *    None.
11376df26cacSmrg *
11386df26cacSmrg * Side effects:
11396df26cacSmrg *    See above.
11406df26cacSmrg *
11416df26cacSmrg *-----------------------------------------------------------------------------
11426df26cacSmrg */
11436df26cacSmrg
114416fd1166Smrgstatic void
114516fd1166SmrgvmwareStopVideo(ScrnInfoPtr pScrn, pointer data, Bool Cleanup)
11466df26cacSmrg{
11476df26cacSmrg    VMWAREVideoPtr pVid = data;
11486df26cacSmrg    VMWAREPtr pVMWARE = VMWAREPTR(pScrn);
11496df26cacSmrg    TRACEPOINT
11506df26cacSmrg
11516df26cacSmrg    if (!vmwareVideoEnabled(pVMWARE)) {
11526df26cacSmrg        return;
11536df26cacSmrg    }
1154a241306cSmrg
1155a241306cSmrg    REGION_EMPTY(pScrn->pScreen, &pVid->clipBoxes);
1156a241306cSmrg
11576df26cacSmrg    if (!Cleanup) {
115816fd1166Smrg        VmwareLog(("vmwareStopVideo: Cleanup is FALSE.\n"));
11596df26cacSmrg        return;
11606df26cacSmrg    }
11616df26cacSmrg    vmwareVideoSetOneReg(pVMWARE, pVid->streamId,
11626df26cacSmrg                         SVGA_VIDEO_ENABLED, FALSE);
11636df26cacSmrg
11646df26cacSmrg    vmwareVideoFlush(pVMWARE, pVid->streamId);
11656df26cacSmrg    vmwareVideoEndStream(pScrn, pVid);
11666df26cacSmrg
11676df26cacSmrg}
11686df26cacSmrg
11696df26cacSmrg
11706df26cacSmrg/*
11716df26cacSmrg *-----------------------------------------------------------------------------
11726df26cacSmrg *
11736df26cacSmrg * vmwareQueryImageAttributes --
11746df26cacSmrg *
11756df26cacSmrg *    From the spec: This function is called to let the driver specify how data
11766df26cacSmrg *    for a particular image of size width by height should be stored.
11776df26cacSmrg *    Sometimes only the size and corrected width and height are needed. In
11786df26cacSmrg *    that case pitches and offsets are NULL.
11796df26cacSmrg *
11806df26cacSmrg * Results:
11816df26cacSmrg *    The size of the memory required for the image, or -1 on error.
11826df26cacSmrg *
11836df26cacSmrg * Side effects:
11846df26cacSmrg *    None.
11856df26cacSmrg *
11866df26cacSmrg *-----------------------------------------------------------------------------
11876df26cacSmrg */
11886df26cacSmrg
118916fd1166Smrgstatic int
119016fd1166SmrgvmwareQueryImageAttributes(ScrnInfoPtr pScrn, int format,
119116fd1166Smrg                           unsigned short *width, unsigned short *height,
119216fd1166Smrg                           int *pitches, int *offsets)
11936df26cacSmrg{
11946df26cacSmrg    INT32 size, tmp;
11956df26cacSmrg
11966df26cacSmrg    TRACEPOINT
11976df26cacSmrg
11986df26cacSmrg    if (*width > VMWARE_VID_MAX_WIDTH) {
11996df26cacSmrg        *width = VMWARE_VID_MAX_WIDTH;
12006df26cacSmrg    }
12016df26cacSmrg    if (*height > VMWARE_VID_MAX_HEIGHT) {
12026df26cacSmrg        *height = VMWARE_VID_MAX_HEIGHT;
12036df26cacSmrg    }
12046df26cacSmrg
12056df26cacSmrg    *width = (*width + 1) & ~1;
12066df26cacSmrg    if (offsets != NULL) {
12076df26cacSmrg        offsets[0] = 0;
12086df26cacSmrg    }
12096df26cacSmrg
12106df26cacSmrg    switch (format) {
12116df26cacSmrg       case FOURCC_YV12:
12126df26cacSmrg           *height = (*height + 1) & ~1;
12136df26cacSmrg           size = (*width + 3) & ~3;
12146df26cacSmrg           if (pitches) {
12156df26cacSmrg               pitches[0] = size;
12166df26cacSmrg           }
12176df26cacSmrg           size *= *height;
12186df26cacSmrg           if (offsets) {
12196df26cacSmrg               offsets[1] = size;
12206df26cacSmrg           }
12216df26cacSmrg           tmp = ((*width >> 1) + 3) & ~3;
12226df26cacSmrg           if (pitches) {
12236df26cacSmrg                pitches[1] = pitches[2] = tmp;
12246df26cacSmrg           }
12256df26cacSmrg           tmp *= (*height >> 1);
12266df26cacSmrg           size += tmp;
12276df26cacSmrg           if (offsets) {
12286df26cacSmrg               offsets[2] = size;
12296df26cacSmrg           }
12306df26cacSmrg           size += tmp;
12316df26cacSmrg           break;
123216fd1166Smrg       case FOURCC_UYVY:
12336df26cacSmrg       case FOURCC_YUY2:
12346df26cacSmrg           size = *width * 2;
12356df26cacSmrg           if (pitches) {
12366df26cacSmrg               pitches[0] = size;
12376df26cacSmrg           }
12386df26cacSmrg           size *= *height;
12396df26cacSmrg           break;
12406df26cacSmrg       default:
12416df26cacSmrg           VmwareLog(("Query for invalid video format %d\n", format));
12426df26cacSmrg           return -1;
12436df26cacSmrg    }
12446df26cacSmrg    return size;
12456df26cacSmrg}
12466df26cacSmrg
12476df26cacSmrg
12486df26cacSmrg/*
12496df26cacSmrg *-----------------------------------------------------------------------------
12506df26cacSmrg *
12516df26cacSmrg * vmwareSetPortAttribute --
12526df26cacSmrg *
12536df26cacSmrg *    From the spec: A port may have particular attributes such as colorKey, hue,
12546df26cacSmrg *    saturation, brightness or contrast. Xv clients set these
12556df26cacSmrg *    attribute values by sending attribute strings (Atoms) to the server.
12566df26cacSmrg *
12576df26cacSmrg * Results:
12586df26cacSmrg *    Success if the attribute exists and XvBadAlloc otherwise.
12596df26cacSmrg *
12606df26cacSmrg * Side effects:
12616df26cacSmrg *    The respective attribute gets the new value.
12626df26cacSmrg *
12636df26cacSmrg *-----------------------------------------------------------------------------
12646df26cacSmrg */
12656df26cacSmrg
126616fd1166Smrgstatic int
126716fd1166SmrgvmwareSetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
126816fd1166Smrg                       INT32 value, pointer data)
12696df26cacSmrg{
12706df26cacSmrg    VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
12716df26cacSmrg    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
127216fd1166Smrg    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
12736df26cacSmrg
12746df26cacSmrg    if (attribute == xvColorKey) {
127516fd1166Smrg        VmwareLog(("Set colorkey:0x%x\n", value));
12766df26cacSmrg        pVid->colorKey = value;
127716fd1166Smrg    } else if (attribute == xvAutoPaint) {
127816fd1166Smrg        VmwareLog(("Set autoPaint: %s\n", value? "TRUE": "FALSE"));
127916fd1166Smrg        pVid->isAutoPaintColorkey = value;
12806df26cacSmrg    } else {
12816df26cacSmrg        return XvBadAlloc;
12826df26cacSmrg    }
128316fd1166Smrg
12846df26cacSmrg    return Success;
12856df26cacSmrg}
12866df26cacSmrg
12876df26cacSmrg
12886df26cacSmrg/*
12896df26cacSmrg *-----------------------------------------------------------------------------
12906df26cacSmrg *
12916df26cacSmrg * vmwareGetPortAttribute --
12926df26cacSmrg *
12936df26cacSmrg *    From the spec: A port may have particular attributes such as hue,
12946df26cacSmrg *    saturation, brightness or contrast. Xv clients get these
12956df26cacSmrg *    attribute values by sending attribute strings (Atoms) to the server
12966df26cacSmrg *
12976df26cacSmrg * Results:
12986df26cacSmrg *    Success if the attribute exists and XvBadAlloc otherwise.
12996df26cacSmrg *
13006df26cacSmrg * Side effects:
13016df26cacSmrg *    "value" contains the requested attribute on success.
13026df26cacSmrg *
13036df26cacSmrg *-----------------------------------------------------------------------------
13046df26cacSmrg */
13056df26cacSmrg
130616fd1166Smrgstatic int
130716fd1166SmrgvmwareGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute,
130816fd1166Smrg                       INT32 *value, pointer data)
13096df26cacSmrg{
13106df26cacSmrg    VMWAREVideoPtr pVid = (VMWAREVideoPtr) data;
13116df26cacSmrg    Atom xvColorKey = MAKE_ATOM("XV_COLORKEY");
131216fd1166Smrg    Atom xvAutoPaint = MAKE_ATOM("XV_AUTOPAINT_COLORKEY");
13136df26cacSmrg
13146df26cacSmrg    if (attribute == xvColorKey) {
13156df26cacSmrg        *value = pVid->colorKey;
131616fd1166Smrg    } else if (attribute == xvAutoPaint) {
131716fd1166Smrg        *value = pVid->isAutoPaintColorkey;
13186df26cacSmrg    } else {
13196df26cacSmrg        return XvBadAlloc;
13206df26cacSmrg    }
132116fd1166Smrg
13226df26cacSmrg    return Success;
13236df26cacSmrg}
13246df26cacSmrg
13256df26cacSmrg
13266df26cacSmrg/*
13276df26cacSmrg *-----------------------------------------------------------------------------
13286df26cacSmrg *
13296df26cacSmrg * vmwareQueryBestSize --
13306df26cacSmrg *
13316df26cacSmrg *    From the spec: QueryBestSize provides the client with a way to query what
13326df26cacSmrg *    the destination dimensions would end up being if they were to request
13336df26cacSmrg *    that an area vid_w by vid_h from the video stream be scaled to rectangle
13346df26cacSmrg *    of drw_w by drw_h on the screen. Since it is not expected that all
13356df26cacSmrg *    hardware will be able to get the target dimensions exactly, it is
13366df26cacSmrg *    important that the driver provide this function.
13376df26cacSmrg *
13386df26cacSmrg *    This function seems to never be called, but to be on the safe side
13396df26cacSmrg *    we apply the same logic that QueryImageAttributes has for width
13406df26cacSmrg *    and height
13416df26cacSmrg *
13426df26cacSmrg * Results:
13436df26cacSmrg *    None.
13446df26cacSmrg *
13456df26cacSmrg * Side effects:
13466df26cacSmrg *    None
13476df26cacSmrg *
13486df26cacSmrg *-----------------------------------------------------------------------------
13496df26cacSmrg */
13506df26cacSmrg
135116fd1166Smrgstatic void
135216fd1166SmrgvmwareQueryBestSize(ScrnInfoPtr pScrn, Bool motion,
135316fd1166Smrg                    short vid_w, short vid_h, short drw_w,
135416fd1166Smrg                    short drw_h, unsigned int *p_w,
135516fd1166Smrg                    unsigned int *p_h, pointer data)
13566df26cacSmrg{
13576df26cacSmrg    *p_w = (drw_w + 1) & ~1;
13586df26cacSmrg    *p_h = drw_h;
13596df26cacSmrg
13606df26cacSmrg    return;
13616df26cacSmrg}
13626df26cacSmrg
1363