gx_video.c revision 04007eba
1f29dbc25Smrg/* Copyright (c) 2003-2005 Advanced Micro Devices, Inc. 2f29dbc25Smrg * 3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to 5f29dbc25Smrg * deal in the Software without restriction, including without limitation the 6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is 8f29dbc25Smrg * furnished to do so, subject to the following conditions: 9f29dbc25Smrg * 10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 11f29dbc25Smrg * all copies or substantial portions of the Software. 12f29dbc25Smrg * 13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14f29dbc25Smrg * IMPDIs2IED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19f29dbc25Smrg * IN THE SOFTWARE. 20f29dbc25Smrg * 21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 23f29dbc25Smrg * software without specific prior written permission. 24f29dbc25Smrg * */ 25f29dbc25Smrg 26f29dbc25Smrg/* 27f29dbc25Smrg * File Contents: This file consists of main Xfree video supported routines. 28f29dbc25Smrg * 29f29dbc25Smrg * Project: Geode Xfree Frame buffer device driver. 30f29dbc25Smrg * */ 31f29dbc25Smrg 32f29dbc25Smrg/* 33f29dbc25Smrg * Fixes & Extensions to support Y800 greyscale modes 34f29dbc25Smrg * Alan Hourihane <alanh@fairlite.demon.co.uk> 35f29dbc25Smrg 36f29dbc25Smrg * code to allocate offscreen memory from EXA - is borrowed from Radeon 37f29dbc25Smrg */ 38f29dbc25Smrg 39f29dbc25Smrg#ifdef HAVE_CONFIG_H 40f29dbc25Smrg#include "config.h" 41f29dbc25Smrg#endif 42f29dbc25Smrg 43f29dbc25Smrg#include <stdlib.h> 44f29dbc25Smrg#include <string.h> 45f29dbc25Smrg 46f29dbc25Smrg#include "xf86.h" 47f29dbc25Smrg#include "xf86_OSproc.h" 48f29dbc25Smrg#include "compiler.h" 49f29dbc25Smrg#include "xf86PciInfo.h" 50f29dbc25Smrg#include "xf86Pci.h" 51f29dbc25Smrg#include "xf86fbman.h" 52f29dbc25Smrg#include "regionstr.h" 53f29dbc25Smrg 54f29dbc25Smrg#include "geode.h" 55f29dbc25Smrg#include "xf86xv.h" 56f29dbc25Smrg#include <X11/extensions/Xv.h> 5704007ebaSmrg#ifdef HAVE_XAA_H 58f29dbc25Smrg#include "xaa.h" 59f29dbc25Smrg#include "xaalocal.h" 6004007ebaSmrg#endif 61f29dbc25Smrg#include "dixstruct.h" 62f29dbc25Smrg#include "fourcc.h" 63f29dbc25Smrg#include "geode_fourcc.h" 64f29dbc25Smrg 6504007ebaSmrg#define OFF_DELAY 200 /* milliseconds */ 66f29dbc25Smrg#define FREE_DELAY 60000 67f29dbc25Smrg 68f29dbc25Smrg#define OFF_TIMER 0x01 69f29dbc25Smrg#define FREE_TIMER 0x02 70f29dbc25Smrg#define CLIENT_VIDEO_ON 0x04 71f29dbc25Smrg 72f29dbc25Smrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 73f29dbc25Smrg#define XV_PROFILE 0 74f29dbc25Smrg#define REINIT 1 75f29dbc25Smrg 76f29dbc25Smrg#ifndef XvExtension 77f29dbc25Smrg#error "It didn't work!" 78f29dbc25Smrgvoid 79f29dbc25SmrgGXInitVideo(ScreenPtr pScrn) 80f29dbc25Smrg{ 81f29dbc25Smrg} 82f29dbc25Smrg 83f29dbc25Smrgvoid 84f29dbc25SmrgGXResetVideo(ScrnInfoPtr pScrni) 85f29dbc25Smrg{ 86f29dbc25Smrg} 87f29dbc25Smrg 88f29dbc25Smrgvoid 89f29dbc25SmrgGXSetVideoPosition() 90f29dbc25Smrg{ 91f29dbc25Smrg} 92f29dbc25Smrg#else 93f29dbc25Smrg 94f29dbc25Smrg#define DBUF 1 95f29dbc25Smrgvoid GXResetVideo(ScrnInfoPtr pScrni); 96f29dbc25Smrgstatic XF86VideoAdaptorPtr GXSetupImageVideo(ScreenPtr); 97f29dbc25Smrgstatic void GXInitOffscreenImages(ScreenPtr); 98f29dbc25Smrgstatic void GXStopVideo(ScrnInfoPtr, pointer, Bool); 99f29dbc25Smrgstatic int GXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 100f29dbc25Smrgstatic int GXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); 101f29dbc25Smrgstatic void GXQueryBestSize(ScrnInfoPtr, Bool, 10204007ebaSmrg short, short, short, short, unsigned int *, 10304007ebaSmrg unsigned int *, pointer); 104f29dbc25Smrgstatic int GXPutImage(ScrnInfoPtr, short, short, short, short, short, short, 10504007ebaSmrg short, short, int, unsigned char *, short, short, Bool, 10604007ebaSmrg RegionPtr, pointer, DrawablePtr pDraw); 107f29dbc25Smrg 10804007ebaSmrgstatic void GXBlockHandler(BLOCKHANDLER_ARGS_DECL); 109f29dbc25Smrgvoid GXSetVideoPosition(int x, int y, int width, int height, 11004007ebaSmrg short src_w, short src_h, short drw_w, 11104007ebaSmrg short drw_h, int id, int offset, ScrnInfoPtr pScrni); 112f29dbc25Smrg 113f29dbc25Smrgextern void GXAccelSync(ScrnInfoPtr pScrni); 114f29dbc25Smrg 115f29dbc25Smrgint DeltaX, DeltaY; 116f29dbc25Smrg 117f29dbc25Smrgunsigned long graphics_lut[256]; 118f29dbc25Smrgstatic int lutflag = 0; 119f29dbc25Smrg 120f29dbc25Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 121f29dbc25Smrg 122f29dbc25Smrgstatic Atom xvColorKey, xvColorKeyMode, xvFilter 123f29dbc25Smrg#if DBUF 12404007ebaSmrg, xvDoubleBuffer 125f29dbc25Smrg#endif 12604007ebaSmrg; 127f29dbc25Smrg 128f29dbc25Smrg#define PALETTE_ADDRESS 0x038 129f29dbc25Smrg#define PALETTE_DATA 0x040 130f29dbc25Smrg#define DISPLAY_CONFIG 0x008 131f29dbc25Smrg#define MISC 0x050 132f29dbc25Smrg 133f29dbc25Smrgstatic void 134f29dbc25Smrgget_gamma_ram(unsigned long *lut) 135f29dbc25Smrg{ 136f29dbc25Smrg 137f29dbc25Smrg int i; 138f29dbc25Smrg 139f29dbc25Smrg gfx_write_vid32(PALETTE_ADDRESS, 0); 140f29dbc25Smrg 141f29dbc25Smrg for (i = 0; i < 256; i++) 14204007ebaSmrg lut[i] = gfx_read_vid32(PALETTE_DATA); 143f29dbc25Smrg} 144f29dbc25Smrg 145f29dbc25Smrg/*---------------------------------------------------------------------------- 146f29dbc25Smrg * GXInitVideo 147f29dbc25Smrg * 148f29dbc25Smrg * Description :This is the initialization routine.It creates a new video 149f29dbc25Smrg * adapter and calls GXSetupImageVideo to initialize the adaptor 150f29dbc25Smrg * by filling XF86VideoAdaptorREc.Then it lists the existing 151f29dbc25Smrg * adaptors and adds the new one to it. Finally the list of 152f29dbc25Smrg * XF86VideoAdaptorPtr pointers are passed to the 153f29dbc25Smrg * xf86XVScreenInit(). 154f29dbc25Smrg * 155f29dbc25Smrg * Parameters. 156f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 157f29dbc25Smrg * 158f29dbc25Smrg * Returns :none 159f29dbc25Smrg * 160f29dbc25Smrg * Comments :none 161f29dbc25Smrg *---------------------------------------------------------------------------- 162f29dbc25Smrg */ 163f29dbc25Smrgvoid 164f29dbc25SmrgGXInitVideo(ScreenPtr pScrn) 165f29dbc25Smrg{ 166f29dbc25Smrg GeodeRec *pGeode; 16704007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 168f29dbc25Smrg 169f29dbc25Smrg pGeode = GEODEPTR(pScrni); 170f29dbc25Smrg 171f29dbc25Smrg if (!pGeode->NoAccel) { 17204007ebaSmrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 17304007ebaSmrg XF86VideoAdaptorPtr newAdaptor = NULL; 17404007ebaSmrg 17504007ebaSmrg int num_adaptors; 17604007ebaSmrg 17704007ebaSmrg newAdaptor = GXSetupImageVideo(pScrn); 17804007ebaSmrg GXInitOffscreenImages(pScrn); 17904007ebaSmrg 18004007ebaSmrg num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); 18104007ebaSmrg 18204007ebaSmrg if (newAdaptor) { 18304007ebaSmrg if (!num_adaptors) { 18404007ebaSmrg num_adaptors = 1; 18504007ebaSmrg adaptors = &newAdaptor; 18604007ebaSmrg } 18704007ebaSmrg else { 18804007ebaSmrg newAdaptors = /* need to free this someplace */ 18904007ebaSmrg malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); 19004007ebaSmrg if (newAdaptors) { 19104007ebaSmrg memcpy(newAdaptors, adaptors, num_adaptors * 19204007ebaSmrg sizeof(XF86VideoAdaptorPtr)); 19304007ebaSmrg newAdaptors[num_adaptors] = newAdaptor; 19404007ebaSmrg adaptors = newAdaptors; 19504007ebaSmrg num_adaptors++; 19604007ebaSmrg } 19704007ebaSmrg } 19804007ebaSmrg } 19904007ebaSmrg 20004007ebaSmrg if (num_adaptors) 20104007ebaSmrg xf86XVScreenInit(pScrn, adaptors, num_adaptors); 20204007ebaSmrg 20304007ebaSmrg if (newAdaptors) 20404007ebaSmrg free(newAdaptors); 205f29dbc25Smrg } 206f29dbc25Smrg} 207f29dbc25Smrg 208f29dbc25Smrg/* client libraries expect an encoding */ 209f29dbc25Smrgstatic XF86VideoEncodingRec DummyEncoding[1] = { 210f29dbc25Smrg { 21104007ebaSmrg 0, 21204007ebaSmrg "XV_IMAGE", 21304007ebaSmrg 1024, 1024, 21404007ebaSmrg {1, 1} 21504007ebaSmrg } 216f29dbc25Smrg}; 217f29dbc25Smrg 218f29dbc25Smrg#define NUM_FORMATS 4 219f29dbc25Smrg 220f29dbc25Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = { 221f29dbc25Smrg {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 222f29dbc25Smrg}; 223f29dbc25Smrg 224f29dbc25Smrg#if DBUF 225f29dbc25Smrg#define NUM_ATTRIBUTES 4 226f29dbc25Smrg#else 227f29dbc25Smrg#define NUM_ATTRIBUTES 3 228f29dbc25Smrg#endif 229f29dbc25Smrg 230f29dbc25Smrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { 231f29dbc25Smrg#if DBUF 232f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 233f29dbc25Smrg#endif 234f29dbc25Smrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 235f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, 236f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} 237f29dbc25Smrg}; 238f29dbc25Smrg 239f29dbc25Smrg#define NUM_IMAGES 8 240f29dbc25Smrg 241f29dbc25Smrgstatic XF86ImageRec Images[NUM_IMAGES] = { 242f29dbc25Smrg XVIMAGE_UYVY, 243f29dbc25Smrg XVIMAGE_YUY2, 244f29dbc25Smrg XVIMAGE_Y2YU, 245f29dbc25Smrg XVIMAGE_YVYU, 246f29dbc25Smrg XVIMAGE_Y800, 247f29dbc25Smrg XVIMAGE_I420, 248f29dbc25Smrg XVIMAGE_YV12, 249f29dbc25Smrg XVIMAGE_RGB565 250f29dbc25Smrg}; 251f29dbc25Smrg 25204007ebaSmrgtypedef struct { 253f29dbc25Smrg void *area; 254f29dbc25Smrg int offset; 255f29dbc25Smrg RegionRec clip; 256f29dbc25Smrg CARD32 filter; 257f29dbc25Smrg CARD32 colorKey; 258f29dbc25Smrg CARD32 colorKeyMode; 259f29dbc25Smrg CARD32 videoStatus; 260f29dbc25Smrg Time offTime; 261f29dbc25Smrg Time freeTime; 262f29dbc25Smrg#if DBUF 263f29dbc25Smrg Bool doubleBuffer; 264f29dbc25Smrg int currentBuffer; 265f29dbc25Smrg#endif 266f29dbc25Smrg} GeodePortPrivRec, *GeodePortPrivPtr; 267f29dbc25Smrg 268f29dbc25Smrg#define GET_PORT_PRIVATE(pScrni) \ 269f29dbc25Smrg (GeodePortPrivRec *)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr) 270f29dbc25Smrg 271f29dbc25Smrg/*---------------------------------------------------------------------------- 272f29dbc25Smrg * GXSetColorKey 273f29dbc25Smrg * 274f29dbc25Smrg * Description :This function reads the color key for the pallete and 275f29dbc25Smrg * sets the video color key register. 276f29dbc25Smrg * 277f29dbc25Smrg * Parameters. 278f29dbc25Smrg * ScreenInfoPtr 279f29dbc25Smrg * pScrni :Screen pointer having screen information. 280f29dbc25Smrg * pPriv :Video port private data 281f29dbc25Smrg * 282f29dbc25Smrg * Returns :none 283f29dbc25Smrg * 284f29dbc25Smrg * Comments :none 285f29dbc25Smrg * 286f29dbc25Smrg *---------------------------------------------------------------------------- 287f29dbc25Smrg */ 288f29dbc25Smrgstatic INT32 289f29dbc25SmrgGXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) 290f29dbc25Smrg{ 291f29dbc25Smrg int red, green, blue; 292f29dbc25Smrg unsigned long key; 293f29dbc25Smrg 294f29dbc25Smrg switch (pScrni->depth) { 295f29dbc25Smrg case 8: 29604007ebaSmrg GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); 29704007ebaSmrg red = ((key >> 16) & 0xFF); 29804007ebaSmrg green = ((key >> 8) & 0xFF); 29904007ebaSmrg blue = (key & 0xFF); 30004007ebaSmrg break; 301f29dbc25Smrg case 16: 30204007ebaSmrg red = (pPriv->colorKey & pScrni->mask.red) >> 30304007ebaSmrg pScrni->offset.red << (8 - pScrni->weight.red); 30404007ebaSmrg green = (pPriv->colorKey & pScrni->mask.green) >> 30504007ebaSmrg pScrni->offset.green << (8 - pScrni->weight.green); 30604007ebaSmrg blue = (pPriv->colorKey & pScrni->mask.blue) >> 30704007ebaSmrg pScrni->offset.blue << (8 - pScrni->weight.blue); 30804007ebaSmrg break; 309f29dbc25Smrg default: 31004007ebaSmrg /* for > 16 bpp we send in the mask in xf86SetWeight. This 31104007ebaSmrg * function is providing the offset by 1 more. So we take 31204007ebaSmrg * this as a special case and subtract 1 for > 16 31304007ebaSmrg */ 31404007ebaSmrg red = (pPriv->colorKey & pScrni->mask.red) >> 31504007ebaSmrg (pScrni->offset.red - 1) << (8 - pScrni->weight.red); 31604007ebaSmrg green = (pPriv->colorKey & pScrni->mask.green) >> 31704007ebaSmrg (pScrni->offset.green - 1) << (8 - pScrni->weight.green); 31804007ebaSmrg blue = (pPriv->colorKey & pScrni->mask.blue) >> 31904007ebaSmrg (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); 32004007ebaSmrg break; 321f29dbc25Smrg } 322f29dbc25Smrg 323f29dbc25Smrg GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, 32404007ebaSmrg (pPriv->colorKeyMode == 0))); 325f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &pPriv->clip); 326f29dbc25Smrg return 0; 327f29dbc25Smrg} 328f29dbc25Smrg 329f29dbc25Smrg/*---------------------------------------------------------------------------- 330f29dbc25Smrg * GXResetVideo 331f29dbc25Smrg * 332f29dbc25Smrg * Description : This function resets the video 333f29dbc25Smrg * 334f29dbc25Smrg * Parameters. 335f29dbc25Smrg * pScrni :Screen pointer having screen information. 336f29dbc25Smrg * 337f29dbc25Smrg * Returns :None 338f29dbc25Smrg * 339f29dbc25Smrg * Comments :none 340f29dbc25Smrg * 341f29dbc25Smrg *---------------------------------------------------------------------------- 342f29dbc25Smrg */ 343f29dbc25Smrgvoid 344f29dbc25SmrgGXResetVideo(ScrnInfoPtr pScrni) 345f29dbc25Smrg{ 346f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 347f29dbc25Smrg 348f29dbc25Smrg if (!pGeode->NoAccel) { 34904007ebaSmrg GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; 350f29dbc25Smrg 35104007ebaSmrg GXAccelSync(pScrni); 35204007ebaSmrg GXSetColorkey(pScrni, pPriv); 35304007ebaSmrg GFX(set_video_filter(pPriv->filter, pPriv->filter)); 354f29dbc25Smrg } 355f29dbc25Smrg} 356f29dbc25Smrg 357f29dbc25Smrg/*---------------------------------------------------------------------------- 358f29dbc25Smrg * GXSetupImageVideo 359f29dbc25Smrg * 360f29dbc25Smrg * Description : This function allocates space for a Videoadaptor and 361f29dbc25Smrg * initializes the XF86VideoAdaptorPtr record. 362f29dbc25Smrg * 363f29dbc25Smrg * Parameters. 364f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 365f29dbc25Smrg * 366f29dbc25Smrg * Returns :pointer to the initialized video adaptor record. 367f29dbc25Smrg * 368f29dbc25Smrg * Comments :none 369f29dbc25Smrg *---------------------------------------------------------------------------- 370f29dbc25Smrg */ 371f29dbc25Smrgstatic XF86VideoAdaptorPtr 372f29dbc25SmrgGXSetupImageVideo(ScreenPtr pScrn) 373f29dbc25Smrg{ 37404007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 375f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 376f29dbc25Smrg XF86VideoAdaptorPtr adapt; 377f29dbc25Smrg GeodePortPrivRec *pPriv; 378f29dbc25Smrg 379170d5fdcSmrg if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 38004007ebaSmrg sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) 38104007ebaSmrg return NULL; 382f29dbc25Smrg 383f29dbc25Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 384f29dbc25Smrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 385f29dbc25Smrg adapt->name = "Advanced Micro Devices"; 386f29dbc25Smrg adapt->nEncodings = 1; 387f29dbc25Smrg adapt->pEncodings = DummyEncoding; 388f29dbc25Smrg adapt->nFormats = NUM_FORMATS; 389f29dbc25Smrg adapt->pFormats = Formats; 390f29dbc25Smrg adapt->nPorts = 1; 391f29dbc25Smrg adapt->pPortPrivates = (DevUnion *) (&adapt[1]); 392f29dbc25Smrg pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); 393f29dbc25Smrg adapt->pPortPrivates[0].ptr = (pointer) (pPriv); 394f29dbc25Smrg adapt->pAttributes = Attributes; 395f29dbc25Smrg adapt->nImages = NUM_IMAGES; 396f29dbc25Smrg adapt->nAttributes = NUM_ATTRIBUTES; 397f29dbc25Smrg adapt->pImages = Images; 398f29dbc25Smrg adapt->PutVideo = NULL; 399f29dbc25Smrg adapt->PutStill = NULL; 400f29dbc25Smrg adapt->GetVideo = NULL; 401f29dbc25Smrg adapt->GetStill = NULL; 402f29dbc25Smrg adapt->StopVideo = GXStopVideo; 403f29dbc25Smrg adapt->SetPortAttribute = GXSetPortAttribute; 404f29dbc25Smrg adapt->GetPortAttribute = GXGetPortAttribute; 405f29dbc25Smrg adapt->QueryBestSize = GXQueryBestSize; 406f29dbc25Smrg adapt->PutImage = GXPutImage; 407f29dbc25Smrg adapt->QueryImageAttributes = GeodeQueryImageAttributes; 408f29dbc25Smrg 409f29dbc25Smrg pPriv->filter = 0; 410f29dbc25Smrg pPriv->colorKey = 0; 411f29dbc25Smrg pPriv->colorKeyMode = 0; 412f29dbc25Smrg pPriv->videoStatus = 0; 413f29dbc25Smrg#if DBUF 414f29dbc25Smrg pPriv->doubleBuffer = TRUE; 41504007ebaSmrg pPriv->currentBuffer = 0; /* init to first buffer */ 416f29dbc25Smrg#endif 417f29dbc25Smrg 418f29dbc25Smrg /* gotta uninit this someplace */ 419f29dbc25Smrg#if defined(REGION_NULL) 420f29dbc25Smrg REGION_NULL(pScrn, &pPriv->clip); 421f29dbc25Smrg#else 422f29dbc25Smrg REGION_INIT(pScrn, &pPriv->clip, NullBox, 0); 423f29dbc25Smrg#endif 424f29dbc25Smrg 425f29dbc25Smrg pGeode->adaptor = adapt; 426f29dbc25Smrg 427f29dbc25Smrg pGeode->BlockHandler = pScrn->BlockHandler; 428f29dbc25Smrg pScrn->BlockHandler = GXBlockHandler; 429f29dbc25Smrg 430f29dbc25Smrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 431f29dbc25Smrg xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); 432f29dbc25Smrg xvFilter = MAKE_ATOM("XV_FILTER"); 433f29dbc25Smrg#if DBUF 434f29dbc25Smrg xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 435f29dbc25Smrg#endif 436f29dbc25Smrg 437f29dbc25Smrg GXResetVideo(pScrni); 438f29dbc25Smrg 439f29dbc25Smrg return adapt; 440f29dbc25Smrg} 441f29dbc25Smrg 442f29dbc25Smrg/*---------------------------------------------------------------------------- 443f29dbc25Smrg * GXStopVideo 444f29dbc25Smrg * 445f29dbc25Smrg * Description :This function is used to stop input and output video 446f29dbc25Smrg * 447f29dbc25Smrg * Parameters. 448f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 449f29dbc25Smrg * data :Pointer to the video port's private data 450f29dbc25Smrg * exit :Flag indicating whether the offscreen areas used for 451f29dbc25Smrg * video to be deallocated or not. 452f29dbc25Smrg * 453f29dbc25Smrg * Returns :none 454f29dbc25Smrg * 455f29dbc25Smrg * Comments :none 456f29dbc25Smrg *---------------------------------------------------------------------------- 457f29dbc25Smrg */ 458f29dbc25Smrgstatic void 459f29dbc25SmrgGXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) 460f29dbc25Smrg{ 461f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 462f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 463f29dbc25Smrg 464f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &pPriv->clip); 465f29dbc25Smrg 466f29dbc25Smrg GXAccelSync(pScrni); 467f29dbc25Smrg if (exit) { 46804007ebaSmrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 46904007ebaSmrg GFX(set_video_enable(0)); 470f29dbc25Smrg 47104007ebaSmrg /* If we have saved graphics LUT data - restore it */ 47204007ebaSmrg /* Otherwise, turn bypass on */ 473f29dbc25Smrg 47404007ebaSmrg if (lutflag) 47504007ebaSmrg GFX(set_graphics_palette(graphics_lut)); 47604007ebaSmrg else 47704007ebaSmrg GFX(set_video_palette_bypass(1)); 478f29dbc25Smrg 47904007ebaSmrg lutflag = 0; 48004007ebaSmrg } 481f29dbc25Smrg 48204007ebaSmrg if (pPriv->area) { 483f29dbc25Smrg#ifdef XF86EXA 48404007ebaSmrg if (pGeode->useEXA) 48504007ebaSmrg exaOffscreenFree(pScrni->pScreen, pPriv->area); 486f29dbc25Smrg#endif 487f29dbc25Smrg 48804007ebaSmrg if (!pGeode->useEXA) 48904007ebaSmrg xf86FreeOffscreenArea(pPriv->area); 490f29dbc25Smrg 49104007ebaSmrg pPriv->area = NULL; 49204007ebaSmrg } 493f29dbc25Smrg 49404007ebaSmrg pPriv->videoStatus = 0; 49504007ebaSmrg pGeode->OverlayON = FALSE; 49604007ebaSmrg } 49704007ebaSmrg else { 49804007ebaSmrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 49904007ebaSmrg pPriv->videoStatus |= OFF_TIMER; 50004007ebaSmrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 50104007ebaSmrg } 502f29dbc25Smrg } 503f29dbc25Smrg} 504f29dbc25Smrg 505f29dbc25Smrg/*---------------------------------------------------------------------------- 506f29dbc25Smrg * GXSetPortAttribute 507f29dbc25Smrg * 508f29dbc25Smrg * Description :This function is used to set the attributes of a port 509f29dbc25Smrg * like colorkeymode, double buffer support and filter. 510f29dbc25Smrg * 511f29dbc25Smrg * Parameters. 512f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 513f29dbc25Smrg * data :Pointer to the video port's private data 514f29dbc25Smrg * attribute :The port attribute to be set 515f29dbc25Smrg * value :Value of the attribute to be set. 516f29dbc25Smrg * 517f29dbc25Smrg * Returns :Sucess if the attribute is supported, else BadMatch 518f29dbc25Smrg * 519f29dbc25Smrg * Comments :none 520f29dbc25Smrg *---------------------------------------------------------------------------- 521f29dbc25Smrg */ 522f29dbc25Smrgstatic int 523f29dbc25SmrgGXSetPortAttribute(ScrnInfoPtr pScrni, 52404007ebaSmrg Atom attribute, INT32 value, pointer data) 525f29dbc25Smrg{ 526f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 527f29dbc25Smrg 528f29dbc25Smrg GXAccelSync(pScrni); 529f29dbc25Smrg if (attribute == xvColorKey) { 53004007ebaSmrg pPriv->colorKey = value; 53104007ebaSmrg GXSetColorkey(pScrni, pPriv); 532f29dbc25Smrg } 533f29dbc25Smrg#if DBUF 534f29dbc25Smrg else if (attribute == xvDoubleBuffer) { 53504007ebaSmrg if ((value < 0) || (value > 1)) 53604007ebaSmrg return BadValue; 53704007ebaSmrg pPriv->doubleBuffer = value; 538f29dbc25Smrg } 539f29dbc25Smrg#endif 540f29dbc25Smrg else if (attribute == xvColorKeyMode) { 54104007ebaSmrg pPriv->colorKeyMode = value; 54204007ebaSmrg GXSetColorkey(pScrni, pPriv); 54304007ebaSmrg } 54404007ebaSmrg else if (attribute == xvFilter) { 54504007ebaSmrg if ((value < 0) || (value > 1)) 54604007ebaSmrg return BadValue; 54704007ebaSmrg pPriv->filter = value; 54804007ebaSmrg } 54904007ebaSmrg else 55004007ebaSmrg return BadMatch; 551f29dbc25Smrg 552f29dbc25Smrg return Success; 553f29dbc25Smrg} 554f29dbc25Smrg 555f29dbc25Smrg/*---------------------------------------------------------------------------- 556f29dbc25Smrg * GXGetPortAttribute 557f29dbc25Smrg * 558f29dbc25Smrg * Description :This function is used to get the attributes of a port 559f29dbc25Smrg * like hue, saturation,brightness or contrast. 560f29dbc25Smrg * 561f29dbc25Smrg * Parameters. 562f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 563f29dbc25Smrg * data :Pointer to the video port's private data 564f29dbc25Smrg * attribute :The port attribute to be read 565f29dbc25Smrg * value :Pointer to the value of the attribute to be read. 566f29dbc25Smrg * 567f29dbc25Smrg * Returns :Sucess if the attribute is supported, else BadMatch 568f29dbc25Smrg * 569f29dbc25Smrg * Comments :none 570f29dbc25Smrg *---------------------------------------------------------------------------- 571f29dbc25Smrg */ 572f29dbc25Smrgstatic int 573f29dbc25SmrgGXGetPortAttribute(ScrnInfoPtr pScrni, 57404007ebaSmrg Atom attribute, INT32 *value, pointer data) 575f29dbc25Smrg{ 576f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 577f29dbc25Smrg 578f29dbc25Smrg if (attribute == xvColorKey) { 57904007ebaSmrg *value = pPriv->colorKey; 580f29dbc25Smrg } 581f29dbc25Smrg#if DBUF 582f29dbc25Smrg else if (attribute == xvDoubleBuffer) { 58304007ebaSmrg *value = (pPriv->doubleBuffer) ? 1 : 0; 584f29dbc25Smrg } 585f29dbc25Smrg#endif 586f29dbc25Smrg else if (attribute == xvColorKeyMode) { 58704007ebaSmrg *value = pPriv->colorKeyMode; 58804007ebaSmrg } 58904007ebaSmrg else if (attribute == xvFilter) { 59004007ebaSmrg *value = pPriv->filter; 59104007ebaSmrg } 59204007ebaSmrg else 59304007ebaSmrg return BadMatch; 594f29dbc25Smrg 595f29dbc25Smrg return Success; 596f29dbc25Smrg} 597f29dbc25Smrg 598f29dbc25Smrg/*---------------------------------------------------------------------------- 599f29dbc25Smrg * GXQueryBestSize 600f29dbc25Smrg * 601f29dbc25Smrg * Description :This function provides a way to query what the 602f29dbc25Smrg * destination dimensions would end up being if they were to 603f29dbc25Smrg * request that an area vid_w by vid_h from the video stream 604f29dbc25Smrg * be scaled to rectangle of drw_w by drw_h on the screen. 605f29dbc25Smrg * 606f29dbc25Smrg * Parameters. 607f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 608f29dbc25Smrg * data :Pointer to the video port's private data 609f29dbc25Smrg * vid_w,vid_h :Width and height of the video data. 610f29dbc25Smrg * drw_w,drw_h :Width and height of the scaled rectangle. 611f29dbc25Smrg * p_w,p_h :Width and height of the destination rectangle. 612f29dbc25Smrg * 613f29dbc25Smrg * Returns :None 614f29dbc25Smrg * 615f29dbc25Smrg * Comments :None 616f29dbc25Smrg *---------------------------------------------------------------------------- 617f29dbc25Smrg */ 618f29dbc25Smrgstatic void 619f29dbc25SmrgGXQueryBestSize(ScrnInfoPtr pScrni, 62004007ebaSmrg Bool motion, 62104007ebaSmrg short vid_w, short vid_h, 62204007ebaSmrg short drw_w, short drw_h, 62304007ebaSmrg unsigned int *p_w, unsigned int *p_h, pointer data) 624f29dbc25Smrg{ 625f29dbc25Smrg *p_w = drw_w; 626f29dbc25Smrg *p_h = drw_h; 627f29dbc25Smrg 628f29dbc25Smrg if (*p_w > 16384) 62904007ebaSmrg *p_w = 16384; 630f29dbc25Smrg} 631f29dbc25Smrg 632f29dbc25Smrg/*---------------------------------------------------------------------------- 633f29dbc25Smrg * GXCopyData420 634f29dbc25Smrg * 635f29dbc25Smrg * Description : Copies data from src to destination 636f29dbc25Smrg * 637f29dbc25Smrg * Parameters. 638f29dbc25Smrg * src : pointer to the source data 639f29dbc25Smrg * dst : pointer to destination data 640f29dbc25Smrg * srcPitch : pitch of the srcdata 641f29dbc25Smrg * dstPitch : pitch of the destination data 642f29dbc25Smrg * h & w : height and width of source data 643f29dbc25Smrg * 644f29dbc25Smrg * Returns :None 645f29dbc25Smrg * 646f29dbc25Smrg * Comments :None 647f29dbc25Smrg *---------------------------------------------------------------------------- 648f29dbc25Smrg */ 649f29dbc25Smrgstatic void 650f29dbc25SmrgGXCopyData420(unsigned char *src, unsigned char *dst, 65104007ebaSmrg int srcPitch, int dstPitch, int h, int w) 652f29dbc25Smrg{ 653f29dbc25Smrg while (h--) { 65404007ebaSmrg memcpy(dst, src, w); 65504007ebaSmrg src += srcPitch; 65604007ebaSmrg dst += dstPitch; 657f29dbc25Smrg } 658f29dbc25Smrg} 659f29dbc25Smrg 660f29dbc25Smrg/*---------------------------------------------------------------------------- 661f29dbc25Smrg * GXCopyData422 662f29dbc25Smrg * 663f29dbc25Smrg * Description : Copies data from src to destination 664f29dbc25Smrg * 665f29dbc25Smrg * Parameters. 666f29dbc25Smrg * src : pointer to the source data 667f29dbc25Smrg * dst : pointer to destination data 668f29dbc25Smrg * srcPitch : pitch of the srcdata 669f29dbc25Smrg * dstPitch : pitch of the destination data 670f29dbc25Smrg * h & w : height and width of source data 671f29dbc25Smrg * 672f29dbc25Smrg * Returns :None 673f29dbc25Smrg * 674f29dbc25Smrg * Comments :None 675f29dbc25Smrg *---------------------------------------------------------------------------- 676f29dbc25Smrg */ 677f29dbc25Smrgstatic void 678f29dbc25SmrgGXCopyData422(unsigned char *src, unsigned char *dst, 67904007ebaSmrg int srcPitch, int dstPitch, int h, int w) 680f29dbc25Smrg{ 681f29dbc25Smrg w <<= 1; 682f29dbc25Smrg while (h--) { 68304007ebaSmrg memcpy(dst, src, w); 68404007ebaSmrg src += srcPitch; 68504007ebaSmrg dst += dstPitch; 686f29dbc25Smrg } 687f29dbc25Smrg} 688f29dbc25Smrg 689f29dbc25Smrg#ifdef XF86EXA 690f29dbc25Smrgstatic void 691f29dbc25SmrgGXVideoSave(ScreenPtr pScreen, ExaOffscreenArea * area) 692f29dbc25Smrg{ 69304007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 694f29dbc25Smrg GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); 695f29dbc25Smrg 696f29dbc25Smrg if (area == pPriv->area) 69704007ebaSmrg pPriv->area = NULL; 698f29dbc25Smrg} 699f29dbc25Smrg#endif 700f29dbc25Smrg 701f29dbc25Smrgstatic int 702f29dbc25SmrgGXAllocateMemory(ScrnInfoPtr pScrni, void **memp, int numlines) 703f29dbc25Smrg{ 70404007ebaSmrg ScreenPtr pScrn = xf86ScrnToScreen(pScrni); 705f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 706f29dbc25Smrg 707f29dbc25Smrg //long displayWidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); 708f29dbc25Smrg int size = numlines * pGeode->displayWidth; 709f29dbc25Smrg 710f29dbc25Smrg#if XF86EXA 711f29dbc25Smrg if (pGeode->useEXA) { 71204007ebaSmrg ExaOffscreenArea *area = *memp; 713f29dbc25Smrg 71404007ebaSmrg if (area != NULL) { 71504007ebaSmrg if (area->size >= size) 71604007ebaSmrg return area->offset; 717f29dbc25Smrg 71804007ebaSmrg exaOffscreenFree(pScrni->pScreen, area); 71904007ebaSmrg } 720f29dbc25Smrg 72104007ebaSmrg area = exaOffscreenAlloc(pScrni->pScreen, size, 16, 72204007ebaSmrg TRUE, GXVideoSave, NULL); 72304007ebaSmrg *memp = area; 724f29dbc25Smrg 72504007ebaSmrg return area == NULL ? 0 : area->offset; 726f29dbc25Smrg } 727f29dbc25Smrg#endif 728f29dbc25Smrg 729f29dbc25Smrg if (!pGeode->useEXA) { 73004007ebaSmrg FBAreaPtr area = *memp; 73104007ebaSmrg FBAreaPtr new_area; 732f29dbc25Smrg 73304007ebaSmrg if (area) { 73404007ebaSmrg if ((area->box.y2 - area->box.y1) >= numlines) 73504007ebaSmrg return (area->box.y1 * pGeode->Pitch); 736f29dbc25Smrg 73704007ebaSmrg if (xf86ResizeOffscreenArea(area, pGeode->displayWidth, numlines)) 73804007ebaSmrg return (area->box.y1 * pGeode->Pitch); 739f29dbc25Smrg 74004007ebaSmrg xf86FreeOffscreenArea(area); 74104007ebaSmrg } 742f29dbc25Smrg 74304007ebaSmrg new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, 74404007ebaSmrg numlines, 0, NULL, NULL, NULL); 745f29dbc25Smrg 74604007ebaSmrg if (!new_area) { 74704007ebaSmrg int max_w, max_h; 748f29dbc25Smrg 74904007ebaSmrg xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, 75004007ebaSmrg FAVOR_WIDTH_THEN_AREA, 75104007ebaSmrg PRIORITY_EXTREME); 752f29dbc25Smrg 75304007ebaSmrg if ((max_w < pGeode->displayWidth) || (max_h < numlines)) { 75404007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 75504007ebaSmrg "No room - how sad %x, %x, %x, %x\n", max_w, 75604007ebaSmrg pGeode->displayWidth, max_h, numlines); 75704007ebaSmrg return 0; 75804007ebaSmrg } 759f29dbc25Smrg 76004007ebaSmrg xf86PurgeUnlockedOffscreenAreas(pScrn); 76104007ebaSmrg new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, 76204007ebaSmrg numlines, 0, NULL, NULL, NULL); 76304007ebaSmrg } 764f29dbc25Smrg 76504007ebaSmrg return (new_area->box.y1 * pGeode->Pitch); 766f29dbc25Smrg } 767f29dbc25Smrg 768f29dbc25Smrg return 0; 769f29dbc25Smrg} 770f29dbc25Smrg 771f29dbc25Smrgstatic BoxRec dstBox; 772f29dbc25Smrgstatic int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; 773f29dbc25Smrgstatic INT32 Bx1, Bx2, By1, By2; 774f29dbc25Smrgstatic int top, left, npixels, nlines; 775f29dbc25Smrgstatic int offset, s1offset = 0, s2offset = 0, s3offset = 0; 776f29dbc25Smrgstatic unsigned char *dst_start; 777f29dbc25Smrgstatic int d2offset = 0, d3offset = 0; 778f29dbc25Smrg 779f29dbc25Smrg#if 0 780f29dbc25Smrgstatic Bool 781f29dbc25SmrgRegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) 782f29dbc25Smrg{ 783f29dbc25Smrg pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); 784f29dbc25Smrg pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); 785f29dbc25Smrg 786f29dbc25Smrg if (pRclResult->x1 <= pRclResult->x2) { 78704007ebaSmrg pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); 78804007ebaSmrg pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); 789f29dbc25Smrg 79004007ebaSmrg if (pRclResult->y1 <= pRclResult->y2) { 79104007ebaSmrg return (TRUE); 79204007ebaSmrg } 793f29dbc25Smrg } 794f29dbc25Smrg 795f29dbc25Smrg return (FALSE); 796f29dbc25Smrg} 797f29dbc25Smrg#endif 798f29dbc25Smrg 799f29dbc25Smrgvoid 800f29dbc25SmrgGXSetVideoPosition(int x, int y, int width, int height, 80104007ebaSmrg short src_w, short src_h, short drw_w, short drw_h, 80204007ebaSmrg int id, int offset, ScrnInfoPtr pScrni) 803f29dbc25Smrg{ 804f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 805f29dbc25Smrg long ystart, xend, yend; 806f29dbc25Smrg unsigned long lines = 0; 807f29dbc25Smrg unsigned long y_extra, uv_extra = 0; 808f29dbc25Smrg unsigned long startAddress; 809f29dbc25Smrg 810f29dbc25Smrg#if 0 811f29dbc25Smrg BoxRec ovly, display, result; 812f29dbc25Smrg#endif 813f29dbc25Smrg 814f29dbc25Smrg xend = x + drw_w; 815f29dbc25Smrg yend = y + drw_h; 816f29dbc25Smrg 817f29dbc25Smrg /* Take care of panning when panel is present */ 818f29dbc25Smrg 819f29dbc25Smrg startAddress = gfx_get_display_offset(); 820f29dbc25Smrg DeltaY = startAddress / pGeode->Pitch; 821f29dbc25Smrg DeltaX = startAddress & (pGeode->Pitch - 1); 822f29dbc25Smrg DeltaX /= (pScrni->bitsPerPixel >> 3); 823f29dbc25Smrg 824f29dbc25Smrg#if 0 825f29dbc25Smrg /* Thhis code is pretty dang broken - comment it out for now */ 826f29dbc25Smrg 827f29dbc25Smrg if (pGeode->Panel) { 82804007ebaSmrg ovly.x1 = x; 82904007ebaSmrg ovly.x2 = x + pGeode->video_dstw; 83004007ebaSmrg ovly.y1 = y; 83104007ebaSmrg ovly.y2 = y + pGeode->video_dsth; 83204007ebaSmrg 83304007ebaSmrg display.x1 = DeltaX; 83404007ebaSmrg display.x2 = DeltaX + pGeode->FPBX; 83504007ebaSmrg display.y1 = DeltaY; 83604007ebaSmrg display.y2 = DeltaY + pGeode->FPBY; 83704007ebaSmrg x = xend = 0; 83804007ebaSmrg if (RegionsIntersect(&display, &ovly, &result)) { 83904007ebaSmrg x = ovly.x1 - DeltaX; 84004007ebaSmrg xend = ovly.x2 - DeltaX; 84104007ebaSmrg y = ovly.y1 - DeltaY; 84204007ebaSmrg yend = ovly.y2 - DeltaY; 84304007ebaSmrg } 844f29dbc25Smrg } 845f29dbc25Smrg#endif 846f29dbc25Smrg 847f29dbc25Smrg /* TOP CLIPPING */ 848f29dbc25Smrg 849f29dbc25Smrg if (y < 0) { 85004007ebaSmrg if (src_h < drw_h) 85104007ebaSmrg lines = (-y) * src_h / drw_h; 85204007ebaSmrg else 85304007ebaSmrg lines = (-y); 85404007ebaSmrg ystart = 0; 85504007ebaSmrg drw_h += y; 85604007ebaSmrg y_extra = lines * dstPitch; 85704007ebaSmrg uv_extra = (lines >> 1) * (dstPitch2); 85804007ebaSmrg } 85904007ebaSmrg else { 86004007ebaSmrg ystart = y; 86104007ebaSmrg lines = 0; 86204007ebaSmrg y_extra = 0; 863f29dbc25Smrg } 864f29dbc25Smrg 865f29dbc25Smrg GFX(set_video_window(x, ystart, xend - x, yend - ystart)); 866f29dbc25Smrg 867f29dbc25Smrg if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { 86804007ebaSmrg GFX(set_video_yuv_offsets(offset + y_extra, 86904007ebaSmrg offset + d3offset + uv_extra, 87004007ebaSmrg offset + d2offset + uv_extra)); 87104007ebaSmrg } 87204007ebaSmrg else { 87304007ebaSmrg GFX(set_video_offset(offset + y_extra)); 874f29dbc25Smrg } 875f29dbc25Smrg} 876f29dbc25Smrg 877f29dbc25Smrg/*---------------------------------------------------------------------------- 878f29dbc25Smrg * GXDisplayVideo 879f29dbc25Smrg * 880f29dbc25Smrg * Description :This function sets up the video registers for playing video 881f29dbc25Smrg * It sets up the video format,width, height & position of the 882f29dbc25Smrg * video window ,video offsets( y,u,v) and video pitches(y,u,v) 883f29dbc25Smrg * 884f29dbc25Smrg * Parameters 885f29dbc25Smrg * 886f29dbc25Smrg * Returns :None 887f29dbc25Smrg * 888f29dbc25Smrg * Comments :None 889f29dbc25Smrg *---------------------------------------------------------------------------- 890f29dbc25Smrg */ 891f29dbc25Smrg 892f29dbc25Smrgstatic void 893f29dbc25SmrgGXDisplayVideo(ScrnInfoPtr pScrni, 89404007ebaSmrg int id, 89504007ebaSmrg int offset, 89604007ebaSmrg short width, short height, 89704007ebaSmrg int pitch, 89804007ebaSmrg int x1, int y1, int x2, int y2, 89904007ebaSmrg BoxPtr dstBox, short src_w, short src_h, short drw_w, 90004007ebaSmrg short drw_h) 901f29dbc25Smrg{ 902f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 903f29dbc25Smrg unsigned long dcfg, misc; 904f29dbc25Smrg 905f29dbc25Smrg GXAccelSync(pScrni); 906f29dbc25Smrg 907f29dbc25Smrg /* If the gamma LUT is already loaded with graphics data, then save it 908f29dbc25Smrg * off 909f29dbc25Smrg */ 910f29dbc25Smrg 911f29dbc25Smrg if (id != FOURCC_RGB565) { 91204007ebaSmrg dcfg = gfx_read_vid32(DISPLAY_CONFIG); 91304007ebaSmrg misc = gfx_read_vid32(MISC); 914f29dbc25Smrg 91504007ebaSmrg lutflag = (!(misc & 1) && (dcfg & (1 << 21))); 916f29dbc25Smrg 91704007ebaSmrg if (lutflag) 91804007ebaSmrg get_gamma_ram(graphics_lut); 919f29dbc25Smrg 92004007ebaSmrg /* Set the video gamma ram */ 92104007ebaSmrg GFX(set_video_palette(NULL)); 922f29dbc25Smrg } 923f29dbc25Smrg 924f29dbc25Smrg GFX(set_video_enable(1)); 925f29dbc25Smrg 926f29dbc25Smrg switch (id) { 92704007ebaSmrg case FOURCC_UYVY: /* UYVY */ 92804007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_UYVY)); 92904007ebaSmrg GFX(set_video_size(width, height)); 93004007ebaSmrg break; 93104007ebaSmrg case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ 93204007ebaSmrg case FOURCC_YV12: /* YV12 */ 93304007ebaSmrg case FOURCC_I420: /* I420 */ 93404007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_Y0Y1Y2Y3)); 93504007ebaSmrg GFX(set_video_size(width, height)); 93604007ebaSmrg GFX(set_video_yuv_pitch(dstPitch, dstPitch2)); 93704007ebaSmrg break; 93804007ebaSmrg case FOURCC_YUY2: /* YUY2 */ 93904007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_YUYV)); 94004007ebaSmrg GFX(set_video_size(width, height)); 94104007ebaSmrg break; 94204007ebaSmrg case FOURCC_Y2YU: /* Y2YU */ 94304007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_Y2YU)); 94404007ebaSmrg GFX(set_video_size(width, height)); 94504007ebaSmrg break; 94604007ebaSmrg case FOURCC_YVYU: /* YVYU */ 94704007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_YVYU)); 94804007ebaSmrg GFX(set_video_size(width, height)); 94904007ebaSmrg break; 950f29dbc25Smrg case FOURCC_RGB565: 95104007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_RGB)); 95204007ebaSmrg GFX(set_video_size(width, height)); 95304007ebaSmrg break; 954f29dbc25Smrg 955f29dbc25Smrg } 956f29dbc25Smrg 957f29dbc25Smrg if (pGeode->Panel) { 95804007ebaSmrg pGeode->video_x = dstBox->x1; 95904007ebaSmrg pGeode->video_y = dstBox->y1; 96004007ebaSmrg pGeode->video_w = width; 96104007ebaSmrg pGeode->video_h = height; 96204007ebaSmrg pGeode->video_srcw = src_w; 96304007ebaSmrg pGeode->video_srch = src_h; 96404007ebaSmrg pGeode->video_dstw = drw_w; 96504007ebaSmrg pGeode->video_dsth = drw_h; 96604007ebaSmrg pGeode->video_offset = offset; 96704007ebaSmrg pGeode->video_id = id; 96804007ebaSmrg pGeode->video_scrnptr = pScrni; 969f29dbc25Smrg } 970f29dbc25Smrg 971f29dbc25Smrg if ((drw_w >= src_w) && (drw_h >= src_h)) 97204007ebaSmrg GFX(set_video_scale(width, height, drw_w, drw_h)); 973f29dbc25Smrg else if (drw_w < src_w) 97404007ebaSmrg GFX(set_video_scale(drw_w, height, drw_w, drw_h)); 975f29dbc25Smrg else if (drw_h < src_h) 97604007ebaSmrg GFX(set_video_scale(width, drw_h, drw_w, drw_h)); 977f29dbc25Smrg 978f29dbc25Smrg GXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, 97904007ebaSmrg src_h, drw_w, drw_h, id, offset, pScrni); 980f29dbc25Smrg} 981f29dbc25Smrg 982f29dbc25Smrg/* Used by LX as well */ 983f29dbc25Smrg 984f29dbc25SmrgBool 985f29dbc25SmrgRegionsEqual(RegionPtr A, RegionPtr B) 986f29dbc25Smrg{ 987f29dbc25Smrg int *dataA, *dataB; 988f29dbc25Smrg int num; 989f29dbc25Smrg 990f29dbc25Smrg num = REGION_NUM_RECTS(A); 991f29dbc25Smrg if (num != REGION_NUM_RECTS(B)) { 99204007ebaSmrg return FALSE; 993f29dbc25Smrg } 994f29dbc25Smrg 995f29dbc25Smrg if ((A->extents.x1 != B->extents.x1) || 99604007ebaSmrg (A->extents.x2 != B->extents.x2) || 99704007ebaSmrg (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) 99804007ebaSmrg return FALSE; 999f29dbc25Smrg 100004007ebaSmrg dataA = (int *) REGION_RECTS(A); 100104007ebaSmrg dataB = (int *) REGION_RECTS(B); 1002f29dbc25Smrg 1003f29dbc25Smrg while (num--) { 100404007ebaSmrg if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) 100504007ebaSmrg return FALSE; 1006f29dbc25Smrg 100704007ebaSmrg dataA += 2; 100804007ebaSmrg dataB += 2; 1009f29dbc25Smrg } 1010f29dbc25Smrg 1011f29dbc25Smrg return TRUE; 1012f29dbc25Smrg} 1013f29dbc25Smrg 1014f29dbc25Smrg/*---------------------------------------------------------------------------- 1015f29dbc25Smrg * GXPutImage :This function writes a single frame of video into a 1016f29dbc25Smrg * drawable. The position and size of the source rectangle is 1017f29dbc25Smrg * specified by src_x,src_y, src_w and src_h. This data is 1018f29dbc25Smrg * stored in a system memory buffer at buf. The position and 1019f29dbc25Smrg * size of the destination rectangle is specified by drw_x, 1020f29dbc25Smrg * drw_y,drw_w,drw_h.The data is in the format indicated by the 1021f29dbc25Smrg * image descriptor and represents a source of size width by 1022f29dbc25Smrg * height. If sync is TRUE the driver should not return from 1023f29dbc25Smrg * this function until it is through reading the data from buf. 1024f29dbc25Smrg * Returning when sync is TRUE indicates that it is safe for the 1025f29dbc25Smrg * data at buf to be replaced,freed, or modified. 1026f29dbc25Smrg * 1027f29dbc25Smrg * Parameters. 1028f29dbc25Smrg * 1029f29dbc25Smrg * Returns :None 1030f29dbc25Smrg * 1031f29dbc25Smrg * Comments :None 1032f29dbc25Smrg *---------------------------------------------------------------------------- 1033f29dbc25Smrg */ 1034f29dbc25Smrg 1035f29dbc25Smrgstatic int 1036f29dbc25SmrgGXPutImage(ScrnInfoPtr pScrni, 103704007ebaSmrg short src_x, short src_y, 103804007ebaSmrg short drw_x, short drw_y, 103904007ebaSmrg short src_w, short src_h, 104004007ebaSmrg short drw_w, short drw_h, 104104007ebaSmrg int id, unsigned char *buf, 104204007ebaSmrg short width, short height, Bool sync, RegionPtr clipBoxes, 104304007ebaSmrg pointer data, DrawablePtr pDraw) 1044f29dbc25Smrg{ 1045f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 1046f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1047f29dbc25Smrg int new_h; 1048f29dbc25Smrg 1049f29dbc25Smrg#if REINIT 1050f29dbc25Smrg BOOL ReInitVideo = FALSE; 1051f29dbc25Smrg static BOOL DoReinitAgain = 0; 1052f29dbc25Smrg#endif 1053f29dbc25Smrg 1054f29dbc25Smrg#if XV_PROFILE 1055f29dbc25Smrg long oldtime, newtime; 1056f29dbc25Smrg 1057f29dbc25Smrg UpdateCurrentTime(); 1058f29dbc25Smrg oldtime = currentTime.milliseconds; 1059f29dbc25Smrg#endif 1060f29dbc25Smrg 1061f29dbc25Smrg#if REINIT 1062f29dbc25Smrg/* update cliplist */ 1063f29dbc25Smrg if (!RegionsEqual(&pPriv->clip, clipBoxes)) { 106404007ebaSmrg ReInitVideo = TRUE; 1065f29dbc25Smrg } 1066f29dbc25Smrg 1067f29dbc25Smrg if (DoReinitAgain) 106804007ebaSmrg ReInitVideo = TRUE; 1069f29dbc25Smrg 1070f29dbc25Smrg if (ReInitVideo) { 107104007ebaSmrg DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); 1072f29dbc25Smrg#endif 107304007ebaSmrg DoReinitAgain = ~DoReinitAgain; 107404007ebaSmrg if (drw_w > 16384) 107504007ebaSmrg drw_w = 16384; 107604007ebaSmrg 107704007ebaSmrg /* Clip */ 107804007ebaSmrg Bx1 = src_x; 107904007ebaSmrg Bx2 = src_x + src_w; 108004007ebaSmrg By1 = src_y; 108104007ebaSmrg By2 = src_y + src_h; 108204007ebaSmrg 108304007ebaSmrg if ((Bx1 >= Bx2) || (By1 >= By2)) 108404007ebaSmrg return Success; 108504007ebaSmrg 108604007ebaSmrg dstBox.x1 = drw_x; 108704007ebaSmrg dstBox.x2 = drw_x + drw_w; 108804007ebaSmrg dstBox.y1 = drw_y; 108904007ebaSmrg dstBox.y2 = drw_y + drw_h; 109004007ebaSmrg 109104007ebaSmrg dstBox.x1 -= pScrni->frameX0; 109204007ebaSmrg dstBox.x2 -= pScrni->frameX0; 109304007ebaSmrg dstBox.y1 -= pScrni->frameY0; 109404007ebaSmrg dstBox.y2 -= pScrni->frameY0; 109504007ebaSmrg 109604007ebaSmrg switch (id) { 109704007ebaSmrg case FOURCC_YV12: 109804007ebaSmrg case FOURCC_I420: 109904007ebaSmrg srcPitch = (width + 3) & ~3; /* of luma */ 110004007ebaSmrg dstPitch = (width + 31) & ~31; 110104007ebaSmrg 110204007ebaSmrg s2offset = srcPitch * height; 110304007ebaSmrg d2offset = dstPitch * height; 110404007ebaSmrg 110504007ebaSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 110604007ebaSmrg dstPitch2 = ((width >> 1) + 15) & ~15; 110704007ebaSmrg 110804007ebaSmrg s3offset = (srcPitch2 * (height >> 1)) + s2offset; 110904007ebaSmrg d3offset = (dstPitch2 * (height >> 1)) + d2offset; 111004007ebaSmrg 111104007ebaSmrg new_h = dstPitch * height; /* Y */ 111204007ebaSmrg new_h += (dstPitch2 * height); /* U+V */ 111304007ebaSmrg new_h += pGeode->Pitch - 1; 111404007ebaSmrg new_h /= pGeode->Pitch; 111504007ebaSmrg break; 111604007ebaSmrg case FOURCC_UYVY: 111704007ebaSmrg case FOURCC_YUY2: 111804007ebaSmrg case FOURCC_Y800: 111904007ebaSmrg case FOURCC_RGB565: 112004007ebaSmrg default: 112104007ebaSmrg dstPitch = ((width << 1) + 3) & ~3; 112204007ebaSmrg srcPitch = (width << 1); 112304007ebaSmrg new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; 112404007ebaSmrg break; 112504007ebaSmrg } 1126f29dbc25Smrg#if DBUF 112704007ebaSmrg if (pPriv->doubleBuffer) 112804007ebaSmrg new_h <<= 1; 1129f29dbc25Smrg#endif 1130f29dbc25Smrg 113104007ebaSmrg if (!(pPriv->offset = GXAllocateMemory(pScrni, &pPriv->area, new_h))) { 113204007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 113304007ebaSmrg "Could not allocate area of size %d\n", new_h); 113404007ebaSmrg return BadAlloc; 113504007ebaSmrg } 1136f29dbc25Smrg 113704007ebaSmrg /* copy data */ 113804007ebaSmrg top = By1; 113904007ebaSmrg left = Bx1 & ~1; 114004007ebaSmrg npixels = ((Bx2 + 1) & ~1) - left; 1141f29dbc25Smrg 114204007ebaSmrg switch (id) { 114304007ebaSmrg case FOURCC_YV12: 114404007ebaSmrg case FOURCC_I420: 114504007ebaSmrg { 114604007ebaSmrg int tmp; 1147f29dbc25Smrg 114804007ebaSmrg top &= ~1; 1149f29dbc25Smrg 115004007ebaSmrg offset = pPriv->offset + (top * dstPitch); 1151f29dbc25Smrg 1152f29dbc25Smrg#if DBUF 115304007ebaSmrg if (pPriv->doubleBuffer && pPriv->currentBuffer) 115404007ebaSmrg offset += (new_h >> 1) * pGeode->Pitch; 1155f29dbc25Smrg#endif 115604007ebaSmrg dst_start = pGeode->FBBase + offset + left; 115704007ebaSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 1); 115804007ebaSmrg s2offset += tmp; 115904007ebaSmrg s3offset += tmp; 116004007ebaSmrg if (id == FOURCC_I420) { 116104007ebaSmrg tmp = s2offset; 116204007ebaSmrg s2offset = s3offset; 116304007ebaSmrg s3offset = tmp; 116404007ebaSmrg } 116504007ebaSmrg nlines = ((By2 + 1) & ~1) - top; 116604007ebaSmrg } 116704007ebaSmrg break; 116804007ebaSmrg case FOURCC_UYVY: 116904007ebaSmrg case FOURCC_YUY2: 117004007ebaSmrg case FOURCC_Y800: 117104007ebaSmrg case FOURCC_RGB565: 117204007ebaSmrg default: 117304007ebaSmrg left <<= 1; 117404007ebaSmrg buf += (top * srcPitch) + left; 117504007ebaSmrg nlines = By2 - top; 117604007ebaSmrg offset = (pPriv->offset) + (top * dstPitch); 1177f29dbc25Smrg 1178f29dbc25Smrg#if DBUF 117904007ebaSmrg if (pPriv->doubleBuffer && pPriv->currentBuffer) 118004007ebaSmrg offset += (new_h >> 1) * pGeode->Pitch; 1181f29dbc25Smrg#endif 118204007ebaSmrg dst_start = pGeode->FBBase + offset + left; 118304007ebaSmrg break; 118404007ebaSmrg } 118504007ebaSmrg s1offset = (top * srcPitch) + left; 1186f29dbc25Smrg#if REINIT 118704007ebaSmrg /* update cliplist */ 118804007ebaSmrg REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); 1189f29dbc25Smrg 119004007ebaSmrg if (pPriv->colorKeyMode == 0) { 119104007ebaSmrg xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes); 119204007ebaSmrg } 1193f29dbc25Smrg 119404007ebaSmrg GXDisplayVideo(pScrni, id, offset, width, height, dstPitch, 119504007ebaSmrg Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1196f29dbc25Smrg } 1197f29dbc25Smrg#endif 1198f29dbc25Smrg switch (id) { 1199f29dbc25Smrg case FOURCC_Y800: 120004007ebaSmrg /* This is shared between LX and GX, so it lives in amd_common.c */ 120104007ebaSmrg GeodeCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 120204007ebaSmrg break; 1203f29dbc25Smrg case FOURCC_YV12: 1204f29dbc25Smrg case FOURCC_I420: 120504007ebaSmrg GXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, 120604007ebaSmrg npixels); 120704007ebaSmrg GXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, 120804007ebaSmrg dstPitch2, nlines >> 1, npixels >> 1); 120904007ebaSmrg GXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, 121004007ebaSmrg dstPitch2, nlines >> 1, npixels >> 1); 121104007ebaSmrg break; 1212f29dbc25Smrg case FOURCC_UYVY: 1213f29dbc25Smrg case FOURCC_YUY2: 1214f29dbc25Smrg case FOURCC_RGB565: 1215f29dbc25Smrg default: 121604007ebaSmrg GXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 121704007ebaSmrg break; 1218f29dbc25Smrg } 1219f29dbc25Smrg#if !REINIT 1220f29dbc25Smrg /* update cliplist */ 1221f29dbc25Smrg REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); 1222f29dbc25Smrg if (pPriv->colorKeyMode == 0) { 122304007ebaSmrg /* draw these */ 122404007ebaSmrg XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, 122504007ebaSmrg REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); 1226f29dbc25Smrg } 1227f29dbc25Smrg 1228f29dbc25Smrg GXDisplayVideo(pScrni, id, offset, width, height, dstPitch, 122904007ebaSmrg Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1230f29dbc25Smrg#endif 1231f29dbc25Smrg 1232f29dbc25Smrg#if XV_PROFILE 1233f29dbc25Smrg UpdateCurrentTime(); 1234f29dbc25Smrg newtime = currentTime.milliseconds; 1235f29dbc25Smrg DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); 1236f29dbc25Smrg#endif 1237f29dbc25Smrg 1238f29dbc25Smrg#if DBUF 1239f29dbc25Smrg pPriv->currentBuffer ^= 1; 1240f29dbc25Smrg#endif 1241f29dbc25Smrg 1242f29dbc25Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 1243f29dbc25Smrg pGeode->OverlayON = TRUE; 1244f29dbc25Smrg return Success; 1245f29dbc25Smrg} 1246f29dbc25Smrg 1247f29dbc25Smrg/*---------------------------------------------------------------------------- 1248f29dbc25Smrg * GXQueryImageAttributes 1249f29dbc25Smrg * 1250f29dbc25Smrg * Description :This function is called to let the driver specify how data 1251f29dbc25Smrg * for a particular image of size width by height should be 1252f29dbc25Smrg * stored. 1253f29dbc25Smrg * 1254f29dbc25Smrg * Parameters. 1255f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 1256f29dbc25Smrg * id :Id for the video format 1257f29dbc25Smrg * width :width of the image (can be modified by the driver) 1258f29dbc25Smrg * height :height of the image (can be modified by the driver) 1259f29dbc25Smrg * Returns : Size of the memory required for storing this image 1260f29dbc25Smrg * 1261f29dbc25Smrg * Comments :None 1262f29dbc25Smrg * 1263f29dbc25Smrg *---------------------------------------------------------------------------- 1264f29dbc25Smrg */ 1265f29dbc25Smrg 1266f29dbc25Smrgint 1267f29dbc25SmrgGeodeQueryImageAttributes(ScrnInfoPtr pScrni, 126804007ebaSmrg int id, unsigned short *w, unsigned short *h, 126904007ebaSmrg int *pitches, int *offsets) 1270f29dbc25Smrg{ 1271f29dbc25Smrg int size; 1272f29dbc25Smrg int tmp; 1273f29dbc25Smrg 1274f29dbc25Smrg DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); 1275f29dbc25Smrg 1276f29dbc25Smrg if (*w > 1024) 127704007ebaSmrg *w = 1024; 1278f29dbc25Smrg if (*h > 1024) 127904007ebaSmrg *h = 1024; 1280f29dbc25Smrg 1281f29dbc25Smrg *w = (*w + 1) & ~1; 1282f29dbc25Smrg if (offsets) 128304007ebaSmrg offsets[0] = 0; 1284f29dbc25Smrg 1285f29dbc25Smrg switch (id) { 1286f29dbc25Smrg case FOURCC_YV12: 1287f29dbc25Smrg case FOURCC_I420: 128804007ebaSmrg *h = (*h + 1) & ~1; 128904007ebaSmrg size = (*w + 3) & ~3; 129004007ebaSmrg if (pitches) 129104007ebaSmrg pitches[0] = size; 129204007ebaSmrg 129304007ebaSmrg size *= *h; 129404007ebaSmrg if (offsets) 129504007ebaSmrg offsets[1] = size; 129604007ebaSmrg 129704007ebaSmrg tmp = ((*w >> 1) + 3) & ~3; 129804007ebaSmrg if (pitches) 129904007ebaSmrg pitches[1] = pitches[2] = tmp; 130004007ebaSmrg 130104007ebaSmrg tmp *= (*h >> 1); 130204007ebaSmrg size += tmp; 130304007ebaSmrg if (offsets) 130404007ebaSmrg offsets[2] = size; 130504007ebaSmrg 130604007ebaSmrg size += tmp; 130704007ebaSmrg break; 1308f29dbc25Smrg case FOURCC_UYVY: 1309f29dbc25Smrg case FOURCC_YUY2: 1310f29dbc25Smrg case FOURCC_Y800: 1311f29dbc25Smrg default: 131204007ebaSmrg size = *w << 1; 131304007ebaSmrg if (pitches) 131404007ebaSmrg pitches[0] = size; 1315f29dbc25Smrg 131604007ebaSmrg size *= *h; 131704007ebaSmrg break; 1318f29dbc25Smrg } 1319f29dbc25Smrg return size; 1320f29dbc25Smrg} 1321f29dbc25Smrg 1322f29dbc25Smrgstatic void 132304007ebaSmrgGXBlockHandler(BLOCKHANDLER_ARGS_DECL) 1324f29dbc25Smrg{ 132504007ebaSmrg SCREEN_PTR(arg); 132604007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 1327f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1328f29dbc25Smrg GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); 1329f29dbc25Smrg 1330f29dbc25Smrg pScrn->BlockHandler = pGeode->BlockHandler; 133104007ebaSmrg (*pScrn->BlockHandler) (BLOCKHANDLER_ARGS); 1332f29dbc25Smrg pScrn->BlockHandler = GXBlockHandler; 1333f29dbc25Smrg 1334f29dbc25Smrg if (pPriv->videoStatus & TIMER_MASK) { 133504007ebaSmrg GXAccelSync(pScrni); 133604007ebaSmrg UpdateCurrentTime(); 133704007ebaSmrg if (pPriv->videoStatus & OFF_TIMER) { 133804007ebaSmrg if (pPriv->offTime < currentTime.milliseconds) { 133904007ebaSmrg GFX(set_video_enable(0)); 134004007ebaSmrg 134104007ebaSmrg /* If we have saved graphics LUT data - restore it */ 134204007ebaSmrg /* Otherwise, turn bypass on */ 134304007ebaSmrg 134404007ebaSmrg if (lutflag) 134504007ebaSmrg GFX(set_graphics_palette(graphics_lut)); 134604007ebaSmrg else 134704007ebaSmrg GFX(set_video_palette_bypass(1)); 134804007ebaSmrg 134904007ebaSmrg lutflag = 0; 135004007ebaSmrg 135104007ebaSmrg pPriv->videoStatus = FREE_TIMER; 135204007ebaSmrg pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 135304007ebaSmrg } 135404007ebaSmrg } 135504007ebaSmrg else { /* FREE_TIMER */ 135604007ebaSmrg if (pPriv->freeTime < currentTime.milliseconds) { 135704007ebaSmrg 135804007ebaSmrg if (pPriv->area) { 1359f29dbc25Smrg#ifdef XF86EXA 136004007ebaSmrg if (pGeode->useEXA) 136104007ebaSmrg exaOffscreenFree(pScrn, pPriv->area); 1362f29dbc25Smrg#endif 136304007ebaSmrg if (!pGeode->useEXA) 136404007ebaSmrg xf86FreeOffscreenArea(pPriv->area); 1365f29dbc25Smrg 136604007ebaSmrg pPriv->area = NULL; 136704007ebaSmrg } 1368f29dbc25Smrg 136904007ebaSmrg pPriv->videoStatus = 0; 137004007ebaSmrg } 137104007ebaSmrg } 1372f29dbc25Smrg } 1373f29dbc25Smrg} 1374f29dbc25Smrg 1375f29dbc25Smrg/****************** Offscreen stuff ***************/ 1376f29dbc25Smrg 137704007ebaSmrgtypedef struct { 1378f29dbc25Smrg void *area; 1379f29dbc25Smrg int offset; 1380f29dbc25Smrg Bool isOn; 1381f29dbc25Smrg} OffscreenPrivRec, *OffscreenPrivPtr; 1382f29dbc25Smrg 1383f29dbc25Smrg/*---------------------------------------------------------------------------- 1384f29dbc25Smrg * GXAllocateSurface 1385f29dbc25Smrg * 1386f29dbc25Smrg * Description :This function allocates an area of w by h in the offscreen 1387f29dbc25Smrg * 1388f29dbc25Smrg * Parameters. 1389f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 1390f29dbc25Smrg * 1391f29dbc25Smrg * Returns :None 1392f29dbc25Smrg * 1393f29dbc25Smrg * Comments :None 1394f29dbc25Smrg *---------------------------------------------------------------------------- 1395f29dbc25Smrg */ 1396f29dbc25Smrgstatic int 1397f29dbc25SmrgGXAllocateSurface(ScrnInfoPtr pScrni, 139804007ebaSmrg int id, unsigned short w, unsigned short h, 139904007ebaSmrg XF86SurfacePtr surface) 1400f29dbc25Smrg{ 1401f29dbc25Smrg void *area = NULL; 1402f29dbc25Smrg int pitch, fbpitch, numlines; 1403f29dbc25Smrg OffscreenPrivRec *pPriv; 1404f29dbc25Smrg 1405f29dbc25Smrg if ((w > 1024) || (h > 1024)) 140604007ebaSmrg return BadAlloc; 1407f29dbc25Smrg 1408f29dbc25Smrg w = (w + 1) & ~1; 1409f29dbc25Smrg pitch = ((w << 1) + 15) & ~15; 1410f29dbc25Smrg fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3; 1411f29dbc25Smrg numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 1412f29dbc25Smrg 1413f29dbc25Smrg if (!(offset = GXAllocateMemory(pScrni, &area, numlines))) 141404007ebaSmrg return BadAlloc; 1415f29dbc25Smrg 1416f29dbc25Smrg surface->width = w; 1417f29dbc25Smrg surface->height = h; 1418f29dbc25Smrg 1419170d5fdcSmrg if (!(surface->pitches = malloc(sizeof(int)))) 142004007ebaSmrg return BadAlloc; 1421f29dbc25Smrg 1422170d5fdcSmrg if (!(surface->offsets = malloc(sizeof(int)))) { 142304007ebaSmrg free(surface->pitches); 142404007ebaSmrg return BadAlloc; 1425f29dbc25Smrg } 1426f29dbc25Smrg 1427170d5fdcSmrg if (!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 142804007ebaSmrg free(surface->pitches); 142904007ebaSmrg free(surface->offsets); 143004007ebaSmrg return BadAlloc; 1431f29dbc25Smrg } 1432f29dbc25Smrg 1433f29dbc25Smrg pPriv->area = area; 1434f29dbc25Smrg pPriv->offset = offset; 1435f29dbc25Smrg 1436f29dbc25Smrg pPriv->isOn = FALSE; 1437f29dbc25Smrg 1438f29dbc25Smrg surface->pScrn = pScrni; 1439f29dbc25Smrg surface->id = id; 1440f29dbc25Smrg surface->pitches[0] = pitch; 1441f29dbc25Smrg surface->offsets[0] = offset; 1442f29dbc25Smrg surface->devPrivate.ptr = (pointer) pPriv; 1443f29dbc25Smrg 1444f29dbc25Smrg return Success; 1445f29dbc25Smrg} 1446f29dbc25Smrg 1447f29dbc25Smrgstatic int 1448f29dbc25SmrgGXStopSurface(XF86SurfacePtr surface) 1449f29dbc25Smrg{ 1450f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1451f29dbc25Smrg 1452f29dbc25Smrg if (pPriv->isOn) { 145304007ebaSmrg pPriv->isOn = FALSE; 1454f29dbc25Smrg } 1455f29dbc25Smrg 1456f29dbc25Smrg return Success; 1457f29dbc25Smrg} 1458f29dbc25Smrg 1459f29dbc25Smrgstatic int 1460f29dbc25SmrgGXFreeSurface(XF86SurfacePtr surface) 1461f29dbc25Smrg{ 1462f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1463f29dbc25Smrg 1464f29dbc25Smrg if (pPriv->isOn) 146504007ebaSmrg GXStopSurface(surface); 1466f29dbc25Smrg 1467f29dbc25Smrg xf86FreeOffscreenArea(pPriv->area); 1468170d5fdcSmrg free(surface->pitches); 1469170d5fdcSmrg free(surface->offsets); 1470170d5fdcSmrg free(surface->devPrivate.ptr); 1471f29dbc25Smrg 1472f29dbc25Smrg return Success; 1473f29dbc25Smrg} 1474f29dbc25Smrg 1475f29dbc25Smrgstatic int 147604007ebaSmrgGXGetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 *value) 1477f29dbc25Smrg{ 1478f29dbc25Smrg return GXGetPortAttribute(pScrni, attribute, value, 147904007ebaSmrg (pointer) (GET_PORT_PRIVATE(pScrni))); 1480f29dbc25Smrg} 1481f29dbc25Smrg 1482f29dbc25Smrgstatic int 1483f29dbc25SmrgGXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value) 1484f29dbc25Smrg{ 1485f29dbc25Smrg return GXSetPortAttribute(pScrni, attribute, value, 148604007ebaSmrg (pointer) (GET_PORT_PRIVATE(pScrni))); 1487f29dbc25Smrg} 1488f29dbc25Smrg 1489f29dbc25Smrgstatic int 1490f29dbc25SmrgGXDisplaySurface(XF86SurfacePtr surface, 149104007ebaSmrg short src_x, short src_y, 149204007ebaSmrg short drw_x, short drw_y, 149304007ebaSmrg short src_w, short src_h, short drw_w, short drw_h, 149404007ebaSmrg RegionPtr clipBoxes) 1495f29dbc25Smrg{ 1496f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1497f29dbc25Smrg ScrnInfoPtr pScrni = surface->pScrn; 1498f29dbc25Smrg GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); 1499f29dbc25Smrg INT32 x1, y1, x2, y2; 1500f29dbc25Smrg BoxRec dstBox; 1501f29dbc25Smrg 1502f29dbc25Smrg DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); 1503f29dbc25Smrg x1 = src_x; 1504f29dbc25Smrg x2 = src_x + src_w; 1505f29dbc25Smrg y1 = src_y; 1506f29dbc25Smrg y2 = src_y + src_h; 1507f29dbc25Smrg 1508f29dbc25Smrg dstBox.x1 = drw_x; 1509f29dbc25Smrg dstBox.x2 = drw_x + drw_w; 1510f29dbc25Smrg dstBox.y1 = drw_y; 1511f29dbc25Smrg dstBox.y2 = drw_y + drw_h; 1512f29dbc25Smrg 1513f29dbc25Smrg if ((x1 >= x2) || (y1 >= y2)) 151404007ebaSmrg return Success; 1515f29dbc25Smrg 1516f29dbc25Smrg dstBox.x1 -= pScrni->frameX0; 1517f29dbc25Smrg dstBox.x2 -= pScrni->frameX0; 1518f29dbc25Smrg dstBox.y1 -= pScrni->frameY0; 1519f29dbc25Smrg dstBox.y2 -= pScrni->frameY0; 1520f29dbc25Smrg 1521f29dbc25Smrg xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); 1522f29dbc25Smrg 1523f29dbc25Smrg GXDisplayVideo(pScrni, surface->id, surface->offsets[0], 152404007ebaSmrg surface->width, surface->height, surface->pitches[0], 152504007ebaSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1526f29dbc25Smrg 1527f29dbc25Smrg pPriv->isOn = TRUE; 1528f29dbc25Smrg if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 152904007ebaSmrg REGION_EMPTY(pScrni->pScreen, &portPriv->clip); 153004007ebaSmrg UpdateCurrentTime(); 153104007ebaSmrg portPriv->videoStatus = FREE_TIMER; 153204007ebaSmrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1533f29dbc25Smrg } 1534f29dbc25Smrg 1535f29dbc25Smrg return Success; 1536f29dbc25Smrg} 1537f29dbc25Smrg 1538f29dbc25Smrg/*---------------------------------------------------------------------------- 1539f29dbc25Smrg * GXInitOffscreenImages 1540f29dbc25Smrg * 1541f29dbc25Smrg * Description :This function sets up the offscreen memory management. It 1542f29dbc25Smrg * fills in the XF86OffscreenImagePtr structure with functions to 1543f29dbc25Smrg * handle offscreen memory operations. 1544f29dbc25Smrg * 1545f29dbc25Smrg * Parameters. 1546f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 1547f29dbc25Smrg * 1548f29dbc25Smrg * Returns : None 1549f29dbc25Smrg * 1550f29dbc25Smrg * Comments :None 1551f29dbc25Smrg *---------------------------------------------------------------------------- 1552f29dbc25Smrg */ 1553f29dbc25Smrgstatic void 1554f29dbc25SmrgGXInitOffscreenImages(ScreenPtr pScrn) 1555f29dbc25Smrg{ 1556f29dbc25Smrg XF86OffscreenImagePtr offscreenImages; 1557f29dbc25Smrg 1558f29dbc25Smrg /* need to free this someplace */ 1559170d5fdcSmrg if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 156004007ebaSmrg return; 1561f29dbc25Smrg 1562f29dbc25Smrg offscreenImages[0].image = &Images[0]; 1563f29dbc25Smrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1564f29dbc25Smrg offscreenImages[0].alloc_surface = GXAllocateSurface; 1565f29dbc25Smrg offscreenImages[0].free_surface = GXFreeSurface; 1566f29dbc25Smrg offscreenImages[0].display = GXDisplaySurface; 1567f29dbc25Smrg offscreenImages[0].stop = GXStopSurface; 1568f29dbc25Smrg offscreenImages[0].setAttribute = GXSetSurfaceAttribute; 1569f29dbc25Smrg offscreenImages[0].getAttribute = GXGetSurfaceAttribute; 1570f29dbc25Smrg offscreenImages[0].max_width = 1024; 1571f29dbc25Smrg offscreenImages[0].max_height = 1024; 1572f29dbc25Smrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1573f29dbc25Smrg offscreenImages[0].attributes = Attributes; 1574f29dbc25Smrg 1575f29dbc25Smrg xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); 1576f29dbc25Smrg} 1577f29dbc25Smrg 157804007ebaSmrg#endif /* !XvExtension */ 1579