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 4600be8644Schristos#include "xorg-server.h" 4700be8644Schristos 48f29dbc25Smrg#include "xf86.h" 49f29dbc25Smrg#include "xf86_OSproc.h" 50f29dbc25Smrg#include "compiler.h" 5100be8644Schristos// #include "xf86PciInfo.h" 52f29dbc25Smrg#include "xf86Pci.h" 53f29dbc25Smrg#include "xf86fbman.h" 54f29dbc25Smrg#include "regionstr.h" 55f29dbc25Smrg 56f29dbc25Smrg#include "geode.h" 57f29dbc25Smrg#include "xf86xv.h" 58f29dbc25Smrg#include <X11/extensions/Xv.h> 5904007ebaSmrg#ifdef HAVE_XAA_H 60f29dbc25Smrg#include "xaa.h" 61f29dbc25Smrg#include "xaalocal.h" 6204007ebaSmrg#endif 63f29dbc25Smrg#include "dixstruct.h" 64f29dbc25Smrg#include "fourcc.h" 65f29dbc25Smrg#include "geode_fourcc.h" 66f29dbc25Smrg 6704007ebaSmrg#define OFF_DELAY 200 /* milliseconds */ 68f29dbc25Smrg#define FREE_DELAY 60000 69f29dbc25Smrg 70f29dbc25Smrg#define OFF_TIMER 0x01 71f29dbc25Smrg#define FREE_TIMER 0x02 72f29dbc25Smrg#define CLIENT_VIDEO_ON 0x04 73f29dbc25Smrg 74f29dbc25Smrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 75f29dbc25Smrg#define XV_PROFILE 0 76f29dbc25Smrg#define REINIT 1 77f29dbc25Smrg 78f29dbc25Smrg#ifndef XvExtension 79f29dbc25Smrg#error "It didn't work!" 80f29dbc25Smrgvoid 81f29dbc25SmrgGXInitVideo(ScreenPtr pScrn) 82f29dbc25Smrg{ 83f29dbc25Smrg} 84f29dbc25Smrg 85f29dbc25Smrgvoid 86f29dbc25SmrgGXResetVideo(ScrnInfoPtr pScrni) 87f29dbc25Smrg{ 88f29dbc25Smrg} 89f29dbc25Smrg 90f29dbc25Smrgvoid 91f29dbc25SmrgGXSetVideoPosition() 92f29dbc25Smrg{ 93f29dbc25Smrg} 94f29dbc25Smrg#else 95f29dbc25Smrg 96f29dbc25Smrg#define DBUF 1 97f29dbc25Smrgvoid GXResetVideo(ScrnInfoPtr pScrni); 98f29dbc25Smrgstatic XF86VideoAdaptorPtr GXSetupImageVideo(ScreenPtr); 99f29dbc25Smrgstatic void GXInitOffscreenImages(ScreenPtr); 100f29dbc25Smrgstatic void GXStopVideo(ScrnInfoPtr, pointer, Bool); 101f29dbc25Smrgstatic int GXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 102f29dbc25Smrgstatic int GXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); 103f29dbc25Smrgstatic void GXQueryBestSize(ScrnInfoPtr, Bool, 10404007ebaSmrg short, short, short, short, unsigned int *, 10504007ebaSmrg unsigned int *, pointer); 106f29dbc25Smrgstatic int GXPutImage(ScrnInfoPtr, short, short, short, short, short, short, 10704007ebaSmrg short, short, int, unsigned char *, short, short, Bool, 10804007ebaSmrg RegionPtr, pointer, DrawablePtr pDraw); 109f29dbc25Smrg 11004007ebaSmrgstatic void GXBlockHandler(BLOCKHANDLER_ARGS_DECL); 111f29dbc25Smrgvoid GXSetVideoPosition(int x, int y, int width, int height, 11204007ebaSmrg short src_w, short src_h, short drw_w, 11304007ebaSmrg short drw_h, int id, int offset, ScrnInfoPtr pScrni); 114f29dbc25Smrg 115f29dbc25Smrgextern void GXAccelSync(ScrnInfoPtr pScrni); 116f29dbc25Smrg 117ad01e365Sjoergextern int DeltaX, DeltaY; 118f29dbc25Smrg 119f29dbc25Smrgunsigned long graphics_lut[256]; 120f29dbc25Smrgstatic int lutflag = 0; 121f29dbc25Smrg 122f29dbc25Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 123f29dbc25Smrg 124f29dbc25Smrgstatic Atom xvColorKey, xvColorKeyMode, xvFilter 125f29dbc25Smrg#if DBUF 12604007ebaSmrg, xvDoubleBuffer 127f29dbc25Smrg#endif 12804007ebaSmrg; 129f29dbc25Smrg 130f29dbc25Smrg#define PALETTE_ADDRESS 0x038 131f29dbc25Smrg#define PALETTE_DATA 0x040 132f29dbc25Smrg#define DISPLAY_CONFIG 0x008 133f29dbc25Smrg#define MISC 0x050 134f29dbc25Smrg 135f29dbc25Smrgstatic void 136f29dbc25Smrgget_gamma_ram(unsigned long *lut) 137f29dbc25Smrg{ 138f29dbc25Smrg 139f29dbc25Smrg int i; 140f29dbc25Smrg 141f29dbc25Smrg gfx_write_vid32(PALETTE_ADDRESS, 0); 142f29dbc25Smrg 143f29dbc25Smrg for (i = 0; i < 256; i++) 14404007ebaSmrg lut[i] = gfx_read_vid32(PALETTE_DATA); 145f29dbc25Smrg} 146f29dbc25Smrg 147f29dbc25Smrg/*---------------------------------------------------------------------------- 148f29dbc25Smrg * GXInitVideo 149f29dbc25Smrg * 150f29dbc25Smrg * Description :This is the initialization routine.It creates a new video 151f29dbc25Smrg * adapter and calls GXSetupImageVideo to initialize the adaptor 152f29dbc25Smrg * by filling XF86VideoAdaptorREc.Then it lists the existing 153f29dbc25Smrg * adaptors and adds the new one to it. Finally the list of 154f29dbc25Smrg * XF86VideoAdaptorPtr pointers are passed to the 155f29dbc25Smrg * xf86XVScreenInit(). 156f29dbc25Smrg * 157f29dbc25Smrg * Parameters. 158f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 159f29dbc25Smrg * 160f29dbc25Smrg * Returns :none 161f29dbc25Smrg * 162f29dbc25Smrg * Comments :none 163f29dbc25Smrg *---------------------------------------------------------------------------- 164f29dbc25Smrg */ 165f29dbc25Smrgvoid 166f29dbc25SmrgGXInitVideo(ScreenPtr pScrn) 167f29dbc25Smrg{ 168f29dbc25Smrg GeodeRec *pGeode; 16904007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 170f29dbc25Smrg 171f29dbc25Smrg pGeode = GEODEPTR(pScrni); 172f29dbc25Smrg 173f29dbc25Smrg if (!pGeode->NoAccel) { 17404007ebaSmrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 17504007ebaSmrg XF86VideoAdaptorPtr newAdaptor = NULL; 17604007ebaSmrg 17704007ebaSmrg int num_adaptors; 17804007ebaSmrg 17904007ebaSmrg newAdaptor = GXSetupImageVideo(pScrn); 18004007ebaSmrg GXInitOffscreenImages(pScrn); 18104007ebaSmrg 18204007ebaSmrg num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); 18304007ebaSmrg 18404007ebaSmrg if (newAdaptor) { 18504007ebaSmrg if (!num_adaptors) { 18604007ebaSmrg num_adaptors = 1; 18704007ebaSmrg adaptors = &newAdaptor; 18804007ebaSmrg } 18904007ebaSmrg else { 19004007ebaSmrg newAdaptors = /* need to free this someplace */ 19104007ebaSmrg malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); 19204007ebaSmrg if (newAdaptors) { 19304007ebaSmrg memcpy(newAdaptors, adaptors, num_adaptors * 19404007ebaSmrg sizeof(XF86VideoAdaptorPtr)); 19504007ebaSmrg newAdaptors[num_adaptors] = newAdaptor; 19604007ebaSmrg adaptors = newAdaptors; 19704007ebaSmrg num_adaptors++; 19804007ebaSmrg } 19904007ebaSmrg } 20004007ebaSmrg } 20104007ebaSmrg 20204007ebaSmrg if (num_adaptors) 20304007ebaSmrg xf86XVScreenInit(pScrn, adaptors, num_adaptors); 20404007ebaSmrg 20504007ebaSmrg if (newAdaptors) 20604007ebaSmrg free(newAdaptors); 207f29dbc25Smrg } 208f29dbc25Smrg} 209f29dbc25Smrg 210f29dbc25Smrg/* client libraries expect an encoding */ 211f29dbc25Smrgstatic XF86VideoEncodingRec DummyEncoding[1] = { 212f29dbc25Smrg { 21304007ebaSmrg 0, 21404007ebaSmrg "XV_IMAGE", 21504007ebaSmrg 1024, 1024, 21604007ebaSmrg {1, 1} 21704007ebaSmrg } 218f29dbc25Smrg}; 219f29dbc25Smrg 220f29dbc25Smrg#define NUM_FORMATS 4 221f29dbc25Smrg 222f29dbc25Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = { 223f29dbc25Smrg {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 224f29dbc25Smrg}; 225f29dbc25Smrg 226f29dbc25Smrg#if DBUF 227f29dbc25Smrg#define NUM_ATTRIBUTES 4 228f29dbc25Smrg#else 229f29dbc25Smrg#define NUM_ATTRIBUTES 3 230f29dbc25Smrg#endif 231f29dbc25Smrg 232f29dbc25Smrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { 233f29dbc25Smrg#if DBUF 234f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 235f29dbc25Smrg#endif 236f29dbc25Smrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 237f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, 238f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} 239f29dbc25Smrg}; 240f29dbc25Smrg 241f29dbc25Smrg#define NUM_IMAGES 8 242f29dbc25Smrg 243f29dbc25Smrgstatic XF86ImageRec Images[NUM_IMAGES] = { 244f29dbc25Smrg XVIMAGE_UYVY, 245f29dbc25Smrg XVIMAGE_YUY2, 246f29dbc25Smrg XVIMAGE_Y2YU, 247f29dbc25Smrg XVIMAGE_YVYU, 248f29dbc25Smrg XVIMAGE_Y800, 249f29dbc25Smrg XVIMAGE_I420, 250f29dbc25Smrg XVIMAGE_YV12, 251f29dbc25Smrg XVIMAGE_RGB565 252f29dbc25Smrg}; 253f29dbc25Smrg 25404007ebaSmrgtypedef struct { 255f29dbc25Smrg void *area; 256f29dbc25Smrg int offset; 257f29dbc25Smrg RegionRec clip; 258f29dbc25Smrg CARD32 filter; 259f29dbc25Smrg CARD32 colorKey; 260f29dbc25Smrg CARD32 colorKeyMode; 261f29dbc25Smrg CARD32 videoStatus; 262f29dbc25Smrg Time offTime; 263f29dbc25Smrg Time freeTime; 264f29dbc25Smrg#if DBUF 265f29dbc25Smrg Bool doubleBuffer; 266f29dbc25Smrg int currentBuffer; 267f29dbc25Smrg#endif 268f29dbc25Smrg} GeodePortPrivRec, *GeodePortPrivPtr; 269f29dbc25Smrg 270f29dbc25Smrg#define GET_PORT_PRIVATE(pScrni) \ 271f29dbc25Smrg (GeodePortPrivRec *)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr) 272f29dbc25Smrg 273f29dbc25Smrg/*---------------------------------------------------------------------------- 274f29dbc25Smrg * GXSetColorKey 275f29dbc25Smrg * 276c744f008Smrg * Description :This function reads the color key for the palette and 277f29dbc25Smrg * sets the video color key register. 278f29dbc25Smrg * 279f29dbc25Smrg * Parameters. 280f29dbc25Smrg * ScreenInfoPtr 281f29dbc25Smrg * pScrni :Screen pointer having screen information. 282f29dbc25Smrg * pPriv :Video port private data 283f29dbc25Smrg * 284f29dbc25Smrg * Returns :none 285f29dbc25Smrg * 286f29dbc25Smrg * Comments :none 287f29dbc25Smrg * 288f29dbc25Smrg *---------------------------------------------------------------------------- 289f29dbc25Smrg */ 290f29dbc25Smrgstatic INT32 291f29dbc25SmrgGXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) 292f29dbc25Smrg{ 293f29dbc25Smrg int red, green, blue; 294f29dbc25Smrg unsigned long key; 295f29dbc25Smrg 296f29dbc25Smrg switch (pScrni->depth) { 297f29dbc25Smrg case 8: 29804007ebaSmrg GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); 29904007ebaSmrg red = ((key >> 16) & 0xFF); 30004007ebaSmrg green = ((key >> 8) & 0xFF); 30104007ebaSmrg blue = (key & 0xFF); 30204007ebaSmrg break; 303f29dbc25Smrg case 16: 30404007ebaSmrg red = (pPriv->colorKey & pScrni->mask.red) >> 30504007ebaSmrg pScrni->offset.red << (8 - pScrni->weight.red); 30604007ebaSmrg green = (pPriv->colorKey & pScrni->mask.green) >> 30704007ebaSmrg pScrni->offset.green << (8 - pScrni->weight.green); 30804007ebaSmrg blue = (pPriv->colorKey & pScrni->mask.blue) >> 30904007ebaSmrg pScrni->offset.blue << (8 - pScrni->weight.blue); 31004007ebaSmrg break; 311f29dbc25Smrg default: 31204007ebaSmrg /* for > 16 bpp we send in the mask in xf86SetWeight. This 31304007ebaSmrg * function is providing the offset by 1 more. So we take 31404007ebaSmrg * this as a special case and subtract 1 for > 16 31504007ebaSmrg */ 31604007ebaSmrg red = (pPriv->colorKey & pScrni->mask.red) >> 31704007ebaSmrg (pScrni->offset.red - 1) << (8 - pScrni->weight.red); 31804007ebaSmrg green = (pPriv->colorKey & pScrni->mask.green) >> 31904007ebaSmrg (pScrni->offset.green - 1) << (8 - pScrni->weight.green); 32004007ebaSmrg blue = (pPriv->colorKey & pScrni->mask.blue) >> 32104007ebaSmrg (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); 32204007ebaSmrg break; 323f29dbc25Smrg } 324f29dbc25Smrg 325f29dbc25Smrg GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, 32604007ebaSmrg (pPriv->colorKeyMode == 0))); 327f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &pPriv->clip); 328f29dbc25Smrg return 0; 329f29dbc25Smrg} 330f29dbc25Smrg 331f29dbc25Smrg/*---------------------------------------------------------------------------- 332f29dbc25Smrg * GXResetVideo 333f29dbc25Smrg * 334f29dbc25Smrg * Description : This function resets the video 335f29dbc25Smrg * 336f29dbc25Smrg * Parameters. 337f29dbc25Smrg * pScrni :Screen pointer having screen information. 338f29dbc25Smrg * 339f29dbc25Smrg * Returns :None 340f29dbc25Smrg * 341f29dbc25Smrg * Comments :none 342f29dbc25Smrg * 343f29dbc25Smrg *---------------------------------------------------------------------------- 344f29dbc25Smrg */ 345f29dbc25Smrgvoid 346f29dbc25SmrgGXResetVideo(ScrnInfoPtr pScrni) 347f29dbc25Smrg{ 348f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 349f29dbc25Smrg 350f29dbc25Smrg if (!pGeode->NoAccel) { 35104007ebaSmrg GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; 352f29dbc25Smrg 35304007ebaSmrg GXAccelSync(pScrni); 35404007ebaSmrg GXSetColorkey(pScrni, pPriv); 35504007ebaSmrg GFX(set_video_filter(pPriv->filter, pPriv->filter)); 356f29dbc25Smrg } 357f29dbc25Smrg} 358f29dbc25Smrg 359f29dbc25Smrg/*---------------------------------------------------------------------------- 360f29dbc25Smrg * GXSetupImageVideo 361f29dbc25Smrg * 362f29dbc25Smrg * Description : This function allocates space for a Videoadaptor and 363f29dbc25Smrg * initializes the XF86VideoAdaptorPtr record. 364f29dbc25Smrg * 365f29dbc25Smrg * Parameters. 366f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 367f29dbc25Smrg * 368f29dbc25Smrg * Returns :pointer to the initialized video adaptor record. 369f29dbc25Smrg * 370f29dbc25Smrg * Comments :none 371f29dbc25Smrg *---------------------------------------------------------------------------- 372f29dbc25Smrg */ 373f29dbc25Smrgstatic XF86VideoAdaptorPtr 374f29dbc25SmrgGXSetupImageVideo(ScreenPtr pScrn) 375f29dbc25Smrg{ 37604007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 377f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 378f29dbc25Smrg XF86VideoAdaptorPtr adapt; 379f29dbc25Smrg GeodePortPrivRec *pPriv; 380f29dbc25Smrg 381170d5fdcSmrg if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 38204007ebaSmrg sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) 38304007ebaSmrg return NULL; 384f29dbc25Smrg 385f29dbc25Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 386f29dbc25Smrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 387f29dbc25Smrg adapt->name = "Advanced Micro Devices"; 388f29dbc25Smrg adapt->nEncodings = 1; 389f29dbc25Smrg adapt->pEncodings = DummyEncoding; 390f29dbc25Smrg adapt->nFormats = NUM_FORMATS; 391f29dbc25Smrg adapt->pFormats = Formats; 392f29dbc25Smrg adapt->nPorts = 1; 393f29dbc25Smrg adapt->pPortPrivates = (DevUnion *) (&adapt[1]); 394f29dbc25Smrg pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); 395f29dbc25Smrg adapt->pPortPrivates[0].ptr = (pointer) (pPriv); 396f29dbc25Smrg adapt->pAttributes = Attributes; 397f29dbc25Smrg adapt->nImages = NUM_IMAGES; 398f29dbc25Smrg adapt->nAttributes = NUM_ATTRIBUTES; 399f29dbc25Smrg adapt->pImages = Images; 400f29dbc25Smrg adapt->PutVideo = NULL; 401f29dbc25Smrg adapt->PutStill = NULL; 402f29dbc25Smrg adapt->GetVideo = NULL; 403f29dbc25Smrg adapt->GetStill = NULL; 404f29dbc25Smrg adapt->StopVideo = GXStopVideo; 405f29dbc25Smrg adapt->SetPortAttribute = GXSetPortAttribute; 406f29dbc25Smrg adapt->GetPortAttribute = GXGetPortAttribute; 407f29dbc25Smrg adapt->QueryBestSize = GXQueryBestSize; 408f29dbc25Smrg adapt->PutImage = GXPutImage; 409f29dbc25Smrg adapt->QueryImageAttributes = GeodeQueryImageAttributes; 410f29dbc25Smrg 411f29dbc25Smrg pPriv->filter = 0; 412f29dbc25Smrg pPriv->colorKey = 0; 413f29dbc25Smrg pPriv->colorKeyMode = 0; 414f29dbc25Smrg pPriv->videoStatus = 0; 415f29dbc25Smrg#if DBUF 416f29dbc25Smrg pPriv->doubleBuffer = TRUE; 41704007ebaSmrg pPriv->currentBuffer = 0; /* init to first buffer */ 418f29dbc25Smrg#endif 419f29dbc25Smrg 420f29dbc25Smrg /* gotta uninit this someplace */ 421f29dbc25Smrg#if defined(REGION_NULL) 422f29dbc25Smrg REGION_NULL(pScrn, &pPriv->clip); 423f29dbc25Smrg#else 424f29dbc25Smrg REGION_INIT(pScrn, &pPriv->clip, NullBox, 0); 425f29dbc25Smrg#endif 426f29dbc25Smrg 427f29dbc25Smrg pGeode->adaptor = adapt; 428f29dbc25Smrg 429f29dbc25Smrg pGeode->BlockHandler = pScrn->BlockHandler; 430f29dbc25Smrg pScrn->BlockHandler = GXBlockHandler; 431f29dbc25Smrg 432f29dbc25Smrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 433f29dbc25Smrg xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); 434f29dbc25Smrg xvFilter = MAKE_ATOM("XV_FILTER"); 435f29dbc25Smrg#if DBUF 436f29dbc25Smrg xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 437f29dbc25Smrg#endif 438f29dbc25Smrg 439f29dbc25Smrg GXResetVideo(pScrni); 440f29dbc25Smrg 441f29dbc25Smrg return adapt; 442f29dbc25Smrg} 443f29dbc25Smrg 444f29dbc25Smrg/*---------------------------------------------------------------------------- 445f29dbc25Smrg * GXStopVideo 446f29dbc25Smrg * 447f29dbc25Smrg * Description :This function is used to stop input and output video 448f29dbc25Smrg * 449f29dbc25Smrg * Parameters. 450f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 451f29dbc25Smrg * data :Pointer to the video port's private data 452f29dbc25Smrg * exit :Flag indicating whether the offscreen areas used for 453f29dbc25Smrg * video to be deallocated or not. 454f29dbc25Smrg * 455f29dbc25Smrg * Returns :none 456f29dbc25Smrg * 457f29dbc25Smrg * Comments :none 458f29dbc25Smrg *---------------------------------------------------------------------------- 459f29dbc25Smrg */ 460f29dbc25Smrgstatic void 461f29dbc25SmrgGXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) 462f29dbc25Smrg{ 463f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 464f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 465f29dbc25Smrg 466f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &pPriv->clip); 467f29dbc25Smrg 468f29dbc25Smrg GXAccelSync(pScrni); 469f29dbc25Smrg if (exit) { 47004007ebaSmrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 47104007ebaSmrg GFX(set_video_enable(0)); 472f29dbc25Smrg 47304007ebaSmrg /* If we have saved graphics LUT data - restore it */ 47404007ebaSmrg /* Otherwise, turn bypass on */ 475f29dbc25Smrg 47604007ebaSmrg if (lutflag) 47704007ebaSmrg GFX(set_graphics_palette(graphics_lut)); 47804007ebaSmrg else 47904007ebaSmrg GFX(set_video_palette_bypass(1)); 480f29dbc25Smrg 48104007ebaSmrg lutflag = 0; 48204007ebaSmrg } 483f29dbc25Smrg 48404007ebaSmrg if (pPriv->area) { 485f29dbc25Smrg#ifdef XF86EXA 48604007ebaSmrg if (pGeode->useEXA) 48704007ebaSmrg exaOffscreenFree(pScrni->pScreen, pPriv->area); 488f29dbc25Smrg#endif 489f29dbc25Smrg 49004007ebaSmrg if (!pGeode->useEXA) 49104007ebaSmrg xf86FreeOffscreenArea(pPriv->area); 492f29dbc25Smrg 49304007ebaSmrg pPriv->area = NULL; 49404007ebaSmrg } 495f29dbc25Smrg 49604007ebaSmrg pPriv->videoStatus = 0; 49704007ebaSmrg pGeode->OverlayON = FALSE; 49804007ebaSmrg } 49904007ebaSmrg else { 50004007ebaSmrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 50104007ebaSmrg pPriv->videoStatus |= OFF_TIMER; 50204007ebaSmrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 50304007ebaSmrg } 504f29dbc25Smrg } 505f29dbc25Smrg} 506f29dbc25Smrg 507f29dbc25Smrg/*---------------------------------------------------------------------------- 508f29dbc25Smrg * GXSetPortAttribute 509f29dbc25Smrg * 510f29dbc25Smrg * Description :This function is used to set the attributes of a port 511f29dbc25Smrg * like colorkeymode, double buffer support and filter. 512f29dbc25Smrg * 513f29dbc25Smrg * Parameters. 514f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 515f29dbc25Smrg * data :Pointer to the video port's private data 516f29dbc25Smrg * attribute :The port attribute to be set 517f29dbc25Smrg * value :Value of the attribute to be set. 518f29dbc25Smrg * 519c744f008Smrg * Returns :Success if the attribute is supported, else BadMatch 520f29dbc25Smrg * 521f29dbc25Smrg * Comments :none 522f29dbc25Smrg *---------------------------------------------------------------------------- 523f29dbc25Smrg */ 524f29dbc25Smrgstatic int 525f29dbc25SmrgGXSetPortAttribute(ScrnInfoPtr pScrni, 52604007ebaSmrg Atom attribute, INT32 value, pointer data) 527f29dbc25Smrg{ 528f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 529f29dbc25Smrg 530f29dbc25Smrg GXAccelSync(pScrni); 531f29dbc25Smrg if (attribute == xvColorKey) { 53204007ebaSmrg pPriv->colorKey = value; 53304007ebaSmrg GXSetColorkey(pScrni, pPriv); 534f29dbc25Smrg } 535f29dbc25Smrg#if DBUF 536f29dbc25Smrg else if (attribute == xvDoubleBuffer) { 53704007ebaSmrg if ((value < 0) || (value > 1)) 53804007ebaSmrg return BadValue; 53904007ebaSmrg pPriv->doubleBuffer = value; 540f29dbc25Smrg } 541f29dbc25Smrg#endif 542f29dbc25Smrg else if (attribute == xvColorKeyMode) { 54304007ebaSmrg pPriv->colorKeyMode = value; 54404007ebaSmrg GXSetColorkey(pScrni, pPriv); 54504007ebaSmrg } 54604007ebaSmrg else if (attribute == xvFilter) { 54704007ebaSmrg if ((value < 0) || (value > 1)) 54804007ebaSmrg return BadValue; 54904007ebaSmrg pPriv->filter = value; 55004007ebaSmrg } 55104007ebaSmrg else 55204007ebaSmrg return BadMatch; 553f29dbc25Smrg 554f29dbc25Smrg return Success; 555f29dbc25Smrg} 556f29dbc25Smrg 557f29dbc25Smrg/*---------------------------------------------------------------------------- 558f29dbc25Smrg * GXGetPortAttribute 559f29dbc25Smrg * 560f29dbc25Smrg * Description :This function is used to get the attributes of a port 561f29dbc25Smrg * like hue, saturation,brightness or contrast. 562f29dbc25Smrg * 563f29dbc25Smrg * Parameters. 564f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 565f29dbc25Smrg * data :Pointer to the video port's private data 566f29dbc25Smrg * attribute :The port attribute to be read 567f29dbc25Smrg * value :Pointer to the value of the attribute to be read. 568f29dbc25Smrg * 569c744f008Smrg * Returns :Success if the attribute is supported, else BadMatch 570f29dbc25Smrg * 571f29dbc25Smrg * Comments :none 572f29dbc25Smrg *---------------------------------------------------------------------------- 573f29dbc25Smrg */ 574f29dbc25Smrgstatic int 575f29dbc25SmrgGXGetPortAttribute(ScrnInfoPtr pScrni, 57604007ebaSmrg Atom attribute, INT32 *value, pointer data) 577f29dbc25Smrg{ 578f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 579f29dbc25Smrg 580f29dbc25Smrg if (attribute == xvColorKey) { 58104007ebaSmrg *value = pPriv->colorKey; 582f29dbc25Smrg } 583f29dbc25Smrg#if DBUF 584f29dbc25Smrg else if (attribute == xvDoubleBuffer) { 58504007ebaSmrg *value = (pPriv->doubleBuffer) ? 1 : 0; 586f29dbc25Smrg } 587f29dbc25Smrg#endif 588f29dbc25Smrg else if (attribute == xvColorKeyMode) { 58904007ebaSmrg *value = pPriv->colorKeyMode; 59004007ebaSmrg } 59104007ebaSmrg else if (attribute == xvFilter) { 59204007ebaSmrg *value = pPriv->filter; 59304007ebaSmrg } 59404007ebaSmrg else 59504007ebaSmrg return BadMatch; 596f29dbc25Smrg 597f29dbc25Smrg return Success; 598f29dbc25Smrg} 599f29dbc25Smrg 600f29dbc25Smrg/*---------------------------------------------------------------------------- 601f29dbc25Smrg * GXQueryBestSize 602f29dbc25Smrg * 603f29dbc25Smrg * Description :This function provides a way to query what the 604f29dbc25Smrg * destination dimensions would end up being if they were to 605f29dbc25Smrg * request that an area vid_w by vid_h from the video stream 606f29dbc25Smrg * be scaled to rectangle of drw_w by drw_h on the screen. 607f29dbc25Smrg * 608f29dbc25Smrg * Parameters. 609f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 610f29dbc25Smrg * data :Pointer to the video port's private data 611f29dbc25Smrg * vid_w,vid_h :Width and height of the video data. 612f29dbc25Smrg * drw_w,drw_h :Width and height of the scaled rectangle. 613f29dbc25Smrg * p_w,p_h :Width and height of the destination rectangle. 614f29dbc25Smrg * 615f29dbc25Smrg * Returns :None 616f29dbc25Smrg * 617f29dbc25Smrg * Comments :None 618f29dbc25Smrg *---------------------------------------------------------------------------- 619f29dbc25Smrg */ 620f29dbc25Smrgstatic void 621f29dbc25SmrgGXQueryBestSize(ScrnInfoPtr pScrni, 62204007ebaSmrg Bool motion, 62304007ebaSmrg short vid_w, short vid_h, 62404007ebaSmrg short drw_w, short drw_h, 62504007ebaSmrg unsigned int *p_w, unsigned int *p_h, pointer data) 626f29dbc25Smrg{ 627f29dbc25Smrg *p_w = drw_w; 628f29dbc25Smrg *p_h = drw_h; 629f29dbc25Smrg 630f29dbc25Smrg if (*p_w > 16384) 63104007ebaSmrg *p_w = 16384; 632f29dbc25Smrg} 633f29dbc25Smrg 634f29dbc25Smrg/*---------------------------------------------------------------------------- 635f29dbc25Smrg * GXCopyData420 636f29dbc25Smrg * 637f29dbc25Smrg * Description : Copies data from src to destination 638f29dbc25Smrg * 639f29dbc25Smrg * Parameters. 640f29dbc25Smrg * src : pointer to the source data 641f29dbc25Smrg * dst : pointer to destination data 642f29dbc25Smrg * srcPitch : pitch of the srcdata 643f29dbc25Smrg * dstPitch : pitch of the destination data 644f29dbc25Smrg * h & w : height and width of source data 645f29dbc25Smrg * 646f29dbc25Smrg * Returns :None 647f29dbc25Smrg * 648f29dbc25Smrg * Comments :None 649f29dbc25Smrg *---------------------------------------------------------------------------- 650f29dbc25Smrg */ 651f29dbc25Smrgstatic void 652f29dbc25SmrgGXCopyData420(unsigned char *src, unsigned char *dst, 65304007ebaSmrg int srcPitch, int dstPitch, int h, int w) 654f29dbc25Smrg{ 655f29dbc25Smrg while (h--) { 65604007ebaSmrg memcpy(dst, src, w); 65704007ebaSmrg src += srcPitch; 65804007ebaSmrg dst += dstPitch; 659f29dbc25Smrg } 660f29dbc25Smrg} 661f29dbc25Smrg 662f29dbc25Smrg/*---------------------------------------------------------------------------- 663f29dbc25Smrg * GXCopyData422 664f29dbc25Smrg * 665f29dbc25Smrg * Description : Copies data from src to destination 666f29dbc25Smrg * 667f29dbc25Smrg * Parameters. 668f29dbc25Smrg * src : pointer to the source data 669f29dbc25Smrg * dst : pointer to destination data 670f29dbc25Smrg * srcPitch : pitch of the srcdata 671f29dbc25Smrg * dstPitch : pitch of the destination data 672f29dbc25Smrg * h & w : height and width of source data 673f29dbc25Smrg * 674f29dbc25Smrg * Returns :None 675f29dbc25Smrg * 676f29dbc25Smrg * Comments :None 677f29dbc25Smrg *---------------------------------------------------------------------------- 678f29dbc25Smrg */ 679f29dbc25Smrgstatic void 680f29dbc25SmrgGXCopyData422(unsigned char *src, unsigned char *dst, 68104007ebaSmrg int srcPitch, int dstPitch, int h, int w) 682f29dbc25Smrg{ 683f29dbc25Smrg w <<= 1; 684f29dbc25Smrg while (h--) { 68504007ebaSmrg memcpy(dst, src, w); 68604007ebaSmrg src += srcPitch; 68704007ebaSmrg dst += dstPitch; 688f29dbc25Smrg } 689f29dbc25Smrg} 690f29dbc25Smrg 691f29dbc25Smrg#ifdef XF86EXA 692f29dbc25Smrgstatic void 693f29dbc25SmrgGXVideoSave(ScreenPtr pScreen, ExaOffscreenArea * area) 694f29dbc25Smrg{ 69504007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScreen); 696f29dbc25Smrg GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); 697f29dbc25Smrg 698f29dbc25Smrg if (area == pPriv->area) 69904007ebaSmrg pPriv->area = NULL; 700f29dbc25Smrg} 701f29dbc25Smrg#endif 702f29dbc25Smrg 703f29dbc25Smrgstatic int 704f29dbc25SmrgGXAllocateMemory(ScrnInfoPtr pScrni, void **memp, int numlines) 705f29dbc25Smrg{ 70604007ebaSmrg ScreenPtr pScrn = xf86ScrnToScreen(pScrni); 707f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 708f29dbc25Smrg 709f29dbc25Smrg //long displayWidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); 710f29dbc25Smrg int size = numlines * pGeode->displayWidth; 711f29dbc25Smrg 712f29dbc25Smrg#if XF86EXA 713f29dbc25Smrg if (pGeode->useEXA) { 71404007ebaSmrg ExaOffscreenArea *area = *memp; 715f29dbc25Smrg 71604007ebaSmrg if (area != NULL) { 71704007ebaSmrg if (area->size >= size) 71804007ebaSmrg return area->offset; 719f29dbc25Smrg 72004007ebaSmrg exaOffscreenFree(pScrni->pScreen, area); 72104007ebaSmrg } 722f29dbc25Smrg 72304007ebaSmrg area = exaOffscreenAlloc(pScrni->pScreen, size, 16, 72404007ebaSmrg TRUE, GXVideoSave, NULL); 72504007ebaSmrg *memp = area; 726f29dbc25Smrg 72704007ebaSmrg return area == NULL ? 0 : area->offset; 728f29dbc25Smrg } 729f29dbc25Smrg#endif 730f29dbc25Smrg 731f29dbc25Smrg if (!pGeode->useEXA) { 73204007ebaSmrg FBAreaPtr area = *memp; 73304007ebaSmrg FBAreaPtr new_area; 734f29dbc25Smrg 73504007ebaSmrg if (area) { 73604007ebaSmrg if ((area->box.y2 - area->box.y1) >= numlines) 73704007ebaSmrg return (area->box.y1 * pGeode->Pitch); 738f29dbc25Smrg 73904007ebaSmrg if (xf86ResizeOffscreenArea(area, pGeode->displayWidth, numlines)) 74004007ebaSmrg return (area->box.y1 * pGeode->Pitch); 741f29dbc25Smrg 74204007ebaSmrg xf86FreeOffscreenArea(area); 74304007ebaSmrg } 744f29dbc25Smrg 74504007ebaSmrg new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, 74604007ebaSmrg numlines, 0, NULL, NULL, NULL); 747f29dbc25Smrg 74804007ebaSmrg if (!new_area) { 74904007ebaSmrg int max_w, max_h; 750f29dbc25Smrg 75104007ebaSmrg xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, 75204007ebaSmrg FAVOR_WIDTH_THEN_AREA, 75304007ebaSmrg PRIORITY_EXTREME); 754f29dbc25Smrg 75504007ebaSmrg if ((max_w < pGeode->displayWidth) || (max_h < numlines)) { 75604007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 75704007ebaSmrg "No room - how sad %x, %x, %x, %x\n", max_w, 75804007ebaSmrg pGeode->displayWidth, max_h, numlines); 75904007ebaSmrg return 0; 76004007ebaSmrg } 761f29dbc25Smrg 76204007ebaSmrg xf86PurgeUnlockedOffscreenAreas(pScrn); 76304007ebaSmrg new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, 76404007ebaSmrg numlines, 0, NULL, NULL, NULL); 76504007ebaSmrg } 766f29dbc25Smrg 76704007ebaSmrg return (new_area->box.y1 * pGeode->Pitch); 768f29dbc25Smrg } 769f29dbc25Smrg 770f29dbc25Smrg return 0; 771f29dbc25Smrg} 772f29dbc25Smrg 773f29dbc25Smrgstatic BoxRec dstBox; 774f29dbc25Smrgstatic int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; 775f29dbc25Smrgstatic INT32 Bx1, Bx2, By1, By2; 776f29dbc25Smrgstatic int top, left, npixels, nlines; 777f29dbc25Smrgstatic int offset, s1offset = 0, s2offset = 0, s3offset = 0; 778f29dbc25Smrgstatic unsigned char *dst_start; 779f29dbc25Smrgstatic int d2offset = 0, d3offset = 0; 780f29dbc25Smrg 781f29dbc25Smrg#if 0 782f29dbc25Smrgstatic Bool 783f29dbc25SmrgRegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) 784f29dbc25Smrg{ 785f29dbc25Smrg pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); 786f29dbc25Smrg pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); 787f29dbc25Smrg 788f29dbc25Smrg if (pRclResult->x1 <= pRclResult->x2) { 78904007ebaSmrg pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); 79004007ebaSmrg pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); 791f29dbc25Smrg 79204007ebaSmrg if (pRclResult->y1 <= pRclResult->y2) { 79304007ebaSmrg return (TRUE); 79404007ebaSmrg } 795f29dbc25Smrg } 796f29dbc25Smrg 797f29dbc25Smrg return (FALSE); 798f29dbc25Smrg} 799f29dbc25Smrg#endif 800f29dbc25Smrg 801f29dbc25Smrgvoid 802f29dbc25SmrgGXSetVideoPosition(int x, int y, int width, int height, 80304007ebaSmrg short src_w, short src_h, short drw_w, short drw_h, 80404007ebaSmrg int id, int offset, ScrnInfoPtr pScrni) 805f29dbc25Smrg{ 806f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 807f29dbc25Smrg long ystart, xend, yend; 808f29dbc25Smrg unsigned long lines = 0; 809f29dbc25Smrg unsigned long y_extra, uv_extra = 0; 810f29dbc25Smrg unsigned long startAddress; 811f29dbc25Smrg 812f29dbc25Smrg#if 0 813f29dbc25Smrg BoxRec ovly, display, result; 814f29dbc25Smrg#endif 815f29dbc25Smrg 816f29dbc25Smrg xend = x + drw_w; 817f29dbc25Smrg yend = y + drw_h; 818f29dbc25Smrg 819f29dbc25Smrg /* Take care of panning when panel is present */ 820f29dbc25Smrg 821f29dbc25Smrg startAddress = gfx_get_display_offset(); 822f29dbc25Smrg DeltaY = startAddress / pGeode->Pitch; 823f29dbc25Smrg DeltaX = startAddress & (pGeode->Pitch - 1); 824f29dbc25Smrg DeltaX /= (pScrni->bitsPerPixel >> 3); 825f29dbc25Smrg 826f29dbc25Smrg#if 0 827f29dbc25Smrg /* Thhis code is pretty dang broken - comment it out for now */ 828f29dbc25Smrg 829f29dbc25Smrg if (pGeode->Panel) { 83004007ebaSmrg ovly.x1 = x; 83104007ebaSmrg ovly.x2 = x + pGeode->video_dstw; 83204007ebaSmrg ovly.y1 = y; 83304007ebaSmrg ovly.y2 = y + pGeode->video_dsth; 83404007ebaSmrg 83504007ebaSmrg display.x1 = DeltaX; 83604007ebaSmrg display.x2 = DeltaX + pGeode->FPBX; 83704007ebaSmrg display.y1 = DeltaY; 83804007ebaSmrg display.y2 = DeltaY + pGeode->FPBY; 83904007ebaSmrg x = xend = 0; 84004007ebaSmrg if (RegionsIntersect(&display, &ovly, &result)) { 84104007ebaSmrg x = ovly.x1 - DeltaX; 84204007ebaSmrg xend = ovly.x2 - DeltaX; 84304007ebaSmrg y = ovly.y1 - DeltaY; 84404007ebaSmrg yend = ovly.y2 - DeltaY; 84504007ebaSmrg } 846f29dbc25Smrg } 847f29dbc25Smrg#endif 848f29dbc25Smrg 849f29dbc25Smrg /* TOP CLIPPING */ 850f29dbc25Smrg 851f29dbc25Smrg if (y < 0) { 85204007ebaSmrg if (src_h < drw_h) 85304007ebaSmrg lines = (-y) * src_h / drw_h; 85404007ebaSmrg else 85504007ebaSmrg lines = (-y); 85604007ebaSmrg ystart = 0; 85704007ebaSmrg drw_h += y; 85804007ebaSmrg y_extra = lines * dstPitch; 85904007ebaSmrg uv_extra = (lines >> 1) * (dstPitch2); 86004007ebaSmrg } 86104007ebaSmrg else { 86204007ebaSmrg ystart = y; 86304007ebaSmrg lines = 0; 86404007ebaSmrg y_extra = 0; 865f29dbc25Smrg } 866f29dbc25Smrg 867f29dbc25Smrg GFX(set_video_window(x, ystart, xend - x, yend - ystart)); 868f29dbc25Smrg 869f29dbc25Smrg if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { 87004007ebaSmrg GFX(set_video_yuv_offsets(offset + y_extra, 87104007ebaSmrg offset + d3offset + uv_extra, 87204007ebaSmrg offset + d2offset + uv_extra)); 87304007ebaSmrg } 87404007ebaSmrg else { 87504007ebaSmrg GFX(set_video_offset(offset + y_extra)); 876f29dbc25Smrg } 877f29dbc25Smrg} 878f29dbc25Smrg 879f29dbc25Smrg/*---------------------------------------------------------------------------- 880f29dbc25Smrg * GXDisplayVideo 881f29dbc25Smrg * 882f29dbc25Smrg * Description :This function sets up the video registers for playing video 883f29dbc25Smrg * It sets up the video format,width, height & position of the 884f29dbc25Smrg * video window ,video offsets( y,u,v) and video pitches(y,u,v) 885f29dbc25Smrg * 886f29dbc25Smrg * Parameters 887f29dbc25Smrg * 888f29dbc25Smrg * Returns :None 889f29dbc25Smrg * 890f29dbc25Smrg * Comments :None 891f29dbc25Smrg *---------------------------------------------------------------------------- 892f29dbc25Smrg */ 893f29dbc25Smrg 894f29dbc25Smrgstatic void 895f29dbc25SmrgGXDisplayVideo(ScrnInfoPtr pScrni, 89604007ebaSmrg int id, 89704007ebaSmrg int offset, 89804007ebaSmrg short width, short height, 89904007ebaSmrg int pitch, 90004007ebaSmrg int x1, int y1, int x2, int y2, 90104007ebaSmrg BoxPtr dstBox, short src_w, short src_h, short drw_w, 90204007ebaSmrg short drw_h) 903f29dbc25Smrg{ 904f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 905f29dbc25Smrg unsigned long dcfg, misc; 906f29dbc25Smrg 907f29dbc25Smrg GXAccelSync(pScrni); 908f29dbc25Smrg 909f29dbc25Smrg /* If the gamma LUT is already loaded with graphics data, then save it 910f29dbc25Smrg * off 911f29dbc25Smrg */ 912f29dbc25Smrg 913f29dbc25Smrg if (id != FOURCC_RGB565) { 91404007ebaSmrg dcfg = gfx_read_vid32(DISPLAY_CONFIG); 91504007ebaSmrg misc = gfx_read_vid32(MISC); 916f29dbc25Smrg 91704007ebaSmrg lutflag = (!(misc & 1) && (dcfg & (1 << 21))); 918f29dbc25Smrg 91904007ebaSmrg if (lutflag) 92004007ebaSmrg get_gamma_ram(graphics_lut); 921f29dbc25Smrg 92204007ebaSmrg /* Set the video gamma ram */ 92304007ebaSmrg GFX(set_video_palette(NULL)); 924f29dbc25Smrg } 925f29dbc25Smrg 926f29dbc25Smrg GFX(set_video_enable(1)); 927f29dbc25Smrg 928f29dbc25Smrg switch (id) { 92904007ebaSmrg case FOURCC_UYVY: /* UYVY */ 93004007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_UYVY)); 93104007ebaSmrg GFX(set_video_size(width, height)); 93204007ebaSmrg break; 93304007ebaSmrg case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ 93404007ebaSmrg case FOURCC_YV12: /* YV12 */ 93504007ebaSmrg case FOURCC_I420: /* I420 */ 93604007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_Y0Y1Y2Y3)); 93704007ebaSmrg GFX(set_video_size(width, height)); 93804007ebaSmrg GFX(set_video_yuv_pitch(dstPitch, dstPitch2)); 93904007ebaSmrg break; 94004007ebaSmrg case FOURCC_YUY2: /* YUY2 */ 94104007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_YUYV)); 94204007ebaSmrg GFX(set_video_size(width, height)); 94304007ebaSmrg break; 94404007ebaSmrg case FOURCC_Y2YU: /* Y2YU */ 94504007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_Y2YU)); 94604007ebaSmrg GFX(set_video_size(width, height)); 94704007ebaSmrg break; 94804007ebaSmrg case FOURCC_YVYU: /* YVYU */ 94904007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_YVYU)); 95004007ebaSmrg GFX(set_video_size(width, height)); 95104007ebaSmrg break; 952f29dbc25Smrg case FOURCC_RGB565: 95304007ebaSmrg GFX(set_video_format(VIDEO_FORMAT_RGB)); 95404007ebaSmrg GFX(set_video_size(width, height)); 95504007ebaSmrg break; 956f29dbc25Smrg 957f29dbc25Smrg } 958f29dbc25Smrg 959f29dbc25Smrg if (pGeode->Panel) { 96004007ebaSmrg pGeode->video_x = dstBox->x1; 96104007ebaSmrg pGeode->video_y = dstBox->y1; 96204007ebaSmrg pGeode->video_w = width; 96304007ebaSmrg pGeode->video_h = height; 96404007ebaSmrg pGeode->video_srcw = src_w; 96504007ebaSmrg pGeode->video_srch = src_h; 96604007ebaSmrg pGeode->video_dstw = drw_w; 96704007ebaSmrg pGeode->video_dsth = drw_h; 96804007ebaSmrg pGeode->video_offset = offset; 96904007ebaSmrg pGeode->video_id = id; 97004007ebaSmrg pGeode->video_scrnptr = pScrni; 971f29dbc25Smrg } 972f29dbc25Smrg 973f29dbc25Smrg if ((drw_w >= src_w) && (drw_h >= src_h)) 97404007ebaSmrg GFX(set_video_scale(width, height, drw_w, drw_h)); 975f29dbc25Smrg else if (drw_w < src_w) 97604007ebaSmrg GFX(set_video_scale(drw_w, height, drw_w, drw_h)); 977f29dbc25Smrg else if (drw_h < src_h) 97804007ebaSmrg GFX(set_video_scale(width, drw_h, drw_w, drw_h)); 979f29dbc25Smrg 980f29dbc25Smrg GXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, 98104007ebaSmrg src_h, drw_w, drw_h, id, offset, pScrni); 982f29dbc25Smrg} 983f29dbc25Smrg 984f29dbc25Smrg/* Used by LX as well */ 985f29dbc25Smrg 986f29dbc25SmrgBool 987f29dbc25SmrgRegionsEqual(RegionPtr A, RegionPtr B) 988f29dbc25Smrg{ 989f29dbc25Smrg int *dataA, *dataB; 990f29dbc25Smrg int num; 991f29dbc25Smrg 992f29dbc25Smrg num = REGION_NUM_RECTS(A); 993f29dbc25Smrg if (num != REGION_NUM_RECTS(B)) { 99404007ebaSmrg return FALSE; 995f29dbc25Smrg } 996f29dbc25Smrg 997f29dbc25Smrg if ((A->extents.x1 != B->extents.x1) || 99804007ebaSmrg (A->extents.x2 != B->extents.x2) || 99904007ebaSmrg (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) 100004007ebaSmrg return FALSE; 1001f29dbc25Smrg 100204007ebaSmrg dataA = (int *) REGION_RECTS(A); 100304007ebaSmrg dataB = (int *) REGION_RECTS(B); 1004f29dbc25Smrg 1005f29dbc25Smrg while (num--) { 100604007ebaSmrg if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) 100704007ebaSmrg return FALSE; 1008f29dbc25Smrg 100904007ebaSmrg dataA += 2; 101004007ebaSmrg dataB += 2; 1011f29dbc25Smrg } 1012f29dbc25Smrg 1013f29dbc25Smrg return TRUE; 1014f29dbc25Smrg} 1015f29dbc25Smrg 1016f29dbc25Smrg/*---------------------------------------------------------------------------- 1017f29dbc25Smrg * GXPutImage :This function writes a single frame of video into a 1018f29dbc25Smrg * drawable. The position and size of the source rectangle is 1019f29dbc25Smrg * specified by src_x,src_y, src_w and src_h. This data is 1020f29dbc25Smrg * stored in a system memory buffer at buf. The position and 1021f29dbc25Smrg * size of the destination rectangle is specified by drw_x, 1022f29dbc25Smrg * drw_y,drw_w,drw_h.The data is in the format indicated by the 1023f29dbc25Smrg * image descriptor and represents a source of size width by 1024f29dbc25Smrg * height. If sync is TRUE the driver should not return from 1025f29dbc25Smrg * this function until it is through reading the data from buf. 1026f29dbc25Smrg * Returning when sync is TRUE indicates that it is safe for the 1027f29dbc25Smrg * data at buf to be replaced,freed, or modified. 1028f29dbc25Smrg * 1029f29dbc25Smrg * Parameters. 1030f29dbc25Smrg * 1031f29dbc25Smrg * Returns :None 1032f29dbc25Smrg * 1033f29dbc25Smrg * Comments :None 1034f29dbc25Smrg *---------------------------------------------------------------------------- 1035f29dbc25Smrg */ 1036f29dbc25Smrg 1037f29dbc25Smrgstatic int 1038f29dbc25SmrgGXPutImage(ScrnInfoPtr pScrni, 103904007ebaSmrg short src_x, short src_y, 104004007ebaSmrg short drw_x, short drw_y, 104104007ebaSmrg short src_w, short src_h, 104204007ebaSmrg short drw_w, short drw_h, 104304007ebaSmrg int id, unsigned char *buf, 104404007ebaSmrg short width, short height, Bool sync, RegionPtr clipBoxes, 104504007ebaSmrg pointer data, DrawablePtr pDraw) 1046f29dbc25Smrg{ 1047f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 1048f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1049f29dbc25Smrg int new_h; 1050f29dbc25Smrg 1051f29dbc25Smrg#if REINIT 1052f29dbc25Smrg BOOL ReInitVideo = FALSE; 1053f29dbc25Smrg static BOOL DoReinitAgain = 0; 1054f29dbc25Smrg#endif 1055f29dbc25Smrg 1056f29dbc25Smrg#if XV_PROFILE 1057f29dbc25Smrg long oldtime, newtime; 1058f29dbc25Smrg 1059f29dbc25Smrg UpdateCurrentTime(); 1060f29dbc25Smrg oldtime = currentTime.milliseconds; 1061f29dbc25Smrg#endif 1062f29dbc25Smrg 1063f29dbc25Smrg#if REINIT 1064f29dbc25Smrg/* update cliplist */ 1065f29dbc25Smrg if (!RegionsEqual(&pPriv->clip, clipBoxes)) { 106604007ebaSmrg ReInitVideo = TRUE; 1067f29dbc25Smrg } 1068f29dbc25Smrg 1069f29dbc25Smrg if (DoReinitAgain) 107004007ebaSmrg ReInitVideo = TRUE; 1071f29dbc25Smrg 1072f29dbc25Smrg if (ReInitVideo) { 107304007ebaSmrg DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); 1074f29dbc25Smrg#endif 107504007ebaSmrg DoReinitAgain = ~DoReinitAgain; 107604007ebaSmrg if (drw_w > 16384) 107704007ebaSmrg drw_w = 16384; 107804007ebaSmrg 107904007ebaSmrg /* Clip */ 108004007ebaSmrg Bx1 = src_x; 108104007ebaSmrg Bx2 = src_x + src_w; 108204007ebaSmrg By1 = src_y; 108304007ebaSmrg By2 = src_y + src_h; 108404007ebaSmrg 108504007ebaSmrg if ((Bx1 >= Bx2) || (By1 >= By2)) 108604007ebaSmrg return Success; 108704007ebaSmrg 108804007ebaSmrg dstBox.x1 = drw_x; 108904007ebaSmrg dstBox.x2 = drw_x + drw_w; 109004007ebaSmrg dstBox.y1 = drw_y; 109104007ebaSmrg dstBox.y2 = drw_y + drw_h; 109204007ebaSmrg 109304007ebaSmrg dstBox.x1 -= pScrni->frameX0; 109404007ebaSmrg dstBox.x2 -= pScrni->frameX0; 109504007ebaSmrg dstBox.y1 -= pScrni->frameY0; 109604007ebaSmrg dstBox.y2 -= pScrni->frameY0; 109704007ebaSmrg 109804007ebaSmrg switch (id) { 109904007ebaSmrg case FOURCC_YV12: 110004007ebaSmrg case FOURCC_I420: 110104007ebaSmrg srcPitch = (width + 3) & ~3; /* of luma */ 110204007ebaSmrg dstPitch = (width + 31) & ~31; 110304007ebaSmrg 110404007ebaSmrg s2offset = srcPitch * height; 110504007ebaSmrg d2offset = dstPitch * height; 110604007ebaSmrg 110704007ebaSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 110804007ebaSmrg dstPitch2 = ((width >> 1) + 15) & ~15; 110904007ebaSmrg 111004007ebaSmrg s3offset = (srcPitch2 * (height >> 1)) + s2offset; 111104007ebaSmrg d3offset = (dstPitch2 * (height >> 1)) + d2offset; 111204007ebaSmrg 111304007ebaSmrg new_h = dstPitch * height; /* Y */ 111404007ebaSmrg new_h += (dstPitch2 * height); /* U+V */ 111504007ebaSmrg new_h += pGeode->Pitch - 1; 111604007ebaSmrg new_h /= pGeode->Pitch; 111704007ebaSmrg break; 111804007ebaSmrg case FOURCC_UYVY: 111904007ebaSmrg case FOURCC_YUY2: 112004007ebaSmrg case FOURCC_Y800: 112104007ebaSmrg case FOURCC_RGB565: 112204007ebaSmrg default: 112304007ebaSmrg dstPitch = ((width << 1) + 3) & ~3; 112404007ebaSmrg srcPitch = (width << 1); 112504007ebaSmrg new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; 112604007ebaSmrg break; 112704007ebaSmrg } 1128f29dbc25Smrg#if DBUF 112904007ebaSmrg if (pPriv->doubleBuffer) 113004007ebaSmrg new_h <<= 1; 1131f29dbc25Smrg#endif 1132f29dbc25Smrg 113304007ebaSmrg if (!(pPriv->offset = GXAllocateMemory(pScrni, &pPriv->area, new_h))) { 113404007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 113504007ebaSmrg "Could not allocate area of size %d\n", new_h); 113604007ebaSmrg return BadAlloc; 113704007ebaSmrg } 1138f29dbc25Smrg 113904007ebaSmrg /* copy data */ 114004007ebaSmrg top = By1; 114104007ebaSmrg left = Bx1 & ~1; 114204007ebaSmrg npixels = ((Bx2 + 1) & ~1) - left; 1143f29dbc25Smrg 114404007ebaSmrg switch (id) { 114504007ebaSmrg case FOURCC_YV12: 114604007ebaSmrg case FOURCC_I420: 114704007ebaSmrg { 114804007ebaSmrg int tmp; 1149f29dbc25Smrg 115004007ebaSmrg top &= ~1; 1151f29dbc25Smrg 115204007ebaSmrg offset = pPriv->offset + (top * dstPitch); 1153f29dbc25Smrg 1154f29dbc25Smrg#if DBUF 115504007ebaSmrg if (pPriv->doubleBuffer && pPriv->currentBuffer) 115604007ebaSmrg offset += (new_h >> 1) * pGeode->Pitch; 1157f29dbc25Smrg#endif 115804007ebaSmrg dst_start = pGeode->FBBase + offset + left; 115904007ebaSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 1); 116004007ebaSmrg s2offset += tmp; 116104007ebaSmrg s3offset += tmp; 116204007ebaSmrg if (id == FOURCC_I420) { 116304007ebaSmrg tmp = s2offset; 116404007ebaSmrg s2offset = s3offset; 116504007ebaSmrg s3offset = tmp; 116604007ebaSmrg } 116704007ebaSmrg nlines = ((By2 + 1) & ~1) - top; 116804007ebaSmrg } 116904007ebaSmrg break; 117004007ebaSmrg case FOURCC_UYVY: 117104007ebaSmrg case FOURCC_YUY2: 117204007ebaSmrg case FOURCC_Y800: 117304007ebaSmrg case FOURCC_RGB565: 117404007ebaSmrg default: 117504007ebaSmrg left <<= 1; 117604007ebaSmrg buf += (top * srcPitch) + left; 117704007ebaSmrg nlines = By2 - top; 117804007ebaSmrg offset = (pPriv->offset) + (top * dstPitch); 1179f29dbc25Smrg 1180f29dbc25Smrg#if DBUF 118104007ebaSmrg if (pPriv->doubleBuffer && pPriv->currentBuffer) 118204007ebaSmrg offset += (new_h >> 1) * pGeode->Pitch; 1183f29dbc25Smrg#endif 118404007ebaSmrg dst_start = pGeode->FBBase + offset + left; 118504007ebaSmrg break; 118604007ebaSmrg } 118704007ebaSmrg s1offset = (top * srcPitch) + left; 1188f29dbc25Smrg#if REINIT 118904007ebaSmrg /* update cliplist */ 119004007ebaSmrg REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); 1191f29dbc25Smrg 119204007ebaSmrg if (pPriv->colorKeyMode == 0) { 119304007ebaSmrg xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes); 119404007ebaSmrg } 1195f29dbc25Smrg 119604007ebaSmrg GXDisplayVideo(pScrni, id, offset, width, height, dstPitch, 119704007ebaSmrg Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1198f29dbc25Smrg } 1199f29dbc25Smrg#endif 1200f29dbc25Smrg switch (id) { 1201f29dbc25Smrg case FOURCC_Y800: 120204007ebaSmrg /* This is shared between LX and GX, so it lives in amd_common.c */ 120304007ebaSmrg GeodeCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 120404007ebaSmrg break; 1205f29dbc25Smrg case FOURCC_YV12: 1206f29dbc25Smrg case FOURCC_I420: 120704007ebaSmrg GXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, 120804007ebaSmrg npixels); 120904007ebaSmrg GXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, 121004007ebaSmrg dstPitch2, nlines >> 1, npixels >> 1); 121104007ebaSmrg GXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, 121204007ebaSmrg dstPitch2, nlines >> 1, npixels >> 1); 121304007ebaSmrg break; 1214f29dbc25Smrg case FOURCC_UYVY: 1215f29dbc25Smrg case FOURCC_YUY2: 1216f29dbc25Smrg case FOURCC_RGB565: 1217f29dbc25Smrg default: 121804007ebaSmrg GXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 121904007ebaSmrg break; 1220f29dbc25Smrg } 1221f29dbc25Smrg#if !REINIT 1222f29dbc25Smrg /* update cliplist */ 1223f29dbc25Smrg REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); 1224f29dbc25Smrg if (pPriv->colorKeyMode == 0) { 122504007ebaSmrg /* draw these */ 122604007ebaSmrg XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, 122704007ebaSmrg REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); 1228f29dbc25Smrg } 1229f29dbc25Smrg 1230f29dbc25Smrg GXDisplayVideo(pScrni, id, offset, width, height, dstPitch, 123104007ebaSmrg Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1232f29dbc25Smrg#endif 1233f29dbc25Smrg 1234f29dbc25Smrg#if XV_PROFILE 1235f29dbc25Smrg UpdateCurrentTime(); 1236f29dbc25Smrg newtime = currentTime.milliseconds; 1237f29dbc25Smrg DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); 1238f29dbc25Smrg#endif 1239f29dbc25Smrg 1240f29dbc25Smrg#if DBUF 1241f29dbc25Smrg pPriv->currentBuffer ^= 1; 1242f29dbc25Smrg#endif 1243f29dbc25Smrg 1244f29dbc25Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 1245f29dbc25Smrg pGeode->OverlayON = TRUE; 1246f29dbc25Smrg return Success; 1247f29dbc25Smrg} 1248f29dbc25Smrg 1249f29dbc25Smrg/*---------------------------------------------------------------------------- 1250f29dbc25Smrg * GXQueryImageAttributes 1251f29dbc25Smrg * 1252f29dbc25Smrg * Description :This function is called to let the driver specify how data 1253f29dbc25Smrg * for a particular image of size width by height should be 1254f29dbc25Smrg * stored. 1255f29dbc25Smrg * 1256f29dbc25Smrg * Parameters. 1257f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 1258f29dbc25Smrg * id :Id for the video format 1259f29dbc25Smrg * width :width of the image (can be modified by the driver) 1260f29dbc25Smrg * height :height of the image (can be modified by the driver) 1261f29dbc25Smrg * Returns : Size of the memory required for storing this image 1262f29dbc25Smrg * 1263f29dbc25Smrg * Comments :None 1264f29dbc25Smrg * 1265f29dbc25Smrg *---------------------------------------------------------------------------- 1266f29dbc25Smrg */ 1267f29dbc25Smrg 1268f29dbc25Smrgint 1269f29dbc25SmrgGeodeQueryImageAttributes(ScrnInfoPtr pScrni, 127004007ebaSmrg int id, unsigned short *w, unsigned short *h, 127104007ebaSmrg int *pitches, int *offsets) 1272f29dbc25Smrg{ 1273f29dbc25Smrg int size; 1274f29dbc25Smrg int tmp; 1275f29dbc25Smrg 1276f29dbc25Smrg DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); 1277f29dbc25Smrg 1278f29dbc25Smrg if (*w > 1024) 127904007ebaSmrg *w = 1024; 1280f29dbc25Smrg if (*h > 1024) 128104007ebaSmrg *h = 1024; 1282f29dbc25Smrg 1283f29dbc25Smrg *w = (*w + 1) & ~1; 1284f29dbc25Smrg if (offsets) 128504007ebaSmrg offsets[0] = 0; 1286f29dbc25Smrg 1287f29dbc25Smrg switch (id) { 1288f29dbc25Smrg case FOURCC_YV12: 1289f29dbc25Smrg case FOURCC_I420: 129004007ebaSmrg *h = (*h + 1) & ~1; 129104007ebaSmrg size = (*w + 3) & ~3; 129204007ebaSmrg if (pitches) 129304007ebaSmrg pitches[0] = size; 129404007ebaSmrg 129504007ebaSmrg size *= *h; 129604007ebaSmrg if (offsets) 129704007ebaSmrg offsets[1] = size; 129804007ebaSmrg 129904007ebaSmrg tmp = ((*w >> 1) + 3) & ~3; 130004007ebaSmrg if (pitches) 130104007ebaSmrg pitches[1] = pitches[2] = tmp; 130204007ebaSmrg 130304007ebaSmrg tmp *= (*h >> 1); 130404007ebaSmrg size += tmp; 130504007ebaSmrg if (offsets) 130604007ebaSmrg offsets[2] = size; 130704007ebaSmrg 130804007ebaSmrg size += tmp; 130904007ebaSmrg break; 1310f29dbc25Smrg case FOURCC_UYVY: 1311f29dbc25Smrg case FOURCC_YUY2: 1312f29dbc25Smrg case FOURCC_Y800: 1313f29dbc25Smrg default: 131404007ebaSmrg size = *w << 1; 131504007ebaSmrg if (pitches) 131604007ebaSmrg pitches[0] = size; 1317f29dbc25Smrg 131804007ebaSmrg size *= *h; 131904007ebaSmrg break; 1320f29dbc25Smrg } 1321f29dbc25Smrg return size; 1322f29dbc25Smrg} 1323f29dbc25Smrg 1324f29dbc25Smrgstatic void 132504007ebaSmrgGXBlockHandler(BLOCKHANDLER_ARGS_DECL) 1326f29dbc25Smrg{ 132704007ebaSmrg SCREEN_PTR(arg); 132804007ebaSmrg ScrnInfoPtr pScrni = xf86ScreenToScrn(pScrn); 1329f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1330f29dbc25Smrg GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); 1331f29dbc25Smrg 1332f29dbc25Smrg pScrn->BlockHandler = pGeode->BlockHandler; 133304007ebaSmrg (*pScrn->BlockHandler) (BLOCKHANDLER_ARGS); 1334f29dbc25Smrg pScrn->BlockHandler = GXBlockHandler; 1335f29dbc25Smrg 1336f29dbc25Smrg if (pPriv->videoStatus & TIMER_MASK) { 133704007ebaSmrg GXAccelSync(pScrni); 133804007ebaSmrg UpdateCurrentTime(); 133904007ebaSmrg if (pPriv->videoStatus & OFF_TIMER) { 134004007ebaSmrg if (pPriv->offTime < currentTime.milliseconds) { 134104007ebaSmrg GFX(set_video_enable(0)); 134204007ebaSmrg 134304007ebaSmrg /* If we have saved graphics LUT data - restore it */ 134404007ebaSmrg /* Otherwise, turn bypass on */ 134504007ebaSmrg 134604007ebaSmrg if (lutflag) 134704007ebaSmrg GFX(set_graphics_palette(graphics_lut)); 134804007ebaSmrg else 134904007ebaSmrg GFX(set_video_palette_bypass(1)); 135004007ebaSmrg 135104007ebaSmrg lutflag = 0; 135204007ebaSmrg 135304007ebaSmrg pPriv->videoStatus = FREE_TIMER; 135404007ebaSmrg pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 135504007ebaSmrg } 135604007ebaSmrg } 135704007ebaSmrg else { /* FREE_TIMER */ 135804007ebaSmrg if (pPriv->freeTime < currentTime.milliseconds) { 135904007ebaSmrg 136004007ebaSmrg if (pPriv->area) { 1361f29dbc25Smrg#ifdef XF86EXA 136204007ebaSmrg if (pGeode->useEXA) 136304007ebaSmrg exaOffscreenFree(pScrn, pPriv->area); 1364f29dbc25Smrg#endif 136504007ebaSmrg if (!pGeode->useEXA) 136604007ebaSmrg xf86FreeOffscreenArea(pPriv->area); 1367f29dbc25Smrg 136804007ebaSmrg pPriv->area = NULL; 136904007ebaSmrg } 1370f29dbc25Smrg 137104007ebaSmrg pPriv->videoStatus = 0; 137204007ebaSmrg } 137304007ebaSmrg } 1374f29dbc25Smrg } 1375f29dbc25Smrg} 1376f29dbc25Smrg 1377f29dbc25Smrg/****************** Offscreen stuff ***************/ 1378f29dbc25Smrg 137904007ebaSmrgtypedef struct { 1380f29dbc25Smrg void *area; 1381f29dbc25Smrg int offset; 1382f29dbc25Smrg Bool isOn; 1383f29dbc25Smrg} OffscreenPrivRec, *OffscreenPrivPtr; 1384f29dbc25Smrg 1385f29dbc25Smrg/*---------------------------------------------------------------------------- 1386f29dbc25Smrg * GXAllocateSurface 1387f29dbc25Smrg * 1388f29dbc25Smrg * Description :This function allocates an area of w by h in the offscreen 1389f29dbc25Smrg * 1390f29dbc25Smrg * Parameters. 1391f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 1392f29dbc25Smrg * 1393f29dbc25Smrg * Returns :None 1394f29dbc25Smrg * 1395f29dbc25Smrg * Comments :None 1396f29dbc25Smrg *---------------------------------------------------------------------------- 1397f29dbc25Smrg */ 1398f29dbc25Smrgstatic int 1399f29dbc25SmrgGXAllocateSurface(ScrnInfoPtr pScrni, 140004007ebaSmrg int id, unsigned short w, unsigned short h, 140104007ebaSmrg XF86SurfacePtr surface) 1402f29dbc25Smrg{ 1403f29dbc25Smrg void *area = NULL; 1404f29dbc25Smrg int pitch, fbpitch, numlines; 1405f29dbc25Smrg OffscreenPrivRec *pPriv; 1406f29dbc25Smrg 1407f29dbc25Smrg if ((w > 1024) || (h > 1024)) 140804007ebaSmrg return BadAlloc; 1409f29dbc25Smrg 1410f29dbc25Smrg w = (w + 1) & ~1; 1411f29dbc25Smrg pitch = ((w << 1) + 15) & ~15; 1412f29dbc25Smrg fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3; 1413f29dbc25Smrg numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 1414f29dbc25Smrg 1415f29dbc25Smrg if (!(offset = GXAllocateMemory(pScrni, &area, numlines))) 141604007ebaSmrg return BadAlloc; 1417f29dbc25Smrg 1418f29dbc25Smrg surface->width = w; 1419f29dbc25Smrg surface->height = h; 1420f29dbc25Smrg 1421170d5fdcSmrg if (!(surface->pitches = malloc(sizeof(int)))) 142204007ebaSmrg return BadAlloc; 1423f29dbc25Smrg 1424170d5fdcSmrg if (!(surface->offsets = malloc(sizeof(int)))) { 142504007ebaSmrg free(surface->pitches); 142604007ebaSmrg return BadAlloc; 1427f29dbc25Smrg } 1428f29dbc25Smrg 1429170d5fdcSmrg if (!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 143004007ebaSmrg free(surface->pitches); 143104007ebaSmrg free(surface->offsets); 143204007ebaSmrg return BadAlloc; 1433f29dbc25Smrg } 1434f29dbc25Smrg 1435f29dbc25Smrg pPriv->area = area; 1436f29dbc25Smrg pPriv->offset = offset; 1437f29dbc25Smrg 1438f29dbc25Smrg pPriv->isOn = FALSE; 1439f29dbc25Smrg 1440f29dbc25Smrg surface->pScrn = pScrni; 1441f29dbc25Smrg surface->id = id; 1442f29dbc25Smrg surface->pitches[0] = pitch; 1443f29dbc25Smrg surface->offsets[0] = offset; 1444f29dbc25Smrg surface->devPrivate.ptr = (pointer) pPriv; 1445f29dbc25Smrg 1446f29dbc25Smrg return Success; 1447f29dbc25Smrg} 1448f29dbc25Smrg 1449f29dbc25Smrgstatic int 1450f29dbc25SmrgGXStopSurface(XF86SurfacePtr surface) 1451f29dbc25Smrg{ 1452f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1453f29dbc25Smrg 1454f29dbc25Smrg if (pPriv->isOn) { 145504007ebaSmrg pPriv->isOn = FALSE; 1456f29dbc25Smrg } 1457f29dbc25Smrg 1458f29dbc25Smrg return Success; 1459f29dbc25Smrg} 1460f29dbc25Smrg 1461f29dbc25Smrgstatic int 1462f29dbc25SmrgGXFreeSurface(XF86SurfacePtr surface) 1463f29dbc25Smrg{ 1464f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1465f29dbc25Smrg 1466f29dbc25Smrg if (pPriv->isOn) 146704007ebaSmrg GXStopSurface(surface); 1468f29dbc25Smrg 1469f29dbc25Smrg xf86FreeOffscreenArea(pPriv->area); 1470170d5fdcSmrg free(surface->pitches); 1471170d5fdcSmrg free(surface->offsets); 1472170d5fdcSmrg free(surface->devPrivate.ptr); 1473f29dbc25Smrg 1474f29dbc25Smrg return Success; 1475f29dbc25Smrg} 1476f29dbc25Smrg 1477f29dbc25Smrgstatic int 147804007ebaSmrgGXGetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 *value) 1479f29dbc25Smrg{ 1480f29dbc25Smrg return GXGetPortAttribute(pScrni, attribute, value, 148104007ebaSmrg (pointer) (GET_PORT_PRIVATE(pScrni))); 1482f29dbc25Smrg} 1483f29dbc25Smrg 1484f29dbc25Smrgstatic int 1485f29dbc25SmrgGXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value) 1486f29dbc25Smrg{ 1487f29dbc25Smrg return GXSetPortAttribute(pScrni, attribute, value, 148804007ebaSmrg (pointer) (GET_PORT_PRIVATE(pScrni))); 1489f29dbc25Smrg} 1490f29dbc25Smrg 1491f29dbc25Smrgstatic int 1492f29dbc25SmrgGXDisplaySurface(XF86SurfacePtr surface, 149304007ebaSmrg short src_x, short src_y, 149404007ebaSmrg short drw_x, short drw_y, 149504007ebaSmrg short src_w, short src_h, short drw_w, short drw_h, 149604007ebaSmrg RegionPtr clipBoxes) 1497f29dbc25Smrg{ 1498f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1499f29dbc25Smrg ScrnInfoPtr pScrni = surface->pScrn; 1500f29dbc25Smrg GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); 1501f29dbc25Smrg INT32 x1, y1, x2, y2; 1502f29dbc25Smrg BoxRec dstBox; 1503f29dbc25Smrg 1504f29dbc25Smrg DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); 1505f29dbc25Smrg x1 = src_x; 1506f29dbc25Smrg x2 = src_x + src_w; 1507f29dbc25Smrg y1 = src_y; 1508f29dbc25Smrg y2 = src_y + src_h; 1509f29dbc25Smrg 1510f29dbc25Smrg dstBox.x1 = drw_x; 1511f29dbc25Smrg dstBox.x2 = drw_x + drw_w; 1512f29dbc25Smrg dstBox.y1 = drw_y; 1513f29dbc25Smrg dstBox.y2 = drw_y + drw_h; 1514f29dbc25Smrg 1515f29dbc25Smrg if ((x1 >= x2) || (y1 >= y2)) 151604007ebaSmrg return Success; 1517f29dbc25Smrg 1518f29dbc25Smrg dstBox.x1 -= pScrni->frameX0; 1519f29dbc25Smrg dstBox.x2 -= pScrni->frameX0; 1520f29dbc25Smrg dstBox.y1 -= pScrni->frameY0; 1521f29dbc25Smrg dstBox.y2 -= pScrni->frameY0; 1522f29dbc25Smrg 1523f29dbc25Smrg xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); 1524f29dbc25Smrg 1525f29dbc25Smrg GXDisplayVideo(pScrni, surface->id, surface->offsets[0], 152604007ebaSmrg surface->width, surface->height, surface->pitches[0], 152704007ebaSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1528f29dbc25Smrg 1529f29dbc25Smrg pPriv->isOn = TRUE; 1530f29dbc25Smrg if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 153104007ebaSmrg REGION_EMPTY(pScrni->pScreen, &portPriv->clip); 153204007ebaSmrg UpdateCurrentTime(); 153304007ebaSmrg portPriv->videoStatus = FREE_TIMER; 153404007ebaSmrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1535f29dbc25Smrg } 1536f29dbc25Smrg 1537f29dbc25Smrg return Success; 1538f29dbc25Smrg} 1539f29dbc25Smrg 1540f29dbc25Smrg/*---------------------------------------------------------------------------- 1541f29dbc25Smrg * GXInitOffscreenImages 1542f29dbc25Smrg * 1543f29dbc25Smrg * Description :This function sets up the offscreen memory management. It 1544f29dbc25Smrg * fills in the XF86OffscreenImagePtr structure with functions to 1545f29dbc25Smrg * handle offscreen memory operations. 1546f29dbc25Smrg * 1547f29dbc25Smrg * Parameters. 1548f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 1549f29dbc25Smrg * 1550f29dbc25Smrg * Returns : None 1551f29dbc25Smrg * 1552f29dbc25Smrg * Comments :None 1553f29dbc25Smrg *---------------------------------------------------------------------------- 1554f29dbc25Smrg */ 1555f29dbc25Smrgstatic void 1556f29dbc25SmrgGXInitOffscreenImages(ScreenPtr pScrn) 1557f29dbc25Smrg{ 1558f29dbc25Smrg XF86OffscreenImagePtr offscreenImages; 1559f29dbc25Smrg 1560f29dbc25Smrg /* need to free this someplace */ 1561170d5fdcSmrg if (!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 156204007ebaSmrg return; 1563f29dbc25Smrg 1564f29dbc25Smrg offscreenImages[0].image = &Images[0]; 1565f29dbc25Smrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1566f29dbc25Smrg offscreenImages[0].alloc_surface = GXAllocateSurface; 1567f29dbc25Smrg offscreenImages[0].free_surface = GXFreeSurface; 1568f29dbc25Smrg offscreenImages[0].display = GXDisplaySurface; 1569f29dbc25Smrg offscreenImages[0].stop = GXStopSurface; 1570f29dbc25Smrg offscreenImages[0].setAttribute = GXSetSurfaceAttribute; 1571f29dbc25Smrg offscreenImages[0].getAttribute = GXGetSurfaceAttribute; 1572f29dbc25Smrg offscreenImages[0].max_width = 1024; 1573f29dbc25Smrg offscreenImages[0].max_height = 1024; 1574f29dbc25Smrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1575f29dbc25Smrg offscreenImages[0].attributes = Attributes; 1576f29dbc25Smrg 1577f29dbc25Smrg xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); 1578f29dbc25Smrg} 1579f29dbc25Smrg 158004007ebaSmrg#endif /* !XvExtension */ 1581