1c06b6b69Smrg 2c06b6b69Smrg#ifdef HAVE_CONFIG_H 3c06b6b69Smrg#include "config.h" 4c06b6b69Smrg#endif 5c06b6b69Smrg 6c06b6b69Smrg#include "xf86.h" 7c06b6b69Smrg#include "xf86_OSproc.h" 8c06b6b69Smrg#include "compiler.h" 9c06b6b69Smrg#include "xf86Pci.h" 10c06b6b69Smrg#include "xf86fbman.h" 11c06b6b69Smrg#include "regionstr.h" 12c06b6b69Smrg 13c06b6b69Smrg#include "ct_driver.h" 14c06b6b69Smrg#include <X11/extensions/Xv.h> 15c06b6b69Smrg#include "dixstruct.h" 16c06b6b69Smrg#include "fourcc.h" 17c06b6b69Smrg 18c06b6b69Smrg#define OFF_DELAY 200 /* milliseconds */ 19c06b6b69Smrg#define FREE_DELAY 60000 20c06b6b69Smrg 21c06b6b69Smrg#define OFF_TIMER 0x01 22c06b6b69Smrg#define FREE_TIMER 0x02 23c06b6b69Smrg#define CLIENT_VIDEO_ON 0x04 24c06b6b69Smrg 25c06b6b69Smrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 26c06b6b69Smrg 27c06b6b69Smrgstatic XF86VideoAdaptorPtr CHIPSSetupImageVideo(ScreenPtr); 28c06b6b69Smrgstatic void CHIPSInitOffscreenImages(ScreenPtr); 29c06b6b69Smrgstatic void CHIPSStopVideo(ScrnInfoPtr, pointer, Bool); 30c06b6b69Smrgstatic int CHIPSSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 31c06b6b69Smrgstatic int CHIPSGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 32c06b6b69Smrgstatic void CHIPSQueryBestSize(ScrnInfoPtr, Bool, 33c06b6b69Smrg short, short, short, short, unsigned int *, unsigned int *, pointer); 34c06b6b69Smrgstatic int CHIPSPutImage( ScrnInfoPtr, 35c06b6b69Smrg short, short, short, short, short, short, short, short, 36c06b6b69Smrg int, unsigned char*, short, short, Bool, RegionPtr, pointer, 37c06b6b69Smrg DrawablePtr); 38c06b6b69Smrgstatic int CHIPSQueryImageAttributes(ScrnInfoPtr, 39c06b6b69Smrg int, unsigned short *, unsigned short *, int *, int *); 40c06b6b69Smrgstatic void CHIPSVideoTimerCallback(ScrnInfoPtr pScrn, Time time); 41c06b6b69Smrg 42c06b6b69Smrg 43c06b6b69Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 44c06b6b69Smrg 45c06b6b69Smrgstatic Atom xvColorKey; 46c06b6b69Smrg 47c06b6b69Smrgvoid 48c06b6b69SmrgCHIPSInitVideo(ScreenPtr pScreen) 49c06b6b69Smrg{ 50a1d73b4bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 51c06b6b69Smrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 52c06b6b69Smrg XF86VideoAdaptorPtr newAdaptor = NULL; 53c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 54c06b6b69Smrg int num_adaptors; 55c06b6b69Smrg 56a1d73b4bSmrg if ((cPtr->Flags & ChipsVideoSupport)) { 57c06b6b69Smrg newAdaptor = CHIPSSetupImageVideo(pScreen); 58c06b6b69Smrg CHIPSInitOffscreenImages(pScreen); 59c06b6b69Smrg } 60c06b6b69Smrg 61c06b6b69Smrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 62c06b6b69Smrg 63c06b6b69Smrg if(newAdaptor) { 64c06b6b69Smrg if(!num_adaptors) { 65c06b6b69Smrg num_adaptors = 1; 66c06b6b69Smrg adaptors = &newAdaptor; 67c06b6b69Smrg } else { 68c06b6b69Smrg newAdaptors = /* need to free this someplace */ 693699b6c4Smrg malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 70c06b6b69Smrg if(newAdaptors) { 71c06b6b69Smrg memcpy(newAdaptors, adaptors, num_adaptors * 72c06b6b69Smrg sizeof(XF86VideoAdaptorPtr)); 73c06b6b69Smrg newAdaptors[num_adaptors] = newAdaptor; 74c06b6b69Smrg adaptors = newAdaptors; 75c06b6b69Smrg num_adaptors++; 76c06b6b69Smrg } 77c06b6b69Smrg } 78c06b6b69Smrg } 79c06b6b69Smrg 80c06b6b69Smrg if(num_adaptors) 81c06b6b69Smrg xf86XVScreenInit(pScreen, adaptors, num_adaptors); 82c06b6b69Smrg 833699b6c4Smrg free(newAdaptors); 84c06b6b69Smrg} 85c06b6b69Smrg 86c06b6b69Smrg/* client libraries expect an encoding */ 87c06b6b69Smrgstatic 88c06b6b69SmrgXF86VideoEncodingRec DummyEncoding[1] = 89c06b6b69Smrg{ 90c06b6b69Smrg { 91c06b6b69Smrg 0, 92c06b6b69Smrg "XV_IMAGE", 93c06b6b69Smrg 1024, 1024, 94c06b6b69Smrg {1, 1} 95c06b6b69Smrg } 96c06b6b69Smrg}; 97c06b6b69Smrg 98c06b6b69Smrg#define NUM_FORMATS 4 99c06b6b69Smrg 100c06b6b69Smrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = 101c06b6b69Smrg{ 102c06b6b69Smrg {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 103c06b6b69Smrg}; 104c06b6b69Smrg 105c06b6b69Smrg#define NUM_ATTRIBUTES 1 106c06b6b69Smrg 107c06b6b69Smrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 108c06b6b69Smrg{ 109c06b6b69Smrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"} 110c06b6b69Smrg}; 111c06b6b69Smrg 112c06b6b69Smrg#define NUM_IMAGES 4 113c06b6b69Smrg 114c06b6b69Smrgstatic XF86ImageRec Images[NUM_IMAGES] = 115c06b6b69Smrg{ 116c06b6b69Smrg { 117c06b6b69Smrg 0x35315652, 118c06b6b69Smrg XvRGB, 119c06b6b69Smrg LSBFirst, 120c06b6b69Smrg {'R','V','1','5', 121c06b6b69Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 122c06b6b69Smrg 16, 123c06b6b69Smrg XvPacked, 124c06b6b69Smrg 1, 125c06b6b69Smrg 15, 0x7C00, 0x03E0, 0x001F, 126c06b6b69Smrg 0, 0, 0, 127c06b6b69Smrg 0, 0, 0, 128c06b6b69Smrg 0, 0, 0, 129c06b6b69Smrg {'R','V','B',0, 130c06b6b69Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 131c06b6b69Smrg XvTopToBottom 132c06b6b69Smrg }, 133c06b6b69Smrg { 134c06b6b69Smrg 0x36315652, 135c06b6b69Smrg XvRGB, 136c06b6b69Smrg LSBFirst, 137c06b6b69Smrg {'R','V','1','6', 138c06b6b69Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 139c06b6b69Smrg 16, 140c06b6b69Smrg XvPacked, 141c06b6b69Smrg 1, 142c06b6b69Smrg 16, 0xF800, 0x07E0, 0x001F, 143c06b6b69Smrg 0, 0, 0, 144c06b6b69Smrg 0, 0, 0, 145c06b6b69Smrg 0, 0, 0, 146c06b6b69Smrg {'R','V','B',0, 147c06b6b69Smrg 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, 148c06b6b69Smrg XvTopToBottom 149c06b6b69Smrg }, 150c06b6b69Smrg XVIMAGE_YV12, 151c06b6b69Smrg XVIMAGE_YUY2 152c06b6b69Smrg}; 153c06b6b69Smrg 154c06b6b69Smrgtypedef struct { 155c06b6b69Smrg FBLinearPtr linear; 156c06b6b69Smrg RegionRec clip; 157c06b6b69Smrg CARD32 colorKey; 158c06b6b69Smrg CARD32 videoStatus; 159c06b6b69Smrg Time offTime; 160c06b6b69Smrg Time freeTime; 161c06b6b69Smrg Bool doubleBuffer; 162c06b6b69Smrg Bool manualDoubleBuffer; 163c06b6b69Smrg int currentBuffer; 164c06b6b69Smrg} CHIPSPortPrivRec, *CHIPSPortPrivPtr; 165c06b6b69Smrg 166c06b6b69Smrg 167c06b6b69Smrg#define GET_PORT_PRIVATE(pScrn) \ 168c06b6b69Smrg (CHIPSPortPrivPtr)((CHIPSPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 169c06b6b69Smrg 170c06b6b69Smrgvoid 171c06b6b69SmrgCHIPSResetVideo(ScrnInfoPtr pScrn) 172c06b6b69Smrg{ 173c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 174c06b6b69Smrg CHIPSPortPrivPtr pPriv = cPtr->adaptor->pPortPrivates[0].ptr; 175c06b6b69Smrg unsigned char mr3c; 176c06b6b69Smrg int red, green, blue; 177c06b6b69Smrg 17804109a1cSmacallan#ifdef HAVE_XAA_H 179c06b6b69Smrg if (cPtr->Flags & ChipsAccelSupport) 180c06b6b69Smrg CHIPSHiQVSync(pScrn); 18104109a1cSmacallan#endif 182c06b6b69Smrg 183c06b6b69Smrg mr3c = cPtr->readMR(cPtr, 0x3C); 184c06b6b69Smrg cPtr->writeMR(cPtr, 0x3C, (mr3c | 0x6)); 185c06b6b69Smrg switch (pScrn->depth) { 186c06b6b69Smrg case 8: 187c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, 0x00); 188c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, 0x00); 189c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, (pPriv->colorKey & 0xFF)); 190c06b6b69Smrg cPtr->writeMR(cPtr, 0x40, 0xFF); 191c06b6b69Smrg cPtr->writeMR(cPtr, 0x41, 0xFF); 192c06b6b69Smrg cPtr->writeMR(cPtr, 0x42, 0x00); 193c06b6b69Smrg break; 194c06b6b69Smrg default: 195c06b6b69Smrg red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 196c06b6b69Smrg green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 197c06b6b69Smrg blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 198c06b6b69Smrg switch (pScrn->depth) { 199c06b6b69Smrg case 15: 200c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, (red << 3)); 201c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, (green << 3)); 202c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, (blue << 3)); 203c06b6b69Smrg cPtr->writeMR(cPtr, 0x40, 0x07); 204c06b6b69Smrg cPtr->writeMR(cPtr, 0x41, 0x07); 205c06b6b69Smrg cPtr->writeMR(cPtr, 0x42, 0x07); 206c06b6b69Smrg break; 207c06b6b69Smrg case 16: 208c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, (red << 3)); 209c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, (green << 2)); 210c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, (blue << 3)); 211c06b6b69Smrg cPtr->writeMR(cPtr, 0x40, 0x07); 212c06b6b69Smrg cPtr->writeMR(cPtr, 0x41, 0x03); 213c06b6b69Smrg cPtr->writeMR(cPtr, 0x42, 0x07); 214c06b6b69Smrg break; 215c06b6b69Smrg case 24: 216c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, red); 217c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, green); 218c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, blue); 219c06b6b69Smrg cPtr->writeMR(cPtr, 0x40, 0x00); 220c06b6b69Smrg cPtr->writeMR(cPtr, 0x41, 0x00); 221c06b6b69Smrg cPtr->writeMR(cPtr, 0x42, 0x00); 222c06b6b69Smrg break; 223c06b6b69Smrg } 224c06b6b69Smrg } 225c06b6b69Smrg} 226c06b6b69Smrg 227c06b6b69Smrg 228c06b6b69Smrgstatic XF86VideoAdaptorPtr 229c06b6b69SmrgCHIPSSetupImageVideo(ScreenPtr pScreen) 230c06b6b69Smrg{ 231a1d73b4bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 232c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 233c06b6b69Smrg XF86VideoAdaptorPtr adapt; 234c06b6b69Smrg CHIPSPortPrivPtr pPriv; 235c06b6b69Smrg 2363699b6c4Smrg if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 2373699b6c4Smrg sizeof(CHIPSPortPrivRec) + 2383699b6c4Smrg sizeof(DevUnion)))) 239c06b6b69Smrg return NULL; 240c06b6b69Smrg 241c06b6b69Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 242c06b6b69Smrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 243c06b6b69Smrg adapt->name = "Chips and Technologies Backend Scaler"; 244c06b6b69Smrg adapt->nEncodings = 1; 245c06b6b69Smrg adapt->pEncodings = DummyEncoding; 246c06b6b69Smrg adapt->nFormats = NUM_FORMATS; 247c06b6b69Smrg adapt->pFormats = Formats; 248c06b6b69Smrg adapt->nPorts = 1; 249c06b6b69Smrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 250c06b6b69Smrg pPriv = (CHIPSPortPrivPtr)(&adapt->pPortPrivates[1]); 251c06b6b69Smrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 252c06b6b69Smrg adapt->pAttributes = Attributes; 253c06b6b69Smrg adapt->nImages = NUM_IMAGES; 254c06b6b69Smrg adapt->nAttributes = NUM_ATTRIBUTES; 255c06b6b69Smrg adapt->pImages = Images; 256c06b6b69Smrg adapt->PutVideo = NULL; 257c06b6b69Smrg adapt->PutStill = NULL; 258c06b6b69Smrg adapt->GetVideo = NULL; 259c06b6b69Smrg adapt->GetStill = NULL; 260c06b6b69Smrg adapt->StopVideo = CHIPSStopVideo; 261c06b6b69Smrg adapt->SetPortAttribute = CHIPSSetPortAttribute; 262c06b6b69Smrg adapt->GetPortAttribute = CHIPSGetPortAttribute; 263c06b6b69Smrg adapt->QueryBestSize = CHIPSQueryBestSize; 264c06b6b69Smrg adapt->PutImage = CHIPSPutImage; 265c06b6b69Smrg adapt->QueryImageAttributes = CHIPSQueryImageAttributes; 266c06b6b69Smrg 267c06b6b69Smrg pPriv->colorKey = cPtr->videoKey; 268c06b6b69Smrg pPriv->videoStatus = 0; 269c06b6b69Smrg pPriv->manualDoubleBuffer = FALSE; 270c06b6b69Smrg pPriv->currentBuffer = 0; 271c06b6b69Smrg 272c06b6b69Smrg /* gotta uninit this someplace */ 273c06b6b69Smrg REGION_NULL(pScreen, &pPriv->clip); 274c06b6b69Smrg 275c06b6b69Smrg cPtr->adaptor = adapt; 276c06b6b69Smrg 277c06b6b69Smrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 278c06b6b69Smrg 279c06b6b69Smrg CHIPSResetVideo(pScrn); 280c06b6b69Smrg 281c06b6b69Smrg return adapt; 282c06b6b69Smrg} 283c06b6b69Smrg 284c06b6b69Smrg 285c06b6b69Smrgstatic void 286c06b6b69SmrgCHIPSStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shadow) 287c06b6b69Smrg{ 288c06b6b69Smrg CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data; 289c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 290c06b6b69Smrg unsigned char mr3c, tmp; 291c06b6b69Smrg 292c06b6b69Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 29304109a1cSmacallan#ifdef HAVE_XAA_H 294c06b6b69Smrg if (cPtr->Flags & ChipsAccelSupport) 295c06b6b69Smrg CHIPSHiQVSync(pScrn); 29604109a1cSmacallan#endif 297c06b6b69Smrg if(shadow) { 298c06b6b69Smrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 299c06b6b69Smrg mr3c = cPtr->readMR(cPtr, 0x3C); 300c06b6b69Smrg cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE)); 301c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xD0); 302c06b6b69Smrg cPtr->writeXR(cPtr, 0xD0, (tmp & 0xf)); 303c06b6b69Smrg } 304c06b6b69Smrg if(pPriv->linear) { 305c06b6b69Smrg xf86FreeOffscreenLinear(pPriv->linear); 306c06b6b69Smrg pPriv->linear = NULL; 307c06b6b69Smrg } 308c06b6b69Smrg pPriv->videoStatus = 0; 309c06b6b69Smrg } else { 310c06b6b69Smrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 311c06b6b69Smrg pPriv->videoStatus |= OFF_TIMER; 312c06b6b69Smrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 313c06b6b69Smrg cPtr->VideoTimerCallback = CHIPSVideoTimerCallback; 314c06b6b69Smrg } 315c06b6b69Smrg } 316c06b6b69Smrg} 317c06b6b69Smrg 318c06b6b69Smrgstatic int 319c06b6b69SmrgCHIPSSetPortAttribute( 320c06b6b69Smrg ScrnInfoPtr pScrn, 321c06b6b69Smrg Atom attribute, 322c06b6b69Smrg INT32 value, 323c06b6b69Smrg pointer data 324c06b6b69Smrg){ 325c06b6b69Smrg CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data; 326c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 327c06b6b69Smrg 32804109a1cSmacallan#ifdef HAVE_XAA_H 329c06b6b69Smrg if (cPtr->Flags & ChipsAccelSupport) 330c06b6b69Smrg CHIPSHiQVSync(pScrn); 33104109a1cSmacallan#endif 332c06b6b69Smrg if(attribute == xvColorKey) { 333c06b6b69Smrg int red, green, blue; 334c06b6b69Smrg pPriv->colorKey = value; 335c06b6b69Smrg switch (pScrn->depth) { 336c06b6b69Smrg case 8: 337c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, 0x00); 338c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, 0x00); 339c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, (pPriv->colorKey & 0xFF)); 340c06b6b69Smrg break; 341c06b6b69Smrg default: 342c06b6b69Smrg red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 343c06b6b69Smrg green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 344c06b6b69Smrg blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 345c06b6b69Smrg switch (pScrn->depth) { 346c06b6b69Smrg case 15: 347c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, (red << 3)); 348c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, (green << 3)); 349c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, (blue << 3)); 350c06b6b69Smrg break; 351c06b6b69Smrg case 16: 352c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, (red << 3)); 353c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, (green << 2)); 354c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, (blue << 3)); 355c06b6b69Smrg break; 356c06b6b69Smrg case 24: 357c06b6b69Smrg cPtr->writeMR(cPtr, 0x3D, red); 358c06b6b69Smrg cPtr->writeMR(cPtr, 0x3E, green); 359c06b6b69Smrg cPtr->writeMR(cPtr, 0x3F, blue); 360c06b6b69Smrg break; 361c06b6b69Smrg } 362c06b6b69Smrg } 363c06b6b69Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 364c06b6b69Smrg } else return BadMatch; 365c06b6b69Smrg 366c06b6b69Smrg return Success; 367c06b6b69Smrg} 368c06b6b69Smrg 369c06b6b69Smrgstatic int 370c06b6b69SmrgCHIPSGetPortAttribute( 371c06b6b69Smrg ScrnInfoPtr pScrn, 372c06b6b69Smrg Atom attribute, 373c06b6b69Smrg INT32 *value, 374c06b6b69Smrg pointer data 375c06b6b69Smrg){ 376c06b6b69Smrg CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data; 377c06b6b69Smrg 378c06b6b69Smrg if(attribute == xvColorKey) { 379c06b6b69Smrg *value = pPriv->colorKey; 380c06b6b69Smrg } else return BadMatch; 381c06b6b69Smrg 382c06b6b69Smrg return Success; 383c06b6b69Smrg} 384c06b6b69Smrg 385c06b6b69Smrgstatic void 386c06b6b69SmrgCHIPSQueryBestSize( 387c06b6b69Smrg ScrnInfoPtr pScrn, 388c06b6b69Smrg Bool motion, 389c06b6b69Smrg short vid_w, short vid_h, 390c06b6b69Smrg short drw_w, short drw_h, 391c06b6b69Smrg unsigned int *p_w, unsigned int *p_h, 392c06b6b69Smrg pointer data 393c06b6b69Smrg){ 394c06b6b69Smrg *p_w = drw_w; 395c06b6b69Smrg *p_h = drw_h; 396c06b6b69Smrg 397c06b6b69Smrg if(*p_w > 16384) *p_w = 16384; 398c06b6b69Smrg} 399c06b6b69Smrg 400c06b6b69Smrg 401c06b6b69Smrgstatic void 402c06b6b69SmrgCHIPSCopyData( 403c06b6b69Smrg unsigned char *src, 404c06b6b69Smrg unsigned char *dst, 405c06b6b69Smrg int srcPitch, 406c06b6b69Smrg int dstPitch, 407c06b6b69Smrg int h, 408c06b6b69Smrg int w 409c06b6b69Smrg){ 410c06b6b69Smrg w <<= 1; 411c06b6b69Smrg while(h--) { 412c06b6b69Smrg memcpy(dst, src, w); 413c06b6b69Smrg src += srcPitch; 414c06b6b69Smrg dst += dstPitch; 415c06b6b69Smrg } 416c06b6b69Smrg} 417c06b6b69Smrg 418c06b6b69Smrgstatic void 419c06b6b69SmrgCHIPSCopyMungedData( 420c06b6b69Smrg unsigned char *src1, 421c06b6b69Smrg unsigned char *src2, 422c06b6b69Smrg unsigned char *src3, 423c06b6b69Smrg unsigned char *dst1, 424c06b6b69Smrg int srcPitch, 425c06b6b69Smrg int srcPitch2, 426c06b6b69Smrg int dstPitch, 427c06b6b69Smrg int h, 428c06b6b69Smrg int w 429c06b6b69Smrg){ 430c06b6b69Smrg CARD32 *dst = (CARD32*)dst1; 431c06b6b69Smrg int i, j; 432c06b6b69Smrg 433c06b6b69Smrg dstPitch >>= 2; 434c06b6b69Smrg w >>= 1; 435c06b6b69Smrg 436c06b6b69Smrg for(j = 0; j < h; j++) { 437c06b6b69Smrg for(i = 0; i < w; i++) { 438c06b6b69Smrg dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | 439c06b6b69Smrg (src3[i] << 8) | (src2[i] << 24); 440c06b6b69Smrg } 441c06b6b69Smrg dst += dstPitch; 442c06b6b69Smrg src1 += srcPitch; 443c06b6b69Smrg if(j & 1) { 444c06b6b69Smrg src2 += srcPitch2; 445c06b6b69Smrg src3 += srcPitch2; 446c06b6b69Smrg } 447c06b6b69Smrg } 448c06b6b69Smrg} 449c06b6b69Smrg 450c06b6b69Smrgstatic FBLinearPtr 451c06b6b69SmrgCHIPSAllocateMemory( 452c06b6b69Smrg ScrnInfoPtr pScrn, 453c06b6b69Smrg FBLinearPtr linear, 454c06b6b69Smrg int size 455c06b6b69Smrg){ 456c06b6b69Smrg ScreenPtr pScreen; 457c06b6b69Smrg FBLinearPtr new_linear; 458c06b6b69Smrg 459c06b6b69Smrg if(linear) { 460c06b6b69Smrg if(linear->size >= size) 461c06b6b69Smrg return linear; 462c06b6b69Smrg 463c06b6b69Smrg if(xf86ResizeOffscreenLinear(linear, size)) 464c06b6b69Smrg return linear; 465c06b6b69Smrg 466c06b6b69Smrg xf86FreeOffscreenLinear(linear); 467c06b6b69Smrg } 468c06b6b69Smrg 469a1d73b4bSmrg pScreen = xf86ScrnToScreen(pScrn); 470c06b6b69Smrg 471c06b6b69Smrg new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8, 472c06b6b69Smrg NULL, NULL, NULL); 473c06b6b69Smrg 474c06b6b69Smrg if(!new_linear) { 475c06b6b69Smrg int max_size; 476c06b6b69Smrg 477c06b6b69Smrg xf86QueryLargestOffscreenLinear(pScreen, &max_size, 8, 478c06b6b69Smrg PRIORITY_EXTREME); 479c06b6b69Smrg 480c06b6b69Smrg if(max_size < size) 481c06b6b69Smrg return NULL; 482c06b6b69Smrg 483c06b6b69Smrg xf86PurgeUnlockedOffscreenAreas(pScreen); 484c06b6b69Smrg new_linear = xf86AllocateOffscreenLinear(pScreen, size, 8, 485c06b6b69Smrg NULL, NULL, NULL); 486c06b6b69Smrg } 487c06b6b69Smrg 488c06b6b69Smrg return new_linear; 489c06b6b69Smrg} 490c06b6b69Smrg 491c06b6b69Smrgstatic int 492c06b6b69SmrgCHIPSSetCurrentPlaybackBuffer(CHIPSPtr cPtr, int n) 493c06b6b69Smrg{ 494c06b6b69Smrg 495c06b6b69Smrg CARD8 mr20; 496c06b6b69Smrg mr20 = cPtr->readMR(cPtr, 0x20); 497c06b6b69Smrg mr20 &= ~0x1B; 498c06b6b69Smrg if (!n) mr20 |= 0x10; 499c06b6b69Smrg cPtr->writeMR(cPtr, 0x22, mr20); 500c06b6b69Smrg return n; 501c06b6b69Smrg} 502c06b6b69Smrg 503c06b6b69Smrgstatic int 504c06b6b69SmrgCHIPSWaitGetNextFrame(CHIPSPtr cPtr) 505c06b6b69Smrg{ 506c06b6b69Smrg volatile CARD8 mr20; 507c06b6b69Smrg volatile CARD8 mr21; 508c06b6b69Smrg 509c06b6b69Smrg mr20 = cPtr->readMR(cPtr, 0x20); 510c06b6b69Smrg while (1) { 511c06b6b69Smrg mr21 = cPtr->readMR(cPtr, 0x21); 512c06b6b69Smrg if (!(mr20 & (1 << 5)) || !(mr21 & 1)) 513c06b6b69Smrg break; 514c06b6b69Smrg } 515c06b6b69Smrg mr20 &= ~0x4; 516c06b6b69Smrg mr20 = cPtr->readMR(cPtr, 0x20); 517c06b6b69Smrg return (mr21 & 2)? 0 : 1; 518c06b6b69Smrg} 519c06b6b69Smrg 520c06b6b69Smrgstatic void 521c06b6b69SmrgCHIPSDisplayVideo( 522c06b6b69Smrg ScrnInfoPtr pScrn, 523c06b6b69Smrg int id, 524c06b6b69Smrg int offset, 525c06b6b69Smrg short width, short height, 526c06b6b69Smrg int pitch, 527c06b6b69Smrg int x1, int y1, int x2, int y2, 528c06b6b69Smrg BoxPtr dstBox, 529c06b6b69Smrg short src_w, short src_h, 530c06b6b69Smrg short drw_w, short drw_h, 531c06b6b69Smrg Bool triggerBufSwitch 532c06b6b69Smrg){ 533c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 534c06b6b69Smrg CHIPSPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 535c06b6b69Smrg DisplayModePtr mode = pScrn->currentMode; 536c06b6b69Smrg unsigned char tmp, m1f, m1e; 537c06b6b69Smrg int buffer = pPriv->currentBuffer; 538c06b6b69Smrg Bool dblscan = (pScrn->currentMode->Flags & V_DBLSCAN) == V_DBLSCAN; 539c06b6b69Smrg int val; 54004109a1cSmacallan 54104109a1cSmacallan#ifdef HAVE_XAA_H 542c06b6b69Smrg if (cPtr->Flags & ChipsAccelSupport) 543c06b6b69Smrg CHIPSHiQVSync(pScrn); 54404109a1cSmacallan#endif 545c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xD0); 546c06b6b69Smrg cPtr->writeXR(cPtr, 0xD0, (tmp | 0x10)); 547c06b6b69Smrg 548c06b6b69Smrg m1e = cPtr->readMR(cPtr, 0x1E); 549c06b6b69Smrg m1e &= 0xE0; /* Set Zoom and Direction */ 550c06b6b69Smrg if ((!(cPtr->PanelType & ChipsLCD)) && (mode->Flags & V_INTERLACE)) 551c06b6b69Smrg m1e |= 0x10; 552c06b6b69Smrg 553c06b6b69Smrg m1f = cPtr->readMR(cPtr, 0x1F); 554c06b6b69Smrg m1f = (m1f & 0x14); /* Mask reserved bits, unset interpolation */ 555c06b6b69Smrg switch(id) { 556c06b6b69Smrg case 0x35315652: /* RGB15 */ 557c06b6b69Smrg m1f |= 0x09; 558c06b6b69Smrg break; 559c06b6b69Smrg case 0x36315652: /* RGB16 */ 560c06b6b69Smrg m1f |= 0x08; 561c06b6b69Smrg break; 562c06b6b69Smrg case FOURCC_YV12: /* YV12 */ 563c06b6b69Smrg /* m1f |= 0x03 */ 564c06b6b69Smrg m1f |= 0x00; 565c06b6b69Smrg break; 566c06b6b69Smrg case FOURCC_YUY2: /* YUY2 */ 567c06b6b69Smrg default: 568c06b6b69Smrg m1f |= 0x00; /* Do nothing here */ 569c06b6b69Smrg break; 570c06b6b69Smrg } 571c06b6b69Smrg 572c06b6b69Smrg offset += (x1 >> 15) & ~0x01; 573c06b6b69Smrg /* Setup Pointer 1 */ 574c06b6b69Smrg if (!buffer || pPriv->manualDoubleBuffer || !pPriv->doubleBuffer) { 575c06b6b69Smrg cPtr->writeMR(cPtr, 0x22, (offset & 0xF8)); 576c06b6b69Smrg cPtr->writeMR(cPtr, 0x23, ((offset >> 8) & 0xFF)); 577c06b6b69Smrg cPtr->writeMR(cPtr, 0x24, ((offset >> 16) & 0xFF)); 578c06b6b69Smrg } 579c06b6b69Smrg 580c06b6b69Smrg /* Setup Pointer 2 */ 581c06b6b69Smrg if ((buffer && !pPriv->manualDoubleBuffer) || !pPriv->doubleBuffer) { 582c06b6b69Smrg cPtr->writeMR(cPtr, 0x25, (offset & 0xF8)); 583c06b6b69Smrg cPtr->writeMR(cPtr, 0x26, ((offset >> 8) & 0xFF)); 584c06b6b69Smrg cPtr->writeMR(cPtr, 0x27, ((offset >> 16) & 0xFF)); 585c06b6b69Smrg } 586c06b6b69Smrg 587c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x04); 588c06b6b69Smrg if (pPriv->doubleBuffer && !pPriv->manualDoubleBuffer && triggerBufSwitch) 589c06b6b69Smrg tmp |= 0x18; 590c06b6b69Smrg cPtr->writeMR(cPtr, 0x04, tmp); 591c06b6b69Smrg 592c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x20); 593c06b6b69Smrg tmp &= 0xC3; 594c06b6b69Smrg 595c06b6b69Smrg if (pPriv->doubleBuffer && !pPriv->manualDoubleBuffer && triggerBufSwitch) 596c06b6b69Smrg tmp |= ((1 << 2 | 1 << 5) | ((buffer) ? (1 << 4) : 0)); 597c06b6b69Smrg cPtr->writeMR(cPtr, 0x20, tmp); 598c06b6b69Smrg 599c06b6b69Smrg cPtr->writeMR(cPtr, 0x28, ((width >> 2) - 1)); /* Width */ 600c06b6b69Smrg cPtr->writeMR(cPtr, 0x34, ((width >> 2) - 1)); 601c06b6b69Smrg 602c06b6b69Smrg /* Left Edge of Overlay */ 603c06b6b69Smrg cPtr->writeMR(cPtr, 0x2A, ((cPtr->OverlaySkewX + dstBox->x1) & 0xFF)); 604c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x2B); 605c06b6b69Smrg tmp = (tmp & 0xF8) + (((cPtr->OverlaySkewX + dstBox->x1) >> 8) & 0x07); 606c06b6b69Smrg cPtr->writeMR(cPtr, 0x2B, tmp); 607c06b6b69Smrg /* Right Edge of Overlay */ 608c06b6b69Smrg cPtr->writeMR(cPtr, 0x2C, ((cPtr->OverlaySkewX + dstBox->x2 -1) 609c06b6b69Smrg & 0xFF)); 610c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x2D); 611c06b6b69Smrg tmp = (tmp & 0xF8) + (((cPtr->OverlaySkewX + dstBox->x2 - 1) >> 8) & 0x07); 612c06b6b69Smrg cPtr->writeMR(cPtr, 0x2D, tmp); 613c06b6b69Smrg /* Top Edge of Overlay */ 614c06b6b69Smrg val = cPtr->OverlaySkewY + (dstBox->y1 << (dblscan ? 1 : 0)); 615c06b6b69Smrg cPtr->writeMR(cPtr, 0x2E, ((val) & 0xFF)); 616c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x2F); 617c06b6b69Smrg tmp = (tmp & 0xF8) + (((val) >> 8) & 0x07); 618c06b6b69Smrg cPtr->writeMR(cPtr, 0x2F, tmp); 619c06b6b69Smrg /* Bottom Edge of Overlay*/ 620c06b6b69Smrg val = cPtr->OverlaySkewY + (dstBox->y2 << (dblscan ? 1 : 0)); 621c06b6b69Smrg cPtr->writeMR(cPtr, 0x30, ((val - 1) & 0xFF)); 622c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x31); 623c06b6b69Smrg tmp = (tmp & 0xF8) + (((val - 1) >> 8) & 0x07); 624c06b6b69Smrg cPtr->writeMR(cPtr, 0x31, tmp); 625c06b6b69Smrg 626c06b6b69Smrg /* Horizontal Zoom */ 627c06b6b69Smrg if (drw_w > src_w) { 628c06b6b69Smrg m1f = m1f | 0x20; /* set H-interpolation */ 629c06b6b69Smrg m1e = m1e | 0x04; 630c06b6b69Smrg tmp = cPtr->VideoZoomMax * src_w / drw_w; 631c06b6b69Smrg cPtr->writeMR(cPtr, 0x32, tmp); 632c06b6b69Smrg } 633c06b6b69Smrg 634c06b6b69Smrg /* Vertical Zoom */ 635c06b6b69Smrg if (drw_h > src_h || dblscan) { 636c06b6b69Smrg m1f = m1f | 0x80; /* set V-interpolation */ 637c06b6b69Smrg m1e = m1e | 0x08; 638c06b6b69Smrg if (dblscan) 639c06b6b69Smrg tmp = cPtr->VideoZoomMax >> 1; 640c06b6b69Smrg if (drw_h > src_h) 6419f4658d1Smrg tmp = 256 * src_h / drw_h; 6429f4658d1Smrg cPtr->writeMR(cPtr, 0x33, tmp & 0xFC); 643c06b6b69Smrg } 644c06b6b69Smrg cPtr->writeMR(cPtr, 0x1F, m1f); 645c06b6b69Smrg cPtr->writeMR(cPtr, 0x1E, m1e); 646c06b6b69Smrg 647c06b6b69Smrg tmp = cPtr->readMR(cPtr, 0x3C); 648c06b6b69Smrg cPtr->writeMR(cPtr, 0x3C, (tmp | 0x7)); 64904109a1cSmacallan#ifdef HAVE_XAA_H 650c06b6b69Smrg if (cPtr->Flags & ChipsAccelSupport) 651c06b6b69Smrg CHIPSHiQVSync(pScrn); 65204109a1cSmacallan#endif 653c06b6b69Smrg} 654c06b6b69Smrg 655c06b6b69Smrgstatic int 656c06b6b69SmrgCHIPSPutImage( 657c06b6b69Smrg ScrnInfoPtr pScrn, 658c06b6b69Smrg short src_x, short src_y, 659c06b6b69Smrg short drw_x, short drw_y, 660c06b6b69Smrg short src_w, short src_h, 661c06b6b69Smrg short drw_w, short drw_h, 662c06b6b69Smrg int id, unsigned char* buf, 663c06b6b69Smrg short width, short height, 664c06b6b69Smrg Bool sync, 665c06b6b69Smrg RegionPtr clipBoxes, pointer data, 666c06b6b69Smrg DrawablePtr pDraw 667c06b6b69Smrg){ 668c06b6b69Smrg CHIPSPortPrivPtr pPriv = (CHIPSPortPrivPtr)data; 669c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 670c06b6b69Smrg INT32 x1, x2, y1, y2; 671c06b6b69Smrg unsigned char *dst_start; 672c06b6b69Smrg int new_size, offset, offset2 = 0, offset3 = 0; 673c06b6b69Smrg int srcPitch, srcPitch2 = 0, dstPitch; 674c06b6b69Smrg int top, left, npixels, nlines, bpp; 675c06b6b69Smrg BoxRec dstBox; 676c06b6b69Smrg CARD32 tmp; 677c06b6b69Smrg 678c06b6b69Smrg if(drw_w > 16384) drw_w = 16384; 679c06b6b69Smrg 680c06b6b69Smrg /* Clip */ 681c06b6b69Smrg x1 = src_x; 682c06b6b69Smrg x2 = src_x + src_w; 683c06b6b69Smrg y1 = src_y; 684c06b6b69Smrg y2 = src_y + src_h; 685c06b6b69Smrg 686c06b6b69Smrg dstBox.x1 = drw_x; 687c06b6b69Smrg dstBox.x2 = drw_x + drw_w; 688c06b6b69Smrg dstBox.y1 = drw_y; 689c06b6b69Smrg dstBox.y2 = drw_y + drw_h; 690c06b6b69Smrg 691c06b6b69Smrg if (!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, 692c06b6b69Smrg clipBoxes, width, height)) 693c06b6b69Smrg return Success; 694c06b6b69Smrg 695c06b6b69Smrg dstBox.x1 -= pScrn->frameX0 & cPtr->viewportMask; 696c06b6b69Smrg dstBox.x2 -= pScrn->frameX0 & cPtr->viewportMask; 697c06b6b69Smrg dstBox.y1 -= pScrn->frameY0; 698c06b6b69Smrg dstBox.y2 -= pScrn->frameY0; 699c06b6b69Smrg 700c06b6b69Smrg bpp = pScrn->bitsPerPixel >> 3; 701c06b6b69Smrg 702c06b6b69Smrg dstPitch = ((width << 1) + 15) & ~15; 703c06b6b69Smrg new_size = ((dstPitch * height) + bpp - 1) / bpp; 704c06b6b69Smrg 705c06b6b69Smrg pPriv->doubleBuffer = (pScrn->currentMode->Flags & V_DBLSCAN) != V_DBLSCAN; 706c06b6b69Smrg 707c06b6b69Smrg if (pPriv->doubleBuffer) 708c06b6b69Smrg new_size <<= 1; 709c06b6b69Smrg 710c06b6b69Smrg switch(id) { 711c06b6b69Smrg case FOURCC_YV12: /* YV12 */ 712c06b6b69Smrg srcPitch = (width + 3) & ~3; 713c06b6b69Smrg offset2 = srcPitch * height; 714c06b6b69Smrg srcPitch2 = ((width >> 1) + 3) & ~3; 715c06b6b69Smrg offset3 = (srcPitch2 * (height >> 1)) + offset2; 716c06b6b69Smrg break; 717c06b6b69Smrg default: /* RGB15, RGB16, YUY2 */ 718c06b6b69Smrg srcPitch = (width << 1); 719c06b6b69Smrg break; 720c06b6b69Smrg } 721c06b6b69Smrg 722c06b6b69Smrg if(!(pPriv->linear = CHIPSAllocateMemory(pScrn, pPriv->linear, new_size))) { 723c06b6b69Smrg if (pPriv->doubleBuffer 724c06b6b69Smrg && (pPriv->linear = CHIPSAllocateMemory(pScrn, pPriv->linear, 725c06b6b69Smrg new_size >> 1))) { 726c06b6b69Smrg new_size >>= 1; 727c06b6b69Smrg pPriv->doubleBuffer = FALSE; 728c06b6b69Smrg } else 729c06b6b69Smrg return BadAlloc; 730c06b6b69Smrg } 731c06b6b69Smrg 732c06b6b69Smrg /* copy data */ 733c06b6b69Smrg top = y1 >> 16; 734c06b6b69Smrg left = (x1 >> 16) & ~1; 735c06b6b69Smrg npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 736c06b6b69Smrg left <<= 1; 737c06b6b69Smrg 738c06b6b69Smrg offset = pPriv->linear->offset * bpp; 739c06b6b69Smrg if (!pPriv->manualDoubleBuffer) 740c06b6b69Smrg pPriv->currentBuffer = CHIPSWaitGetNextFrame(cPtr); 741c06b6b69Smrg if(pPriv->doubleBuffer && pPriv->currentBuffer) 742c06b6b69Smrg offset += (new_size * bpp) >> 1; 743c06b6b69Smrg 744c06b6b69Smrg dst_start = cPtr->FbBase + offset + left + (top * dstPitch); 745c06b6b69Smrg 746c06b6b69Smrg switch(id) { 747c06b6b69Smrg case FOURCC_YV12: /* YV12 */ 748c06b6b69Smrg top &= ~1; 749c06b6b69Smrg tmp = ((top >> 1) * srcPitch2) + (left >> 2); 750c06b6b69Smrg offset2 += tmp; 751c06b6b69Smrg offset3 += tmp; 752c06b6b69Smrg nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 753c06b6b69Smrg CHIPSCopyMungedData(buf + (top * srcPitch) + (left >> 1), 754c06b6b69Smrg buf + offset2, buf + offset3, dst_start, 755c06b6b69Smrg srcPitch, srcPitch2, dstPitch, nlines, npixels); 756c06b6b69Smrg break; 757c06b6b69Smrg default: /* RGB15, RGB16, YUY2 */ 758c06b6b69Smrg buf += (top * srcPitch) + left; 759c06b6b69Smrg nlines = ((y2 + 0xffff) >> 16) - top; 760c06b6b69Smrg CHIPSCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 761c06b6b69Smrg break; 762c06b6b69Smrg } 763c06b6b69Smrg 764c06b6b69Smrg /* update cliplist */ 765c06b6b69Smrg if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 766c06b6b69Smrg REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 767c06b6b69Smrg xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 768c06b6b69Smrg } 769c06b6b69Smrg 770c06b6b69Smrg offset += top * dstPitch; 771c06b6b69Smrg CHIPSDisplayVideo(pScrn, id, offset, width, height, dstPitch, 772c06b6b69Smrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h, TRUE); 773c06b6b69Smrg 774c06b6b69Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 775c06b6b69Smrg 776c06b6b69Smrg if (pPriv->manualDoubleBuffer) 777c06b6b69Smrg pPriv->currentBuffer ^= 1; 778c06b6b69Smrg 779c06b6b69Smrg return Success; 780c06b6b69Smrg} 781c06b6b69Smrg 782c06b6b69Smrgstatic int 783c06b6b69SmrgCHIPSQueryImageAttributes( 784c06b6b69Smrg ScrnInfoPtr pScrn, 785c06b6b69Smrg int id, 786c06b6b69Smrg unsigned short *w, unsigned short *h, 787c06b6b69Smrg int *pitches, int *offsets 788c06b6b69Smrg){ 789c06b6b69Smrg int size, tmp; 790c06b6b69Smrg 791c06b6b69Smrg if(*w > 1024) *w = 1024; 792c06b6b69Smrg if(*h > 1024) *h = 1024; 793c06b6b69Smrg 794c06b6b69Smrg *w = (*w + 1) & ~1; 795c06b6b69Smrg if(offsets) offsets[0] = 0; 796c06b6b69Smrg 797c06b6b69Smrg switch(id) { 798c06b6b69Smrg case FOURCC_YV12: /* YV12 */ 799c06b6b69Smrg *h = (*h + 1) & ~1; 800c06b6b69Smrg size = (*w + 3) & ~3; 801c06b6b69Smrg if(pitches) pitches[0] = size; 802c06b6b69Smrg size *= *h; 803c06b6b69Smrg if(offsets) offsets[1] = size; 804c06b6b69Smrg tmp = ((*w >> 1) + 3) & ~3; 805c06b6b69Smrg if(pitches) pitches[1] = pitches[2] = tmp; 806c06b6b69Smrg tmp *= (*h >> 1); 807c06b6b69Smrg size += tmp; 808c06b6b69Smrg if(offsets) offsets[2] = size; 809c06b6b69Smrg size += tmp; 810c06b6b69Smrg break; 811c06b6b69Smrg default: /* RGB15, RGB16, YUY2 */ 812c06b6b69Smrg size = *w << 1; 813c06b6b69Smrg if(pitches) pitches[0] = size; 814c06b6b69Smrg size *= *h; 815c06b6b69Smrg break; 816c06b6b69Smrg } 817c06b6b69Smrg 818c06b6b69Smrg return size; 819c06b6b69Smrg} 820c06b6b69Smrg 821c06b6b69Smrg 822c06b6b69Smrgstatic void 823c06b6b69SmrgCHIPSVideoTimerCallback(ScrnInfoPtr pScrn, Time time) 824c06b6b69Smrg{ 825c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 826c06b6b69Smrg CHIPSPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 827c06b6b69Smrg unsigned char mr3c; 828c06b6b69Smrg 829c06b6b69Smrg if(pPriv->videoStatus & TIMER_MASK) { 830c06b6b69Smrg if(pPriv->videoStatus & OFF_TIMER) { 831c06b6b69Smrg if(pPriv->offTime < time) { 83204109a1cSmacallan#ifdef HAVE_XAA_H 833c06b6b69Smrg if (cPtr->Flags & ChipsAccelSupport) 834c06b6b69Smrg CHIPSHiQVSync(pScrn); 83504109a1cSmacallan#endif 836c06b6b69Smrg mr3c = cPtr->readMR(cPtr, 0x3C); 837c06b6b69Smrg cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE)); 838c06b6b69Smrg pPriv->videoStatus = FREE_TIMER; 839c06b6b69Smrg pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 840c06b6b69Smrg } 841c06b6b69Smrg } else { /* FREE_TIMER */ 842c06b6b69Smrg if(pPriv->freeTime < time) { 843c06b6b69Smrg if(pPriv->linear) { 844c06b6b69Smrg xf86FreeOffscreenLinear(pPriv->linear); 845c06b6b69Smrg pPriv->linear = NULL; 846c06b6b69Smrg } 847c06b6b69Smrg pPriv->videoStatus = 0; 848c06b6b69Smrg cPtr->VideoTimerCallback = NULL; 849c06b6b69Smrg } 850c06b6b69Smrg } 851c06b6b69Smrg } else /* shouldn't get here */ 852c06b6b69Smrg cPtr->VideoTimerCallback = NULL; 853c06b6b69Smrg} 854c06b6b69Smrg 855c06b6b69Smrg 856c06b6b69Smrg/****************** Offscreen stuff ***************/ 857c06b6b69Smrg 858c06b6b69Smrgtypedef struct { 859c06b6b69Smrg FBLinearPtr linear; 860c06b6b69Smrg Bool isOn; 861c06b6b69Smrg} OffscreenPrivRec, * OffscreenPrivPtr; 862c06b6b69Smrg 863c06b6b69Smrgstatic int 864c06b6b69SmrgCHIPSAllocateSurface( 865c06b6b69Smrg ScrnInfoPtr pScrn, 866c06b6b69Smrg int id, 867c06b6b69Smrg unsigned short w, 868c06b6b69Smrg unsigned short h, 869c06b6b69Smrg XF86SurfacePtr surface 870c06b6b69Smrg){ 871c06b6b69Smrg FBLinearPtr linear; 872c06b6b69Smrg int pitch, size, bpp; 873c06b6b69Smrg OffscreenPrivPtr pPriv; 874c06b6b69Smrg 875c06b6b69Smrg if((w > 1024) || (h > 1024)) 876c06b6b69Smrg return BadAlloc; 877c06b6b69Smrg 878c06b6b69Smrg w = (w + 1) & ~1; 879c06b6b69Smrg pitch = ((w << 1) + 15) & ~15; 880c06b6b69Smrg bpp = pScrn->bitsPerPixel >> 3; 881c06b6b69Smrg size = ((pitch * h) + bpp - 1) / bpp; 882c06b6b69Smrg 883c06b6b69Smrg if(!(linear = CHIPSAllocateMemory(pScrn, NULL, size))) 884c06b6b69Smrg return BadAlloc; 885c06b6b69Smrg 886c06b6b69Smrg surface->width = w; 887c06b6b69Smrg surface->height = h; 888c06b6b69Smrg 8893699b6c4Smrg if(!(surface->pitches = malloc(sizeof(int)))) { 890c06b6b69Smrg xf86FreeOffscreenLinear(linear); 891c06b6b69Smrg return BadAlloc; 892c06b6b69Smrg } 8933699b6c4Smrg if(!(surface->offsets = malloc(sizeof(int)))) { 8943699b6c4Smrg free(surface->pitches); 895c06b6b69Smrg xf86FreeOffscreenLinear(linear); 896c06b6b69Smrg return BadAlloc; 897c06b6b69Smrg } 8983699b6c4Smrg if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 8993699b6c4Smrg free(surface->pitches); 9003699b6c4Smrg free(surface->offsets); 901c06b6b69Smrg xf86FreeOffscreenLinear(linear); 902c06b6b69Smrg return BadAlloc; 903c06b6b69Smrg } 904c06b6b69Smrg 905c06b6b69Smrg pPriv->linear = linear; 906c06b6b69Smrg pPriv->isOn = FALSE; 907c06b6b69Smrg 908c06b6b69Smrg surface->pScrn = pScrn; 909c06b6b69Smrg surface->id = id; 910c06b6b69Smrg surface->pitches[0] = pitch; 911c06b6b69Smrg surface->offsets[0] = linear->offset * bpp; 912c06b6b69Smrg surface->devPrivate.ptr = (pointer)pPriv; 913c06b6b69Smrg 914c06b6b69Smrg return Success; 915c06b6b69Smrg} 916c06b6b69Smrg 917c06b6b69Smrgstatic int 918c06b6b69SmrgCHIPSStopSurface( 919c06b6b69Smrg XF86SurfacePtr surface 920c06b6b69Smrg){ 921c06b6b69Smrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 922c06b6b69Smrg 923c06b6b69Smrg if(pPriv->isOn) { 924c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(surface->pScrn); 925c06b6b69Smrg unsigned char mr3c, tmp; 926c06b6b69Smrg tmp = cPtr->readXR(cPtr, 0xD0); 927c06b6b69Smrg cPtr->writeXR(cPtr, 0xD0, (tmp & 0xf)); 928c06b6b69Smrg mr3c = cPtr->readMR(cPtr, 0x3C); 929c06b6b69Smrg cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE)); 930c06b6b69Smrg pPriv->isOn = FALSE; 931c06b6b69Smrg } 932c06b6b69Smrg 933c06b6b69Smrg return Success; 934c06b6b69Smrg} 935c06b6b69Smrg 936c06b6b69Smrg 937c06b6b69Smrgstatic int 938c06b6b69SmrgCHIPSFreeSurface( 939c06b6b69Smrg XF86SurfacePtr surface 940c06b6b69Smrg){ 941c06b6b69Smrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 942c06b6b69Smrg 943c06b6b69Smrg if(pPriv->isOn) 944c06b6b69Smrg CHIPSStopSurface(surface); 945c06b6b69Smrg xf86FreeOffscreenLinear(pPriv->linear); 9463699b6c4Smrg free(surface->pitches); 9473699b6c4Smrg free(surface->offsets); 9483699b6c4Smrg free(surface->devPrivate.ptr); 949c06b6b69Smrg 950c06b6b69Smrg return Success; 951c06b6b69Smrg} 952c06b6b69Smrg 953c06b6b69Smrgstatic int 954c06b6b69SmrgCHIPSGetSurfaceAttribute( 955c06b6b69Smrg ScrnInfoPtr pScrn, 956c06b6b69Smrg Atom attribute, 957c06b6b69Smrg INT32 *value 958c06b6b69Smrg){ 959c06b6b69Smrg return CHIPSGetPortAttribute(pScrn, attribute, value, 960c06b6b69Smrg (pointer)(GET_PORT_PRIVATE(pScrn))); 961c06b6b69Smrg} 962c06b6b69Smrg 963c06b6b69Smrgstatic int 964c06b6b69SmrgCHIPSSetSurfaceAttribute( 965c06b6b69Smrg ScrnInfoPtr pScrn, 966c06b6b69Smrg Atom attribute, 967c06b6b69Smrg INT32 value 968c06b6b69Smrg){ 969c06b6b69Smrg return CHIPSSetPortAttribute(pScrn, attribute, value, 970c06b6b69Smrg (pointer)(GET_PORT_PRIVATE(pScrn))); 971c06b6b69Smrg} 972c06b6b69Smrg 973c06b6b69Smrg 974c06b6b69Smrgstatic int 975c06b6b69SmrgCHIPSDisplaySurface( 976c06b6b69Smrg XF86SurfacePtr surface, 977c06b6b69Smrg short src_x, short src_y, 978c06b6b69Smrg short drw_x, short drw_y, 979c06b6b69Smrg short src_w, short src_h, 980c06b6b69Smrg short drw_w, short drw_h, 981c06b6b69Smrg RegionPtr clipBoxes 982c06b6b69Smrg){ 983c06b6b69Smrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 984c06b6b69Smrg ScrnInfoPtr pScrn = surface->pScrn; 985c06b6b69Smrg CHIPSPtr cPtr = CHIPSPTR(pScrn); 986c06b6b69Smrg CHIPSPortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); 987c06b6b69Smrg INT32 x1, y1, x2, y2; 988c06b6b69Smrg BoxRec dstBox; 989c06b6b69Smrg 990c06b6b69Smrg x1 = src_x; 991c06b6b69Smrg x2 = src_x + src_w; 992c06b6b69Smrg y1 = src_y; 993c06b6b69Smrg y2 = src_y + src_h; 994c06b6b69Smrg 995c06b6b69Smrg dstBox.x1 = drw_x; 996c06b6b69Smrg dstBox.x2 = drw_x + drw_w; 997c06b6b69Smrg dstBox.y1 = drw_y; 998c06b6b69Smrg dstBox.y2 = drw_y + drw_h; 999c06b6b69Smrg 1000c06b6b69Smrg if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, 1001c06b6b69Smrg surface->width, surface->height)) 1002c06b6b69Smrg return Success; 1003c06b6b69Smrg 1004c06b6b69Smrg dstBox.x1 -= pScrn->frameX0; 1005c06b6b69Smrg dstBox.x2 -= pScrn->frameX0; 1006c06b6b69Smrg dstBox.y1 -= pScrn->frameY0; 1007c06b6b69Smrg dstBox.y2 -= pScrn->frameY0; 1008c06b6b69Smrg 1009c06b6b69Smrg if (portPriv->doubleBuffer) 1010c06b6b69Smrg portPriv->currentBuffer = CHIPSSetCurrentPlaybackBuffer(cPtr,0); 1011c06b6b69Smrg else 1012c06b6b69Smrg portPriv->currentBuffer = 0; 1013c06b6b69Smrg 1014c06b6b69Smrg CHIPSDisplayVideo(pScrn, surface->id, surface->offsets[0], 1015c06b6b69Smrg surface->width, surface->height, surface->pitches[0], 1016c06b6b69Smrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h, FALSE); 1017c06b6b69Smrg xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 1018c06b6b69Smrg 1019c06b6b69Smrg pPriv->isOn = TRUE; 1020c06b6b69Smrg if(portPriv->videoStatus & CLIENT_VIDEO_ON) { 1021c06b6b69Smrg REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 1022c06b6b69Smrg UpdateCurrentTime(); 1023c06b6b69Smrg portPriv->videoStatus = FREE_TIMER; 1024c06b6b69Smrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1025c06b6b69Smrg cPtr->VideoTimerCallback = CHIPSVideoTimerCallback; 1026c06b6b69Smrg } 1027c06b6b69Smrg 1028c06b6b69Smrg return Success; 1029c06b6b69Smrg} 1030c06b6b69Smrg 1031c06b6b69Smrg 1032c06b6b69Smrgstatic void 1033c06b6b69SmrgCHIPSInitOffscreenImages(ScreenPtr pScreen) 1034c06b6b69Smrg{ 1035c06b6b69Smrg XF86OffscreenImagePtr offscreenImages; 1036c06b6b69Smrg 1037c06b6b69Smrg /* need to free this someplace */ 10383699b6c4Smrg if(!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 1039c06b6b69Smrg return; 1040c06b6b69Smrg 1041c06b6b69Smrg offscreenImages[0].image = &Images[0]; 1042c06b6b69Smrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | 1043c06b6b69Smrg VIDEO_CLIP_TO_VIEWPORT; 1044c06b6b69Smrg offscreenImages[0].alloc_surface = CHIPSAllocateSurface; 1045c06b6b69Smrg offscreenImages[0].free_surface = CHIPSFreeSurface; 1046c06b6b69Smrg offscreenImages[0].display = CHIPSDisplaySurface; 1047c06b6b69Smrg offscreenImages[0].stop = CHIPSStopSurface; 1048c06b6b69Smrg offscreenImages[0].setAttribute = CHIPSSetSurfaceAttribute; 1049c06b6b69Smrg offscreenImages[0].getAttribute = CHIPSGetSurfaceAttribute; 1050c06b6b69Smrg offscreenImages[0].max_width = 1024; 1051c06b6b69Smrg offscreenImages[0].max_height = 1024; 1052c06b6b69Smrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1053c06b6b69Smrg offscreenImages[0].attributes = Attributes; 1054c06b6b69Smrg 1055c06b6b69Smrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1056c06b6b69Smrg} 1057