gx_video.c revision f29dbc25
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> 57f29dbc25Smrg#include "xaa.h" 58f29dbc25Smrg#include "xaalocal.h" 59f29dbc25Smrg#include "dixstruct.h" 60f29dbc25Smrg#include "fourcc.h" 61f29dbc25Smrg#include "geode_fourcc.h" 62f29dbc25Smrg 63f29dbc25Smrg#define OFF_DELAY 200 /* milliseconds */ 64f29dbc25Smrg#define FREE_DELAY 60000 65f29dbc25Smrg 66f29dbc25Smrg#define OFF_TIMER 0x01 67f29dbc25Smrg#define FREE_TIMER 0x02 68f29dbc25Smrg#define CLIENT_VIDEO_ON 0x04 69f29dbc25Smrg 70f29dbc25Smrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 71f29dbc25Smrg#define XV_PROFILE 0 72f29dbc25Smrg#define REINIT 1 73f29dbc25Smrg 74f29dbc25Smrg#ifndef XvExtension 75f29dbc25Smrg#error "It didn't work!" 76f29dbc25Smrgvoid 77f29dbc25SmrgGXInitVideo(ScreenPtr pScrn) 78f29dbc25Smrg{ 79f29dbc25Smrg} 80f29dbc25Smrg 81f29dbc25Smrgvoid 82f29dbc25SmrgGXResetVideo(ScrnInfoPtr pScrni) 83f29dbc25Smrg{ 84f29dbc25Smrg} 85f29dbc25Smrg 86f29dbc25Smrgvoid 87f29dbc25SmrgGXSetVideoPosition() 88f29dbc25Smrg{ 89f29dbc25Smrg} 90f29dbc25Smrg#else 91f29dbc25Smrg 92f29dbc25Smrg#define DBUF 1 93f29dbc25Smrgvoid GXResetVideo(ScrnInfoPtr pScrni); 94f29dbc25Smrgstatic XF86VideoAdaptorPtr GXSetupImageVideo(ScreenPtr); 95f29dbc25Smrgstatic void GXInitOffscreenImages(ScreenPtr); 96f29dbc25Smrgstatic void GXStopVideo(ScrnInfoPtr, pointer, Bool); 97f29dbc25Smrgstatic int GXSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 98f29dbc25Smrgstatic int GXGetPortAttribute(ScrnInfoPtr, Atom, INT32 *, pointer); 99f29dbc25Smrgstatic void GXQueryBestSize(ScrnInfoPtr, Bool, 100f29dbc25Smrg short, short, short, short, unsigned int *, unsigned int *, pointer); 101f29dbc25Smrgstatic int GXPutImage(ScrnInfoPtr, short, short, short, short, short, short, 102f29dbc25Smrg short, short, int, unsigned char *, short, short, Bool, 103f29dbc25Smrg RegionPtr, pointer, DrawablePtr pDraw); 104f29dbc25Smrg 105f29dbc25Smrgstatic void GXBlockHandler(int, pointer, pointer, pointer); 106f29dbc25Smrgvoid GXSetVideoPosition(int x, int y, int width, int height, 107f29dbc25Smrg short src_w, short src_h, short drw_w, 108f29dbc25Smrg short drw_h, int id, int offset, ScrnInfoPtr pScrni); 109f29dbc25Smrg 110f29dbc25Smrgextern void GXAccelSync(ScrnInfoPtr pScrni); 111f29dbc25Smrg 112f29dbc25Smrgint DeltaX, DeltaY; 113f29dbc25Smrg 114f29dbc25Smrgunsigned long graphics_lut[256]; 115f29dbc25Smrgstatic int lutflag = 0; 116f29dbc25Smrg 117f29dbc25Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 118f29dbc25Smrg 119f29dbc25Smrgstatic Atom xvColorKey, xvColorKeyMode, xvFilter 120f29dbc25Smrg#if DBUF 121f29dbc25Smrg , xvDoubleBuffer 122f29dbc25Smrg#endif 123f29dbc25Smrg ; 124f29dbc25Smrg 125f29dbc25Smrg#define PALETTE_ADDRESS 0x038 126f29dbc25Smrg#define PALETTE_DATA 0x040 127f29dbc25Smrg#define DISPLAY_CONFIG 0x008 128f29dbc25Smrg#define MISC 0x050 129f29dbc25Smrg 130f29dbc25Smrgstatic void 131f29dbc25Smrgget_gamma_ram(unsigned long *lut) 132f29dbc25Smrg{ 133f29dbc25Smrg 134f29dbc25Smrg int i; 135f29dbc25Smrg 136f29dbc25Smrg gfx_write_vid32(PALETTE_ADDRESS, 0); 137f29dbc25Smrg 138f29dbc25Smrg for (i = 0; i < 256; i++) 139f29dbc25Smrg lut[i] = gfx_read_vid32(PALETTE_DATA); 140f29dbc25Smrg} 141f29dbc25Smrg 142f29dbc25Smrg/*---------------------------------------------------------------------------- 143f29dbc25Smrg * GXInitVideo 144f29dbc25Smrg * 145f29dbc25Smrg * Description :This is the initialization routine.It creates a new video 146f29dbc25Smrg * adapter and calls GXSetupImageVideo to initialize the adaptor 147f29dbc25Smrg * by filling XF86VideoAdaptorREc.Then it lists the existing 148f29dbc25Smrg * adaptors and adds the new one to it. Finally the list of 149f29dbc25Smrg * XF86VideoAdaptorPtr pointers are passed to the 150f29dbc25Smrg * xf86XVScreenInit(). 151f29dbc25Smrg * 152f29dbc25Smrg * Parameters. 153f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 154f29dbc25Smrg * 155f29dbc25Smrg * Returns :none 156f29dbc25Smrg * 157f29dbc25Smrg * Comments :none 158f29dbc25Smrg *---------------------------------------------------------------------------- 159f29dbc25Smrg */ 160f29dbc25Smrgvoid 161f29dbc25SmrgGXInitVideo(ScreenPtr pScrn) 162f29dbc25Smrg{ 163f29dbc25Smrg GeodeRec *pGeode; 164f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; 165f29dbc25Smrg 166f29dbc25Smrg pGeode = GEODEPTR(pScrni); 167f29dbc25Smrg 168f29dbc25Smrg if (!pGeode->NoAccel) { 169f29dbc25Smrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 170f29dbc25Smrg XF86VideoAdaptorPtr newAdaptor = NULL; 171f29dbc25Smrg 172f29dbc25Smrg int num_adaptors; 173f29dbc25Smrg 174f29dbc25Smrg newAdaptor = GXSetupImageVideo(pScrn); 175f29dbc25Smrg GXInitOffscreenImages(pScrn); 176f29dbc25Smrg 177f29dbc25Smrg num_adaptors = xf86XVListGenericAdaptors(pScrni, &adaptors); 178f29dbc25Smrg 179f29dbc25Smrg if (newAdaptor) { 180f29dbc25Smrg if (!num_adaptors) { 181f29dbc25Smrg num_adaptors = 1; 182f29dbc25Smrg adaptors = &newAdaptor; 183f29dbc25Smrg } else { 184f29dbc25Smrg newAdaptors = /* need to free this someplace */ 185f29dbc25Smrg xalloc((num_adaptors + 186f29dbc25Smrg 1) * sizeof(XF86VideoAdaptorPtr *)); 187f29dbc25Smrg if (newAdaptors) { 188f29dbc25Smrg memcpy(newAdaptors, adaptors, num_adaptors * 189f29dbc25Smrg sizeof(XF86VideoAdaptorPtr)); 190f29dbc25Smrg newAdaptors[num_adaptors] = newAdaptor; 191f29dbc25Smrg adaptors = newAdaptors; 192f29dbc25Smrg num_adaptors++; 193f29dbc25Smrg } 194f29dbc25Smrg } 195f29dbc25Smrg } 196f29dbc25Smrg 197f29dbc25Smrg if (num_adaptors) 198f29dbc25Smrg xf86XVScreenInit(pScrn, adaptors, num_adaptors); 199f29dbc25Smrg 200f29dbc25Smrg if (newAdaptors) 201f29dbc25Smrg xfree(newAdaptors); 202f29dbc25Smrg } 203f29dbc25Smrg} 204f29dbc25Smrg 205f29dbc25Smrg/* client libraries expect an encoding */ 206f29dbc25Smrgstatic XF86VideoEncodingRec DummyEncoding[1] = { 207f29dbc25Smrg { 208f29dbc25Smrg 0, 209f29dbc25Smrg "XV_IMAGE", 210f29dbc25Smrg 1024, 1024, 211f29dbc25Smrg {1, 1} 212f29dbc25Smrg } 213f29dbc25Smrg}; 214f29dbc25Smrg 215f29dbc25Smrg#define NUM_FORMATS 4 216f29dbc25Smrg 217f29dbc25Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = { 218f29dbc25Smrg {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 219f29dbc25Smrg}; 220f29dbc25Smrg 221f29dbc25Smrg#if DBUF 222f29dbc25Smrg#define NUM_ATTRIBUTES 4 223f29dbc25Smrg#else 224f29dbc25Smrg#define NUM_ATTRIBUTES 3 225f29dbc25Smrg#endif 226f29dbc25Smrg 227f29dbc25Smrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = { 228f29dbc25Smrg#if DBUF 229f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 230f29dbc25Smrg#endif 231f29dbc25Smrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 232f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_FILTER"}, 233f29dbc25Smrg {XvSettable | XvGettable, 0, 1, "XV_COLORKEYMODE"} 234f29dbc25Smrg}; 235f29dbc25Smrg 236f29dbc25Smrg#define NUM_IMAGES 8 237f29dbc25Smrg 238f29dbc25Smrgstatic XF86ImageRec Images[NUM_IMAGES] = { 239f29dbc25Smrg XVIMAGE_UYVY, 240f29dbc25Smrg XVIMAGE_YUY2, 241f29dbc25Smrg XVIMAGE_Y2YU, 242f29dbc25Smrg XVIMAGE_YVYU, 243f29dbc25Smrg XVIMAGE_Y800, 244f29dbc25Smrg XVIMAGE_I420, 245f29dbc25Smrg XVIMAGE_YV12, 246f29dbc25Smrg XVIMAGE_RGB565 247f29dbc25Smrg}; 248f29dbc25Smrg 249f29dbc25Smrgtypedef struct 250f29dbc25Smrg{ 251f29dbc25Smrg void *area; 252f29dbc25Smrg int offset; 253f29dbc25Smrg RegionRec clip; 254f29dbc25Smrg CARD32 filter; 255f29dbc25Smrg CARD32 colorKey; 256f29dbc25Smrg CARD32 colorKeyMode; 257f29dbc25Smrg CARD32 videoStatus; 258f29dbc25Smrg Time offTime; 259f29dbc25Smrg Time freeTime; 260f29dbc25Smrg#if DBUF 261f29dbc25Smrg Bool doubleBuffer; 262f29dbc25Smrg int currentBuffer; 263f29dbc25Smrg#endif 264f29dbc25Smrg} GeodePortPrivRec, *GeodePortPrivPtr; 265f29dbc25Smrg 266f29dbc25Smrg#define GET_PORT_PRIVATE(pScrni) \ 267f29dbc25Smrg (GeodePortPrivRec *)((GEODEPTR(pScrni))->adaptor->pPortPrivates[0].ptr) 268f29dbc25Smrg 269f29dbc25Smrg/*---------------------------------------------------------------------------- 270f29dbc25Smrg * GXSetColorKey 271f29dbc25Smrg * 272f29dbc25Smrg * Description :This function reads the color key for the pallete and 273f29dbc25Smrg * sets the video color key register. 274f29dbc25Smrg * 275f29dbc25Smrg * Parameters. 276f29dbc25Smrg * ScreenInfoPtr 277f29dbc25Smrg * pScrni :Screen pointer having screen information. 278f29dbc25Smrg * pPriv :Video port private data 279f29dbc25Smrg * 280f29dbc25Smrg * Returns :none 281f29dbc25Smrg * 282f29dbc25Smrg * Comments :none 283f29dbc25Smrg * 284f29dbc25Smrg *---------------------------------------------------------------------------- 285f29dbc25Smrg */ 286f29dbc25Smrgstatic INT32 287f29dbc25SmrgGXSetColorkey(ScrnInfoPtr pScrni, GeodePortPrivRec * pPriv) 288f29dbc25Smrg{ 289f29dbc25Smrg int red, green, blue; 290f29dbc25Smrg unsigned long key; 291f29dbc25Smrg 292f29dbc25Smrg switch (pScrni->depth) { 293f29dbc25Smrg case 8: 294f29dbc25Smrg GFX(get_display_palette_entry(pPriv->colorKey & 0xFF, &key)); 295f29dbc25Smrg red = ((key >> 16) & 0xFF); 296f29dbc25Smrg green = ((key >> 8) & 0xFF); 297f29dbc25Smrg blue = (key & 0xFF); 298f29dbc25Smrg break; 299f29dbc25Smrg case 16: 300f29dbc25Smrg red = (pPriv->colorKey & pScrni->mask.red) >> 301f29dbc25Smrg pScrni->offset.red << (8 - pScrni->weight.red); 302f29dbc25Smrg green = (pPriv->colorKey & pScrni->mask.green) >> 303f29dbc25Smrg pScrni->offset.green << (8 - pScrni->weight.green); 304f29dbc25Smrg blue = (pPriv->colorKey & pScrni->mask.blue) >> 305f29dbc25Smrg pScrni->offset.blue << (8 - pScrni->weight.blue); 306f29dbc25Smrg break; 307f29dbc25Smrg default: 308f29dbc25Smrg /* for > 16 bpp we send in the mask in xf86SetWeight. This 309f29dbc25Smrg * function is providing the offset by 1 more. So we take 310f29dbc25Smrg * this as a special case and subtract 1 for > 16 311f29dbc25Smrg */ 312f29dbc25Smrg red = (pPriv->colorKey & pScrni->mask.red) >> 313f29dbc25Smrg (pScrni->offset.red - 1) << (8 - pScrni->weight.red); 314f29dbc25Smrg green = (pPriv->colorKey & pScrni->mask.green) >> 315f29dbc25Smrg (pScrni->offset.green - 1) << (8 - pScrni->weight.green); 316f29dbc25Smrg blue = (pPriv->colorKey & pScrni->mask.blue) >> 317f29dbc25Smrg (pScrni->offset.blue - 1) << (8 - pScrni->weight.blue); 318f29dbc25Smrg break; 319f29dbc25Smrg } 320f29dbc25Smrg 321f29dbc25Smrg GFX(set_video_color_key((blue | (green << 8) | (red << 16)), 0xFFFFFF, 322f29dbc25Smrg (pPriv->colorKeyMode == 0))); 323f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &pPriv->clip); 324f29dbc25Smrg return 0; 325f29dbc25Smrg} 326f29dbc25Smrg 327f29dbc25Smrg/*---------------------------------------------------------------------------- 328f29dbc25Smrg * GXResetVideo 329f29dbc25Smrg * 330f29dbc25Smrg * Description : This function resets the video 331f29dbc25Smrg * 332f29dbc25Smrg * Parameters. 333f29dbc25Smrg * pScrni :Screen pointer having screen information. 334f29dbc25Smrg * 335f29dbc25Smrg * Returns :None 336f29dbc25Smrg * 337f29dbc25Smrg * Comments :none 338f29dbc25Smrg * 339f29dbc25Smrg *---------------------------------------------------------------------------- 340f29dbc25Smrg */ 341f29dbc25Smrgvoid 342f29dbc25SmrgGXResetVideo(ScrnInfoPtr pScrni) 343f29dbc25Smrg{ 344f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 345f29dbc25Smrg 346f29dbc25Smrg if (!pGeode->NoAccel) { 347f29dbc25Smrg GeodePortPrivRec *pPriv = pGeode->adaptor->pPortPrivates[0].ptr; 348f29dbc25Smrg 349f29dbc25Smrg GXAccelSync(pScrni); 350f29dbc25Smrg GXSetColorkey(pScrni, pPriv); 351f29dbc25Smrg GFX(set_video_filter(pPriv->filter, pPriv->filter)); 352f29dbc25Smrg } 353f29dbc25Smrg} 354f29dbc25Smrg 355f29dbc25Smrg/*---------------------------------------------------------------------------- 356f29dbc25Smrg * GXSetupImageVideo 357f29dbc25Smrg * 358f29dbc25Smrg * Description : This function allocates space for a Videoadaptor and 359f29dbc25Smrg * initializes the XF86VideoAdaptorPtr record. 360f29dbc25Smrg * 361f29dbc25Smrg * Parameters. 362f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 363f29dbc25Smrg * 364f29dbc25Smrg * Returns :pointer to the initialized video adaptor record. 365f29dbc25Smrg * 366f29dbc25Smrg * Comments :none 367f29dbc25Smrg *---------------------------------------------------------------------------- 368f29dbc25Smrg */ 369f29dbc25Smrgstatic XF86VideoAdaptorPtr 370f29dbc25SmrgGXSetupImageVideo(ScreenPtr pScrn) 371f29dbc25Smrg{ 372f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[pScrn->myNum]; 373f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 374f29dbc25Smrg XF86VideoAdaptorPtr adapt; 375f29dbc25Smrg GeodePortPrivRec *pPriv; 376f29dbc25Smrg 377f29dbc25Smrg if (!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 378f29dbc25Smrg sizeof(GeodePortPrivRec) + sizeof(DevUnion)))) 379f29dbc25Smrg return NULL; 380f29dbc25Smrg 381f29dbc25Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 382f29dbc25Smrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 383f29dbc25Smrg adapt->name = "Advanced Micro Devices"; 384f29dbc25Smrg adapt->nEncodings = 1; 385f29dbc25Smrg adapt->pEncodings = DummyEncoding; 386f29dbc25Smrg adapt->nFormats = NUM_FORMATS; 387f29dbc25Smrg adapt->pFormats = Formats; 388f29dbc25Smrg adapt->nPorts = 1; 389f29dbc25Smrg adapt->pPortPrivates = (DevUnion *) (&adapt[1]); 390f29dbc25Smrg pPriv = (GeodePortPrivRec *) (&adapt->pPortPrivates[1]); 391f29dbc25Smrg adapt->pPortPrivates[0].ptr = (pointer) (pPriv); 392f29dbc25Smrg adapt->pAttributes = Attributes; 393f29dbc25Smrg adapt->nImages = NUM_IMAGES; 394f29dbc25Smrg adapt->nAttributes = NUM_ATTRIBUTES; 395f29dbc25Smrg adapt->pImages = Images; 396f29dbc25Smrg adapt->PutVideo = NULL; 397f29dbc25Smrg adapt->PutStill = NULL; 398f29dbc25Smrg adapt->GetVideo = NULL; 399f29dbc25Smrg adapt->GetStill = NULL; 400f29dbc25Smrg adapt->StopVideo = GXStopVideo; 401f29dbc25Smrg adapt->SetPortAttribute = GXSetPortAttribute; 402f29dbc25Smrg adapt->GetPortAttribute = GXGetPortAttribute; 403f29dbc25Smrg adapt->QueryBestSize = GXQueryBestSize; 404f29dbc25Smrg adapt->PutImage = GXPutImage; 405f29dbc25Smrg adapt->QueryImageAttributes = GeodeQueryImageAttributes; 406f29dbc25Smrg 407f29dbc25Smrg pPriv->filter = 0; 408f29dbc25Smrg pPriv->colorKey = 0; 409f29dbc25Smrg pPriv->colorKeyMode = 0; 410f29dbc25Smrg pPriv->videoStatus = 0; 411f29dbc25Smrg#if DBUF 412f29dbc25Smrg pPriv->doubleBuffer = TRUE; 413f29dbc25Smrg pPriv->currentBuffer = 0; /* init to first buffer */ 414f29dbc25Smrg#endif 415f29dbc25Smrg 416f29dbc25Smrg /* gotta uninit this someplace */ 417f29dbc25Smrg#if defined(REGION_NULL) 418f29dbc25Smrg REGION_NULL(pScrn, &pPriv->clip); 419f29dbc25Smrg#else 420f29dbc25Smrg REGION_INIT(pScrn, &pPriv->clip, NullBox, 0); 421f29dbc25Smrg#endif 422f29dbc25Smrg 423f29dbc25Smrg pGeode->adaptor = adapt; 424f29dbc25Smrg 425f29dbc25Smrg pGeode->BlockHandler = pScrn->BlockHandler; 426f29dbc25Smrg pScrn->BlockHandler = GXBlockHandler; 427f29dbc25Smrg 428f29dbc25Smrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 429f29dbc25Smrg xvColorKeyMode = MAKE_ATOM("XV_COLORKEYMODE"); 430f29dbc25Smrg xvFilter = MAKE_ATOM("XV_FILTER"); 431f29dbc25Smrg#if DBUF 432f29dbc25Smrg xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 433f29dbc25Smrg#endif 434f29dbc25Smrg 435f29dbc25Smrg GXResetVideo(pScrni); 436f29dbc25Smrg 437f29dbc25Smrg return adapt; 438f29dbc25Smrg} 439f29dbc25Smrg 440f29dbc25Smrg/*---------------------------------------------------------------------------- 441f29dbc25Smrg * GXStopVideo 442f29dbc25Smrg * 443f29dbc25Smrg * Description :This function is used to stop input and output video 444f29dbc25Smrg * 445f29dbc25Smrg * Parameters. 446f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 447f29dbc25Smrg * data :Pointer to the video port's private data 448f29dbc25Smrg * exit :Flag indicating whether the offscreen areas used for 449f29dbc25Smrg * video to be deallocated or not. 450f29dbc25Smrg * 451f29dbc25Smrg * Returns :none 452f29dbc25Smrg * 453f29dbc25Smrg * Comments :none 454f29dbc25Smrg *---------------------------------------------------------------------------- 455f29dbc25Smrg */ 456f29dbc25Smrgstatic void 457f29dbc25SmrgGXStopVideo(ScrnInfoPtr pScrni, pointer data, Bool exit) 458f29dbc25Smrg{ 459f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 460f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 461f29dbc25Smrg 462f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &pPriv->clip); 463f29dbc25Smrg 464f29dbc25Smrg GXAccelSync(pScrni); 465f29dbc25Smrg if (exit) { 466f29dbc25Smrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 467f29dbc25Smrg GFX(set_video_enable(0)); 468f29dbc25Smrg 469f29dbc25Smrg /* If we have saved graphics LUT data - restore it */ 470f29dbc25Smrg /* Otherwise, turn bypass on */ 471f29dbc25Smrg 472f29dbc25Smrg if (lutflag) 473f29dbc25Smrg GFX(set_graphics_palette(graphics_lut)); 474f29dbc25Smrg else 475f29dbc25Smrg GFX(set_video_palette_bypass(1)); 476f29dbc25Smrg 477f29dbc25Smrg lutflag = 0; 478f29dbc25Smrg } 479f29dbc25Smrg 480f29dbc25Smrg if (pPriv->area) { 481f29dbc25Smrg#ifdef XF86EXA 482f29dbc25Smrg if (pGeode->useEXA) 483f29dbc25Smrg exaOffscreenFree(pScrni->pScreen, pPriv->area); 484f29dbc25Smrg#endif 485f29dbc25Smrg 486f29dbc25Smrg if (!pGeode->useEXA) 487f29dbc25Smrg xf86FreeOffscreenArea(pPriv->area); 488f29dbc25Smrg 489f29dbc25Smrg pPriv->area = NULL; 490f29dbc25Smrg } 491f29dbc25Smrg 492f29dbc25Smrg pPriv->videoStatus = 0; 493f29dbc25Smrg pGeode->OverlayON = FALSE; 494f29dbc25Smrg } else { 495f29dbc25Smrg if (pPriv->videoStatus & CLIENT_VIDEO_ON) { 496f29dbc25Smrg pPriv->videoStatus |= OFF_TIMER; 497f29dbc25Smrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 498f29dbc25Smrg } 499f29dbc25Smrg } 500f29dbc25Smrg} 501f29dbc25Smrg 502f29dbc25Smrg/*---------------------------------------------------------------------------- 503f29dbc25Smrg * GXSetPortAttribute 504f29dbc25Smrg * 505f29dbc25Smrg * Description :This function is used to set the attributes of a port 506f29dbc25Smrg * like colorkeymode, double buffer support and filter. 507f29dbc25Smrg * 508f29dbc25Smrg * Parameters. 509f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 510f29dbc25Smrg * data :Pointer to the video port's private data 511f29dbc25Smrg * attribute :The port attribute to be set 512f29dbc25Smrg * value :Value of the attribute to be set. 513f29dbc25Smrg * 514f29dbc25Smrg * Returns :Sucess if the attribute is supported, else BadMatch 515f29dbc25Smrg * 516f29dbc25Smrg * Comments :none 517f29dbc25Smrg *---------------------------------------------------------------------------- 518f29dbc25Smrg */ 519f29dbc25Smrgstatic int 520f29dbc25SmrgGXSetPortAttribute(ScrnInfoPtr pScrni, 521f29dbc25Smrg Atom attribute, INT32 value, pointer data) 522f29dbc25Smrg{ 523f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 524f29dbc25Smrg 525f29dbc25Smrg GXAccelSync(pScrni); 526f29dbc25Smrg if (attribute == xvColorKey) { 527f29dbc25Smrg pPriv->colorKey = value; 528f29dbc25Smrg GXSetColorkey(pScrni, pPriv); 529f29dbc25Smrg } 530f29dbc25Smrg#if DBUF 531f29dbc25Smrg else if (attribute == xvDoubleBuffer) { 532f29dbc25Smrg if ((value < 0) || (value > 1)) 533f29dbc25Smrg return BadValue; 534f29dbc25Smrg pPriv->doubleBuffer = value; 535f29dbc25Smrg } 536f29dbc25Smrg#endif 537f29dbc25Smrg else if (attribute == xvColorKeyMode) { 538f29dbc25Smrg pPriv->colorKeyMode = value; 539f29dbc25Smrg GXSetColorkey(pScrni, pPriv); 540f29dbc25Smrg } else if (attribute == xvFilter) { 541f29dbc25Smrg if ((value < 0) || (value > 1)) 542f29dbc25Smrg return BadValue; 543f29dbc25Smrg pPriv->filter = value; 544f29dbc25Smrg } else 545f29dbc25Smrg return BadMatch; 546f29dbc25Smrg 547f29dbc25Smrg return Success; 548f29dbc25Smrg} 549f29dbc25Smrg 550f29dbc25Smrg/*---------------------------------------------------------------------------- 551f29dbc25Smrg * GXGetPortAttribute 552f29dbc25Smrg * 553f29dbc25Smrg * Description :This function is used to get the attributes of a port 554f29dbc25Smrg * like hue, saturation,brightness or contrast. 555f29dbc25Smrg * 556f29dbc25Smrg * Parameters. 557f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 558f29dbc25Smrg * data :Pointer to the video port's private data 559f29dbc25Smrg * attribute :The port attribute to be read 560f29dbc25Smrg * value :Pointer to the value of the attribute to be read. 561f29dbc25Smrg * 562f29dbc25Smrg * Returns :Sucess if the attribute is supported, else BadMatch 563f29dbc25Smrg * 564f29dbc25Smrg * Comments :none 565f29dbc25Smrg *---------------------------------------------------------------------------- 566f29dbc25Smrg */ 567f29dbc25Smrgstatic int 568f29dbc25SmrgGXGetPortAttribute(ScrnInfoPtr pScrni, 569f29dbc25Smrg Atom attribute, INT32 * value, pointer data) 570f29dbc25Smrg{ 571f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 572f29dbc25Smrg 573f29dbc25Smrg if (attribute == xvColorKey) { 574f29dbc25Smrg *value = pPriv->colorKey; 575f29dbc25Smrg } 576f29dbc25Smrg#if DBUF 577f29dbc25Smrg else if (attribute == xvDoubleBuffer) { 578f29dbc25Smrg *value = (pPriv->doubleBuffer) ? 1 : 0; 579f29dbc25Smrg } 580f29dbc25Smrg#endif 581f29dbc25Smrg else if (attribute == xvColorKeyMode) { 582f29dbc25Smrg *value = pPriv->colorKeyMode; 583f29dbc25Smrg } else if (attribute == xvFilter) { 584f29dbc25Smrg *value = pPriv->filter; 585f29dbc25Smrg } else 586f29dbc25Smrg return BadMatch; 587f29dbc25Smrg 588f29dbc25Smrg return Success; 589f29dbc25Smrg} 590f29dbc25Smrg 591f29dbc25Smrg/*---------------------------------------------------------------------------- 592f29dbc25Smrg * GXQueryBestSize 593f29dbc25Smrg * 594f29dbc25Smrg * Description :This function provides a way to query what the 595f29dbc25Smrg * destination dimensions would end up being if they were to 596f29dbc25Smrg * request that an area vid_w by vid_h from the video stream 597f29dbc25Smrg * be scaled to rectangle of drw_w by drw_h on the screen. 598f29dbc25Smrg * 599f29dbc25Smrg * Parameters. 600f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 601f29dbc25Smrg * data :Pointer to the video port's private data 602f29dbc25Smrg * vid_w,vid_h :Width and height of the video data. 603f29dbc25Smrg * drw_w,drw_h :Width and height of the scaled rectangle. 604f29dbc25Smrg * p_w,p_h :Width and height of the destination rectangle. 605f29dbc25Smrg * 606f29dbc25Smrg * Returns :None 607f29dbc25Smrg * 608f29dbc25Smrg * Comments :None 609f29dbc25Smrg *---------------------------------------------------------------------------- 610f29dbc25Smrg */ 611f29dbc25Smrgstatic void 612f29dbc25SmrgGXQueryBestSize(ScrnInfoPtr pScrni, 613f29dbc25Smrg Bool motion, 614f29dbc25Smrg short vid_w, short vid_h, 615f29dbc25Smrg short drw_w, short drw_h, 616f29dbc25Smrg unsigned int *p_w, unsigned int *p_h, pointer data) 617f29dbc25Smrg{ 618f29dbc25Smrg *p_w = drw_w; 619f29dbc25Smrg *p_h = drw_h; 620f29dbc25Smrg 621f29dbc25Smrg if (*p_w > 16384) 622f29dbc25Smrg *p_w = 16384; 623f29dbc25Smrg} 624f29dbc25Smrg 625f29dbc25Smrg/*---------------------------------------------------------------------------- 626f29dbc25Smrg * GXCopyData420 627f29dbc25Smrg * 628f29dbc25Smrg * Description : Copies data from src to destination 629f29dbc25Smrg * 630f29dbc25Smrg * Parameters. 631f29dbc25Smrg * src : pointer to the source data 632f29dbc25Smrg * dst : pointer to destination data 633f29dbc25Smrg * srcPitch : pitch of the srcdata 634f29dbc25Smrg * dstPitch : pitch of the destination data 635f29dbc25Smrg * h & w : height and width of source data 636f29dbc25Smrg * 637f29dbc25Smrg * Returns :None 638f29dbc25Smrg * 639f29dbc25Smrg * Comments :None 640f29dbc25Smrg *---------------------------------------------------------------------------- 641f29dbc25Smrg */ 642f29dbc25Smrgstatic void 643f29dbc25SmrgGXCopyData420(unsigned char *src, unsigned char *dst, 644f29dbc25Smrg int srcPitch, int dstPitch, int h, int w) 645f29dbc25Smrg{ 646f29dbc25Smrg while (h--) { 647f29dbc25Smrg memcpy(dst, src, w); 648f29dbc25Smrg src += srcPitch; 649f29dbc25Smrg dst += dstPitch; 650f29dbc25Smrg } 651f29dbc25Smrg} 652f29dbc25Smrg 653f29dbc25Smrg/*---------------------------------------------------------------------------- 654f29dbc25Smrg * GXCopyData422 655f29dbc25Smrg * 656f29dbc25Smrg * Description : Copies data from src to destination 657f29dbc25Smrg * 658f29dbc25Smrg * Parameters. 659f29dbc25Smrg * src : pointer to the source data 660f29dbc25Smrg * dst : pointer to destination data 661f29dbc25Smrg * srcPitch : pitch of the srcdata 662f29dbc25Smrg * dstPitch : pitch of the destination data 663f29dbc25Smrg * h & w : height and width of source data 664f29dbc25Smrg * 665f29dbc25Smrg * Returns :None 666f29dbc25Smrg * 667f29dbc25Smrg * Comments :None 668f29dbc25Smrg *---------------------------------------------------------------------------- 669f29dbc25Smrg */ 670f29dbc25Smrgstatic void 671f29dbc25SmrgGXCopyData422(unsigned char *src, unsigned char *dst, 672f29dbc25Smrg int srcPitch, int dstPitch, int h, int w) 673f29dbc25Smrg{ 674f29dbc25Smrg w <<= 1; 675f29dbc25Smrg while (h--) { 676f29dbc25Smrg memcpy(dst, src, w); 677f29dbc25Smrg src += srcPitch; 678f29dbc25Smrg dst += dstPitch; 679f29dbc25Smrg } 680f29dbc25Smrg} 681f29dbc25Smrg 682f29dbc25Smrg#ifdef XF86EXA 683f29dbc25Smrgstatic void 684f29dbc25SmrgGXVideoSave(ScreenPtr pScreen, ExaOffscreenArea * area) 685f29dbc25Smrg{ 686f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[pScreen->myNum]; 687f29dbc25Smrg GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); 688f29dbc25Smrg 689f29dbc25Smrg if (area == pPriv->area) 690f29dbc25Smrg pPriv->area = NULL; 691f29dbc25Smrg} 692f29dbc25Smrg#endif 693f29dbc25Smrg 694f29dbc25Smrgstatic int 695f29dbc25SmrgGXAllocateMemory(ScrnInfoPtr pScrni, void **memp, int numlines) 696f29dbc25Smrg{ 697f29dbc25Smrg ScreenPtr pScrn = screenInfo.screens[pScrni->scrnIndex]; 698f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 699f29dbc25Smrg 700f29dbc25Smrg //long displayWidth = pGeode->Pitch / ((pScrni->bitsPerPixel + 7) / 8); 701f29dbc25Smrg int size = numlines * pGeode->displayWidth; 702f29dbc25Smrg 703f29dbc25Smrg#if XF86EXA 704f29dbc25Smrg if (pGeode->useEXA) { 705f29dbc25Smrg ExaOffscreenArea *area = *memp; 706f29dbc25Smrg 707f29dbc25Smrg if (area != NULL) { 708f29dbc25Smrg if (area->size >= size) 709f29dbc25Smrg return area->offset; 710f29dbc25Smrg 711f29dbc25Smrg exaOffscreenFree(pScrni->pScreen, area); 712f29dbc25Smrg } 713f29dbc25Smrg 714f29dbc25Smrg area = exaOffscreenAlloc(pScrni->pScreen, size, 16, 715f29dbc25Smrg TRUE, GXVideoSave, NULL); 716f29dbc25Smrg *memp = area; 717f29dbc25Smrg 718f29dbc25Smrg return area == NULL ? 0 : area->offset; 719f29dbc25Smrg } 720f29dbc25Smrg#endif 721f29dbc25Smrg 722f29dbc25Smrg if (!pGeode->useEXA) { 723f29dbc25Smrg FBAreaPtr area = *memp; 724f29dbc25Smrg FBAreaPtr new_area; 725f29dbc25Smrg 726f29dbc25Smrg if (area) { 727f29dbc25Smrg if ((area->box.y2 - area->box.y1) >= numlines) 728f29dbc25Smrg return (area->box.y1 * pGeode->Pitch); 729f29dbc25Smrg 730f29dbc25Smrg if (xf86ResizeOffscreenArea(area, pGeode->displayWidth, numlines)) 731f29dbc25Smrg return (area->box.y1 * pGeode->Pitch); 732f29dbc25Smrg 733f29dbc25Smrg xf86FreeOffscreenArea(area); 734f29dbc25Smrg } 735f29dbc25Smrg 736f29dbc25Smrg new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, 737f29dbc25Smrg numlines, 0, NULL, NULL, NULL); 738f29dbc25Smrg 739f29dbc25Smrg if (!new_area) { 740f29dbc25Smrg int max_w, max_h; 741f29dbc25Smrg 742f29dbc25Smrg xf86QueryLargestOffscreenArea(pScrn, &max_w, &max_h, 0, 743f29dbc25Smrg FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); 744f29dbc25Smrg 745f29dbc25Smrg if ((max_w < pGeode->displayWidth) || (max_h < numlines)) { 746f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 747f29dbc25Smrg "No room - how sad %x, %x, %x, %x\n", max_w, 748f29dbc25Smrg pGeode->displayWidth, max_h, numlines); 749f29dbc25Smrg return 0; 750f29dbc25Smrg } 751f29dbc25Smrg 752f29dbc25Smrg xf86PurgeUnlockedOffscreenAreas(pScrn); 753f29dbc25Smrg new_area = xf86AllocateOffscreenArea(pScrn, pGeode->displayWidth, 754f29dbc25Smrg numlines, 0, NULL, NULL, NULL); 755f29dbc25Smrg } 756f29dbc25Smrg 757f29dbc25Smrg return (new_area->box.y1 * pGeode->Pitch); 758f29dbc25Smrg } 759f29dbc25Smrg 760f29dbc25Smrg return 0; 761f29dbc25Smrg} 762f29dbc25Smrg 763f29dbc25Smrgstatic BoxRec dstBox; 764f29dbc25Smrgstatic int srcPitch = 0, srcPitch2 = 0, dstPitch = 0, dstPitch2 = 0; 765f29dbc25Smrgstatic INT32 Bx1, Bx2, By1, By2; 766f29dbc25Smrgstatic int top, left, npixels, nlines; 767f29dbc25Smrgstatic int offset, s1offset = 0, s2offset = 0, s3offset = 0; 768f29dbc25Smrgstatic unsigned char *dst_start; 769f29dbc25Smrgstatic int d2offset = 0, d3offset = 0; 770f29dbc25Smrg 771f29dbc25Smrg#if 0 772f29dbc25Smrgstatic Bool 773f29dbc25SmrgRegionsIntersect(BoxPtr pRcl1, BoxPtr pRcl2, BoxPtr pRclResult) 774f29dbc25Smrg{ 775f29dbc25Smrg pRclResult->x1 = max(pRcl1->x1, pRcl2->x1); 776f29dbc25Smrg pRclResult->x2 = min(pRcl1->x2, pRcl2->x2); 777f29dbc25Smrg 778f29dbc25Smrg if (pRclResult->x1 <= pRclResult->x2) { 779f29dbc25Smrg pRclResult->y1 = max(pRcl1->y1, pRcl2->y1); 780f29dbc25Smrg pRclResult->y2 = min(pRcl1->y2, pRcl2->y2); 781f29dbc25Smrg 782f29dbc25Smrg if (pRclResult->y1 <= pRclResult->y2) { 783f29dbc25Smrg return (TRUE); 784f29dbc25Smrg } 785f29dbc25Smrg } 786f29dbc25Smrg 787f29dbc25Smrg return (FALSE); 788f29dbc25Smrg} 789f29dbc25Smrg#endif 790f29dbc25Smrg 791f29dbc25Smrgvoid 792f29dbc25SmrgGXSetVideoPosition(int x, int y, int width, int height, 793f29dbc25Smrg short src_w, short src_h, short drw_w, short drw_h, 794f29dbc25Smrg int id, int offset, ScrnInfoPtr pScrni) 795f29dbc25Smrg{ 796f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 797f29dbc25Smrg long ystart, xend, yend; 798f29dbc25Smrg unsigned long lines = 0; 799f29dbc25Smrg unsigned long y_extra, uv_extra = 0; 800f29dbc25Smrg unsigned long startAddress; 801f29dbc25Smrg 802f29dbc25Smrg#if 0 803f29dbc25Smrg BoxRec ovly, display, result; 804f29dbc25Smrg#endif 805f29dbc25Smrg 806f29dbc25Smrg xend = x + drw_w; 807f29dbc25Smrg yend = y + drw_h; 808f29dbc25Smrg 809f29dbc25Smrg /* Take care of panning when panel is present */ 810f29dbc25Smrg 811f29dbc25Smrg startAddress = gfx_get_display_offset(); 812f29dbc25Smrg DeltaY = startAddress / pGeode->Pitch; 813f29dbc25Smrg DeltaX = startAddress & (pGeode->Pitch - 1); 814f29dbc25Smrg DeltaX /= (pScrni->bitsPerPixel >> 3); 815f29dbc25Smrg 816f29dbc25Smrg#if 0 817f29dbc25Smrg /* Thhis code is pretty dang broken - comment it out for now */ 818f29dbc25Smrg 819f29dbc25Smrg if (pGeode->Panel) { 820f29dbc25Smrg ovly.x1 = x; 821f29dbc25Smrg ovly.x2 = x + pGeode->video_dstw; 822f29dbc25Smrg ovly.y1 = y; 823f29dbc25Smrg ovly.y2 = y + pGeode->video_dsth; 824f29dbc25Smrg 825f29dbc25Smrg display.x1 = DeltaX; 826f29dbc25Smrg display.x2 = DeltaX + pGeode->FPBX; 827f29dbc25Smrg display.y1 = DeltaY; 828f29dbc25Smrg display.y2 = DeltaY + pGeode->FPBY; 829f29dbc25Smrg x = xend = 0; 830f29dbc25Smrg if (RegionsIntersect(&display, &ovly, &result)) { 831f29dbc25Smrg x = ovly.x1 - DeltaX; 832f29dbc25Smrg xend = ovly.x2 - DeltaX; 833f29dbc25Smrg y = ovly.y1 - DeltaY; 834f29dbc25Smrg yend = ovly.y2 - DeltaY; 835f29dbc25Smrg } 836f29dbc25Smrg } 837f29dbc25Smrg#endif 838f29dbc25Smrg 839f29dbc25Smrg /* TOP CLIPPING */ 840f29dbc25Smrg 841f29dbc25Smrg if (y < 0) { 842f29dbc25Smrg if (src_h < drw_h) 843f29dbc25Smrg lines = (-y) * src_h / drw_h; 844f29dbc25Smrg else 845f29dbc25Smrg lines = (-y); 846f29dbc25Smrg ystart = 0; 847f29dbc25Smrg drw_h += y; 848f29dbc25Smrg y_extra = lines * dstPitch; 849f29dbc25Smrg uv_extra = (lines >> 1) * (dstPitch2); 850f29dbc25Smrg } else { 851f29dbc25Smrg ystart = y; 852f29dbc25Smrg lines = 0; 853f29dbc25Smrg y_extra = 0; 854f29dbc25Smrg } 855f29dbc25Smrg 856f29dbc25Smrg GFX(set_video_window(x, ystart, xend - x, yend - ystart)); 857f29dbc25Smrg 858f29dbc25Smrg if ((id == FOURCC_Y800) || (id == FOURCC_I420) || (id == FOURCC_YV12)) { 859f29dbc25Smrg GFX(set_video_yuv_offsets(offset + y_extra, 860f29dbc25Smrg offset + d3offset + uv_extra, offset + d2offset + uv_extra)); 861f29dbc25Smrg } else { 862f29dbc25Smrg GFX(set_video_offset(offset + y_extra)); 863f29dbc25Smrg } 864f29dbc25Smrg} 865f29dbc25Smrg 866f29dbc25Smrg/*---------------------------------------------------------------------------- 867f29dbc25Smrg * GXDisplayVideo 868f29dbc25Smrg * 869f29dbc25Smrg * Description :This function sets up the video registers for playing video 870f29dbc25Smrg * It sets up the video format,width, height & position of the 871f29dbc25Smrg * video window ,video offsets( y,u,v) and video pitches(y,u,v) 872f29dbc25Smrg * 873f29dbc25Smrg * Parameters 874f29dbc25Smrg * 875f29dbc25Smrg * Returns :None 876f29dbc25Smrg * 877f29dbc25Smrg * Comments :None 878f29dbc25Smrg *---------------------------------------------------------------------------- 879f29dbc25Smrg */ 880f29dbc25Smrg 881f29dbc25Smrgstatic void 882f29dbc25SmrgGXDisplayVideo(ScrnInfoPtr pScrni, 883f29dbc25Smrg int id, 884f29dbc25Smrg int offset, 885f29dbc25Smrg short width, short height, 886f29dbc25Smrg int pitch, 887f29dbc25Smrg int x1, int y1, int x2, int y2, 888f29dbc25Smrg BoxPtr dstBox, short src_w, short src_h, short drw_w, short drw_h) 889f29dbc25Smrg{ 890f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 891f29dbc25Smrg unsigned long dcfg, misc; 892f29dbc25Smrg 893f29dbc25Smrg GXAccelSync(pScrni); 894f29dbc25Smrg 895f29dbc25Smrg /* If the gamma LUT is already loaded with graphics data, then save it 896f29dbc25Smrg * off 897f29dbc25Smrg */ 898f29dbc25Smrg 899f29dbc25Smrg if (id != FOURCC_RGB565) { 900f29dbc25Smrg dcfg = gfx_read_vid32(DISPLAY_CONFIG); 901f29dbc25Smrg misc = gfx_read_vid32(MISC); 902f29dbc25Smrg 903f29dbc25Smrg lutflag = (!(misc & 1) && (dcfg & (1 << 21))); 904f29dbc25Smrg 905f29dbc25Smrg if (lutflag) 906f29dbc25Smrg get_gamma_ram(graphics_lut); 907f29dbc25Smrg 908f29dbc25Smrg /* Set the video gamma ram */ 909f29dbc25Smrg GFX(set_video_palette(NULL)); 910f29dbc25Smrg } 911f29dbc25Smrg 912f29dbc25Smrg GFX(set_video_enable(1)); 913f29dbc25Smrg 914f29dbc25Smrg switch (id) { 915f29dbc25Smrg case FOURCC_UYVY: /* UYVY */ 916f29dbc25Smrg GFX(set_video_format(VIDEO_FORMAT_UYVY)); 917f29dbc25Smrg GFX(set_video_size(width, height)); 918f29dbc25Smrg break; 919f29dbc25Smrg case FOURCC_Y800: /* Y800 - greyscale - we munge it! */ 920f29dbc25Smrg case FOURCC_YV12: /* YV12 */ 921f29dbc25Smrg case FOURCC_I420: /* I420 */ 922f29dbc25Smrg GFX(set_video_format(VIDEO_FORMAT_Y0Y1Y2Y3)); 923f29dbc25Smrg GFX(set_video_size(width, height)); 924f29dbc25Smrg GFX(set_video_yuv_pitch(dstPitch, dstPitch2)); 925f29dbc25Smrg break; 926f29dbc25Smrg case FOURCC_YUY2: /* YUY2 */ 927f29dbc25Smrg GFX(set_video_format(VIDEO_FORMAT_YUYV)); 928f29dbc25Smrg GFX(set_video_size(width, height)); 929f29dbc25Smrg break; 930f29dbc25Smrg case FOURCC_Y2YU: /* Y2YU */ 931f29dbc25Smrg GFX(set_video_format(VIDEO_FORMAT_Y2YU)); 932f29dbc25Smrg GFX(set_video_size(width, height)); 933f29dbc25Smrg break; 934f29dbc25Smrg case FOURCC_YVYU: /* YVYU */ 935f29dbc25Smrg GFX(set_video_format(VIDEO_FORMAT_YVYU)); 936f29dbc25Smrg GFX(set_video_size(width, height)); 937f29dbc25Smrg break; 938f29dbc25Smrg case FOURCC_RGB565: 939f29dbc25Smrg GFX(set_video_format(VIDEO_FORMAT_RGB)); 940f29dbc25Smrg GFX(set_video_size(width, height)); 941f29dbc25Smrg break; 942f29dbc25Smrg 943f29dbc25Smrg } 944f29dbc25Smrg 945f29dbc25Smrg if (pGeode->Panel) { 946f29dbc25Smrg pGeode->video_x = dstBox->x1; 947f29dbc25Smrg pGeode->video_y = dstBox->y1; 948f29dbc25Smrg pGeode->video_w = width; 949f29dbc25Smrg pGeode->video_h = height; 950f29dbc25Smrg pGeode->video_srcw = src_w; 951f29dbc25Smrg pGeode->video_srch = src_h; 952f29dbc25Smrg pGeode->video_dstw = drw_w; 953f29dbc25Smrg pGeode->video_dsth = drw_h; 954f29dbc25Smrg pGeode->video_offset = offset; 955f29dbc25Smrg pGeode->video_id = id; 956f29dbc25Smrg pGeode->video_scrnptr = pScrni; 957f29dbc25Smrg } 958f29dbc25Smrg 959f29dbc25Smrg if ((drw_w >= src_w) && (drw_h >= src_h)) 960f29dbc25Smrg GFX(set_video_scale(width, height, drw_w, drw_h)); 961f29dbc25Smrg else if (drw_w < src_w) 962f29dbc25Smrg GFX(set_video_scale(drw_w, height, drw_w, drw_h)); 963f29dbc25Smrg else if (drw_h < src_h) 964f29dbc25Smrg GFX(set_video_scale(width, drw_h, drw_w, drw_h)); 965f29dbc25Smrg 966f29dbc25Smrg GXSetVideoPosition(dstBox->x1, dstBox->y1, width, height, src_w, 967f29dbc25Smrg src_h, drw_w, drw_h, id, offset, pScrni); 968f29dbc25Smrg} 969f29dbc25Smrg 970f29dbc25Smrg/* Used by LX as well */ 971f29dbc25Smrg 972f29dbc25SmrgBool 973f29dbc25SmrgRegionsEqual(RegionPtr A, RegionPtr B) 974f29dbc25Smrg{ 975f29dbc25Smrg int *dataA, *dataB; 976f29dbc25Smrg int num; 977f29dbc25Smrg 978f29dbc25Smrg num = REGION_NUM_RECTS(A); 979f29dbc25Smrg if (num != REGION_NUM_RECTS(B)) { 980f29dbc25Smrg return FALSE; 981f29dbc25Smrg } 982f29dbc25Smrg 983f29dbc25Smrg if ((A->extents.x1 != B->extents.x1) || 984f29dbc25Smrg (A->extents.x2 != B->extents.x2) || 985f29dbc25Smrg (A->extents.y1 != B->extents.y1) || (A->extents.y2 != B->extents.y2)) 986f29dbc25Smrg return FALSE; 987f29dbc25Smrg 988f29dbc25Smrg dataA = (int *)REGION_RECTS(A); 989f29dbc25Smrg dataB = (int *)REGION_RECTS(B); 990f29dbc25Smrg 991f29dbc25Smrg while (num--) { 992f29dbc25Smrg if ((dataA[0] != dataB[0]) || (dataA[1] != dataB[1])) 993f29dbc25Smrg return FALSE; 994f29dbc25Smrg 995f29dbc25Smrg dataA += 2; 996f29dbc25Smrg dataB += 2; 997f29dbc25Smrg } 998f29dbc25Smrg 999f29dbc25Smrg return TRUE; 1000f29dbc25Smrg} 1001f29dbc25Smrg 1002f29dbc25Smrg/*---------------------------------------------------------------------------- 1003f29dbc25Smrg * GXPutImage :This function writes a single frame of video into a 1004f29dbc25Smrg * drawable. The position and size of the source rectangle is 1005f29dbc25Smrg * specified by src_x,src_y, src_w and src_h. This data is 1006f29dbc25Smrg * stored in a system memory buffer at buf. The position and 1007f29dbc25Smrg * size of the destination rectangle is specified by drw_x, 1008f29dbc25Smrg * drw_y,drw_w,drw_h.The data is in the format indicated by the 1009f29dbc25Smrg * image descriptor and represents a source of size width by 1010f29dbc25Smrg * height. If sync is TRUE the driver should not return from 1011f29dbc25Smrg * this function until it is through reading the data from buf. 1012f29dbc25Smrg * Returning when sync is TRUE indicates that it is safe for the 1013f29dbc25Smrg * data at buf to be replaced,freed, or modified. 1014f29dbc25Smrg * 1015f29dbc25Smrg * Parameters. 1016f29dbc25Smrg * 1017f29dbc25Smrg * Returns :None 1018f29dbc25Smrg * 1019f29dbc25Smrg * Comments :None 1020f29dbc25Smrg *---------------------------------------------------------------------------- 1021f29dbc25Smrg */ 1022f29dbc25Smrg 1023f29dbc25Smrgstatic int 1024f29dbc25SmrgGXPutImage(ScrnInfoPtr pScrni, 1025f29dbc25Smrg short src_x, short src_y, 1026f29dbc25Smrg short drw_x, short drw_y, 1027f29dbc25Smrg short src_w, short src_h, 1028f29dbc25Smrg short drw_w, short drw_h, 1029f29dbc25Smrg int id, unsigned char *buf, 1030f29dbc25Smrg short width, short height, Bool sync, RegionPtr clipBoxes, pointer data, 1031f29dbc25Smrg DrawablePtr pDraw) 1032f29dbc25Smrg{ 1033f29dbc25Smrg GeodePortPrivRec *pPriv = (GeodePortPrivRec *) data; 1034f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1035f29dbc25Smrg int new_h; 1036f29dbc25Smrg 1037f29dbc25Smrg#if REINIT 1038f29dbc25Smrg BOOL ReInitVideo = FALSE; 1039f29dbc25Smrg static BOOL DoReinitAgain = 0; 1040f29dbc25Smrg#endif 1041f29dbc25Smrg 1042f29dbc25Smrg#if XV_PROFILE 1043f29dbc25Smrg long oldtime, newtime; 1044f29dbc25Smrg 1045f29dbc25Smrg UpdateCurrentTime(); 1046f29dbc25Smrg oldtime = currentTime.milliseconds; 1047f29dbc25Smrg#endif 1048f29dbc25Smrg 1049f29dbc25Smrg#if REINIT 1050f29dbc25Smrg/* update cliplist */ 1051f29dbc25Smrg if (!RegionsEqual(&pPriv->clip, clipBoxes)) { 1052f29dbc25Smrg ReInitVideo = TRUE; 1053f29dbc25Smrg } 1054f29dbc25Smrg 1055f29dbc25Smrg if (DoReinitAgain) 1056f29dbc25Smrg ReInitVideo = TRUE; 1057f29dbc25Smrg 1058f29dbc25Smrg if (ReInitVideo) { 1059f29dbc25Smrg DEBUGMSG(1, (0, X_NONE, "Regional Not Equal - Init\n")); 1060f29dbc25Smrg#endif 1061f29dbc25Smrg DoReinitAgain = ~DoReinitAgain; 1062f29dbc25Smrg if (drw_w > 16384) 1063f29dbc25Smrg drw_w = 16384; 1064f29dbc25Smrg 1065f29dbc25Smrg /* Clip */ 1066f29dbc25Smrg Bx1 = src_x; 1067f29dbc25Smrg Bx2 = src_x + src_w; 1068f29dbc25Smrg By1 = src_y; 1069f29dbc25Smrg By2 = src_y + src_h; 1070f29dbc25Smrg 1071f29dbc25Smrg if ((Bx1 >= Bx2) || (By1 >= By2)) 1072f29dbc25Smrg return Success; 1073f29dbc25Smrg 1074f29dbc25Smrg dstBox.x1 = drw_x; 1075f29dbc25Smrg dstBox.x2 = drw_x + drw_w; 1076f29dbc25Smrg dstBox.y1 = drw_y; 1077f29dbc25Smrg dstBox.y2 = drw_y + drw_h; 1078f29dbc25Smrg 1079f29dbc25Smrg dstBox.x1 -= pScrni->frameX0; 1080f29dbc25Smrg dstBox.x2 -= pScrni->frameX0; 1081f29dbc25Smrg dstBox.y1 -= pScrni->frameY0; 1082f29dbc25Smrg dstBox.y2 -= pScrni->frameY0; 1083f29dbc25Smrg 1084f29dbc25Smrg switch (id) { 1085f29dbc25Smrg case FOURCC_YV12: 1086f29dbc25Smrg case FOURCC_I420: 1087f29dbc25Smrg srcPitch = (width + 3) & ~3; /* of luma */ 1088f29dbc25Smrg dstPitch = (width + 31) & ~31; 1089f29dbc25Smrg 1090f29dbc25Smrg s2offset = srcPitch * height; 1091f29dbc25Smrg d2offset = dstPitch * height; 1092f29dbc25Smrg 1093f29dbc25Smrg srcPitch2 = ((width >> 1) + 3) & ~3; 1094f29dbc25Smrg dstPitch2 = ((width >> 1) + 15) & ~15; 1095f29dbc25Smrg 1096f29dbc25Smrg s3offset = (srcPitch2 * (height >> 1)) + s2offset; 1097f29dbc25Smrg d3offset = (dstPitch2 * (height >> 1)) + d2offset; 1098f29dbc25Smrg 1099f29dbc25Smrg new_h = dstPitch * height; /* Y */ 1100f29dbc25Smrg new_h += (dstPitch2 * height); /* U+V */ 1101f29dbc25Smrg new_h += pGeode->Pitch - 1; 1102f29dbc25Smrg new_h /= pGeode->Pitch; 1103f29dbc25Smrg break; 1104f29dbc25Smrg case FOURCC_UYVY: 1105f29dbc25Smrg case FOURCC_YUY2: 1106f29dbc25Smrg case FOURCC_Y800: 1107f29dbc25Smrg case FOURCC_RGB565: 1108f29dbc25Smrg default: 1109f29dbc25Smrg dstPitch = ((width << 1) + 3) & ~3; 1110f29dbc25Smrg srcPitch = (width << 1); 1111f29dbc25Smrg new_h = ((dstPitch * height) + pGeode->Pitch - 1) / pGeode->Pitch; 1112f29dbc25Smrg break; 1113f29dbc25Smrg } 1114f29dbc25Smrg#if DBUF 1115f29dbc25Smrg if (pPriv->doubleBuffer) 1116f29dbc25Smrg new_h <<= 1; 1117f29dbc25Smrg#endif 1118f29dbc25Smrg 1119f29dbc25Smrg if (!(pPriv->offset = GXAllocateMemory(pScrni, &pPriv->area, new_h))) { 1120f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 1121f29dbc25Smrg "Could not allocate area of size %d\n", new_h); 1122f29dbc25Smrg return BadAlloc; 1123f29dbc25Smrg } 1124f29dbc25Smrg 1125f29dbc25Smrg /* copy data */ 1126f29dbc25Smrg top = By1; 1127f29dbc25Smrg left = Bx1 & ~1; 1128f29dbc25Smrg npixels = ((Bx2 + 1) & ~1) - left; 1129f29dbc25Smrg 1130f29dbc25Smrg switch (id) { 1131f29dbc25Smrg case FOURCC_YV12: 1132f29dbc25Smrg case FOURCC_I420: 1133f29dbc25Smrg { 1134f29dbc25Smrg int tmp; 1135f29dbc25Smrg 1136f29dbc25Smrg top &= ~1; 1137f29dbc25Smrg 1138f29dbc25Smrg offset = pPriv->offset + (top * dstPitch); 1139f29dbc25Smrg 1140f29dbc25Smrg#if DBUF 1141f29dbc25Smrg if (pPriv->doubleBuffer && pPriv->currentBuffer) 1142f29dbc25Smrg offset += (new_h >> 1) * pGeode->Pitch; 1143f29dbc25Smrg#endif 1144f29dbc25Smrg dst_start = pGeode->FBBase + offset + left; 1145f29dbc25Smrg tmp = ((top >> 1) * srcPitch2) + (left >> 1); 1146f29dbc25Smrg s2offset += tmp; 1147f29dbc25Smrg s3offset += tmp; 1148f29dbc25Smrg if (id == FOURCC_I420) { 1149f29dbc25Smrg tmp = s2offset; 1150f29dbc25Smrg s2offset = s3offset; 1151f29dbc25Smrg s3offset = tmp; 1152f29dbc25Smrg } 1153f29dbc25Smrg nlines = ((By2 + 1) & ~1) - top; 1154f29dbc25Smrg } 1155f29dbc25Smrg break; 1156f29dbc25Smrg case FOURCC_UYVY: 1157f29dbc25Smrg case FOURCC_YUY2: 1158f29dbc25Smrg case FOURCC_Y800: 1159f29dbc25Smrg case FOURCC_RGB565: 1160f29dbc25Smrg default: 1161f29dbc25Smrg left <<= 1; 1162f29dbc25Smrg buf += (top * srcPitch) + left; 1163f29dbc25Smrg nlines = By2 - top; 1164f29dbc25Smrg offset = (pPriv->offset) + (top * dstPitch); 1165f29dbc25Smrg 1166f29dbc25Smrg#if DBUF 1167f29dbc25Smrg if (pPriv->doubleBuffer && pPriv->currentBuffer) 1168f29dbc25Smrg offset += (new_h >> 1) * pGeode->Pitch; 1169f29dbc25Smrg#endif 1170f29dbc25Smrg dst_start = pGeode->FBBase + offset + left; 1171f29dbc25Smrg break; 1172f29dbc25Smrg } 1173f29dbc25Smrg s1offset = (top * srcPitch) + left; 1174f29dbc25Smrg#if REINIT 1175f29dbc25Smrg /* update cliplist */ 1176f29dbc25Smrg REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); 1177f29dbc25Smrg 1178f29dbc25Smrg if (pPriv->colorKeyMode == 0) { 1179f29dbc25Smrg xf86XVFillKeyHelper(pScrni->pScreen, pPriv->colorKey, clipBoxes); 1180f29dbc25Smrg } 1181f29dbc25Smrg 1182f29dbc25Smrg GXDisplayVideo(pScrni, id, offset, width, height, dstPitch, 1183f29dbc25Smrg Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1184f29dbc25Smrg } 1185f29dbc25Smrg#endif 1186f29dbc25Smrg switch (id) { 1187f29dbc25Smrg case FOURCC_Y800: 1188f29dbc25Smrg /* This is shared between LX and GX, so it lives in amd_common.c */ 1189f29dbc25Smrg GeodeCopyGreyscale(buf, dst_start, srcPitch, dstPitch, nlines, 1190f29dbc25Smrg npixels); 1191f29dbc25Smrg break; 1192f29dbc25Smrg case FOURCC_YV12: 1193f29dbc25Smrg case FOURCC_I420: 1194f29dbc25Smrg GXCopyData420(buf + s1offset, dst_start, srcPitch, dstPitch, nlines, 1195f29dbc25Smrg npixels); 1196f29dbc25Smrg GXCopyData420(buf + s2offset, dst_start + d2offset, srcPitch2, 1197f29dbc25Smrg dstPitch2, nlines >> 1, npixels >> 1); 1198f29dbc25Smrg GXCopyData420(buf + s3offset, dst_start + d3offset, srcPitch2, 1199f29dbc25Smrg dstPitch2, nlines >> 1, npixels >> 1); 1200f29dbc25Smrg break; 1201f29dbc25Smrg case FOURCC_UYVY: 1202f29dbc25Smrg case FOURCC_YUY2: 1203f29dbc25Smrg case FOURCC_RGB565: 1204f29dbc25Smrg default: 1205f29dbc25Smrg GXCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1206f29dbc25Smrg break; 1207f29dbc25Smrg } 1208f29dbc25Smrg#if !REINIT 1209f29dbc25Smrg /* update cliplist */ 1210f29dbc25Smrg REGION_COPY(pScrni->pScreen, &pPriv->clip, clipBoxes); 1211f29dbc25Smrg if (pPriv->colorKeyMode == 0) { 1212f29dbc25Smrg /* draw these */ 1213f29dbc25Smrg XAAFillSolidRects(pScrni, pPriv->colorKey, GXcopy, ~0, 1214f29dbc25Smrg REGION_NUM_RECTS(clipBoxes), REGION_RECTS(clipBoxes)); 1215f29dbc25Smrg } 1216f29dbc25Smrg 1217f29dbc25Smrg GXDisplayVideo(pScrni, id, offset, width, height, dstPitch, 1218f29dbc25Smrg Bx1, By1, Bx2, By2, &dstBox, src_w, src_h, drw_w, drw_h); 1219f29dbc25Smrg#endif 1220f29dbc25Smrg 1221f29dbc25Smrg#if XV_PROFILE 1222f29dbc25Smrg UpdateCurrentTime(); 1223f29dbc25Smrg newtime = currentTime.milliseconds; 1224f29dbc25Smrg DEBUGMSG(1, (0, X_NONE, "PI %d\n", newtime - oldtime)); 1225f29dbc25Smrg#endif 1226f29dbc25Smrg 1227f29dbc25Smrg#if DBUF 1228f29dbc25Smrg pPriv->currentBuffer ^= 1; 1229f29dbc25Smrg#endif 1230f29dbc25Smrg 1231f29dbc25Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 1232f29dbc25Smrg pGeode->OverlayON = TRUE; 1233f29dbc25Smrg return Success; 1234f29dbc25Smrg} 1235f29dbc25Smrg 1236f29dbc25Smrg/*---------------------------------------------------------------------------- 1237f29dbc25Smrg * GXQueryImageAttributes 1238f29dbc25Smrg * 1239f29dbc25Smrg * Description :This function is called to let the driver specify how data 1240f29dbc25Smrg * for a particular image of size width by height should be 1241f29dbc25Smrg * stored. 1242f29dbc25Smrg * 1243f29dbc25Smrg * Parameters. 1244f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 1245f29dbc25Smrg * id :Id for the video format 1246f29dbc25Smrg * width :width of the image (can be modified by the driver) 1247f29dbc25Smrg * height :height of the image (can be modified by the driver) 1248f29dbc25Smrg * Returns : Size of the memory required for storing this image 1249f29dbc25Smrg * 1250f29dbc25Smrg * Comments :None 1251f29dbc25Smrg * 1252f29dbc25Smrg *---------------------------------------------------------------------------- 1253f29dbc25Smrg */ 1254f29dbc25Smrg 1255f29dbc25Smrgint 1256f29dbc25SmrgGeodeQueryImageAttributes(ScrnInfoPtr pScrni, 1257f29dbc25Smrg int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets) 1258f29dbc25Smrg{ 1259f29dbc25Smrg int size; 1260f29dbc25Smrg int tmp; 1261f29dbc25Smrg 1262f29dbc25Smrg DEBUGMSG(0, (0, X_NONE, "QueryImageAttributes %X\n", id)); 1263f29dbc25Smrg 1264f29dbc25Smrg if (*w > 1024) 1265f29dbc25Smrg *w = 1024; 1266f29dbc25Smrg if (*h > 1024) 1267f29dbc25Smrg *h = 1024; 1268f29dbc25Smrg 1269f29dbc25Smrg *w = (*w + 1) & ~1; 1270f29dbc25Smrg if (offsets) 1271f29dbc25Smrg offsets[0] = 0; 1272f29dbc25Smrg 1273f29dbc25Smrg switch (id) { 1274f29dbc25Smrg case FOURCC_YV12: 1275f29dbc25Smrg case FOURCC_I420: 1276f29dbc25Smrg *h = (*h + 1) & ~1; 1277f29dbc25Smrg size = (*w + 3) & ~3; 1278f29dbc25Smrg if (pitches) 1279f29dbc25Smrg pitches[0] = size; 1280f29dbc25Smrg 1281f29dbc25Smrg size *= *h; 1282f29dbc25Smrg if (offsets) 1283f29dbc25Smrg offsets[1] = size; 1284f29dbc25Smrg 1285f29dbc25Smrg tmp = ((*w >> 1) + 3) & ~3; 1286f29dbc25Smrg if (pitches) 1287f29dbc25Smrg pitches[1] = pitches[2] = tmp; 1288f29dbc25Smrg 1289f29dbc25Smrg tmp *= (*h >> 1); 1290f29dbc25Smrg size += tmp; 1291f29dbc25Smrg if (offsets) 1292f29dbc25Smrg offsets[2] = size; 1293f29dbc25Smrg 1294f29dbc25Smrg size += tmp; 1295f29dbc25Smrg break; 1296f29dbc25Smrg case FOURCC_UYVY: 1297f29dbc25Smrg case FOURCC_YUY2: 1298f29dbc25Smrg case FOURCC_Y800: 1299f29dbc25Smrg default: 1300f29dbc25Smrg size = *w << 1; 1301f29dbc25Smrg if (pitches) 1302f29dbc25Smrg pitches[0] = size; 1303f29dbc25Smrg 1304f29dbc25Smrg size *= *h; 1305f29dbc25Smrg break; 1306f29dbc25Smrg } 1307f29dbc25Smrg return size; 1308f29dbc25Smrg} 1309f29dbc25Smrg 1310f29dbc25Smrgstatic void 1311f29dbc25SmrgGXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) 1312f29dbc25Smrg{ 1313f29dbc25Smrg ScreenPtr pScrn = screenInfo.screens[i]; 1314f29dbc25Smrg ScrnInfoPtr pScrni = xf86Screens[i]; 1315f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 1316f29dbc25Smrg GeodePortPrivRec *pPriv = GET_PORT_PRIVATE(pScrni); 1317f29dbc25Smrg 1318f29dbc25Smrg pScrn->BlockHandler = pGeode->BlockHandler; 1319f29dbc25Smrg (*pScrn->BlockHandler) (i, blockData, pTimeout, pReadmask); 1320f29dbc25Smrg pScrn->BlockHandler = GXBlockHandler; 1321f29dbc25Smrg 1322f29dbc25Smrg if (pPriv->videoStatus & TIMER_MASK) { 1323f29dbc25Smrg GXAccelSync(pScrni); 1324f29dbc25Smrg UpdateCurrentTime(); 1325f29dbc25Smrg if (pPriv->videoStatus & OFF_TIMER) { 1326f29dbc25Smrg if (pPriv->offTime < currentTime.milliseconds) { 1327f29dbc25Smrg GFX(set_video_enable(0)); 1328f29dbc25Smrg 1329f29dbc25Smrg /* If we have saved graphics LUT data - restore it */ 1330f29dbc25Smrg /* Otherwise, turn bypass on */ 1331f29dbc25Smrg 1332f29dbc25Smrg if (lutflag) 1333f29dbc25Smrg GFX(set_graphics_palette(graphics_lut)); 1334f29dbc25Smrg else 1335f29dbc25Smrg GFX(set_video_palette_bypass(1)); 1336f29dbc25Smrg 1337f29dbc25Smrg lutflag = 0; 1338f29dbc25Smrg 1339f29dbc25Smrg pPriv->videoStatus = FREE_TIMER; 1340f29dbc25Smrg pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1341f29dbc25Smrg } 1342f29dbc25Smrg } else { /* FREE_TIMER */ 1343f29dbc25Smrg if (pPriv->freeTime < currentTime.milliseconds) { 1344f29dbc25Smrg 1345f29dbc25Smrg if (pPriv->area) { 1346f29dbc25Smrg#ifdef XF86EXA 1347f29dbc25Smrg if (pGeode->useEXA) 1348f29dbc25Smrg exaOffscreenFree(pScrn, pPriv->area); 1349f29dbc25Smrg#endif 1350f29dbc25Smrg if (!pGeode->useEXA) 1351f29dbc25Smrg xf86FreeOffscreenArea(pPriv->area); 1352f29dbc25Smrg 1353f29dbc25Smrg pPriv->area = NULL; 1354f29dbc25Smrg } 1355f29dbc25Smrg 1356f29dbc25Smrg pPriv->videoStatus = 0; 1357f29dbc25Smrg } 1358f29dbc25Smrg } 1359f29dbc25Smrg } 1360f29dbc25Smrg} 1361f29dbc25Smrg 1362f29dbc25Smrg/****************** Offscreen stuff ***************/ 1363f29dbc25Smrg 1364f29dbc25Smrgtypedef struct 1365f29dbc25Smrg{ 1366f29dbc25Smrg void *area; 1367f29dbc25Smrg int offset; 1368f29dbc25Smrg Bool isOn; 1369f29dbc25Smrg} OffscreenPrivRec, *OffscreenPrivPtr; 1370f29dbc25Smrg 1371f29dbc25Smrg/*---------------------------------------------------------------------------- 1372f29dbc25Smrg * GXAllocateSurface 1373f29dbc25Smrg * 1374f29dbc25Smrg * Description :This function allocates an area of w by h in the offscreen 1375f29dbc25Smrg * 1376f29dbc25Smrg * Parameters. 1377f29dbc25Smrg * pScrni :Screen handler pointer having screen information. 1378f29dbc25Smrg * 1379f29dbc25Smrg * Returns :None 1380f29dbc25Smrg * 1381f29dbc25Smrg * Comments :None 1382f29dbc25Smrg *---------------------------------------------------------------------------- 1383f29dbc25Smrg */ 1384f29dbc25Smrgstatic int 1385f29dbc25SmrgGXAllocateSurface(ScrnInfoPtr pScrni, 1386f29dbc25Smrg int id, unsigned short w, unsigned short h, XF86SurfacePtr surface) 1387f29dbc25Smrg{ 1388f29dbc25Smrg void *area = NULL; 1389f29dbc25Smrg int pitch, fbpitch, numlines; 1390f29dbc25Smrg OffscreenPrivRec *pPriv; 1391f29dbc25Smrg 1392f29dbc25Smrg if ((w > 1024) || (h > 1024)) 1393f29dbc25Smrg return BadAlloc; 1394f29dbc25Smrg 1395f29dbc25Smrg w = (w + 1) & ~1; 1396f29dbc25Smrg pitch = ((w << 1) + 15) & ~15; 1397f29dbc25Smrg fbpitch = pScrni->bitsPerPixel * pScrni->displayWidth >> 3; 1398f29dbc25Smrg numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 1399f29dbc25Smrg 1400f29dbc25Smrg if (!(offset = GXAllocateMemory(pScrni, &area, numlines))) 1401f29dbc25Smrg return BadAlloc; 1402f29dbc25Smrg 1403f29dbc25Smrg surface->width = w; 1404f29dbc25Smrg surface->height = h; 1405f29dbc25Smrg 1406f29dbc25Smrg if (!(surface->pitches = xalloc(sizeof(int)))) 1407f29dbc25Smrg return BadAlloc; 1408f29dbc25Smrg 1409f29dbc25Smrg if (!(surface->offsets = xalloc(sizeof(int)))) { 1410f29dbc25Smrg xfree(surface->pitches); 1411f29dbc25Smrg return BadAlloc; 1412f29dbc25Smrg } 1413f29dbc25Smrg 1414f29dbc25Smrg if (!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 1415f29dbc25Smrg xfree(surface->pitches); 1416f29dbc25Smrg xfree(surface->offsets); 1417f29dbc25Smrg return BadAlloc; 1418f29dbc25Smrg } 1419f29dbc25Smrg 1420f29dbc25Smrg pPriv->area = area; 1421f29dbc25Smrg pPriv->offset = offset; 1422f29dbc25Smrg 1423f29dbc25Smrg pPriv->isOn = FALSE; 1424f29dbc25Smrg 1425f29dbc25Smrg surface->pScrn = pScrni; 1426f29dbc25Smrg surface->id = id; 1427f29dbc25Smrg surface->pitches[0] = pitch; 1428f29dbc25Smrg surface->offsets[0] = offset; 1429f29dbc25Smrg surface->devPrivate.ptr = (pointer) pPriv; 1430f29dbc25Smrg 1431f29dbc25Smrg return Success; 1432f29dbc25Smrg} 1433f29dbc25Smrg 1434f29dbc25Smrgstatic int 1435f29dbc25SmrgGXStopSurface(XF86SurfacePtr surface) 1436f29dbc25Smrg{ 1437f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1438f29dbc25Smrg 1439f29dbc25Smrg if (pPriv->isOn) { 1440f29dbc25Smrg pPriv->isOn = FALSE; 1441f29dbc25Smrg } 1442f29dbc25Smrg 1443f29dbc25Smrg return Success; 1444f29dbc25Smrg} 1445f29dbc25Smrg 1446f29dbc25Smrgstatic int 1447f29dbc25SmrgGXFreeSurface(XF86SurfacePtr surface) 1448f29dbc25Smrg{ 1449f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1450f29dbc25Smrg 1451f29dbc25Smrg if (pPriv->isOn) 1452f29dbc25Smrg GXStopSurface(surface); 1453f29dbc25Smrg 1454f29dbc25Smrg xf86FreeOffscreenArea(pPriv->area); 1455f29dbc25Smrg xfree(surface->pitches); 1456f29dbc25Smrg xfree(surface->offsets); 1457f29dbc25Smrg xfree(surface->devPrivate.ptr); 1458f29dbc25Smrg 1459f29dbc25Smrg return Success; 1460f29dbc25Smrg} 1461f29dbc25Smrg 1462f29dbc25Smrgstatic int 1463f29dbc25SmrgGXGetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 * value) 1464f29dbc25Smrg{ 1465f29dbc25Smrg return GXGetPortAttribute(pScrni, attribute, value, 1466f29dbc25Smrg (pointer) (GET_PORT_PRIVATE(pScrni))); 1467f29dbc25Smrg} 1468f29dbc25Smrg 1469f29dbc25Smrgstatic int 1470f29dbc25SmrgGXSetSurfaceAttribute(ScrnInfoPtr pScrni, Atom attribute, INT32 value) 1471f29dbc25Smrg{ 1472f29dbc25Smrg return GXSetPortAttribute(pScrni, attribute, value, 1473f29dbc25Smrg (pointer) (GET_PORT_PRIVATE(pScrni))); 1474f29dbc25Smrg} 1475f29dbc25Smrg 1476f29dbc25Smrgstatic int 1477f29dbc25SmrgGXDisplaySurface(XF86SurfacePtr surface, 1478f29dbc25Smrg short src_x, short src_y, 1479f29dbc25Smrg short drw_x, short drw_y, 1480f29dbc25Smrg short src_w, short src_h, short drw_w, short drw_h, RegionPtr clipBoxes) 1481f29dbc25Smrg{ 1482f29dbc25Smrg OffscreenPrivRec *pPriv = (OffscreenPrivRec *) surface->devPrivate.ptr; 1483f29dbc25Smrg ScrnInfoPtr pScrni = surface->pScrn; 1484f29dbc25Smrg GeodePortPrivRec *portPriv = GET_PORT_PRIVATE(pScrni); 1485f29dbc25Smrg INT32 x1, y1, x2, y2; 1486f29dbc25Smrg BoxRec dstBox; 1487f29dbc25Smrg 1488f29dbc25Smrg DEBUGMSG(0, (0, X_NONE, "DisplaySuface\n")); 1489f29dbc25Smrg x1 = src_x; 1490f29dbc25Smrg x2 = src_x + src_w; 1491f29dbc25Smrg y1 = src_y; 1492f29dbc25Smrg y2 = src_y + src_h; 1493f29dbc25Smrg 1494f29dbc25Smrg dstBox.x1 = drw_x; 1495f29dbc25Smrg dstBox.x2 = drw_x + drw_w; 1496f29dbc25Smrg dstBox.y1 = drw_y; 1497f29dbc25Smrg dstBox.y2 = drw_y + drw_h; 1498f29dbc25Smrg 1499f29dbc25Smrg if ((x1 >= x2) || (y1 >= y2)) 1500f29dbc25Smrg return Success; 1501f29dbc25Smrg 1502f29dbc25Smrg dstBox.x1 -= pScrni->frameX0; 1503f29dbc25Smrg dstBox.x2 -= pScrni->frameX0; 1504f29dbc25Smrg dstBox.y1 -= pScrni->frameY0; 1505f29dbc25Smrg dstBox.y2 -= pScrni->frameY0; 1506f29dbc25Smrg 1507f29dbc25Smrg xf86XVFillKeyHelper(pScrni->pScreen, portPriv->colorKey, clipBoxes); 1508f29dbc25Smrg 1509f29dbc25Smrg GXDisplayVideo(pScrni, surface->id, surface->offsets[0], 1510f29dbc25Smrg surface->width, surface->height, surface->pitches[0], 1511f29dbc25Smrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1512f29dbc25Smrg 1513f29dbc25Smrg pPriv->isOn = TRUE; 1514f29dbc25Smrg if (portPriv->videoStatus & CLIENT_VIDEO_ON) { 1515f29dbc25Smrg REGION_EMPTY(pScrni->pScreen, &portPriv->clip); 1516f29dbc25Smrg UpdateCurrentTime(); 1517f29dbc25Smrg portPriv->videoStatus = FREE_TIMER; 1518f29dbc25Smrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1519f29dbc25Smrg } 1520f29dbc25Smrg 1521f29dbc25Smrg return Success; 1522f29dbc25Smrg} 1523f29dbc25Smrg 1524f29dbc25Smrg/*---------------------------------------------------------------------------- 1525f29dbc25Smrg * GXInitOffscreenImages 1526f29dbc25Smrg * 1527f29dbc25Smrg * Description :This function sets up the offscreen memory management. It 1528f29dbc25Smrg * fills in the XF86OffscreenImagePtr structure with functions to 1529f29dbc25Smrg * handle offscreen memory operations. 1530f29dbc25Smrg * 1531f29dbc25Smrg * Parameters. 1532f29dbc25Smrg * pScrn :Screen handler pointer having screen information. 1533f29dbc25Smrg * 1534f29dbc25Smrg * Returns : None 1535f29dbc25Smrg * 1536f29dbc25Smrg * Comments :None 1537f29dbc25Smrg *---------------------------------------------------------------------------- 1538f29dbc25Smrg */ 1539f29dbc25Smrgstatic void 1540f29dbc25SmrgGXInitOffscreenImages(ScreenPtr pScrn) 1541f29dbc25Smrg{ 1542f29dbc25Smrg XF86OffscreenImagePtr offscreenImages; 1543f29dbc25Smrg 1544f29dbc25Smrg /* need to free this someplace */ 1545f29dbc25Smrg if (!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) 1546f29dbc25Smrg return; 1547f29dbc25Smrg 1548f29dbc25Smrg offscreenImages[0].image = &Images[0]; 1549f29dbc25Smrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1550f29dbc25Smrg offscreenImages[0].alloc_surface = GXAllocateSurface; 1551f29dbc25Smrg offscreenImages[0].free_surface = GXFreeSurface; 1552f29dbc25Smrg offscreenImages[0].display = GXDisplaySurface; 1553f29dbc25Smrg offscreenImages[0].stop = GXStopSurface; 1554f29dbc25Smrg offscreenImages[0].setAttribute = GXSetSurfaceAttribute; 1555f29dbc25Smrg offscreenImages[0].getAttribute = GXGetSurfaceAttribute; 1556f29dbc25Smrg offscreenImages[0].max_width = 1024; 1557f29dbc25Smrg offscreenImages[0].max_height = 1024; 1558f29dbc25Smrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1559f29dbc25Smrg offscreenImages[0].attributes = Attributes; 1560f29dbc25Smrg 1561f29dbc25Smrg xf86XVRegisterOffscreenImages(pScrn, offscreenImages, 1); 1562f29dbc25Smrg} 1563f29dbc25Smrg 1564f29dbc25Smrg#endif /* !XvExtension */ 1565