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