171d7fec4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nsc/nsc_gx1_video.c,v 1.7tsi Exp $ */
271d7fec4Smrg/*
371d7fec4Smrg * $Workfile: nsc_gx1_video.c $
471d7fec4Smrg * $Revision: 1.1.1.1 $
571d7fec4Smrg * $Author: mrg $
671d7fec4Smrg *
771d7fec4Smrg * File Contents: This file consists of main Xfree video supported routines.
871d7fec4Smrg *
971d7fec4Smrg * Project:       Geode Xfree Frame buffer device driver.
1071d7fec4Smrg *
1171d7fec4Smrg */
1271d7fec4Smrg
1371d7fec4Smrg/*
1471d7fec4Smrg * NSC_LIC_ALTERNATIVE_PREAMBLE
1571d7fec4Smrg *
1671d7fec4Smrg * Revision 1.0
1771d7fec4Smrg *
1871d7fec4Smrg * National Semiconductor Alternative GPL-BSD License
1971d7fec4Smrg *
2071d7fec4Smrg * National Semiconductor Corporation licenses this software
2171d7fec4Smrg * ("Software"):
2271d7fec4Smrg *
2371d7fec4Smrg * National Xfree frame buffer driver
2471d7fec4Smrg *
2571d7fec4Smrg * under one of the two following licenses, depending on how the
2671d7fec4Smrg * Software is received by the Licensee.
2771d7fec4Smrg *
2871d7fec4Smrg * If this Software is received as part of the Linux Framebuffer or
2971d7fec4Smrg * other GPL licensed software, then the GPL license designated
3071d7fec4Smrg * NSC_LIC_GPL applies to this Software; in all other circumstances
3171d7fec4Smrg * then the BSD-style license designated NSC_LIC_BSD shall apply.
3271d7fec4Smrg *
3371d7fec4Smrg * END_NSC_LIC_ALTERNATIVE_PREAMBLE */
3471d7fec4Smrg
3571d7fec4Smrg/* NSC_LIC_BSD
3671d7fec4Smrg *
3771d7fec4Smrg * National Semiconductor Corporation Open Source License for
3871d7fec4Smrg *
3971d7fec4Smrg * National Xfree frame buffer driver
4071d7fec4Smrg *
4171d7fec4Smrg * (BSD License with Export Notice)
4271d7fec4Smrg *
4371d7fec4Smrg * Copyright (c) 1999-2001
4471d7fec4Smrg * National Semiconductor Corporation.
4571d7fec4Smrg * All rights reserved.
4671d7fec4Smrg *
4771d7fec4Smrg * Redistribution and use in source and binary forms, with or without
4871d7fec4Smrg * modification, are permitted provided that the following conditions
4971d7fec4Smrg * are met:
5071d7fec4Smrg *
5171d7fec4Smrg *   * Redistributions of source code must retain the above copyright
5271d7fec4Smrg *     notice, this list of conditions and the following disclaimer.
5371d7fec4Smrg *
5471d7fec4Smrg *   * Redistributions in binary form must reproduce the above
5571d7fec4Smrg *     copyright notice, this list of conditions and the following
5671d7fec4Smrg *     disclaimer in the documentation and/or other materials provided
5771d7fec4Smrg *     with the distribution.
5871d7fec4Smrg *
5971d7fec4Smrg *   * Neither the name of the National Semiconductor Corporation nor
6071d7fec4Smrg *     the names of its contributors may be used to endorse or promote
6171d7fec4Smrg *     products derived from this software without specific prior
6271d7fec4Smrg *     written permission.
6371d7fec4Smrg *
6471d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6571d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6671d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
6771d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6871d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
6971d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7071d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
7171d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
7271d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
7371d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
7471d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
7571d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
7671d7fec4Smrg * OF SUCH DAMAGE.
7771d7fec4Smrg *
7871d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
7971d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with
8071d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under
8171d7fec4Smrg * CURRENT (2001) U.S. export regulations this software
8271d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or
8371d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
8471d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
8571d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S.
8671d7fec4Smrg * has embargoed goods and services.
8771d7fec4Smrg *
8871d7fec4Smrg * END_NSC_LIC_BSD */
8971d7fec4Smrg
9071d7fec4Smrg/* NSC_LIC_GPL
9171d7fec4Smrg *
9271d7fec4Smrg * National Semiconductor Corporation Gnu General Public License for
9371d7fec4Smrg *
9471d7fec4Smrg * National Xfree frame buffer driver
9571d7fec4Smrg *
9671d7fec4Smrg * (GPL License with Export Notice)
9771d7fec4Smrg *
9871d7fec4Smrg * Copyright (c) 1999-2001
9971d7fec4Smrg * National Semiconductor Corporation.
10071d7fec4Smrg * All rights reserved.
10171d7fec4Smrg *
10271d7fec4Smrg * Redistribution and use in source and binary forms, with or without
10371d7fec4Smrg * modification, are permitted under the terms of the GNU General
10471d7fec4Smrg * Public License as published by the Free Software Foundation; either
10571d7fec4Smrg * version 2 of the License, or (at your option) any later version
10671d7fec4Smrg *
10771d7fec4Smrg * In addition to the terms of the GNU General Public License, neither
10871d7fec4Smrg * the name of the National Semiconductor Corporation nor the names of
10971d7fec4Smrg * its contributors may be used to endorse or promote products derived
11071d7fec4Smrg * from this software without specific prior written permission.
11171d7fec4Smrg *
11271d7fec4Smrg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
11371d7fec4Smrg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11471d7fec4Smrg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11571d7fec4Smrg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
11671d7fec4Smrg * NATIONAL SEMICONDUCTOR CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY
11771d7fec4Smrg * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11871d7fec4Smrg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
11971d7fec4Smrg * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
12071d7fec4Smrg * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
12171d7fec4Smrg * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE,
12271d7fec4Smrg * INTELLECTUAL PROPERTY INFRINGEMENT, OR OTHERWISE) ARISING IN ANY WAY
12371d7fec4Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
12471d7fec4Smrg * OF SUCH DAMAGE. See the GNU General Public License for more details.
12571d7fec4Smrg *
12671d7fec4Smrg * EXPORT LAWS: THIS LICENSE ADDS NO RESTRICTIONS TO THE EXPORT LAWS OF
12771d7fec4Smrg * YOUR JURISDICTION. It is licensee's responsibility to comply with
12871d7fec4Smrg * any export regulations applicable in licensee's jurisdiction. Under
12971d7fec4Smrg * CURRENT (2001) U.S. export regulations this software
13071d7fec4Smrg * is eligible for export from the U.S. and can be downloaded by or
13171d7fec4Smrg * otherwise exported or reexported worldwide EXCEPT to U.S. embargoed
13271d7fec4Smrg * destinations which include Cuba, Iraq, Libya, North Korea, Iran,
13371d7fec4Smrg * Syria, Sudan, Afghanistan and any other country to which the U.S.
13471d7fec4Smrg * has embargoed goods and services.
13571d7fec4Smrg *
13671d7fec4Smrg * You should have received a copy of the GNU General Public License
13771d7fec4Smrg * along with this file; if not, write to the Free Software Foundation,
13871d7fec4Smrg * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13971d7fec4Smrg *
14071d7fec4Smrg * END_NSC_LIC_GPL */
14171d7fec4Smrg
14271d7fec4Smrg/*
14371d7fec4Smrg * Fixes & Extensions to support Y800 greyscale modes
14471d7fec4Smrg * Alan Hourihane <alanh@fairlite.demon.co.uk>
14571d7fec4Smrg */
14671d7fec4Smrg
14771d7fec4Smrg#ifdef HAVE_CONFIG_H
14871d7fec4Smrg#include "config.h"
14971d7fec4Smrg#endif
15071d7fec4Smrg
15171d7fec4Smrg#include "xf86.h"
15271d7fec4Smrg#include "xf86_OSproc.h"
15371d7fec4Smrg#include "xf86Resources.h"
15471d7fec4Smrg#include "compiler.h"
15571d7fec4Smrg#include "xf86PciInfo.h"
15671d7fec4Smrg#include "xf86Pci.h"
15771d7fec4Smrg#include "xf86fbman.h"
15871d7fec4Smrg#include "regionstr.h"
15971d7fec4Smrg
16071d7fec4Smrg#include "nsc.h"
16171d7fec4Smrg#include <X11/extensions/Xv.h>
16271d7fec4Smrg#include "xaa.h"
16371d7fec4Smrg#include "xaalocal.h"
16471d7fec4Smrg#include "dixstruct.h"
16571d7fec4Smrg#include "fourcc.h"
16671d7fec4Smrg#include "nsc_fourcc.h"
16771d7fec4Smrg
16871d7fec4Smrg#define OFF_DELAY 	200		/* milliseconds */
16971d7fec4Smrg#define FREE_DELAY 	60000
17071d7fec4Smrg
17171d7fec4Smrg#define OFF_TIMER 	0x01
17271d7fec4Smrg#define FREE_TIMER	0x02
17371d7fec4Smrg#define CLIENT_VIDEO_ON	0x04
17471d7fec4Smrg
17571d7fec4Smrg#define TIMER_MASK      (OFF_TIMER | FREE_TIMER)
17671d7fec4Smrg#define XV_PROFILE 0
17771d7fec4Smrg#define REINIT  1
17871d7fec4Smrg
17971d7fec4Smrgvoid GX1InitVideo(ScreenPtr pScreen);
18071d7fec4Smrgvoid GX1ResetVideo(ScrnInfoPtr pScrn);
18171d7fec4Smrg
18271d7fec4Smrg#define DBUF 0
18371d7fec4Smrg
18471d7fec4Smrgstatic XF86VideoAdaptorPtr GX1SetupImageVideo(ScreenPtr);
18571d7fec4Smrgstatic void GX1InitOffscreenImages(ScreenPtr);
18671d7fec4Smrgstatic void GX1StopVideo(ScrnInfoPtr, pointer, Bool);
18771d7fec4Smrgstatic int GX1SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer);
18871d7fec4Smrgstatic int GX1GetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer);
18971d7fec4Smrgstatic void GX1QueryBestSize(ScrnInfoPtr, Bool,
19071d7fec4Smrg			     short, short, short, short, unsigned int *,
19171d7fec4Smrg			     unsigned int *, pointer);
19271d7fec4Smrgstatic int GX1PutImage(ScrnInfoPtr,
19371d7fec4Smrg		       short, short, short, short, short, short,
19471d7fec4Smrg		       short, short, int, unsigned char *, short, short,
19571d7fec4Smrg		       Bool, RegionPtr, pointer, DrawablePtr);
19671d7fec4Smrgstatic int GX1QueryImageAttributes(ScrnInfoPtr,
19771d7fec4Smrg				   int, unsigned short *, unsigned short *,
19871d7fec4Smrg				   int *, int *);
19971d7fec4Smrg
20071d7fec4Smrgstatic void GX1BlockHandler(int, pointer, pointer, pointer);
20171d7fec4Smrg
20271d7fec4Smrgvoid GX1SetVideoPosition(int, int, int, int,
20371d7fec4Smrg			 short, short, short, short, int, int, ScrnInfoPtr);
20471d7fec4Smrg
20571d7fec4Smrgextern void GX1AccelSync(ScrnInfoPtr pScreenInfo);
20671d7fec4Smrg
20771d7fec4Smrg#if !defined(STB_X)
20871d7fec4Smrgextern int DeltaX, DeltaY;
20971d7fec4Smrg#else
21071d7fec4Smrgint DeltaX, DeltaY;
21171d7fec4Smrg#endif
21271d7fec4Smrg
21371d7fec4Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
21471d7fec4Smrg
21571d7fec4Smrgstatic Atom xvColorKey, xvColorKeyMode, xvFilter
21671d7fec4Smrg#if DBUF
21771d7fec4Smrg  , xvDoubleBuffer
21871d7fec4Smrg#endif
21971d7fec4Smrg  ;
22071d7fec4Smrg
22171d7fec4Smrg/*----------------------------------------------------------------------------
22271d7fec4Smrg * GX1InitVideo
22371d7fec4Smrg *
22471d7fec4Smrg * Description	:This is the initialization routine.It creates a new video adapter
22571d7fec4Smrg *				 and calls GX1SetupImageVideo to initialize the adaptor by filling
22671d7fec4Smrg *				 XF86VideoAdaptorREc.Then it lists the existing adaptors and adds the
22771d7fec4Smrg *				 new one to it. Finally the list of XF86VideoAdaptorPtr pointers are
22871d7fec4Smrg *				 passed to the xf86XVScreenInit().
22971d7fec4Smrg *
23071d7fec4Smrg * Parameters.
23171d7fec4Smrg * ScreenPtr
23271d7fec4Smrg *		pScreen	:Screen handler pointer having screen information.
23371d7fec4Smrg *
23471d7fec4Smrg * Returns		:none
23571d7fec4Smrg *
23671d7fec4Smrg * Comments		:none
23771d7fec4Smrg *
23871d7fec4Smrg*----------------------------------------------------------------------------
23971d7fec4Smrg*/
24071d7fec4Smrgvoid
24171d7fec4SmrgGX1InitVideo(ScreenPtr pScreen)
24271d7fec4Smrg{
24371d7fec4Smrg   GeodePtr pGeode;
24471d7fec4Smrg
24571d7fec4Smrg   ScrnInfoPtr pScreenInfo = xf86Screens[pScreen->myNum];
24671d7fec4Smrg    XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL;
24771d7fec4Smrg   XF86VideoAdaptorPtr newAdaptor = NULL;
24871d7fec4Smrg
24971d7fec4Smrg   int num_adaptors;
25071d7fec4Smrg
25171d7fec4Smrg   pGeode = GEODEPTR(pScreenInfo);
25271d7fec4Smrg
25371d7fec4Smrg
25471d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "InitVideo\n"));
25571d7fec4Smrg   newAdaptor = GX1SetupImageVideo(pScreen);
25671d7fec4Smrg   GX1InitOffscreenImages(pScreen);
25771d7fec4Smrg
25871d7fec4Smrg   num_adaptors = xf86XVListGenericAdaptors(pScreenInfo, &adaptors);
25971d7fec4Smrg
26071d7fec4Smrg   if (newAdaptor) {
26171d7fec4Smrg       if (!num_adaptors) {
26271d7fec4Smrg	   num_adaptors = 1;
26371d7fec4Smrg	   adaptors = &newAdaptor;
26471d7fec4Smrg       } else {
26571d7fec4Smrg	   newAdaptors =		/* need to free this someplace */
26671d7fec4Smrg	       xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
26771d7fec4Smrg	   if (newAdaptors) {
26871d7fec4Smrg	       memcpy(newAdaptors, adaptors, num_adaptors *
26971d7fec4Smrg		      sizeof(XF86VideoAdaptorPtr));
27071d7fec4Smrg	       newAdaptors[num_adaptors] = newAdaptor;
27171d7fec4Smrg	       adaptors = newAdaptors;
27271d7fec4Smrg	       num_adaptors++;
27371d7fec4Smrg	   }
27471d7fec4Smrg       }
27571d7fec4Smrg   }
27671d7fec4Smrg
27771d7fec4Smrg   if (num_adaptors)
27871d7fec4Smrg       xf86XVScreenInit(pScreen, adaptors, num_adaptors);
27971d7fec4Smrg
28071d7fec4Smrg   if (newAdaptors)
28171d7fec4Smrg       xfree(newAdaptors);
28271d7fec4Smrg}
28371d7fec4Smrg
28471d7fec4Smrg/* client libraries expect an encoding */
28571d7fec4Smrgstatic XF86VideoEncodingRec DummyEncoding[1] = {
28671d7fec4Smrg   {
28771d7fec4Smrg    0,
28871d7fec4Smrg    "XV_IMAGE",
28971d7fec4Smrg    1024, 1024,
29071d7fec4Smrg    {1, 1}
29171d7fec4Smrg    }
29271d7fec4Smrg};
29371d7fec4Smrg
29471d7fec4Smrg#define NUM_FORMATS 4
29571d7fec4Smrg
29671d7fec4Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = {
29771d7fec4Smrg   {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
29871d7fec4Smrg};
29971d7fec4Smrg
30071d7fec4Smrg#if DBUF
30171d7fec4Smrg#define NUM_ATTRIBUTES 4
30271d7fec4Smrg#else
30371d7fec4Smrg#define NUM_ATTRIBUTES 3
30471d7fec4Smrg#endif
30571d7fec4Smrg
30671d7fec4Smrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = {
30771d7fec4Smrg#if DBUF
30871d7fec4Smrg   {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"},
30971d7fec4Smrg#endif
31071d7fec4Smrg   {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
31171d7fec4Smrg   {XvSettable | XvGettable, 0, 1, "XV_FILTER"},
31271d7fec4Smrg   {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"}
31371d7fec4Smrg};
31471d7fec4Smrg
31571d7fec4Smrg#define NUM_IMAGES 7
31671d7fec4Smrg
31771d7fec4Smrgstatic XF86ImageRec Images[NUM_IMAGES] = {
31871d7fec4Smrg   XVIMAGE_UYVY,
31971d7fec4Smrg   XVIMAGE_YUY2,
32071d7fec4Smrg   XVIMAGE_Y2YU,
32171d7fec4Smrg   XVIMAGE_YVYU,
32271d7fec4Smrg   XVIMAGE_Y800,
32371d7fec4Smrg   XVIMAGE_I420,
32471d7fec4Smrg   XVIMAGE_YV12
32571d7fec4Smrg};
32671d7fec4Smrg
32771d7fec4Smrgtypedef struct
32871d7fec4Smrg{
32971d7fec4Smrg   FBAreaPtr area;
33071d7fec4Smrg   FBLinearPtr linear;
33171d7fec4Smrg   RegionRec clip;
33271d7fec4Smrg   CARD32 colorKey;
33371d7fec4Smrg   CARD32 colorKeyMode;
33471d7fec4Smrg   CARD32 filter;
33571d7fec4Smrg   CARD32 videoStatus;
33671d7fec4Smrg   Time offTime;
33771d7fec4Smrg   Time freeTime;
33871d7fec4Smrg#if DBUF
33971d7fec4Smrg   Bool doubleBuffer;
34071d7fec4Smrg   int currentBuffer;
34171d7fec4Smrg#endif
34271d7fec4Smrg}
34371d7fec4SmrgGeodePortPrivRec, *GeodePortPrivPtr;
34471d7fec4Smrg
34571d7fec4Smrg#define GET_PORT_PRIVATE(pScrn) \
34671d7fec4Smrg	(GeodePortPrivPtr)((GEODEPTR(pScrn))->adaptor->pPortPrivates[0].ptr)
34771d7fec4Smrg
34871d7fec4Smrg/*----------------------------------------------------------------------------
34971d7fec4Smrg * GX1SetColorKey
35071d7fec4Smrg *
35171d7fec4Smrg * Description	:This function reads the color key for the pallete and
35271d7fec4Smrg *				  sets the video color key register.
35371d7fec4Smrg *
35471d7fec4Smrg * Parameters.
35571d7fec4Smrg * ScreenInfoPtr
35671d7fec4Smrg *		pScrn	:Screen  pointer having screen information.
35771d7fec4Smrg *		pPriv	:Video port private data
35871d7fec4Smrg *
35971d7fec4Smrg * Returns		:none
36071d7fec4Smrg *
36171d7fec4Smrg * Comments		:none
36271d7fec4Smrg *
36371d7fec4Smrg*----------------------------------------------------------------------------
36471d7fec4Smrg*/
36571d7fec4Smrgstatic INT32
36671d7fec4SmrgGX1SetColorkey(ScrnInfoPtr pScrn, GeodePortPrivPtr pPriv)
36771d7fec4Smrg{
36871d7fec4Smrg   int red, green, blue;
36971d7fec4Smrg   unsigned long key;
37071d7fec4Smrg
37171d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "ColorKey\n"));
37271d7fec4Smrg   switch (pScrn->depth) {
37371d7fec4Smrg   case 8:
37471d7fec4Smrg      GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key));
37571d7fec4Smrg      red = ((key >> 16) & 0xFF);
37671d7fec4Smrg      green = ((key >> 8) & 0xFF);
37771d7fec4Smrg      blue = (key & 0xFF);
37871d7fec4Smrg      break;
37971d7fec4Smrg   default:
38071d7fec4Smrg      red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red << (8 -
38171d7fec4Smrg									 pScrn->
38271d7fec4Smrg									 weight.
38371d7fec4Smrg									 red);
38471d7fec4Smrg      green =
38571d7fec4Smrg	    (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.
38671d7fec4Smrg	    green << (8 - pScrn->weight.green);
38771d7fec4Smrg      blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.
38871d7fec4Smrg	    blue << (8 - pScrn->weight.blue);
38971d7fec4Smrg      break;
39071d7fec4Smrg   }
39171d7fec4Smrg   GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFCFCFC,
39271d7fec4Smrg			   (pPriv->colorKeyMode == 0)));
39371d7fec4Smrg   REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
39471d7fec4Smrg   return 0;
39571d7fec4Smrg}
39671d7fec4Smrg
39771d7fec4Smrg/*----------------------------------------------------------------------------
39871d7fec4Smrg * GX1ResetVideo
39971d7fec4Smrg *
40071d7fec4Smrg * Description	: This function resets the video
40171d7fec4Smrg *
40271d7fec4Smrg * Parameters.
40371d7fec4Smrg * ScreenInfoPtr
40471d7fec4Smrg *		pScrn	:Screen  pointer having screen information.
40571d7fec4Smrg *
40671d7fec4Smrg * Returns		:None
40771d7fec4Smrg *
40871d7fec4Smrg * Comments		:none
40971d7fec4Smrg *
41071d7fec4Smrg*----------------------------------------------------------------------------
41171d7fec4Smrg*/
41271d7fec4Smrg
41371d7fec4Smrgvoid
41471d7fec4SmrgGX1ResetVideo(ScrnInfoPtr pScrn)
41571d7fec4Smrg{
41671d7fec4Smrg    GeodePtr pGeode = GEODEPTR(pScrn);
41771d7fec4Smrg
41871d7fec4Smrg    GeodePortPrivPtr pPriv = pGeode->adaptor->pPortPrivates[0].ptr;
41971d7fec4Smrg
42071d7fec4Smrg    DEBUGMSG(0, (0, X_NONE, "ResetVideo\n"));
42171d7fec4Smrg    if (!pGeode->NoAccel) GX1AccelSync(pScrn);
42271d7fec4Smrg    GFX(set_video_palette(NULL));
42371d7fec4Smrg    GX1SetColorkey(pScrn, pPriv);
42471d7fec4Smrg    GFX(set_video_filter(pPriv->filter, pPriv->filter));
42571d7fec4Smrg}
42671d7fec4Smrg
42771d7fec4Smrg/*----------------------------------------------------------------------------
42871d7fec4Smrg * GX1SetupImageVideo
42971d7fec4Smrg *
43071d7fec4Smrg * Description	: This function allocates space for a Videoadaptor and initializes
43171d7fec4Smrg *				  the XF86VideoAdaptorPtr record.
43271d7fec4Smrg *
43371d7fec4Smrg * Parameters.
43471d7fec4Smrg * ScreenPtr
43571d7fec4Smrg *		pScreen	:Screen handler pointer having screen information.
43671d7fec4Smrg *
43771d7fec4Smrg * Returns		:XF86VideoAdaptorPtr :- pointer to the initialized video adaptor record.
43871d7fec4Smrg *
43971d7fec4Smrg * Comments		:none
44071d7fec4Smrg *
44171d7fec4Smrg*----------------------------------------------------------------------------
44271d7fec4Smrg*/
44371d7fec4Smrg
44471d7fec4Smrgstatic XF86VideoAdaptorPtr
44571d7fec4SmrgGX1SetupImageVideo(ScreenPtr pScreen)
44671d7fec4Smrg{
44771d7fec4Smrg   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
44871d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
44971d7fec4Smrg   XF86VideoAdaptorPtr adapt;
45071d7fec4Smrg   GeodePortPrivPtr pPriv;
45171d7fec4Smrg
45271d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "SetupImageVideo\n"));
45371d7fec4Smrg   if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) +
45471d7fec4Smrg			 sizeof(GeodePortPrivRec) + sizeof(DevUnion))))
45571d7fec4Smrg      return NULL;
45671d7fec4Smrg
45771d7fec4Smrg   adapt->type = XvWindowMask | XvInputMask | XvImageMask;
45871d7fec4Smrg   adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
45971d7fec4Smrg   adapt->name = "National Semiconductor Corporation";
46071d7fec4Smrg   adapt->nEncodings = 1;
46171d7fec4Smrg   adapt->pEncodings = DummyEncoding;
46271d7fec4Smrg   adapt->nFormats = NUM_FORMATS;
46371d7fec4Smrg   adapt->pFormats = Formats;
46471d7fec4Smrg   adapt->nPorts = 1;
46571d7fec4Smrg   adapt->pPortPrivates = (DevUnion *) (&adapt[1]);
46671d7fec4Smrg   pPriv = (GeodePortPrivPtr) (&adapt->pPortPrivates[1]);
46771d7fec4Smrg   adapt->pPortPrivates[0].ptr = (pointer) (pPriv);
46871d7fec4Smrg   adapt->pAttributes = Attributes;
46971d7fec4Smrg   adapt->nImages = NUM_IMAGES;
47071d7fec4Smrg   adapt->nAttributes = NUM_ATTRIBUTES;
47171d7fec4Smrg   adapt->pImages = Images;
47271d7fec4Smrg   adapt->PutVideo = NULL;
47371d7fec4Smrg   adapt->PutStill = NULL;
47471d7fec4Smrg   adapt->GetVideo = NULL;
47571d7fec4Smrg   adapt->GetStill = NULL;
47671d7fec4Smrg   adapt->StopVideo = GX1StopVideo;
47771d7fec4Smrg   adapt->SetPortAttribute = GX1SetPortAttribute;
47871d7fec4Smrg   adapt->GetPortAttribute = GX1GetPortAttribute;
47971d7fec4Smrg   adapt->QueryBestSize = GX1QueryBestSize;
48071d7fec4Smrg   adapt->PutImage = GX1PutImage;
48171d7fec4Smrg   adapt->QueryImageAttributes = GX1QueryImageAttributes;
48271d7fec4Smrg
48371d7fec4Smrg   pPriv->colorKey = pGeode->videoKey;
48471d7fec4Smrg   pPriv->colorKeyMode = 0;
48571d7fec4Smrg   pPriv->filter = 0;
48671d7fec4Smrg   pPriv->videoStatus = 0;
48771d7fec4Smrg#if DBUF
48871d7fec4Smrg   pPriv->doubleBuffer = TRUE;
48971d7fec4Smrg   pPriv->currentBuffer = 0;		/* init to first buffer */
49071d7fec4Smrg#endif
49171d7fec4Smrg
49271d7fec4Smrg   /* gotta uninit this someplace */
49371d7fec4Smrg   REGION_NULL(pScreen, &pPriv->clip);
49471d7fec4Smrg
49571d7fec4Smrg   pGeode->adaptor = adapt;
49671d7fec4Smrg
49771d7fec4Smrg   pGeode->BlockHandler = pScreen->BlockHandler;
49871d7fec4Smrg   pScreen->BlockHandler = GX1BlockHandler;
49971d7fec4Smrg
50071d7fec4Smrg   xvColorKey = MAKE_ATOM("XV_COLORKEY");
50171d7fec4Smrg   xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE");
50271d7fec4Smrg   xvFilter = MAKE_ATOM("XV_FILTER");
50371d7fec4Smrg#if DBUF
50471d7fec4Smrg   xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER");
50571d7fec4Smrg#endif
50671d7fec4Smrg
50771d7fec4Smrg   GX1ResetVideo(pScrn);
50871d7fec4Smrg
50971d7fec4Smrg   return adapt;
51071d7fec4Smrg}
51171d7fec4Smrg
51271d7fec4Smrg/*----------------------------------------------------------------------------
51371d7fec4Smrg * GX1StopVideo
51471d7fec4Smrg *
51571d7fec4Smrg * Description	:This function is used to stop input and output video
51671d7fec4Smrg *
51771d7fec4Smrg * Parameters.
51871d7fec4Smrg * pScreenInfo
51971d7fec4Smrg *		pScrn		:Screen handler pointer having screen information.
52071d7fec4Smrg *		data		:Pointer to the video port's private data
52171d7fec4Smrg *		exit		:Flag indicating whether the offscreen areas used for video
52271d7fec4Smrg *					 to be deallocated or not.
52371d7fec4Smrg * Returns		:none
52471d7fec4Smrg *
52571d7fec4Smrg * Comments		:none
52671d7fec4Smrg *
52771d7fec4Smrg*----------------------------------------------------------------------------
52871d7fec4Smrg*/
52971d7fec4Smrgstatic void
53071d7fec4SmrgGX1StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit)
53171d7fec4Smrg{
53271d7fec4Smrg   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
53371d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
53471d7fec4Smrg
53571d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "StopVideo\n"));
53671d7fec4Smrg   REGION_EMPTY(pScrn->pScreen, &pPriv->clip);
53771d7fec4Smrg
53871d7fec4Smrg   if (!pGeode->NoAccel) GX1AccelSync(pScrn);
53971d7fec4Smrg   if (exit) {
54071d7fec4Smrg      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
54171d7fec4Smrg	 GFX(set_video_enable(0));
54271d7fec4Smrg      }
54371d7fec4Smrg      if (pPriv->area) {
54471d7fec4Smrg	 xf86FreeOffscreenArea(pPriv->area);
54571d7fec4Smrg	 pPriv->area = NULL;
54671d7fec4Smrg      }
54771d7fec4Smrg      pPriv->videoStatus = 0;
54871d7fec4Smrg      pGeode->OverlayON = FALSE;
54971d7fec4Smrg   } else {
55071d7fec4Smrg      if (pPriv->videoStatus & CLIENT_VIDEO_ON) {
55171d7fec4Smrg	 pPriv->videoStatus |= OFF_TIMER;
55271d7fec4Smrg	 pPriv->offTime = currentTime.milliseconds + OFF_DELAY;
55371d7fec4Smrg      }
55471d7fec4Smrg   }
55571d7fec4Smrg}
55671d7fec4Smrg
55771d7fec4Smrg/*----------------------------------------------------------------------------
55871d7fec4Smrg * GX1SetPortAttribute
55971d7fec4Smrg *
56071d7fec4Smrg * Description	:This function is used to set the attributes of a port like colorkeymode,
56171d7fec4Smrg *				  double buffer support and filter.
56271d7fec4Smrg *
56371d7fec4Smrg * Parameters.
56471d7fec4Smrg * pScreenInfo
56571d7fec4Smrg *		Ptr			:Screen handler pointer having screen information.
56671d7fec4Smrg *		data		:Pointer to the video port's private data
56771d7fec4Smrg *		attribute	:The port attribute to be set
56871d7fec4Smrg *		value		:Value of the attribute to be set.
56971d7fec4Smrg *
57071d7fec4Smrg * Returns		:Sucess if the attribute is supported, else BadMatch
57171d7fec4Smrg *
57271d7fec4Smrg * Comments		:none
57371d7fec4Smrg *
57471d7fec4Smrg*----------------------------------------------------------------------------
57571d7fec4Smrg*/
57671d7fec4Smrgstatic int
57771d7fec4SmrgGX1SetPortAttribute(ScrnInfoPtr pScrn,
57871d7fec4Smrg		    Atom attribute, INT32 value, pointer data)
57971d7fec4Smrg{
58071d7fec4Smrg   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
58171d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
58271d7fec4Smrg
58371d7fec4Smrg   if (!pGeode->NoAccel) GX1AccelSync(pScrn);
58471d7fec4Smrg   if (attribute == xvColorKey) {
58571d7fec4Smrg      pPriv->colorKey = value;
58671d7fec4Smrg      GX1SetColorkey(pScrn, pPriv);
58771d7fec4Smrg   }
58871d7fec4Smrg#if DBUF
58971d7fec4Smrg   else if (attribute == xvDoubleBuffer) {
59071d7fec4Smrg      if ((value < 0) || (value > 1))
59171d7fec4Smrg	 return BadValue;
59271d7fec4Smrg      pPriv->doubleBuffer = value;
59371d7fec4Smrg   }
59471d7fec4Smrg#endif
59571d7fec4Smrg   else if (attribute == xvColorKeyMode) {
59671d7fec4Smrg      pPriv->colorKeyMode = value;
59771d7fec4Smrg      GX1SetColorkey(pScrn, pPriv);
59871d7fec4Smrg   } else if (attribute == xvFilter) {
59971d7fec4Smrg      pPriv->filter = value;
60071d7fec4Smrg      GFX(set_video_filter(pPriv->filter, pPriv->filter));
60171d7fec4Smrg   } else
60271d7fec4Smrg      return BadMatch;
60371d7fec4Smrg
60471d7fec4Smrg   return Success;
60571d7fec4Smrg}
60671d7fec4Smrg
60771d7fec4Smrg/*----------------------------------------------------------------------------
60871d7fec4Smrg * GX1GetPortAttribute
60971d7fec4Smrg *
61071d7fec4Smrg * Description	:This function is used to get the attributes of a port like hue,
61171d7fec4Smrg *				 saturation,brightness or contrast.
61271d7fec4Smrg *
61371d7fec4Smrg * Parameters.
61471d7fec4Smrg * pScreenInfo
61571d7fec4Smrg *		Ptr			:Screen handler pointer having screen information.
61671d7fec4Smrg *		data		:Pointer to the video port's private data
61771d7fec4Smrg *		attribute	:The port attribute to be read
61871d7fec4Smrg *		value		:Pointer to the value of the attribute to be read.
61971d7fec4Smrg *
62071d7fec4Smrg * Returns		:Sucess if the attribute is supported, else BadMatch
62171d7fec4Smrg *
62271d7fec4Smrg * Comments		:none
62371d7fec4Smrg *
62471d7fec4Smrg*----------------------------------------------------------------------------
62571d7fec4Smrg*/
62671d7fec4Smrgstatic int
62771d7fec4SmrgGX1GetPortAttribute(ScrnInfoPtr pScrn,
62871d7fec4Smrg		    Atom attribute, INT32 * value, pointer data)
62971d7fec4Smrg{
63071d7fec4Smrg   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
63171d7fec4Smrg
63271d7fec4Smrg   if (attribute == xvColorKey) {
63371d7fec4Smrg      *value = pPriv->colorKey;
63471d7fec4Smrg   }
63571d7fec4Smrg#if DBUF
63671d7fec4Smrg   else if (attribute == xvDoubleBuffer) {
63771d7fec4Smrg      *value = (pPriv->doubleBuffer) ? 1 : 0;
63871d7fec4Smrg   }
63971d7fec4Smrg#endif
64071d7fec4Smrg   else if (attribute == xvColorKeyMode) {
64171d7fec4Smrg      *value = pPriv->colorKeyMode;
64271d7fec4Smrg   } else if (attribute == xvFilter) {
64371d7fec4Smrg      *value = pPriv->filter;
64471d7fec4Smrg   } else
64571d7fec4Smrg      return BadMatch;
64671d7fec4Smrg
64771d7fec4Smrg   return Success;
64871d7fec4Smrg}
64971d7fec4Smrg
65071d7fec4Smrg/*----------------------------------------------------------------------------
65171d7fec4Smrg * GX1QueryBestSize
65271d7fec4Smrg *
65371d7fec4Smrg * Description	:This function provides a way to query what the destination dimensions
65471d7fec4Smrg *				 would end up being if they were to request that an area vid_w by vid_h
65571d7fec4Smrg *               from the video stream be scaled to rectangle of drw_w by drw_h on
65671d7fec4Smrg *				 the screen.
65771d7fec4Smrg *
65871d7fec4Smrg * Parameters.
65971d7fec4Smrg * ScreenInfoPtr
66071d7fec4Smrg *		pScrn		:Screen handler pointer having screen information.
66171d7fec4Smrg *		data		:Pointer to the video port's private data
66271d7fec4Smrg *      vid_w,vid_h	:Width and height of the video data.
66371d7fec4Smrg *		drw_w,drw_h :Width and height of the scaled rectangle.
66471d7fec4Smrg *		p_w,p_h		:Width and height of the destination rectangle.
66571d7fec4Smrg *
66671d7fec4Smrg * Returns		:None
66771d7fec4Smrg *
66871d7fec4Smrg * Comments		:None
66971d7fec4Smrg *
67071d7fec4Smrg*----------------------------------------------------------------------------
67171d7fec4Smrg*/
67271d7fec4Smrgstatic void
67371d7fec4SmrgGX1QueryBestSize(ScrnInfoPtr pScrn,
67471d7fec4Smrg		 Bool motion,
67571d7fec4Smrg		 short vid_w, short vid_h,
67671d7fec4Smrg		 short drw_w, short drw_h,
67771d7fec4Smrg		 unsigned int *p_w, unsigned int *p_h, pointer data)
67871d7fec4Smrg{
67971d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "QueryBestSize\n"));
68071d7fec4Smrg   *p_w = drw_w;
68171d7fec4Smrg   *p_h = drw_h;
68271d7fec4Smrg
68371d7fec4Smrg   if (*p_w > 16384)
68471d7fec4Smrg      *p_w = 16384;
68571d7fec4Smrg}
68671d7fec4Smrgstatic void
68771d7fec4SmrgGX1CopyGreyscale(unsigned char *src,
68871d7fec4Smrg		 unsigned char *dst, int srcPitch, int dstPitch, int h, int w)
68971d7fec4Smrg{
69071d7fec4Smrg   int i;
69171d7fec4Smrg   unsigned char *src2 = src;
69271d7fec4Smrg   unsigned char *dst2 = dst;
69371d7fec4Smrg   unsigned char *dst3;
69471d7fec4Smrg   unsigned char *src3;
69571d7fec4Smrg
69671d7fec4Smrg   dstPitch <<= 1;
69771d7fec4Smrg
69871d7fec4Smrg   while (h--) {
69971d7fec4Smrg      dst3 = dst2;
70071d7fec4Smrg      src3 = src2;
70171d7fec4Smrg      for (i = 0; i < w; i++) {
70271d7fec4Smrg	 *dst3++ = *src3++;		/* Copy Y data */
70371d7fec4Smrg	 *dst3++ = 0x80;		/* Fill UV with 0x80 - greyscale */
70471d7fec4Smrg      }
70571d7fec4Smrg      src3 = src2;
70671d7fec4Smrg      for (i = 0; i < w; i++) {
70771d7fec4Smrg	 *dst3++ = *src3++;		/* Copy Y data */
70871d7fec4Smrg	 *dst3++ = 0x80;		/* Fill UV with 0x80 - greyscale */
70971d7fec4Smrg      }
71071d7fec4Smrg      dst2 += dstPitch;
71171d7fec4Smrg      src2 += srcPitch;
71271d7fec4Smrg   }
71371d7fec4Smrg}
71471d7fec4Smrg
71571d7fec4Smrg/*----------------------------------------------------------------------------
71671d7fec4Smrg * GX1CopyData
71771d7fec4Smrg *
71871d7fec4Smrg * Description	: Copies data from src to destination
71971d7fec4Smrg *
72071d7fec4Smrg * Parameters.
72171d7fec4Smrg *		src			: pointer to the source data
72271d7fec4Smrg *		dst			: pointer to destination data
72371d7fec4Smrg *		srcPitch	: pitch of the srcdata
72471d7fec4Smrg *		dstPitch	: pitch of the destination data
72571d7fec4Smrg *		h & w		: height and width of source data
72671d7fec4Smrg *
72771d7fec4Smrg * Returns		:None
72871d7fec4Smrg *
72971d7fec4Smrg * Comments		:None
73071d7fec4Smrg *
73171d7fec4Smrg*----------------------------------------------------------------------------
73271d7fec4Smrg*/
73371d7fec4Smrg
73471d7fec4Smrgstatic void
73571d7fec4SmrgGX1CopyData(unsigned char *src, unsigned char *dst,
73671d7fec4Smrg	    int srcPitch, int dstPitch, int h, int w)
73771d7fec4Smrg{
73871d7fec4Smrg   w <<= 1;
73971d7fec4Smrg   while (h--) {
74071d7fec4Smrg      memcpy(dst, src, w);
74171d7fec4Smrg      src += srcPitch;
74271d7fec4Smrg      dst += dstPitch;
74371d7fec4Smrg   }
74471d7fec4Smrg}
74571d7fec4Smrg
74671d7fec4Smrgstatic void
74771d7fec4SmrgGX1CopyMungedData(unsigned char *src1,
74871d7fec4Smrg		  unsigned char *src2,
74971d7fec4Smrg		  unsigned char *src3,
75071d7fec4Smrg		  unsigned char *dst1,
75171d7fec4Smrg		  int srcPitch, int srcPitch2, int dstPitch, int h, int w)
75271d7fec4Smrg{
75371d7fec4Smrg   CARD32 *dstCur = (CARD32 *) dst1;
75471d7fec4Smrg   CARD32 *dstNext = (CARD32 *) dst1;
75571d7fec4Smrg   int i, j, k, m, n;
75671d7fec4Smrg   CARD32 crcb;
75771d7fec4Smrg
75871d7fec4Smrg#if XV_PROFILE
75971d7fec4Smrg   long oldtime, newtime;
76071d7fec4Smrg#endif
76171d7fec4Smrg
76271d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "CopyMungedData\n"));
76371d7fec4Smrg   /* dstPitch is in byte count, but we write longs.
76471d7fec4Smrg    * so divide dstpitch by 4
76571d7fec4Smrg    */
76671d7fec4Smrg   dstPitch >>= 2;
76771d7fec4Smrg   /* Width is in byte but video data is 16bit
76871d7fec4Smrg    */
76971d7fec4Smrg   w >>= 1;
77071d7fec4Smrg   /* We render 2 scanlines at one shot, handle the odd count */
77171d7fec4Smrg   m = h & 1;
77271d7fec4Smrg   /* decrement the height since we write 2 scans */
77371d7fec4Smrg   h -= 1;
77471d7fec4Smrg   /* we traverse by 2 bytes in src Y */
77571d7fec4Smrg   srcPitch <<= 1;
77671d7fec4Smrg#if XV_PROFILE
77771d7fec4Smrg   UpdateCurrentTime();
77871d7fec4Smrg   oldtime = currentTime.milliseconds;
77971d7fec4Smrg#endif
78071d7fec4Smrg
78171d7fec4Smrg   for (j = 0; j < h; j += 2) {
78271d7fec4Smrg      /* calc the next dest scan start */
78371d7fec4Smrg      dstNext = dstCur + dstPitch;
78471d7fec4Smrg      for (i = 0; i < w; i++) {
78571d7fec4Smrg	 /* crcb is same for the x pixel for 2 scans */
78671d7fec4Smrg	 crcb = (src3[i] << 8) | (src2[i] << 24);
78771d7fec4Smrg
78871d7fec4Smrg	 n = i << 1;
78971d7fec4Smrg
79071d7fec4Smrg	 /* write the first scan pixel DWORD */
79171d7fec4Smrg	 dstCur[i] = src1[n] | (src1[n + 1] << 16) | crcb;
79271d7fec4Smrg
79371d7fec4Smrg	 /* calc the offset of next pixel */
79471d7fec4Smrg	 k = n + srcPitch;
79571d7fec4Smrg
79671d7fec4Smrg	 /* write the 2nd scan pixel DWORD */
79771d7fec4Smrg	 dstNext[i] = src1[k] | (src1[k + 1] << 16) | crcb;
79871d7fec4Smrg      }
79971d7fec4Smrg      /* increment the offsets */
80071d7fec4Smrg
80171d7fec4Smrg      /* Y */
80271d7fec4Smrg      src1 += srcPitch;
80371d7fec4Smrg      /* crcb */
80471d7fec4Smrg      src2 += srcPitch2;
80571d7fec4Smrg      src3 += srcPitch2;
80671d7fec4Smrg      /* processed dest */
80771d7fec4Smrg      dstCur += (dstPitch << 1);
80871d7fec4Smrg   }
80971d7fec4Smrg
81071d7fec4Smrg   /* if any scans remaining */
81171d7fec4Smrg   if (m) {
81271d7fec4Smrg      for (i = 0, k = 0; i < w; i++, k += 2) {
81371d7fec4Smrg	 dstCur[i] = src1[k] | (src1[k + 1] << 16) |
81471d7fec4Smrg	       (src3[i] << 8) | (src2[i] << 24);
81571d7fec4Smrg      }
81671d7fec4Smrg   }
81771d7fec4Smrg#if XV_PROFILE
81871d7fec4Smrg   UpdateCurrentTime();
81971d7fec4Smrg   newtime = currentTime.milliseconds;
82071d7fec4Smrg   DEBUGMSG(1, (0, X_NONE, "CMD %d\n", newtime - oldtime));
82171d7fec4Smrg#endif
82271d7fec4Smrg}
82371d7fec4Smrg
82471d7fec4Smrgstatic FBAreaPtr
82571d7fec4SmrgGX1AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int numlines)
82671d7fec4Smrg{
82771d7fec4Smrg   ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
82871d7fec4Smrg   FBAreaPtr new_area;
82971d7fec4Smrg
83071d7fec4Smrg   if (area) {
83171d7fec4Smrg      if ((area->box.y2 - area->box.y1) >= numlines)
83271d7fec4Smrg	 return area;
83371d7fec4Smrg
83471d7fec4Smrg      if (xf86ResizeOffscreenArea(area, pScrn->displayWidth, numlines))
83571d7fec4Smrg	 return area;
83671d7fec4Smrg
83771d7fec4Smrg      xf86FreeOffscreenArea(area);
83871d7fec4Smrg   }
83971d7fec4Smrg
84071d7fec4Smrg   new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
84171d7fec4Smrg					numlines, 0, NULL, NULL, NULL);
84271d7fec4Smrg
84371d7fec4Smrg   if (!new_area) {
84471d7fec4Smrg      int max_w, max_h;
84571d7fec4Smrg
84671d7fec4Smrg      xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0,
84771d7fec4Smrg				    FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME);
84871d7fec4Smrg
84971d7fec4Smrg      if ((max_w < pScrn->displayWidth) || (max_h < numlines))
85071d7fec4Smrg	 return NULL;
85171d7fec4Smrg
85271d7fec4Smrg      xf86PurgeUnlockedOffscreenAreas(pScreen);
85371d7fec4Smrg      new_area = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth,
85471d7fec4Smrg					   numlines, 0, NULL, NULL, NULL);
85571d7fec4Smrg   }
85671d7fec4Smrg   return new_area;
85771d7fec4Smrg}
85871d7fec4Smrg
85971d7fec4Smrgstatic BoxRec dstBox;
86071d7fec4Smrgstatic int srcPitch = 0, srcPitch2 = 0, dstPitch = 0;
86171d7fec4Smrgstatic INT32 Bx1, Bx2, By1, By2;
86271d7fec4Smrgstatic int top, left, npixels, nlines;
86371d7fec4Smrgstatic int offset, s1offset = 0, s2offset = 0, s3offset = 0;
86471d7fec4Smrgstatic unsigned char *dst_start;
86571d7fec4Smrgstatic int TVOverScanX;
86671d7fec4Smrg
86771d7fec4Smrgstatic Bool
86871d7fec4SmrgRegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult)
86971d7fec4Smrg{
87071d7fec4Smrg   pRclResult->x1 = max(pRcl1->x1, pRcl2->x1);
87171d7fec4Smrg   pRclResult->x2 = min(pRcl1->x2, pRcl2->x2);
87271d7fec4Smrg
87371d7fec4Smrg   if (pRclResult->x1 <= pRclResult->x2) {
87471d7fec4Smrg      pRclResult->y1 = max(pRcl1->y1, pRcl2->y1);
87571d7fec4Smrg      pRclResult->y2 = min(pRcl1->y2, pRcl2->y2);
87671d7fec4Smrg
87771d7fec4Smrg      if (pRclResult->y1 <= pRclResult->y2) {
87871d7fec4Smrg	 return (TRUE);
87971d7fec4Smrg      }
88071d7fec4Smrg   }
88171d7fec4Smrg
88271d7fec4Smrg   return (FALSE);
88371d7fec4Smrg}
88471d7fec4Smrg
88571d7fec4Smrgvoid
88671d7fec4SmrgGX1SetVideoPosition(int x, int y, int width, int height,
88771d7fec4Smrg		    short src_w, short src_h, short drw_w, short drw_h,
88871d7fec4Smrg		    int id, int offset, ScrnInfoPtr pScrn)
88971d7fec4Smrg{
89071d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
89171d7fec4Smrg   long xstart, ystart, xend, yend;
89271d7fec4Smrg   unsigned long lines = 0;
89371d7fec4Smrg   unsigned long y_extra = 0;
89471d7fec4Smrg   unsigned short crop = 0;
89571d7fec4Smrg   BoxRec ovly, display, result;
89671d7fec4Smrg
89771d7fec4Smrg#if defined(STB_X)
89871d7fec4Smrg   unsigned long startAddress = 0;
89971d7fec4Smrg#endif
90071d7fec4Smrg   xend = x + drw_w;
90171d7fec4Smrg   yend = y + drw_h;
90271d7fec4Smrg
90371d7fec4Smrg   /* Take care of panning when panel is present */
90471d7fec4Smrg
90571d7fec4Smrg#if defined(STB_X)
90671d7fec4Smrg   Gal_get_display_offset(&startAddress);
90771d7fec4Smrg   DeltaY = startAddress / pGeode->Pitch;
90871d7fec4Smrg   DeltaX = startAddress & (pGeode->Pitch - 1);
90971d7fec4Smrg   DeltaX /= (pScrn->bitsPerPixel >> 3);
91071d7fec4Smrg#endif
91171d7fec4Smrg
91271d7fec4Smrg   if (pGeode->Panel) {
91371d7fec4Smrg      ovly.x1 = x;
91471d7fec4Smrg      ovly.x2 = x + pGeode->video_dstw;
91571d7fec4Smrg      ovly.y1 = y;
91671d7fec4Smrg      ovly.y2 = y + pGeode->video_dsth;
91771d7fec4Smrg
91871d7fec4Smrg      display.x1 = DeltaX;
91971d7fec4Smrg      display.x2 = DeltaX + pGeode->FPBX;
92071d7fec4Smrg      display.y1 = DeltaY;
92171d7fec4Smrg      display.y2 = DeltaY + pGeode->FPBY;
92271d7fec4Smrg
92371d7fec4Smrg      x = xend = 0;
92471d7fec4Smrg
92571d7fec4Smrg      if (RegionsIntersect(&display, &ovly, &result)) {
92671d7fec4Smrg	 x = ovly.x1 - DeltaX;
92771d7fec4Smrg	 xend = ovly.x2 - DeltaX;
92871d7fec4Smrg	 y = ovly.y1 - DeltaY;
92971d7fec4Smrg	 yend = ovly.y2 - DeltaY;
93071d7fec4Smrg      }
93171d7fec4Smrg   }
93271d7fec4Smrg
93371d7fec4Smrg   /*  LEFT CLIPPING */
93471d7fec4Smrg
93571d7fec4Smrg   if (x < 0) {
93671d7fec4Smrg      if (TVOverScanX)
93771d7fec4Smrg	 xstart = TVOverScanX;
93871d7fec4Smrg      else
93971d7fec4Smrg	 xstart = 0;
94071d7fec4Smrg   } else {
94171d7fec4Smrg      if (TVOverScanX)
94271d7fec4Smrg	 xstart = TVOverScanX;
94371d7fec4Smrg      else
94471d7fec4Smrg	 xstart = (unsigned long)x;
94571d7fec4Smrg   }
94671d7fec4Smrg   drw_w -= (xstart - x);
94771d7fec4Smrg
94871d7fec4Smrg   /*  TOP CLIPPING */
94971d7fec4Smrg
95071d7fec4Smrg   if (y < 0) {
95171d7fec4Smrg      lines = (-y) * src_h / drw_h;
95271d7fec4Smrg      ystart = 0;
95371d7fec4Smrg      drw_h += y;
95471d7fec4Smrg      y_extra = lines * dstPitch;
95571d7fec4Smrg   } else {
95671d7fec4Smrg      ystart = y;
95771d7fec4Smrg      lines = 0;
95871d7fec4Smrg      y_extra = 0;
95971d7fec4Smrg   }
96071d7fec4Smrg
96171d7fec4Smrg   /* CLIP RIGHT AND BOTTOM FOR TV OVER SCAN */
96271d7fec4Smrg   if (pGeode->TV_Overscan_On) {
96371d7fec4Smrg      crop = (pGeode->TVOw + pGeode->TVOx);
96471d7fec4Smrg      if ((xstart + drw_w) > crop)
96571d7fec4Smrg	 xend = crop;
96671d7fec4Smrg      crop = (pGeode->TVOh + pGeode->TVOy);
96771d7fec4Smrg      if ((ystart + drw_h) > crop)
96871d7fec4Smrg	 yend = crop;
96971d7fec4Smrg   }
97071d7fec4Smrg   GFX(set_video_window(xstart, ystart, xend - xstart, yend - ystart));
97171d7fec4Smrg   GFX(set_video_offset(offset + y_extra));
97271d7fec4Smrg   GFX(set_video_left_crop(xstart - x));
97371d7fec4Smrg
97471d7fec4Smrg}
97571d7fec4Smrg
97671d7fec4Smrg/*----------------------------------------------------------------------------
97771d7fec4Smrg * GX1DisplayVideo
97871d7fec4Smrg *
97971d7fec4Smrg * Description		: This function sets up the video registers for playing video
98071d7fec4Smrg *					  It sets up the video format,width, height & position of the
98171d7fec4Smrg *					  video window ,video offsets( y,u,v) and video pitches(y,u,v)
98271d7fec4Smrg * Parameters.
98371d7fec4Smrg *
98471d7fec4Smrg * Returns		:None
98571d7fec4Smrg *
98671d7fec4Smrg * Comments		:None
98771d7fec4Smrg *
98871d7fec4Smrg*----------------------------------------------------------------------------
98971d7fec4Smrg*/
99071d7fec4Smrg
99171d7fec4Smrgstatic void
99271d7fec4SmrgGX1DisplayVideo(ScrnInfoPtr pScrn,
99371d7fec4Smrg		int id,
99471d7fec4Smrg		int offset,
99571d7fec4Smrg		short width, short height,
99671d7fec4Smrg		int pitch,
99771d7fec4Smrg		int x1, int y1, int x2, int y2,
99871d7fec4Smrg		BoxPtr dstBox,
99971d7fec4Smrg		short src_w, short src_h, short drw_w, short drw_h)
100071d7fec4Smrg{
100171d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
100271d7fec4Smrg
100371d7fec4Smrg   /*    DisplayModePtr mode = pScrn->currentMode; */
100471d7fec4Smrg   if (!pGeode->NoAccel) GX1AccelSync(pScrn);
100571d7fec4Smrg
100671d7fec4Smrg   GFX(set_video_enable(1));
100771d7fec4Smrg
100871d7fec4Smrg   switch (id) {
100971d7fec4Smrg   case FOURCC_UYVY:			/* UYVY */
101071d7fec4Smrg      GFX(set_video_format(VIDEO_FORMAT_UYVY));
101171d7fec4Smrg      break;
101271d7fec4Smrg   case FOURCC_Y800:			/* Y800 - greyscale - we munge it! */
101371d7fec4Smrg   case FOURCC_YV12:
101471d7fec4Smrg   case FOURCC_I420:
101571d7fec4Smrg   case FOURCC_YUY2:			/* YUY2 */
101671d7fec4Smrg      GFX(set_video_format(VIDEO_FORMAT_YUYV));
101771d7fec4Smrg      break;
101871d7fec4Smrg   case FOURCC_Y2YU:			/* Y2YU */
101971d7fec4Smrg      GFX(set_video_format(VIDEO_FORMAT_Y2YU));
102071d7fec4Smrg      break;
102171d7fec4Smrg   case FOURCC_YVYU:			/* YVYU */
102271d7fec4Smrg      GFX(set_video_format(VIDEO_FORMAT_YVYU));
102371d7fec4Smrg      break;
102471d7fec4Smrg   }
102571d7fec4Smrg
102671d7fec4Smrg   if (pGeode->TV_Overscan_On) {
102771d7fec4Smrg      if (dstBox->x1 < 0)
102871d7fec4Smrg	 TVOverScanX = pGeode->TVOx;
102971d7fec4Smrg      else
103071d7fec4Smrg	 TVOverScanX = 0;
103171d7fec4Smrg      dstBox->x1 += pGeode->TVOx;
103271d7fec4Smrg      dstBox->y1 += pGeode->TVOy;
103371d7fec4Smrg   }
103471d7fec4Smrg   if (pGeode->Panel) {
103571d7fec4Smrg      pGeode->video_x = dstBox->x1;
103671d7fec4Smrg      pGeode->video_y = dstBox->y1;
103771d7fec4Smrg      pGeode->video_w = width;
103871d7fec4Smrg      pGeode->video_h = height;
103971d7fec4Smrg      pGeode->video_srcw = src_w;
104071d7fec4Smrg      pGeode->video_srch = src_h;
104171d7fec4Smrg      pGeode->video_dstw = drw_w;
104271d7fec4Smrg      pGeode->video_dsth = drw_h;
104371d7fec4Smrg      pGeode->video_offset = offset;
104471d7fec4Smrg      pGeode->video_id = id;
104571d7fec4Smrg      pGeode->video_scrnptr = pScrn;
104671d7fec4Smrg   }
104771d7fec4Smrg
104871d7fec4Smrg   GFX(set_video_size(width, height));
104971d7fec4Smrg   GFX(set_video_scale(width, height, drw_w, drw_h));
105071d7fec4Smrg   GX1SetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, src_h,
105171d7fec4Smrg		       drw_w, drw_h, id, offset, pScrn);
105271d7fec4Smrg   GFX(set_color_space_YUV(0));
105371d7fec4Smrg}
105471d7fec4Smrg
105571d7fec4Smrg/*----------------------------------------------------------------------------
105671d7fec4Smrg * GX1PutImage	: This function writes a single frame of video into a drawable.
105771d7fec4Smrg *		The position and size of the source rectangle is specified by src_x,src_y,
105871d7fec4Smrg *		src_w and src_h. This data is stored in a system memory buffer at buf.
105971d7fec4Smrg *		The position and size of the destination rectangle is specified by drw_x,
106071d7fec4Smrg *      drw_y,drw_w,drw_h.The data is in the format indicated by the image descriptor
106171d7fec4Smrg *		and represents a source of size width by height.  If sync is TRUE the driver
106271d7fec4Smrg *		should not return from this function until it is through reading the data from
106371d7fec4Smrg *		buf.  Returning when sync is TRUE indicates that it is safe for the data at buf
106471d7fec4Smrg *		to be replaced,freed, or modified.
106571d7fec4Smrg *
106671d7fec4Smrg *
106771d7fec4Smrg * Description		:
106871d7fec4Smrg * Parameters.
106971d7fec4Smrg *
107071d7fec4Smrg * Returns		:None
107171d7fec4Smrg *
107271d7fec4Smrg * Comments		:None
107371d7fec4Smrg *
107471d7fec4Smrg*----------------------------------------------------------------------------
107571d7fec4Smrg*/
107671d7fec4Smrg
107771d7fec4Smrgstatic int
107871d7fec4SmrgGX1PutImage(ScrnInfoPtr pScrn,
107971d7fec4Smrg	    short src_x, short src_y,
108071d7fec4Smrg	    short drw_x, short drw_y,
108171d7fec4Smrg	    short src_w, short src_h,
108271d7fec4Smrg	    short drw_w, short drw_h,
108371d7fec4Smrg	    int id, unsigned char *buf,
108471d7fec4Smrg	    short width, short height,
108571d7fec4Smrg	    Bool sync, RegionPtr clipBoxes, pointer data,
108671d7fec4Smrg	    DrawablePtr pDraw)
108771d7fec4Smrg{
108871d7fec4Smrg   GeodePortPrivPtr pPriv = (GeodePortPrivPtr) data;
108971d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
109071d7fec4Smrg   int pitch, new_h;
109171d7fec4Smrg
109271d7fec4Smrg#if REINIT
109371d7fec4Smrg   BOOL ReInitVideo = FALSE;
109471d7fec4Smrg#endif
109571d7fec4Smrg
109671d7fec4Smrg#if XV_PROFILE
109771d7fec4Smrg   long oldtime, newtime;
109871d7fec4Smrg
109971d7fec4Smrg   UpdateCurrentTime();
110071d7fec4Smrg   oldtime = currentTime.milliseconds;
110171d7fec4Smrg#endif
110271d7fec4Smrg
110371d7fec4Smrg#if REINIT
110471d7fec4Smrg/* update cliplist */
110571d7fec4Smrg   if (!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) {
110671d7fec4Smrg      ReInitVideo = TRUE;
110771d7fec4Smrg   }
110871d7fec4Smrg   if (ReInitVideo) {
110971d7fec4Smrg      DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n"));
111071d7fec4Smrg#endif
111171d7fec4Smrg
111271d7fec4Smrg      if (drw_w > 16384)
111371d7fec4Smrg	 drw_w = 16384;
111471d7fec4Smrg
111571d7fec4Smrg      /* Clip */
111671d7fec4Smrg      Bx1 = src_x;
111771d7fec4Smrg      Bx2 = src_x + src_w;
111871d7fec4Smrg      By1 = src_y;
111971d7fec4Smrg      By2 = src_y + src_h;
112071d7fec4Smrg
112171d7fec4Smrg      if ((Bx1 >= Bx2) || (By1 >= By2))
112271d7fec4Smrg	 return Success;
112371d7fec4Smrg
112471d7fec4Smrg      dstBox.x1 = drw_x;
112571d7fec4Smrg      dstBox.x2 = drw_x + drw_w;
112671d7fec4Smrg      dstBox.y1 = drw_y;
112771d7fec4Smrg      dstBox.y2 = drw_y + drw_h;
112871d7fec4Smrg
112971d7fec4Smrg      dstBox.x1 -= pScrn->frameX0;
113071d7fec4Smrg      dstBox.x2 -= pScrn->frameX0;
113171d7fec4Smrg      dstBox.y1 -= pScrn->frameY0;
113271d7fec4Smrg      dstBox.y2 -= pScrn->frameY0;
113371d7fec4Smrg
113471d7fec4Smrg      pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3;
113571d7fec4Smrg
113671d7fec4Smrg      dstPitch = ((width << 1) + 3) & ~3;
113771d7fec4Smrg
113871d7fec4Smrg      switch (id) {
113971d7fec4Smrg      case FOURCC_YV12:
114071d7fec4Smrg      case FOURCC_I420:
114171d7fec4Smrg	 srcPitch = (width + 3) & ~3;	/* of luma */
114271d7fec4Smrg	 s2offset = srcPitch * height;
114371d7fec4Smrg	 srcPitch2 = ((width >> 1) + 3) & ~3;
114471d7fec4Smrg	 s3offset = (srcPitch2 * (height >> 1)) + s2offset;
114571d7fec4Smrg	 break;
114671d7fec4Smrg      case FOURCC_UYVY:
114771d7fec4Smrg      case FOURCC_YUY2:
114871d7fec4Smrg      case FOURCC_Y800:
114971d7fec4Smrg      default:
115071d7fec4Smrg	 srcPitch = (width << 1);
115171d7fec4Smrg	 break;
115271d7fec4Smrg      }
115371d7fec4Smrg
115471d7fec4Smrg      /* Find how many pitch scanlines required to store the data */
115571d7fec4Smrg      new_h = ((dstPitch * height) + pitch - 1) / pitch;
115671d7fec4Smrg
115771d7fec4Smrg#if DBUF
115871d7fec4Smrg      if (pPriv->doubleBuffer)
115971d7fec4Smrg	 new_h <<= 1;
116071d7fec4Smrg#endif
116171d7fec4Smrg
116271d7fec4Smrg      if (!(pPriv->area = GX1AllocateMemory(pScrn, pPriv->area, new_h)))
116371d7fec4Smrg	 return BadAlloc;
116471d7fec4Smrg
116571d7fec4Smrg      /* copy data */
116671d7fec4Smrg      top = By1;
116771d7fec4Smrg      left = Bx1 & ~1;
116871d7fec4Smrg      npixels = ((Bx2 + 1) & ~1) - left;
116971d7fec4Smrg
117071d7fec4Smrg      switch (id) {
117171d7fec4Smrg      case FOURCC_YV12:
117271d7fec4Smrg      case FOURCC_I420:
117371d7fec4Smrg	 {
117471d7fec4Smrg	    int tmp;
117571d7fec4Smrg
117671d7fec4Smrg	    top &= ~1;
117771d7fec4Smrg	    offset = (pPriv->area->box.y1 * pitch) + (top * dstPitch);
117871d7fec4Smrg
117971d7fec4Smrg#if DBUF
118071d7fec4Smrg	    if (pPriv->doubleBuffer && pPriv->currentBuffer)
118171d7fec4Smrg	       offset += (new_h >> 1) * pitch;
118271d7fec4Smrg#endif
118371d7fec4Smrg
118471d7fec4Smrg	    dst_start = pGeode->FBBase + offset + left;
118571d7fec4Smrg	    tmp = ((top >> 1) * srcPitch2) + (left >> 1);
118671d7fec4Smrg	    s2offset += tmp;
118771d7fec4Smrg	    s3offset += tmp;
118871d7fec4Smrg	    if (id == FOURCC_I420) {
118971d7fec4Smrg	       tmp = s2offset;
119071d7fec4Smrg	       s2offset = s3offset;
119171d7fec4Smrg	       s3offset = tmp;
119271d7fec4Smrg	    }
119371d7fec4Smrg	    nlines = ((By2 + 1) & ~1) - top;
119471d7fec4Smrg	 }
119571d7fec4Smrg	 break;
119671d7fec4Smrg
119771d7fec4Smrg      case FOURCC_UYVY:
119871d7fec4Smrg      case FOURCC_YUY2:
119971d7fec4Smrg      case FOURCC_Y800:
120071d7fec4Smrg      default:
120171d7fec4Smrg	 left <<= 1;
120271d7fec4Smrg	 buf += (top * srcPitch) + left;
120371d7fec4Smrg	 nlines = By2 - top;
120471d7fec4Smrg	 offset = (pPriv->area->box.y1 * pitch) + (top * dstPitch);
120571d7fec4Smrg
120671d7fec4Smrg#if DBUF
120771d7fec4Smrg	 if (pPriv->doubleBuffer && pPriv->currentBuffer)
120871d7fec4Smrg	    offset += (new_h >> 1) * pitch;
120971d7fec4Smrg#endif
121071d7fec4Smrg
121171d7fec4Smrg	 dst_start = pGeode->FBBase + offset + left;
121271d7fec4Smrg	 break;
121371d7fec4Smrg      }
121471d7fec4Smrg      s1offset = (top * srcPitch) + left;
121571d7fec4Smrg
121671d7fec4Smrg#if REINIT
121771d7fec4Smrg      /* update cliplist */
121871d7fec4Smrg      REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes);
121971d7fec4Smrg      if (pPriv->colorKeyMode == 0) {
122071d7fec4Smrg	 /* draw these */
122171d7fec4Smrg	 xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
122271d7fec4Smrg      }
122371d7fec4Smrg      GX1DisplayVideo(pScrn, id, offset, width, height, dstPitch,
122471d7fec4Smrg		      Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w,
122571d7fec4Smrg		      drw_h);
122671d7fec4Smrg   }
122771d7fec4Smrg#endif
122871d7fec4Smrg
122971d7fec4Smrg   switch (id) {
123071d7fec4Smrg
123171d7fec4Smrg   case FOURCC_Y800:
123271d7fec4Smrg      GX1CopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
123371d7fec4Smrg      break;
123471d7fec4Smrg   case FOURCC_YV12:
123571d7fec4Smrg   case FOURCC_I420:
123671d7fec4Smrg      GX1CopyMungedData(buf + s1offset, buf + s2offset,
123771d7fec4Smrg			buf + s3offset, dst_start, srcPitch, srcPitch2,
123871d7fec4Smrg			dstPitch, nlines, npixels);
123971d7fec4Smrg      break;
124071d7fec4Smrg   case FOURCC_UYVY:
124171d7fec4Smrg   case FOURCC_YUY2:
124271d7fec4Smrg   default:
124371d7fec4Smrg      GX1CopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels);
124471d7fec4Smrg      break;
124571d7fec4Smrg   }
124671d7fec4Smrg#if !REINIT
124771d7fec4Smrg   /* update cliplist */
124871d7fec4Smrg   REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
124971d7fec4Smrg   if (pPriv->colorKeyMode == 0) {
125071d7fec4Smrg      /* draw these */
125171d7fec4Smrg      xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
125271d7fec4Smrg   }
125371d7fec4Smrg   GX1DisplayVideo(pScrn, id, offset, width, height, dstPitch,
125471d7fec4Smrg		   Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h);
125571d7fec4Smrg#endif
125671d7fec4Smrg
125771d7fec4Smrg#if XV_PROFILE
125871d7fec4Smrg   UpdateCurrentTime();
125971d7fec4Smrg   newtime = currentTime.milliseconds;
126071d7fec4Smrg   DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime));
126171d7fec4Smrg#endif
126271d7fec4Smrg
126371d7fec4Smrg#if DBUF
126471d7fec4Smrg   pPriv->currentBuffer ^= 1;
126571d7fec4Smrg#endif
126671d7fec4Smrg
126771d7fec4Smrg   pPriv->videoStatus = CLIENT_VIDEO_ON;
126871d7fec4Smrg   pGeode->OverlayON = TRUE;
126971d7fec4Smrg   return Success;
127071d7fec4Smrg}
127171d7fec4Smrg
127271d7fec4Smrg/*----------------------------------------------------------------------------
127371d7fec4Smrg * GX1QueryImageAttributes
127471d7fec4Smrg *
127571d7fec4Smrg * Description	:This function is called to let the driver specify how data
127671d7fec4Smrg *				 for a particular image of size width by height should be
127771d7fec4Smrg *				 stored.
127871d7fec4Smrg *
127971d7fec4Smrg * Parameters.
128071d7fec4Smrg * pScreenInfo
128171d7fec4Smrg *		Ptr			:Screen handler pointer having screen information.
128271d7fec4Smrg *		id			:Id for the video format
128371d7fec4Smrg *		width		:width  of the image (can be modified by the driver)
128471d7fec4Smrg *		height		:height of the image (can be modified by the driver)
128571d7fec4Smrg * Returns		: Size of the memory required for storing this image
128671d7fec4Smrg *
128771d7fec4Smrg * Comments		:None
128871d7fec4Smrg *
128971d7fec4Smrg*----------------------------------------------------------------------------
129071d7fec4Smrg*/
129171d7fec4Smrgstatic int
129271d7fec4SmrgGX1QueryImageAttributes(ScrnInfoPtr pScrn,
129371d7fec4Smrg			int id,
129471d7fec4Smrg			unsigned short *w, unsigned short *h,
129571d7fec4Smrg			int *pitches, int *offsets)
129671d7fec4Smrg{
129771d7fec4Smrg   int size;
129871d7fec4Smrg   int tmp;
129971d7fec4Smrg
130071d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id));
130171d7fec4Smrg
130271d7fec4Smrg   if (*w > 1024)
130371d7fec4Smrg      *w = 1024;
130471d7fec4Smrg   if (*h > 1024)
130571d7fec4Smrg      *h = 1024;
130671d7fec4Smrg
130771d7fec4Smrg   *w = (*w + 1) & ~1;
130871d7fec4Smrg   if (offsets)
130971d7fec4Smrg      offsets[0] = 0;
131071d7fec4Smrg
131171d7fec4Smrg   switch (id) {
131271d7fec4Smrg   case FOURCC_YV12:
131371d7fec4Smrg   case FOURCC_I420:
131471d7fec4Smrg      *h = (*h + 1) & ~1;
131571d7fec4Smrg      size = (*w + 3) & ~3;
131671d7fec4Smrg      if (pitches)
131771d7fec4Smrg	 pitches[0] = size;
131871d7fec4Smrg      size *= *h;
131971d7fec4Smrg      if (offsets)
132071d7fec4Smrg	 offsets[1] = size;
132171d7fec4Smrg      tmp = ((*w >> 1) + 3) & ~3;
132271d7fec4Smrg      if (pitches)
132371d7fec4Smrg	 pitches[1] = pitches[2] = tmp;
132471d7fec4Smrg      tmp *= (*h >> 1);
132571d7fec4Smrg      size += tmp;
132671d7fec4Smrg      if (offsets)
132771d7fec4Smrg	 offsets[2] = size;
132871d7fec4Smrg      size += tmp;
132971d7fec4Smrg      break;
133071d7fec4Smrg   case FOURCC_UYVY:
133171d7fec4Smrg   case FOURCC_YUY2:
133271d7fec4Smrg   case FOURCC_Y800:
133371d7fec4Smrg   default:
133471d7fec4Smrg      size = *w << 1;
133571d7fec4Smrg      if (pitches)
133671d7fec4Smrg	 pitches[0] = size;
133771d7fec4Smrg      size *= *h;
133871d7fec4Smrg      break;
133971d7fec4Smrg   }
134071d7fec4Smrg   return size;
134171d7fec4Smrg}
134271d7fec4Smrg
134371d7fec4Smrgstatic void
134471d7fec4SmrgGX1BlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask)
134571d7fec4Smrg{
134671d7fec4Smrg   ScreenPtr pScreen = screenInfo.screens[i];
134771d7fec4Smrg   ScrnInfoPtr pScrn = xf86Screens[i];
134871d7fec4Smrg   GeodePtr pGeode = GEODEPTR(pScrn);
134971d7fec4Smrg   GeodePortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn);
135071d7fec4Smrg
135171d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "BlockHandler\n"));
135271d7fec4Smrg   pScreen->BlockHandler = pGeode->BlockHandler;
135371d7fec4Smrg   (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
135471d7fec4Smrg   pScreen->BlockHandler = GX1BlockHandler;
135571d7fec4Smrg
135671d7fec4Smrg   if (!pGeode->NoAccel) GX1AccelSync(pScrn);
135771d7fec4Smrg   if (pPriv->videoStatus & TIMER_MASK) {
135871d7fec4Smrg      UpdateCurrentTime();
135971d7fec4Smrg      if (pPriv->videoStatus & OFF_TIMER) {
136071d7fec4Smrg	 if (pPriv->offTime < currentTime.milliseconds) {
136171d7fec4Smrg	    GFX(set_video_enable(0));
136271d7fec4Smrg	    pPriv->videoStatus = FREE_TIMER;
136371d7fec4Smrg	    pPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
136471d7fec4Smrg	 }
136571d7fec4Smrg      } else {				/* FREE_TIMER */
136671d7fec4Smrg	 if (pPriv->freeTime < currentTime.milliseconds) {
136771d7fec4Smrg	    if (pPriv->area) {
136871d7fec4Smrg	       xf86FreeOffscreenArea(pPriv->area);
136971d7fec4Smrg	       pPriv->area = NULL;
137071d7fec4Smrg	    }
137171d7fec4Smrg	    pPriv->videoStatus = 0;
137271d7fec4Smrg	 }
137371d7fec4Smrg      }
137471d7fec4Smrg   }
137571d7fec4Smrg}
137671d7fec4Smrg
137771d7fec4Smrg/****************** Offscreen stuff ***************/
137871d7fec4Smrg
137971d7fec4Smrgtypedef struct
138071d7fec4Smrg{
138171d7fec4Smrg   FBAreaPtr area;
138271d7fec4Smrg   FBLinearPtr linear;
138371d7fec4Smrg   Bool isOn;
138471d7fec4Smrg}
138571d7fec4SmrgOffscreenPrivRec, *OffscreenPrivPtr;
138671d7fec4Smrg
138771d7fec4Smrg/*----------------------------------------------------------------------------
138871d7fec4Smrg * GX1AllocateSurface
138971d7fec4Smrg *
139071d7fec4Smrg * Description	:This function allocates an area of w by h in the offscreen
139171d7fec4Smrg * Parameters.
139271d7fec4Smrg * ScreenPtr
139371d7fec4Smrg *		pScreen	:Screen handler pointer having screen information.
139471d7fec4Smrg *
139571d7fec4Smrg * Returns		:None
139671d7fec4Smrg *
139771d7fec4Smrg * Comments		:None
139871d7fec4Smrg *
139971d7fec4Smrg*----------------------------------------------------------------------------
140071d7fec4Smrg*/
140171d7fec4Smrg
140271d7fec4Smrgstatic int
140371d7fec4SmrgGX1AllocateSurface(ScrnInfoPtr pScrn,
140471d7fec4Smrg		   int id,
140571d7fec4Smrg		   unsigned short w, unsigned short h, XF86SurfacePtr surface)
140671d7fec4Smrg{
140771d7fec4Smrg   FBAreaPtr area;
140871d7fec4Smrg   int pitch, fbpitch, numlines;
140971d7fec4Smrg   OffscreenPrivPtr pPriv;
141071d7fec4Smrg
141171d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "AllocateSurface %x\n", id));
141271d7fec4Smrg   if ((w > 1024) || (h > 1024))
141371d7fec4Smrg      return BadAlloc;
141471d7fec4Smrg
141571d7fec4Smrg   w = (w + 1) & ~1;
141671d7fec4Smrg   pitch = ((w << 1) + 15) & ~15;
141771d7fec4Smrg   fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3;
141871d7fec4Smrg   numlines = ((pitch * h) + fbpitch - 1) / fbpitch;
141971d7fec4Smrg
142071d7fec4Smrg   if (!(area = GX1AllocateMemory(pScrn, NULL, numlines)))
142171d7fec4Smrg      return BadAlloc;
142271d7fec4Smrg
142371d7fec4Smrg   surface->width = w;
142471d7fec4Smrg   surface->height = h;
142571d7fec4Smrg
142671d7fec4Smrg   if (!(surface->pitches = xalloc(sizeof(int))))
142771d7fec4Smrg      return BadAlloc;
142871d7fec4Smrg   if (!(surface->offsets = xalloc(sizeof(int)))) {
142971d7fec4Smrg      xfree(surface->pitches);
143071d7fec4Smrg      return BadAlloc;
143171d7fec4Smrg   }
143271d7fec4Smrg   if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) {
143371d7fec4Smrg      xfree(surface->pitches);
143471d7fec4Smrg      xfree(surface->offsets);
143571d7fec4Smrg      return BadAlloc;
143671d7fec4Smrg   }
143771d7fec4Smrg
143871d7fec4Smrg   pPriv->area = area;
143971d7fec4Smrg   pPriv->isOn = FALSE;
144071d7fec4Smrg
144171d7fec4Smrg   surface->pScrn = pScrn;
144271d7fec4Smrg   surface->id = id;
144371d7fec4Smrg   surface->pitches[0] = pitch;
144471d7fec4Smrg   surface->offsets[0] = area->box.y1 * fbpitch;
144571d7fec4Smrg   surface->devPrivate.ptr = (pointer) pPriv;
144671d7fec4Smrg
144771d7fec4Smrg   return Success;
144871d7fec4Smrg}
144971d7fec4Smrg
145071d7fec4Smrgstatic int
145171d7fec4SmrgGX1StopSurface(XF86SurfacePtr surface)
145271d7fec4Smrg{
145371d7fec4Smrg   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
145471d7fec4Smrg
145571d7fec4Smrg   if (pPriv->isOn) {
145671d7fec4Smrg      pPriv->isOn = FALSE;
145771d7fec4Smrg   }
145871d7fec4Smrg
145971d7fec4Smrg   return Success;
146071d7fec4Smrg}
146171d7fec4Smrg
146271d7fec4Smrgstatic int
146371d7fec4SmrgGX1FreeSurface(XF86SurfacePtr surface)
146471d7fec4Smrg{
146571d7fec4Smrg   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
146671d7fec4Smrg
146771d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "FreeSurface\n"));
146871d7fec4Smrg
146971d7fec4Smrg   if (pPriv->isOn)
147071d7fec4Smrg      GX1StopSurface(surface);
147171d7fec4Smrg   xf86FreeOffscreenArea(pPriv->area);
147271d7fec4Smrg   xfree(surface->pitches);
147371d7fec4Smrg   xfree(surface->offsets);
147471d7fec4Smrg   xfree(surface->devPrivate.ptr);
147571d7fec4Smrg
147671d7fec4Smrg   return Success;
147771d7fec4Smrg}
147871d7fec4Smrg
147971d7fec4Smrgstatic int
148071d7fec4SmrgGX1GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 * value)
148171d7fec4Smrg{
148271d7fec4Smrg   return GX1GetPortAttribute(pScrn, attribute, value,
148371d7fec4Smrg			      (pointer) (GET_PORT_PRIVATE(pScrn)));
148471d7fec4Smrg}
148571d7fec4Smrg
148671d7fec4Smrgstatic int
148771d7fec4SmrgGX1SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value)
148871d7fec4Smrg{
148971d7fec4Smrg   return GX1SetPortAttribute(pScrn, attribute, value,
149071d7fec4Smrg			      (pointer) (GET_PORT_PRIVATE(pScrn)));
149171d7fec4Smrg}
149271d7fec4Smrg
149371d7fec4Smrgstatic int
149471d7fec4SmrgGX1DisplaySurface(XF86SurfacePtr surface,
149571d7fec4Smrg		  short src_x, short src_y,
149671d7fec4Smrg		  short drw_x, short drw_y,
149771d7fec4Smrg		  short src_w, short src_h,
149871d7fec4Smrg		  short drw_w, short drw_h, RegionPtr clipBoxes)
149971d7fec4Smrg{
150071d7fec4Smrg   OffscreenPrivPtr pPriv = (OffscreenPrivPtr) surface->devPrivate.ptr;
150171d7fec4Smrg   ScrnInfoPtr pScrn = surface->pScrn;
150271d7fec4Smrg   GeodePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn);
150371d7fec4Smrg   INT32 x1, y1, x2, y2;
150471d7fec4Smrg   BoxRec dstBox;
150571d7fec4Smrg
150671d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n"));
150771d7fec4Smrg   x1 = src_x;
150871d7fec4Smrg   x2 = src_x + src_w;
150971d7fec4Smrg   y1 = src_y;
151071d7fec4Smrg   y2 = src_y + src_h;
151171d7fec4Smrg
151271d7fec4Smrg   dstBox.x1 = drw_x;
151371d7fec4Smrg   dstBox.x2 = drw_x + drw_w;
151471d7fec4Smrg   dstBox.y1 = drw_y;
151571d7fec4Smrg   dstBox.y2 = drw_y + drw_h;
151671d7fec4Smrg
151771d7fec4Smrg   if ((x1 >= x2) || (y1 >= y2))
151871d7fec4Smrg      return Success;
151971d7fec4Smrg
152071d7fec4Smrg   dstBox.x1 -= pScrn->frameX0;
152171d7fec4Smrg   dstBox.x2 -= pScrn->frameX0;
152271d7fec4Smrg   dstBox.y1 -= pScrn->frameY0;
152371d7fec4Smrg   dstBox.y2 -= pScrn->frameY0;
152471d7fec4Smrg
152571d7fec4Smrg   xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes);
152671d7fec4Smrg
152771d7fec4Smrg   GX1DisplayVideo(pScrn, surface->id, surface->offsets[0],
152871d7fec4Smrg		   surface->width, surface->height, surface->pitches[0],
152971d7fec4Smrg		   x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h);
153071d7fec4Smrg
153171d7fec4Smrg   pPriv->isOn = TRUE;
153271d7fec4Smrg   if (portPriv->videoStatus & CLIENT_VIDEO_ON) {
153371d7fec4Smrg      REGION_EMPTY(pScrn->pScreen, &portPriv->clip);
153471d7fec4Smrg      UpdateCurrentTime();
153571d7fec4Smrg      portPriv->videoStatus = FREE_TIMER;
153671d7fec4Smrg      portPriv->freeTime = currentTime.milliseconds + FREE_DELAY;
153771d7fec4Smrg   }
153871d7fec4Smrg
153971d7fec4Smrg   return Success;
154071d7fec4Smrg}
154171d7fec4Smrg
154271d7fec4Smrg/*----------------------------------------------------------------------------
154371d7fec4Smrg * GX1InitOffscreenImages
154471d7fec4Smrg *
154571d7fec4Smrg * Description	:This function sets up the offscreen memory management.It fills
154671d7fec4Smrg *				 in the XF86OffscreenImagePtr structure with functions to handle
154771d7fec4Smrg *				 offscreen memory operations.
154871d7fec4Smrg *
154971d7fec4Smrg * Parameters.
155071d7fec4Smrg * ScreenPtr
155171d7fec4Smrg *		pScreen	:Screen handler pointer having screen information.
155271d7fec4Smrg *
155371d7fec4Smrg * Returns		: None
155471d7fec4Smrg *
155571d7fec4Smrg * Comments		:None
155671d7fec4Smrg *
155771d7fec4Smrg*----------------------------------------------------------------------------
155871d7fec4Smrg*/
155971d7fec4Smrgstatic void
156071d7fec4SmrgGX1InitOffscreenImages(ScreenPtr pScreen)
156171d7fec4Smrg{
156271d7fec4Smrg   XF86OffscreenImagePtr offscreenImages;
156371d7fec4Smrg
156471d7fec4Smrg   DEBUGMSG(0, (0, X_NONE, "InitOffscreenImages\n"));
156571d7fec4Smrg   /* need to free this someplace */
156671d7fec4Smrg   if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec))))
156771d7fec4Smrg      return;
156871d7fec4Smrg
156971d7fec4Smrg   offscreenImages[0].image = &Images[0];
157071d7fec4Smrg   offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
157171d7fec4Smrg   offscreenImages[0].alloc_surface = GX1AllocateSurface;
157271d7fec4Smrg   offscreenImages[0].free_surface = GX1FreeSurface;
157371d7fec4Smrg   offscreenImages[0].display = GX1DisplaySurface;
157471d7fec4Smrg   offscreenImages[0].stop = GX1StopSurface;
157571d7fec4Smrg   offscreenImages[0].setAttribute = GX1SetSurfaceAttribute;
157671d7fec4Smrg   offscreenImages[0].getAttribute = GX1GetSurfaceAttribute;
157771d7fec4Smrg   offscreenImages[0].max_width = 1024;
157871d7fec4Smrg   offscreenImages[0].max_height = 1024;
157971d7fec4Smrg   offscreenImages[0].num_attributes = NUM_ATTRIBUTES;
158071d7fec4Smrg   offscreenImages[0].attributes = Attributes;
158171d7fec4Smrg
158271d7fec4Smrg   xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
158371d7fec4Smrg}
1584