1fc5a983dSmrg#ifdef HAVE_CONFIG_H 2fc5a983dSmrg#include "config.h" 3fc5a983dSmrg#endif 4fc5a983dSmrg 5fc5a983dSmrg#include "xf86.h" 6fc5a983dSmrg#include "xf86_OSproc.h" 7fc5a983dSmrg#include "compiler.h" 8d422ce2eSmrg#include "pci_ids.h" 9fc5a983dSmrg#include "xf86Pci.h" 10fc5a983dSmrg#include "xf86fbman.h" 11fc5a983dSmrg#include "regionstr.h" 12fc5a983dSmrg 13fc5a983dSmrg#include "xf86xv.h" 14fc5a983dSmrg#include <X11/extensions/Xv.h> 15fc5a983dSmrg#include "dixstruct.h" 16fc5a983dSmrg#include "fourcc.h" 17fc5a983dSmrg 18fc5a983dSmrg#include "nv_include.h" 19fc5a983dSmrg#include "nv_dma.h" 20fc5a983dSmrg 21fc5a983dSmrg#define OFF_DELAY 500 /* milliseconds */ 22fc5a983dSmrg#define FREE_DELAY 5000 23fc5a983dSmrg 24fc5a983dSmrg#define OFF_TIMER 0x01 25fc5a983dSmrg#define FREE_TIMER 0x02 26fc5a983dSmrg#define CLIENT_VIDEO_ON 0x04 27fc5a983dSmrg 28fc5a983dSmrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 29fc5a983dSmrg 30fc5a983dSmrg#define NUM_BLIT_PORTS 32 31fc5a983dSmrg 32fc5a983dSmrgtypedef struct _NVPortPrivRec { 33fc5a983dSmrg short brightness; 34fc5a983dSmrg short contrast; 35fc5a983dSmrg short saturation; 36fc5a983dSmrg short hue; 37fc5a983dSmrg RegionRec clip; 38fc5a983dSmrg CARD32 colorKey; 39fc5a983dSmrg Bool autopaintColorKey; 40fc5a983dSmrg Bool doubleBuffer; 41fc5a983dSmrg CARD32 videoStatus; 42fc5a983dSmrg int currentBuffer; 43fc5a983dSmrg Time videoTime; 44fc5a983dSmrg Bool grabbedByV4L; 45fc5a983dSmrg Bool iturbt_709; 46fc5a983dSmrg Bool blitter; 47fc5a983dSmrg Bool SyncToVBlank; 48fc5a983dSmrg FBLinearPtr linear; 49fc5a983dSmrg int pitch; 50fc5a983dSmrg int offset; 51fc5a983dSmrg} NVPortPrivRec, *NVPortPrivPtr; 52fc5a983dSmrg 53fc5a983dSmrg 54fc5a983dSmrgstatic XF86VideoAdaptorPtr NVSetupOverlayVideo(ScreenPtr); 55fc5a983dSmrgstatic XF86VideoAdaptorPtr NVSetupBlitVideo(ScreenPtr); 56fc5a983dSmrg 57fc5a983dSmrgstatic void NVStopOverlay (ScrnInfoPtr); 58fc5a983dSmrgstatic void NVPutOverlayImage(ScrnInfoPtr pScrnInfo, 59fc5a983dSmrg int offset, 60fc5a983dSmrg int id, 61fc5a983dSmrg int dstPitch, 62fc5a983dSmrg BoxPtr dstBox, 63fc5a983dSmrg int x1, int y1, int x2, int y2, 64fc5a983dSmrg short width, short height, 65fc5a983dSmrg short src_w, short src_h, 66fc5a983dSmrg short dst_w, short dst_h, 67fc5a983dSmrg RegionPtr cliplist); 68fc5a983dSmrg 69fc5a983dSmrgstatic int NVSetOverlayPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 70fc5a983dSmrgstatic int NVGetOverlayPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 71fc5a983dSmrgstatic int NVSetBlitPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 72fc5a983dSmrgstatic int NVGetBlitPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 73fc5a983dSmrg 74fc5a983dSmrg 75fc5a983dSmrgstatic void NVStopOverlayVideo(ScrnInfoPtr, pointer, Bool); 76fc5a983dSmrgstatic void NVStopBlitVideo(ScrnInfoPtr, pointer, Bool); 77fc5a983dSmrg 78fc5a983dSmrgstatic int NVPutImage( ScrnInfoPtr, short, short, short, short, short, short, short, short, int, unsigned char*, short, short, Bool, RegionPtr, pointer, DrawablePtr); 79fc5a983dSmrg 80fc5a983dSmrgstatic void NVQueryBestSize(ScrnInfoPtr, Bool, short, short, short, short, unsigned int *, unsigned int *, pointer); 81fc5a983dSmrgstatic int NVQueryImageAttributes(ScrnInfoPtr, int, unsigned short *, unsigned short *, int *, int *); 82fc5a983dSmrg 83fc5a983dSmrgstatic void NVVideoTimerCallback(ScrnInfoPtr, Time); 84fc5a983dSmrg 85fc5a983dSmrgstatic void NVInitOffscreenImages (ScreenPtr pScreen); 86fc5a983dSmrg 87fc5a983dSmrg 88fc5a983dSmrg#define GET_OVERLAY_PRIVATE(pNv) \ 89fc5a983dSmrg (NVPortPrivPtr)((pNv)->overlayAdaptor->pPortPrivates[0].ptr) 90fc5a983dSmrg 91fc5a983dSmrg#define GET_BLIT_PRIVATE(pNv) \ 92fc5a983dSmrg (NVPortPrivPtr)((pNv)->blitAdaptor->pPortPrivates[0].ptr) 93fc5a983dSmrg 94fc5a983dSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 95fc5a983dSmrg 96fc5a983dSmrgstatic Atom xvBrightness, xvContrast, xvColorKey, xvSaturation, 97fc5a983dSmrg xvHue, xvAutopaintColorKey, xvSetDefaults, xvDoubleBuffer, 98fc5a983dSmrg xvITURBT709, xvSyncToVBlank; 99fc5a983dSmrg 100fc5a983dSmrg/* client libraries expect an encoding */ 101fc5a983dSmrgstatic XF86VideoEncodingRec DummyEncoding = 102fc5a983dSmrg{ 103fc5a983dSmrg 0, 104fc5a983dSmrg "XV_IMAGE", 105fc5a983dSmrg 2046, 2046, 106fc5a983dSmrg {1, 1} 107fc5a983dSmrg}; 108fc5a983dSmrg 109fc5a983dSmrg#define NUM_FORMATS_ALL 6 110fc5a983dSmrg 111fc5a983dSmrgXF86VideoFormatRec NVFormats[NUM_FORMATS_ALL] = 112fc5a983dSmrg{ 113fc5a983dSmrg {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, 114fc5a983dSmrg {15, DirectColor}, {16, DirectColor}, {24, DirectColor} 115fc5a983dSmrg}; 116fc5a983dSmrg 117fc5a983dSmrg#define NUM_OVERLAY_ATTRIBUTES 9 118fc5a983dSmrgXF86AttributeRec NVOverlayAttributes[NUM_OVERLAY_ATTRIBUTES] = 119fc5a983dSmrg{ 120fc5a983dSmrg {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 121fc5a983dSmrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 122fc5a983dSmrg {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 123fc5a983dSmrg {XvSettable , 0, 0, "XV_SET_DEFAULTS"}, 124fc5a983dSmrg {XvSettable | XvGettable, -512, 511, "XV_BRIGHTNESS"}, 125fc5a983dSmrg {XvSettable | XvGettable, 0, 8191, "XV_CONTRAST"}, 126fc5a983dSmrg {XvSettable | XvGettable, 0, 8191, "XV_SATURATION"}, 127fc5a983dSmrg {XvSettable | XvGettable, 0, 360, "XV_HUE"}, 128fc5a983dSmrg {XvSettable | XvGettable, 0, 1, "XV_ITURBT_709"} 129fc5a983dSmrg}; 130fc5a983dSmrg 131fc5a983dSmrg#define NUM_BLIT_ATTRIBUTES 2 132fc5a983dSmrgXF86AttributeRec NVBlitAttributes[NUM_BLIT_ATTRIBUTES] = 133fc5a983dSmrg{ 134fc5a983dSmrg {XvSettable , 0, 0, "XV_SET_DEFAULTS"}, 135fc5a983dSmrg {XvSettable | XvGettable, 0, 1, "XV_SYNC_TO_VBLANK"} 136fc5a983dSmrg}; 137fc5a983dSmrg 138fc5a983dSmrg 139fc5a983dSmrg#define NUM_IMAGES_YUV 4 140fc5a983dSmrg#define NUM_IMAGES_ALL 5 141fc5a983dSmrg 142fc5a983dSmrg#define FOURCC_RGB 0x0000003 143fc5a983dSmrg#define XVIMAGE_RGB \ 144fc5a983dSmrg { \ 145fc5a983dSmrg FOURCC_RGB, \ 146fc5a983dSmrg XvRGB, \ 147fc5a983dSmrg LSBFirst, \ 148fc5a983dSmrg { 0x03, 0x00, 0x00, 0x00, \ 149fc5a983dSmrg 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, \ 150fc5a983dSmrg 32, \ 151fc5a983dSmrg XvPacked, \ 152fc5a983dSmrg 1, \ 153fc5a983dSmrg 24, 0x00ff0000, 0x0000ff00, 0x000000ff, \ 154fc5a983dSmrg 0, 0, 0, \ 155fc5a983dSmrg 0, 0, 0, \ 156fc5a983dSmrg 0, 0, 0, \ 157fc5a983dSmrg {'B','G','R','X',\ 158fc5a983dSmrg 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}, \ 159fc5a983dSmrg XvTopToBottom \ 160fc5a983dSmrg } 161fc5a983dSmrg 162fc5a983dSmrgstatic XF86ImageRec NVImages[NUM_IMAGES_ALL] = 163fc5a983dSmrg{ 164fc5a983dSmrg XVIMAGE_YUY2, 165fc5a983dSmrg XVIMAGE_YV12, 166fc5a983dSmrg XVIMAGE_UYVY, 167fc5a983dSmrg XVIMAGE_I420, 168fc5a983dSmrg XVIMAGE_RGB 169fc5a983dSmrg}; 170fc5a983dSmrg 171fc5a983dSmrgstatic void 172fc5a983dSmrgNVSetPortDefaults (ScrnInfoPtr pScrnInfo, NVPortPrivPtr pPriv) 173fc5a983dSmrg{ 174fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 175fc5a983dSmrg 176fc5a983dSmrg pPriv->brightness = 0; 177fc5a983dSmrg pPriv->contrast = 4096; 178fc5a983dSmrg pPriv->saturation = 4096; 179fc5a983dSmrg pPriv->hue = 0; 180fc5a983dSmrg pPriv->colorKey = pNv->videoKey; 181fc5a983dSmrg pPriv->autopaintColorKey = TRUE; 182fc5a983dSmrg pPriv->doubleBuffer = TRUE; 183fc5a983dSmrg pPriv->iturbt_709 = FALSE; 184fc5a983dSmrg} 185fc5a983dSmrg 186fc5a983dSmrg 187fc5a983dSmrgvoid 188fc5a983dSmrgNVResetVideo (ScrnInfoPtr pScrnInfo) 189fc5a983dSmrg{ 190fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 191fc5a983dSmrg NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 192fc5a983dSmrg int satSine, satCosine; 193fc5a983dSmrg double angle; 194fc5a983dSmrg 195fc5a983dSmrg angle = (double)pPriv->hue * 3.1415927 / 180.0; 196fc5a983dSmrg 197fc5a983dSmrg satSine = pPriv->saturation * sin(angle); 198fc5a983dSmrg if (satSine < -1024) 199fc5a983dSmrg satSine = -1024; 200fc5a983dSmrg satCosine = pPriv->saturation * cos(angle); 201fc5a983dSmrg if (satCosine < -1024) 202fc5a983dSmrg satCosine = -1024; 203fc5a983dSmrg 204fc5a983dSmrg pNv->PMC[0x8910/4] = (pPriv->brightness << 16) | pPriv->contrast; 205fc5a983dSmrg pNv->PMC[0x8914/4] = (pPriv->brightness << 16) | pPriv->contrast; 206fc5a983dSmrg pNv->PMC[0x8918/4] = (satSine << 16) | (satCosine & 0xffff); 207fc5a983dSmrg pNv->PMC[0x891C/4] = (satSine << 16) | (satCosine & 0xffff); 208fc5a983dSmrg pNv->PMC[0x8b00/4] = pPriv->colorKey; 209fc5a983dSmrg} 210fc5a983dSmrg 211fc5a983dSmrg 212fc5a983dSmrg 213fc5a983dSmrgstatic void 214fc5a983dSmrgNVStopOverlay (ScrnInfoPtr pScrnInfo) 215fc5a983dSmrg{ 216fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 217fc5a983dSmrg 218fc5a983dSmrg pNv->PMC[0x00008704/4] = 1; 219fc5a983dSmrg} 220fc5a983dSmrg 221fc5a983dSmrgstatic FBLinearPtr 222fc5a983dSmrgNVAllocateOverlayMemory( 223fc5a983dSmrg ScrnInfoPtr pScrn, 224fc5a983dSmrg FBLinearPtr linear, 225fc5a983dSmrg int size 226fc5a983dSmrg){ 227fc5a983dSmrg ScreenPtr pScreen; 228fc5a983dSmrg FBLinearPtr new_linear; 229fc5a983dSmrg 230fc5a983dSmrg if(linear) { 231fc5a983dSmrg if(linear->size >= size) 232fc5a983dSmrg return linear; 233fc5a983dSmrg 234fc5a983dSmrg if(xf86ResizeOffscreenLinear(linear, size)) 235fc5a983dSmrg return linear; 236fc5a983dSmrg 237fc5a983dSmrg xf86FreeOffscreenLinear(linear); 238fc5a983dSmrg } 239fc5a983dSmrg 240bd304fc0Smrg pScreen = xf86ScrnToScreen(pScrn); 241fc5a983dSmrg 242fc5a983dSmrg new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32, 243fc5a983dSmrg NULL, NULL, NULL); 244fc5a983dSmrg 245fc5a983dSmrg if(!new_linear) { 246fc5a983dSmrg int max_size; 247fc5a983dSmrg 248fc5a983dSmrg xf86QueryLargestOffscreenLinear(pScreen, &max_size, 32, 249fc5a983dSmrg PRIORITY_EXTREME); 250fc5a983dSmrg 251fc5a983dSmrg if(max_size < size) 252fc5a983dSmrg return NULL; 253fc5a983dSmrg 254fc5a983dSmrg xf86PurgeUnlockedOffscreenAreas(pScreen); 255fc5a983dSmrg new_linear = xf86AllocateOffscreenLinear(pScreen, size, 32, 256fc5a983dSmrg NULL, NULL, NULL); 257fc5a983dSmrg } 258fc5a983dSmrg 259fc5a983dSmrg return new_linear; 260fc5a983dSmrg} 261fc5a983dSmrg 262fc5a983dSmrgstatic void NVFreeOverlayMemory(ScrnInfoPtr pScrnInfo) 263fc5a983dSmrg{ 264fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 265fc5a983dSmrg NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 266fc5a983dSmrg 267fc5a983dSmrg if(pPriv->linear) { 268fc5a983dSmrg xf86FreeOffscreenLinear(pPriv->linear); 269fc5a983dSmrg pPriv->linear = NULL; 270fc5a983dSmrg } 271fc5a983dSmrg} 272fc5a983dSmrg 273fc5a983dSmrg 274fc5a983dSmrgstatic void NVFreeBlitMemory(ScrnInfoPtr pScrnInfo) 275fc5a983dSmrg{ 276fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 277fc5a983dSmrg NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); 278fc5a983dSmrg 279fc5a983dSmrg if(pPriv->linear) { 280fc5a983dSmrg xf86FreeOffscreenLinear(pPriv->linear); 281fc5a983dSmrg pPriv->linear = NULL; 282fc5a983dSmrg } 283fc5a983dSmrg} 284fc5a983dSmrg 285fc5a983dSmrg 286fc5a983dSmrgvoid NVInitVideo (ScreenPtr pScreen) 287fc5a983dSmrg{ 288bd304fc0Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 289fc5a983dSmrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 290fc5a983dSmrg XF86VideoAdaptorPtr overlayAdaptor = NULL; 291fc5a983dSmrg XF86VideoAdaptorPtr blitAdaptor = NULL; 292fc5a983dSmrg NVPtr pNv = NVPTR(pScrn); 293fc5a983dSmrg int num_adaptors; 294fc5a983dSmrg 295fc5a983dSmrg if((pScrn->bitsPerPixel != 8) && (pNv->Architecture >= NV_ARCH_10) && 296fc5a983dSmrg ((pNv->Architecture <= NV_ARCH_30) || 297fc5a983dSmrg ((pNv->Chipset & 0xfff0) == 0x0040))) 298fc5a983dSmrg { 299fc5a983dSmrg overlayAdaptor = NVSetupOverlayVideo(pScreen); 300fc5a983dSmrg 301fc5a983dSmrg if(overlayAdaptor) 302fc5a983dSmrg NVInitOffscreenImages(pScreen); 303fc5a983dSmrg } 304fc5a983dSmrg 305fc5a983dSmrg if((pScrn->bitsPerPixel != 8) && !pNv->NoAccel) 306fc5a983dSmrg blitAdaptor = NVSetupBlitVideo(pScreen); 307fc5a983dSmrg 308fc5a983dSmrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 309fc5a983dSmrg 310fc5a983dSmrg if(blitAdaptor || overlayAdaptor) { 311fc5a983dSmrg int size = num_adaptors; 312fc5a983dSmrg 313fc5a983dSmrg if(overlayAdaptor) size++; 314fc5a983dSmrg if(blitAdaptor) size++; 315fc5a983dSmrg 3166086d97eSmrg if((newAdaptors = malloc(size * sizeof(XF86VideoAdaptorPtr*)))) { 317fc5a983dSmrg if(num_adaptors) { 318fc5a983dSmrg memcpy(newAdaptors, adaptors, 319fc5a983dSmrg num_adaptors * sizeof(XF86VideoAdaptorPtr)); 320fc5a983dSmrg } 321fc5a983dSmrg if(overlayAdaptor) { 322fc5a983dSmrg newAdaptors[num_adaptors] = overlayAdaptor; 323fc5a983dSmrg num_adaptors++; 324fc5a983dSmrg } 325fc5a983dSmrg if(blitAdaptor) { 326fc5a983dSmrg newAdaptors[num_adaptors] = blitAdaptor; 327fc5a983dSmrg num_adaptors++; 328fc5a983dSmrg } 329fc5a983dSmrg adaptors = newAdaptors; 330fc5a983dSmrg } 331fc5a983dSmrg } 332fc5a983dSmrg 333fc5a983dSmrg if (num_adaptors) 334fc5a983dSmrg xf86XVScreenInit(pScreen, adaptors, num_adaptors); 335fc5a983dSmrg 336fc5a983dSmrg if (newAdaptors) 3376086d97eSmrg free(newAdaptors); 338fc5a983dSmrg} 339fc5a983dSmrg 340fc5a983dSmrg 341fc5a983dSmrgstatic XF86VideoAdaptorPtr 342fc5a983dSmrgNVSetupBlitVideo (ScreenPtr pScreen) 343fc5a983dSmrg{ 344bd304fc0Smrg ScrnInfoPtr pScrnInfo = xf86ScreenToScrn(pScreen); 345fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 346fc5a983dSmrg XF86VideoAdaptorPtr adapt; 347fc5a983dSmrg NVPortPrivPtr pPriv; 348fc5a983dSmrg int i; 349fc5a983dSmrg 3506086d97eSmrg if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 351fc5a983dSmrg sizeof(NVPortPrivRec) + 352fc5a983dSmrg (sizeof(DevUnion) * NUM_BLIT_PORTS)))) 353fc5a983dSmrg { 354fc5a983dSmrg return NULL; 355fc5a983dSmrg } 356fc5a983dSmrg 357fc5a983dSmrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 358fc5a983dSmrg adapt->flags = 0; 359fc5a983dSmrg adapt->name = "NV Video Blitter"; 360fc5a983dSmrg adapt->nEncodings = 1; 361fc5a983dSmrg adapt->pEncodings = &DummyEncoding; 362fc5a983dSmrg adapt->nFormats = NUM_FORMATS_ALL; 363fc5a983dSmrg adapt->pFormats = NVFormats; 364fc5a983dSmrg adapt->nPorts = NUM_BLIT_PORTS; 365fc5a983dSmrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 366fc5a983dSmrg 367fc5a983dSmrg pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[NUM_BLIT_PORTS]); 368fc5a983dSmrg for(i = 0; i < NUM_BLIT_PORTS; i++) 369fc5a983dSmrg adapt->pPortPrivates[i].ptr = (pointer)(pPriv); 370fc5a983dSmrg 371fc5a983dSmrg if(pNv->WaitVSyncPossible) { 372fc5a983dSmrg adapt->pAttributes = NVBlitAttributes; 373fc5a983dSmrg adapt->nAttributes = NUM_BLIT_ATTRIBUTES; 374fc5a983dSmrg } else { 375fc5a983dSmrg adapt->pAttributes = NULL; 376fc5a983dSmrg adapt->nAttributes = 0; 377fc5a983dSmrg } 378fc5a983dSmrg adapt->pImages = NVImages; 379fc5a983dSmrg adapt->nImages = NUM_IMAGES_ALL; 380fc5a983dSmrg adapt->PutVideo = NULL; 381fc5a983dSmrg adapt->PutStill = NULL; 382fc5a983dSmrg adapt->GetVideo = NULL; 383fc5a983dSmrg adapt->GetStill = NULL; 384fc5a983dSmrg adapt->StopVideo = NVStopBlitVideo; 385fc5a983dSmrg adapt->SetPortAttribute = NVSetBlitPortAttribute; 386fc5a983dSmrg adapt->GetPortAttribute = NVGetBlitPortAttribute; 387fc5a983dSmrg adapt->QueryBestSize = NVQueryBestSize; 388fc5a983dSmrg adapt->PutImage = NVPutImage; 389fc5a983dSmrg adapt->QueryImageAttributes = NVQueryImageAttributes; 390fc5a983dSmrg 391fc5a983dSmrg pPriv->videoStatus = 0; 392fc5a983dSmrg pPriv->grabbedByV4L = FALSE; 393fc5a983dSmrg pPriv->blitter = TRUE; 394fc5a983dSmrg pPriv->doubleBuffer = FALSE; 395fc5a983dSmrg pPriv->SyncToVBlank = pNv->WaitVSyncPossible; 396fc5a983dSmrg 397fc5a983dSmrg pNv->blitAdaptor = adapt; 398fc5a983dSmrg 399fc5a983dSmrg xvSyncToVBlank = MAKE_ATOM("XV_SYNC_TO_VBLANK"); 400fc5a983dSmrg 401fc5a983dSmrg return adapt; 402fc5a983dSmrg} 403fc5a983dSmrg 404fc5a983dSmrgstatic XF86VideoAdaptorPtr 405fc5a983dSmrgNVSetupOverlayVideo (ScreenPtr pScreen) 406fc5a983dSmrg{ 407bd304fc0Smrg ScrnInfoPtr pScrnInfo = xf86ScreenToScrn(pScreen); 408fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 409fc5a983dSmrg XF86VideoAdaptorPtr adapt; 410fc5a983dSmrg NVPortPrivPtr pPriv; 411fc5a983dSmrg 4126086d97eSmrg if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 413fc5a983dSmrg sizeof(NVPortPrivRec) + 414fc5a983dSmrg sizeof(DevUnion)))) 415fc5a983dSmrg { 416fc5a983dSmrg return NULL; 417fc5a983dSmrg } 418fc5a983dSmrg 419fc5a983dSmrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 420fc5a983dSmrg adapt->flags = VIDEO_OVERLAID_IMAGES|VIDEO_CLIP_TO_VIEWPORT; 421fc5a983dSmrg adapt->name = "NV Video Overlay"; 422fc5a983dSmrg adapt->nEncodings = 1; 423fc5a983dSmrg adapt->pEncodings = &DummyEncoding; 424fc5a983dSmrg adapt->nFormats = NUM_FORMATS_ALL; 425fc5a983dSmrg adapt->pFormats = NVFormats; 426fc5a983dSmrg adapt->nPorts = 1; 427fc5a983dSmrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 428fc5a983dSmrg pPriv = (NVPortPrivPtr)(&adapt->pPortPrivates[1]); 429fc5a983dSmrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 430fc5a983dSmrg adapt->pAttributes = NVOverlayAttributes; 431fc5a983dSmrg adapt->nAttributes = NUM_OVERLAY_ATTRIBUTES; 432fc5a983dSmrg adapt->pImages = NVImages; 433fc5a983dSmrg adapt->nImages = NUM_IMAGES_YUV; 434fc5a983dSmrg adapt->PutVideo = NULL; 435fc5a983dSmrg adapt->PutStill = NULL; 436fc5a983dSmrg adapt->GetVideo = NULL; 437fc5a983dSmrg adapt->GetStill = NULL; 438fc5a983dSmrg adapt->StopVideo = NVStopOverlayVideo; 439fc5a983dSmrg adapt->SetPortAttribute = NVSetOverlayPortAttribute; 440fc5a983dSmrg adapt->GetPortAttribute = NVGetOverlayPortAttribute; 441fc5a983dSmrg adapt->QueryBestSize = NVQueryBestSize; 442fc5a983dSmrg adapt->PutImage = NVPutImage; 443fc5a983dSmrg adapt->QueryImageAttributes = NVQueryImageAttributes; 444fc5a983dSmrg 445fc5a983dSmrg pPriv->videoStatus = 0; 446fc5a983dSmrg pPriv->currentBuffer = 0; 447fc5a983dSmrg pPriv->grabbedByV4L = FALSE; 448fc5a983dSmrg pPriv->blitter = FALSE; 449fc5a983dSmrg 450fc5a983dSmrg NVSetPortDefaults (pScrnInfo, pPriv); 451fc5a983dSmrg 452fc5a983dSmrg /* gotta uninit this someplace */ 453fc5a983dSmrg REGION_NULL(pScreen, &pPriv->clip); 454fc5a983dSmrg 455fc5a983dSmrg pNv->overlayAdaptor = adapt; 456fc5a983dSmrg 457fc5a983dSmrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 458fc5a983dSmrg xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 459fc5a983dSmrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 460fc5a983dSmrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 461fc5a983dSmrg xvSaturation = MAKE_ATOM("XV_SATURATION"); 462fc5a983dSmrg xvHue = MAKE_ATOM("XV_HUE"); 463fc5a983dSmrg xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 464fc5a983dSmrg xvSetDefaults = MAKE_ATOM("XV_SET_DEFAULTS"); 465fc5a983dSmrg xvITURBT709 = MAKE_ATOM("XV_ITURBT_709"); 466fc5a983dSmrg 467fc5a983dSmrg NVResetVideo(pScrnInfo); 468fc5a983dSmrg 469fc5a983dSmrg return adapt; 470fc5a983dSmrg} 471fc5a983dSmrg 472fc5a983dSmrgstatic void 473fc5a983dSmrgNVPutOverlayImage ( 474fc5a983dSmrg ScrnInfoPtr pScrnInfo, 475fc5a983dSmrg int offset, 476fc5a983dSmrg int id, 477fc5a983dSmrg int dstPitch, 478fc5a983dSmrg BoxPtr dstBox, 479fc5a983dSmrg int x1, 480fc5a983dSmrg int y1, 481fc5a983dSmrg int x2, 482fc5a983dSmrg int y2, 483fc5a983dSmrg short width, 484fc5a983dSmrg short height, 485fc5a983dSmrg short src_w, 486fc5a983dSmrg short src_h, 487fc5a983dSmrg short drw_w, 488fc5a983dSmrg short drw_h, 489fc5a983dSmrg RegionPtr clipBoxes 490fc5a983dSmrg) 491fc5a983dSmrg{ 492fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 493fc5a983dSmrg NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 494fc5a983dSmrg int buffer = pPriv->currentBuffer; 495fc5a983dSmrg 496fc5a983dSmrg /* paint the color key */ 497fc5a983dSmrg if(pPriv->autopaintColorKey && 498fc5a983dSmrg (pPriv->grabbedByV4L || 499fc5a983dSmrg !REGION_EQUAL(pScrnInfo->pScreen, &pPriv->clip, clipBoxes))) 500fc5a983dSmrg { 501fc5a983dSmrg /* we always paint V4L's color key */ 502fc5a983dSmrg if(!pPriv->grabbedByV4L) 503fc5a983dSmrg REGION_COPY(pScrnInfo->pScreen, &pPriv->clip, clipBoxes); 504fc5a983dSmrg xf86XVFillKeyHelper(pScrnInfo->pScreen, pPriv->colorKey, clipBoxes); 505fc5a983dSmrg } 506fc5a983dSmrg 507fc5a983dSmrg if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) { 508fc5a983dSmrg dstBox->y1 <<= 1; 509fc5a983dSmrg dstBox->y2 <<= 1; 510fc5a983dSmrg drw_h <<= 1; 511fc5a983dSmrg } 512fc5a983dSmrg 513fc5a983dSmrg pNv->PMC[(0x8900/4) + buffer] = offset; 514fc5a983dSmrg pNv->PMC[(0x8928/4) + buffer] = (height << 16) | width; 515fc5a983dSmrg pNv->PMC[(0x8930/4) + buffer] = ((y1 << 4) & 0xffff0000) | (x1 >> 12); 516fc5a983dSmrg pNv->PMC[(0x8938/4) + buffer] = (src_w << 20) / drw_w; 517fc5a983dSmrg pNv->PMC[(0x8940/4) + buffer] = (src_h << 20) / drw_h; 518fc5a983dSmrg pNv->PMC[(0x8948/4) + buffer] = (dstBox->y1 << 16) | dstBox->x1; 519fc5a983dSmrg pNv->PMC[(0x8950/4) + buffer] = ((dstBox->y2 - dstBox->y1) << 16) | 520fc5a983dSmrg (dstBox->x2 - dstBox->x1); 521fc5a983dSmrg 522fc5a983dSmrg dstPitch |= 1 << 20; /* use color key */ 523fc5a983dSmrg 524fc5a983dSmrg if(id != FOURCC_UYVY) 525fc5a983dSmrg dstPitch |= 1 << 16; 526fc5a983dSmrg if(pPriv->iturbt_709) 527fc5a983dSmrg dstPitch |= 1 << 24; 528fc5a983dSmrg 529fc5a983dSmrg pNv->PMC[(0x8958/4) + buffer] = dstPitch; 530fc5a983dSmrg pNv->PMC[0x00008704/4] = 0; 531fc5a983dSmrg pNv->PMC[0x8700/4] = 1 << (buffer << 2); 532fc5a983dSmrg 533fc5a983dSmrg pPriv->videoStatus = CLIENT_VIDEO_ON; 534fc5a983dSmrg} 535fc5a983dSmrg 536fc5a983dSmrg 537fc5a983dSmrg 538fc5a983dSmrgstatic void 539fc5a983dSmrgNVPutBlitImage ( 540fc5a983dSmrg ScrnInfoPtr pScrnInfo, 541fc5a983dSmrg int offset, 542fc5a983dSmrg int id, 543fc5a983dSmrg int dstPitch, 544fc5a983dSmrg BoxPtr dstBox, 545fc5a983dSmrg int x1, 546fc5a983dSmrg int y1, 547fc5a983dSmrg int x2, 548fc5a983dSmrg int y2, 549fc5a983dSmrg short width, 550fc5a983dSmrg short height, 551fc5a983dSmrg short src_w, 552fc5a983dSmrg short src_h, 553fc5a983dSmrg short drw_w, 554fc5a983dSmrg short drw_h, 555fc5a983dSmrg RegionPtr clipBoxes 556fc5a983dSmrg) 557fc5a983dSmrg{ 558fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 559fc5a983dSmrg NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); 560fc5a983dSmrg BoxPtr pbox = REGION_RECTS(clipBoxes); 561fc5a983dSmrg int nbox = REGION_NUM_RECTS(clipBoxes); 562fc5a983dSmrg CARD32 dsdx, dtdy, size, point, srcpoint, format; 563fc5a983dSmrg 564fc5a983dSmrg dsdx = (src_w << 20) / drw_w; 565fc5a983dSmrg dtdy = (src_h << 20) / drw_h; 566fc5a983dSmrg 567fc5a983dSmrg size = ((dstBox->y2 - dstBox->y1) << 16) | (dstBox->x2 - dstBox->x1); 568fc5a983dSmrg point = (dstBox->y1 << 16) | dstBox->x1; 569fc5a983dSmrg 570fc5a983dSmrg dstPitch |= (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CENTER << 16) | 571fc5a983dSmrg (STRETCH_BLIT_SRC_FORMAT_FILTER_BILINEAR << 24); 572fc5a983dSmrg 573fc5a983dSmrg srcpoint = ((y1 << 4) & 0xffff0000) | (x1 >> 12); 574fc5a983dSmrg 575fc5a983dSmrg switch(id) { 576fc5a983dSmrg case FOURCC_RGB: 577fc5a983dSmrg format = STRETCH_BLIT_FORMAT_X8R8G8B8; 578fc5a983dSmrg break; 579fc5a983dSmrg case FOURCC_UYVY: 580fc5a983dSmrg format = STRETCH_BLIT_FORMAT_UYVY; 581fc5a983dSmrg break; 582fc5a983dSmrg default: 583fc5a983dSmrg format = STRETCH_BLIT_FORMAT_YUYV; 584fc5a983dSmrg break; 585fc5a983dSmrg } 586fc5a983dSmrg 587fc5a983dSmrg if(pNv->CurrentLayout.depth == 15) { 588fc5a983dSmrg NVDmaStart(pNv, SURFACE_FORMAT, 1); 589fc5a983dSmrg NVDmaNext (pNv, SURFACE_FORMAT_DEPTH15); 590fc5a983dSmrg } 591fc5a983dSmrg 592fc5a983dSmrg if(pPriv->SyncToVBlank) { 593fc5a983dSmrg NVDmaKickoff(pNv); 594fc5a983dSmrg NVWaitVSync(pNv); 595fc5a983dSmrg } 596fc5a983dSmrg 597fc5a983dSmrg if(pNv->BlendingPossible) { 598fc5a983dSmrg NVDmaStart(pNv, STRETCH_BLIT_FORMAT, 2); 599fc5a983dSmrg NVDmaNext (pNv, format); 600fc5a983dSmrg NVDmaNext (pNv, STRETCH_BLIT_OPERATION_COPY); 601fc5a983dSmrg } else { 602fc5a983dSmrg NVDmaStart(pNv, STRETCH_BLIT_FORMAT, 1); 603fc5a983dSmrg NVDmaNext (pNv, format); 604fc5a983dSmrg } 605fc5a983dSmrg 606fc5a983dSmrg while(nbox--) { 607fc5a983dSmrg NVDmaStart(pNv, RECT_SOLID_COLOR, 1); 608fc5a983dSmrg NVDmaNext (pNv, 0); 609fc5a983dSmrg 610fc5a983dSmrg NVDmaStart(pNv, STRETCH_BLIT_CLIP_POINT, 6); 611fc5a983dSmrg NVDmaNext (pNv, (pbox->y1 << 16) | pbox->x1); 612fc5a983dSmrg NVDmaNext (pNv, ((pbox->y2 - pbox->y1) << 16) | (pbox->x2 - pbox->x1)); 613fc5a983dSmrg NVDmaNext (pNv, point); 614fc5a983dSmrg NVDmaNext (pNv, size); 615fc5a983dSmrg NVDmaNext (pNv, dsdx); 616fc5a983dSmrg NVDmaNext (pNv, dtdy); 617fc5a983dSmrg 618fc5a983dSmrg NVDmaStart(pNv, STRETCH_BLIT_SRC_SIZE, 4); 619fc5a983dSmrg NVDmaNext (pNv, (height << 16) | width); 620fc5a983dSmrg NVDmaNext (pNv, dstPitch); 621fc5a983dSmrg NVDmaNext (pNv, offset); 622fc5a983dSmrg NVDmaNext (pNv, srcpoint); 623fc5a983dSmrg pbox++; 624fc5a983dSmrg } 625fc5a983dSmrg 626fc5a983dSmrg if(pNv->CurrentLayout.depth == 15) { 627fc5a983dSmrg NVDmaStart(pNv, SURFACE_FORMAT, 1); 628fc5a983dSmrg NVDmaNext (pNv, SURFACE_FORMAT_DEPTH16); 629fc5a983dSmrg } 630fc5a983dSmrg 631fc5a983dSmrg NVDmaKickoff(pNv); 632bd304fc0Smrg#ifdef HAVE_XAA_H 633fc5a983dSmrg SET_SYNC_FLAG(pNv->AccelInfoRec); 634bd304fc0Smrg#endif 635fc5a983dSmrg pPriv->videoStatus = FREE_TIMER; 636fc5a983dSmrg pPriv->videoTime = currentTime.milliseconds + FREE_DELAY; 637fc5a983dSmrg pNv->VideoTimerCallback = NVVideoTimerCallback; 638fc5a983dSmrg} 639fc5a983dSmrg 640fc5a983dSmrg/* 641fc5a983dSmrg * StopVideo 642fc5a983dSmrg */ 643fc5a983dSmrgstatic void NVStopOverlayVideo 644fc5a983dSmrg( 645fc5a983dSmrg ScrnInfoPtr pScrnInfo, 646fc5a983dSmrg pointer data, 647fc5a983dSmrg Bool Exit 648fc5a983dSmrg) 649fc5a983dSmrg{ 650fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 651fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 652fc5a983dSmrg 653fc5a983dSmrg if(pPriv->grabbedByV4L) return; 654fc5a983dSmrg 655fc5a983dSmrg REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip); 656fc5a983dSmrg 657fc5a983dSmrg if(Exit) { 658fc5a983dSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) 659fc5a983dSmrg NVStopOverlay(pScrnInfo); 660fc5a983dSmrg NVFreeOverlayMemory(pScrnInfo); 661fc5a983dSmrg pPriv->videoStatus = 0; 662fc5a983dSmrg } else { 663fc5a983dSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 664fc5a983dSmrg pPriv->videoStatus = OFF_TIMER | CLIENT_VIDEO_ON; 665fc5a983dSmrg pPriv->videoTime = currentTime.milliseconds + OFF_DELAY; 666fc5a983dSmrg pNv->VideoTimerCallback = NVVideoTimerCallback; 667fc5a983dSmrg } 668fc5a983dSmrg } 669fc5a983dSmrg} 670fc5a983dSmrg 671fc5a983dSmrgstatic void NVStopBlitVideo 672fc5a983dSmrg( 673fc5a983dSmrg ScrnInfoPtr pScrnInfo, 674fc5a983dSmrg pointer data, 675fc5a983dSmrg Bool Exit 676fc5a983dSmrg) 677fc5a983dSmrg{ 678fc5a983dSmrg} 679fc5a983dSmrg 680fc5a983dSmrgstatic int NVSetOverlayPortAttribute 681fc5a983dSmrg( 682fc5a983dSmrg ScrnInfoPtr pScrnInfo, 683fc5a983dSmrg Atom attribute, 684fc5a983dSmrg INT32 value, 685fc5a983dSmrg pointer data 686fc5a983dSmrg) 687fc5a983dSmrg{ 688fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 689fc5a983dSmrg 690fc5a983dSmrg if (attribute == xvBrightness) 691fc5a983dSmrg { 692fc5a983dSmrg if ((value < -512) || (value > 512)) 693fc5a983dSmrg return BadValue; 694fc5a983dSmrg pPriv->brightness = value; 695fc5a983dSmrg } 696fc5a983dSmrg else if (attribute == xvDoubleBuffer) 697fc5a983dSmrg { 698fc5a983dSmrg if ((value < 0) || (value > 1)) 699fc5a983dSmrg return BadValue; 700fc5a983dSmrg pPriv->doubleBuffer = value; 701fc5a983dSmrg } 702fc5a983dSmrg else if (attribute == xvContrast) 703fc5a983dSmrg { 704fc5a983dSmrg if ((value < 0) || (value > 8191)) 705fc5a983dSmrg return BadValue; 706fc5a983dSmrg pPriv->contrast = value; 707fc5a983dSmrg } 708fc5a983dSmrg else if (attribute == xvHue) 709fc5a983dSmrg { 710fc5a983dSmrg value %= 360; 711fc5a983dSmrg if (value < 0) 712fc5a983dSmrg value += 360; 713fc5a983dSmrg pPriv->hue = value; 714fc5a983dSmrg } 715fc5a983dSmrg else if (attribute == xvSaturation) 716fc5a983dSmrg { 717fc5a983dSmrg if ((value < 0) || (value > 8191)) 718fc5a983dSmrg return BadValue; 719fc5a983dSmrg pPriv->saturation = value; 720fc5a983dSmrg } 721fc5a983dSmrg else if (attribute == xvColorKey) 722fc5a983dSmrg { 723fc5a983dSmrg pPriv->colorKey = value; 724fc5a983dSmrg REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip); 725fc5a983dSmrg } 726fc5a983dSmrg else if (attribute == xvAutopaintColorKey) 727fc5a983dSmrg { 728fc5a983dSmrg if ((value < 0) || (value > 1)) 729fc5a983dSmrg return BadValue; 730fc5a983dSmrg pPriv->autopaintColorKey = value; 731fc5a983dSmrg } 732fc5a983dSmrg else if (attribute == xvITURBT709) 733fc5a983dSmrg { 734fc5a983dSmrg if ((value < 0) || (value > 1)) 735fc5a983dSmrg return BadValue; 736fc5a983dSmrg pPriv->iturbt_709 = value; 737fc5a983dSmrg } 738fc5a983dSmrg else if (attribute == xvSetDefaults) 739fc5a983dSmrg { 740fc5a983dSmrg NVSetPortDefaults(pScrnInfo, pPriv); 741fc5a983dSmrg } 742fc5a983dSmrg else 743fc5a983dSmrg return BadMatch; 744fc5a983dSmrg 745fc5a983dSmrg NVResetVideo(pScrnInfo); 746fc5a983dSmrg return Success; 747fc5a983dSmrg} 748fc5a983dSmrg 749fc5a983dSmrg 750fc5a983dSmrgstatic int NVGetOverlayPortAttribute 751fc5a983dSmrg( 752fc5a983dSmrg ScrnInfoPtr pScrnInfo, 753fc5a983dSmrg Atom attribute, 754fc5a983dSmrg INT32 *value, 755fc5a983dSmrg pointer data 756fc5a983dSmrg) 757fc5a983dSmrg{ 758fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 759fc5a983dSmrg 760fc5a983dSmrg if (attribute == xvBrightness) 761fc5a983dSmrg *value = pPriv->brightness; 762fc5a983dSmrg else if (attribute == xvDoubleBuffer) 763fc5a983dSmrg *value = (pPriv->doubleBuffer) ? 1 : 0; 764fc5a983dSmrg else if (attribute == xvContrast) 765fc5a983dSmrg *value = pPriv->contrast; 766fc5a983dSmrg else if (attribute == xvSaturation) 767fc5a983dSmrg *value = pPriv->saturation; 768fc5a983dSmrg else if (attribute == xvHue) 769fc5a983dSmrg *value = pPriv->hue; 770fc5a983dSmrg else if (attribute == xvColorKey) 771fc5a983dSmrg *value = pPriv->colorKey; 772fc5a983dSmrg else if (attribute == xvAutopaintColorKey) 773fc5a983dSmrg *value = (pPriv->autopaintColorKey) ? 1 : 0; 774fc5a983dSmrg else if (attribute == xvITURBT709) 775fc5a983dSmrg *value = (pPriv->iturbt_709) ? 1 : 0; 776fc5a983dSmrg else 777fc5a983dSmrg return BadMatch; 778fc5a983dSmrg 779fc5a983dSmrg return Success; 780fc5a983dSmrg} 781fc5a983dSmrg 782fc5a983dSmrgstatic int NVSetBlitPortAttribute 783fc5a983dSmrg( 784fc5a983dSmrg ScrnInfoPtr pScrnInfo, 785fc5a983dSmrg Atom attribute, 786fc5a983dSmrg INT32 value, 787fc5a983dSmrg pointer data 788fc5a983dSmrg) 789fc5a983dSmrg{ 790fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 791fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 792fc5a983dSmrg 793fc5a983dSmrg if ((attribute == xvSyncToVBlank) && pNv->WaitVSyncPossible) { 794fc5a983dSmrg if ((value < 0) || (value > 1)) 795fc5a983dSmrg return BadValue; 796fc5a983dSmrg pPriv->SyncToVBlank = value; 797fc5a983dSmrg } else 798fc5a983dSmrg if (attribute == xvSetDefaults) { 799fc5a983dSmrg pPriv->SyncToVBlank = pNv->WaitVSyncPossible; 800fc5a983dSmrg } else 801fc5a983dSmrg return BadMatch; 802fc5a983dSmrg 803fc5a983dSmrg return Success; 804fc5a983dSmrg} 805fc5a983dSmrg 806fc5a983dSmrgstatic int NVGetBlitPortAttribute 807fc5a983dSmrg( 808fc5a983dSmrg ScrnInfoPtr pScrnInfo, 809fc5a983dSmrg Atom attribute, 810fc5a983dSmrg INT32 *value, 811fc5a983dSmrg pointer data 812fc5a983dSmrg) 813fc5a983dSmrg{ 814fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 815fc5a983dSmrg 816fc5a983dSmrg if(attribute == xvSyncToVBlank) 817fc5a983dSmrg *value = (pPriv->SyncToVBlank) ? 1 : 0; 818fc5a983dSmrg else 819fc5a983dSmrg return BadMatch; 820fc5a983dSmrg 821fc5a983dSmrg return Success; 822fc5a983dSmrg} 823fc5a983dSmrg 824fc5a983dSmrg 825fc5a983dSmrg/* 826fc5a983dSmrg * QueryBestSize 827fc5a983dSmrg */ 828fc5a983dSmrgstatic void NVQueryBestSize 829fc5a983dSmrg( 830fc5a983dSmrg ScrnInfoPtr pScrnInfo, 831fc5a983dSmrg Bool motion, 832fc5a983dSmrg short vid_w, 833fc5a983dSmrg short vid_h, 834fc5a983dSmrg short drw_w, 835fc5a983dSmrg short drw_h, 836fc5a983dSmrg unsigned int *p_w, 837fc5a983dSmrg unsigned int *p_h, 838fc5a983dSmrg pointer data 839fc5a983dSmrg) 840fc5a983dSmrg{ 841fc5a983dSmrg if(vid_w > (drw_w << 3)) 842fc5a983dSmrg drw_w = vid_w >> 3; 843fc5a983dSmrg if(vid_h > (drw_h << 3)) 844fc5a983dSmrg drw_h = vid_h >> 3; 845fc5a983dSmrg 846fc5a983dSmrg *p_w = drw_w; 847fc5a983dSmrg *p_h = drw_h; 848fc5a983dSmrg} 849fc5a983dSmrg 850fc5a983dSmrgstatic void NVCopyData420 851fc5a983dSmrg( 852fc5a983dSmrg unsigned char *src1, 853fc5a983dSmrg unsigned char *src2, 854fc5a983dSmrg unsigned char *src3, 855fc5a983dSmrg unsigned char *dst1, 856fc5a983dSmrg int srcPitch, 857fc5a983dSmrg int srcPitch2, 858fc5a983dSmrg int dstPitch, 859fc5a983dSmrg int h, 860fc5a983dSmrg int w 861fc5a983dSmrg) 862fc5a983dSmrg{ 863fc5a983dSmrg CARD32 *dst; 864fc5a983dSmrg CARD8 *s1, *s2, *s3; 865fc5a983dSmrg int i, j; 866fc5a983dSmrg 867fc5a983dSmrg w >>= 1; 868fc5a983dSmrg 869fc5a983dSmrg for(j = 0; j < h; j++) { 870fc5a983dSmrg dst = (CARD32*)dst1; 871fc5a983dSmrg s1 = src1; s2 = src2; s3 = src3; 872fc5a983dSmrg i = w; 873fc5a983dSmrg while(i > 4) { 874fc5a983dSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 875fc5a983dSmrg dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0]; 876fc5a983dSmrg dst[1] = (s1[2] << 24) | (s1[3] << 8) | (s3[1] << 16) | s2[1]; 877fc5a983dSmrg dst[2] = (s1[4] << 24) | (s1[5] << 8) | (s3[2] << 16) | s2[2]; 878fc5a983dSmrg dst[3] = (s1[6] << 24) | (s1[7] << 8) | (s3[3] << 16) | s2[3]; 879fc5a983dSmrg#else 880fc5a983dSmrg dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 881fc5a983dSmrg dst[1] = s1[2] | (s1[3] << 16) | (s3[1] << 8) | (s2[1] << 24); 882fc5a983dSmrg dst[2] = s1[4] | (s1[5] << 16) | (s3[2] << 8) | (s2[2] << 24); 883fc5a983dSmrg dst[3] = s1[6] | (s1[7] << 16) | (s3[3] << 8) | (s2[3] << 24); 884fc5a983dSmrg#endif 885fc5a983dSmrg dst += 4; s2 += 4; s3 += 4; s1 += 8; 886fc5a983dSmrg i -= 4; 887fc5a983dSmrg } 888fc5a983dSmrg 889fc5a983dSmrg while(i--) { 890fc5a983dSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 891fc5a983dSmrg dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0]; 892fc5a983dSmrg#else 893fc5a983dSmrg dst[0] = s1[0] | (s1[1] << 16) | (s3[0] << 8) | (s2[0] << 24); 894fc5a983dSmrg#endif 895fc5a983dSmrg dst++; s2++; s3++; 896fc5a983dSmrg s1 += 2; 897fc5a983dSmrg } 898fc5a983dSmrg 899fc5a983dSmrg dst1 += dstPitch; 900fc5a983dSmrg src1 += srcPitch; 901fc5a983dSmrg if(j & 1) { 902fc5a983dSmrg src2 += srcPitch2; 903fc5a983dSmrg src3 += srcPitch2; 904fc5a983dSmrg } 905fc5a983dSmrg } 906fc5a983dSmrg} 907fc5a983dSmrg 908fc5a983dSmrg 909fc5a983dSmrgstatic void NVMoveDWORDS( 910fc5a983dSmrg CARD32* dest, 911fc5a983dSmrg CARD32* src, 912fc5a983dSmrg int dwords ) 913fc5a983dSmrg{ 914fc5a983dSmrg while(dwords & ~0x03) { 915fc5a983dSmrg *dest = *src; 916fc5a983dSmrg *(dest + 1) = *(src + 1); 917fc5a983dSmrg *(dest + 2) = *(src + 2); 918fc5a983dSmrg *(dest + 3) = *(src + 3); 919fc5a983dSmrg src += 4; 920fc5a983dSmrg dest += 4; 921fc5a983dSmrg dwords -= 4; 922fc5a983dSmrg } 923fc5a983dSmrg if(!dwords) return; 924fc5a983dSmrg *dest = *src; 925fc5a983dSmrg if(dwords == 1) return; 926fc5a983dSmrg *(dest + 1) = *(src + 1); 927fc5a983dSmrg if(dwords == 2) return; 928fc5a983dSmrg *(dest + 2) = *(src + 2); 929fc5a983dSmrg} 930fc5a983dSmrg 931fc5a983dSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 932fc5a983dSmrgstatic void NVMoveDWORDSSwapped( 933fc5a983dSmrg CARD32* dest, 934fc5a983dSmrg CARD8* src, 935fc5a983dSmrg int dwords ) 936fc5a983dSmrg{ 937fc5a983dSmrg while(dwords--) { 938fc5a983dSmrg *dest++ = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; 939fc5a983dSmrg src += 4; 940fc5a983dSmrg } 941fc5a983dSmrg} 942fc5a983dSmrg#endif 943fc5a983dSmrg 944fc5a983dSmrgstatic void NVCopyData422 945fc5a983dSmrg( 946fc5a983dSmrg unsigned char *src, 947fc5a983dSmrg unsigned char *dst, 948fc5a983dSmrg int srcPitch, 949fc5a983dSmrg int dstPitch, 950fc5a983dSmrg int h, 951fc5a983dSmrg int w 952fc5a983dSmrg) 953fc5a983dSmrg{ 954fc5a983dSmrg w >>= 1; /* pixels to DWORDS */ 955fc5a983dSmrg while(h--) { 956fc5a983dSmrg NVMoveDWORDS((CARD32*)dst, (CARD32*)src, w); 957fc5a983dSmrg src += srcPitch; 958fc5a983dSmrg dst += dstPitch; 959fc5a983dSmrg } 960fc5a983dSmrg} 961fc5a983dSmrg 962fc5a983dSmrgstatic void NVCopyDataRGB 963fc5a983dSmrg( 964fc5a983dSmrg unsigned char *src, 965fc5a983dSmrg unsigned char *dst, 966fc5a983dSmrg int srcPitch, 967fc5a983dSmrg int dstPitch, 968fc5a983dSmrg int h, 969fc5a983dSmrg int w 970fc5a983dSmrg) 971fc5a983dSmrg{ 972fc5a983dSmrg while(h--) { 973fc5a983dSmrg#if X_BYTE_ORDER == X_BIG_ENDIAN 974fc5a983dSmrg NVMoveDWORDSSwapped((CARD32*)dst, (CARD8*)src, w); 975fc5a983dSmrg#else 976fc5a983dSmrg NVMoveDWORDS((CARD32*)dst, (CARD32*)src, w); 977fc5a983dSmrg#endif 978fc5a983dSmrg src += srcPitch; 979fc5a983dSmrg dst += dstPitch; 980fc5a983dSmrg } 981fc5a983dSmrg} 982fc5a983dSmrg 983fc5a983dSmrg 984fc5a983dSmrg/* 985fc5a983dSmrg * PutImage 986fc5a983dSmrg */ 987fc5a983dSmrgstatic int NVPutImage 988fc5a983dSmrg( 989fc5a983dSmrg ScrnInfoPtr pScrnInfo, 990fc5a983dSmrg short src_x, 991fc5a983dSmrg short src_y, 992fc5a983dSmrg short drw_x, 993fc5a983dSmrg short drw_y, 994fc5a983dSmrg short src_w, 995fc5a983dSmrg short src_h, 996fc5a983dSmrg short drw_w, 997fc5a983dSmrg short drw_h, 998fc5a983dSmrg int id, 999fc5a983dSmrg unsigned char *buf, 1000fc5a983dSmrg short width, 1001fc5a983dSmrg short height, 1002fc5a983dSmrg Bool Sync, 1003fc5a983dSmrg RegionPtr clipBoxes, 1004fc5a983dSmrg pointer data, 1005fc5a983dSmrg DrawablePtr pDraw 1006fc5a983dSmrg) 1007fc5a983dSmrg{ 1008fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)data; 1009fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 1010fc5a983dSmrg INT32 xa, xb, ya, yb; 1011fc5a983dSmrg unsigned char *dst_start; 1012fc5a983dSmrg int newSize, offset, s2offset, s3offset; 1013fc5a983dSmrg int srcPitch, srcPitch2, dstPitch; 1014fc5a983dSmrg int top, left, right, bottom, npixels, nlines, bpp; 1015fc5a983dSmrg Bool skip = FALSE; 1016fc5a983dSmrg BoxRec dstBox; 1017fc5a983dSmrg CARD32 tmp; 1018fc5a983dSmrg 1019fc5a983dSmrg /* 1020fc5a983dSmrg * s2offset, s3offset - byte offsets into U and V plane of the 1021fc5a983dSmrg * source where copying starts. Y plane is 1022fc5a983dSmrg * done by editing "buf". 1023fc5a983dSmrg * 1024fc5a983dSmrg * offset - byte offset to the first line of the destination. 1025fc5a983dSmrg * 1026fc5a983dSmrg * dst_start - byte address to the first displayed pel. 1027fc5a983dSmrg * 1028fc5a983dSmrg */ 1029fc5a983dSmrg 1030fc5a983dSmrg if(pPriv->grabbedByV4L) return Success; 1031fc5a983dSmrg 1032fc5a983dSmrg /* make the compiler happy */ 1033fc5a983dSmrg s2offset = s3offset = srcPitch2 = 0; 1034fc5a983dSmrg 1035fc5a983dSmrg if(!pPriv->blitter) { 1036fc5a983dSmrg if(src_w > (drw_w << 3)) 1037fc5a983dSmrg drw_w = src_w >> 3; 1038fc5a983dSmrg if(src_h > (drw_h << 3)) 1039fc5a983dSmrg drw_h = src_h >> 3; 1040fc5a983dSmrg } 1041fc5a983dSmrg 1042fc5a983dSmrg /* Clip */ 1043fc5a983dSmrg xa = src_x; 1044fc5a983dSmrg xb = src_x + src_w; 1045fc5a983dSmrg ya = src_y; 1046fc5a983dSmrg yb = src_y + src_h; 1047fc5a983dSmrg 1048fc5a983dSmrg dstBox.x1 = drw_x; 1049fc5a983dSmrg dstBox.x2 = drw_x + drw_w; 1050fc5a983dSmrg dstBox.y1 = drw_y; 1051fc5a983dSmrg dstBox.y2 = drw_y + drw_h; 1052fc5a983dSmrg 1053fc5a983dSmrg if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, 1054fc5a983dSmrg width, height)) 1055fc5a983dSmrg return Success; 1056fc5a983dSmrg 1057fc5a983dSmrg if(!pPriv->blitter) { 1058fc5a983dSmrg dstBox.x1 -= pScrnInfo->frameX0; 1059fc5a983dSmrg dstBox.x2 -= pScrnInfo->frameX0; 1060fc5a983dSmrg dstBox.y1 -= pScrnInfo->frameY0; 1061fc5a983dSmrg dstBox.y2 -= pScrnInfo->frameY0; 1062fc5a983dSmrg } 1063fc5a983dSmrg 1064fc5a983dSmrg bpp = pScrnInfo->bitsPerPixel >> 3; 1065fc5a983dSmrg 1066fc5a983dSmrg switch(id) { 1067fc5a983dSmrg case FOURCC_YV12: 1068fc5a983dSmrg case FOURCC_I420: 1069fc5a983dSmrg srcPitch = (width + 3) & ~3; /* of luma */ 1070fc5a983dSmrg s2offset = srcPitch * height; 1071fc5a983dSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 1072fc5a983dSmrg s3offset = (srcPitch2 * (height >> 1)) + s2offset; 1073fc5a983dSmrg dstPitch = ((width << 1) + 63) & ~63; 1074fc5a983dSmrg break; 1075fc5a983dSmrg case FOURCC_UYVY: 1076fc5a983dSmrg case FOURCC_YUY2: 1077fc5a983dSmrg srcPitch = width << 1; 1078fc5a983dSmrg dstPitch = ((width << 1) + 63) & ~63; 1079fc5a983dSmrg break; 1080fc5a983dSmrg case FOURCC_RGB: 1081fc5a983dSmrg srcPitch = width << 2; 1082fc5a983dSmrg dstPitch = ((width << 2) + 63) & ~63; 1083fc5a983dSmrg break; 1084fc5a983dSmrg default: 1085fc5a983dSmrg return BadImplementation; 1086fc5a983dSmrg } 1087fc5a983dSmrg 1088fc5a983dSmrg newSize = height * dstPitch / bpp; 1089fc5a983dSmrg 1090fc5a983dSmrg if(pPriv->doubleBuffer) 1091fc5a983dSmrg newSize <<= 1; 1092fc5a983dSmrg 1093fc5a983dSmrg pPriv->linear = NVAllocateOverlayMemory(pScrnInfo, 1094fc5a983dSmrg pPriv->linear, 1095fc5a983dSmrg newSize); 1096fc5a983dSmrg 1097fc5a983dSmrg if(!pPriv->linear) return BadAlloc; 1098fc5a983dSmrg 1099fc5a983dSmrg offset = pPriv->linear->offset * bpp; 1100fc5a983dSmrg 1101fc5a983dSmrg if(pPriv->doubleBuffer) { 1102fc5a983dSmrg int mask = 1 << (pPriv->currentBuffer << 2); 1103fc5a983dSmrg 1104fc5a983dSmrg#if 0 1105fc5a983dSmrg /* burn the CPU until the next buffer is available */ 1106fc5a983dSmrg while(pNv->PMC[0x00008700/4] & mask); 1107fc5a983dSmrg#else 1108fc5a983dSmrg /* overwrite the newest buffer if there's not one free */ 1109fc5a983dSmrg if(pNv->PMC[0x00008700/4] & mask) { 1110fc5a983dSmrg if(!pPriv->currentBuffer) 1111fc5a983dSmrg offset += (newSize * bpp) >> 1; 1112fc5a983dSmrg skip = TRUE; 1113fc5a983dSmrg } else 1114fc5a983dSmrg#endif 1115fc5a983dSmrg if(pPriv->currentBuffer) 1116fc5a983dSmrg offset += (newSize * bpp) >> 1; 1117fc5a983dSmrg } 1118fc5a983dSmrg 1119fc5a983dSmrg dst_start = pNv->FbStart + offset; 1120fc5a983dSmrg 1121fc5a983dSmrg /* We need to enlarge the copied rectangle by a pixel so the HW 1122fc5a983dSmrg filtering doesn't pick up junk laying outside of the source */ 1123fc5a983dSmrg 1124fc5a983dSmrg left = (xa - 0x00010000) >> 16; 1125fc5a983dSmrg if(left < 0) left = 0; 1126fc5a983dSmrg top = (ya - 0x00010000) >> 16; 1127fc5a983dSmrg if(top < 0) top = 0; 1128fc5a983dSmrg right = (xb + 0x0001ffff) >> 16; 1129fc5a983dSmrg if(right > width) right = width; 1130fc5a983dSmrg bottom = (yb + 0x0001ffff) >> 16; 1131fc5a983dSmrg if(bottom > height) bottom = height; 1132fc5a983dSmrg 1133fc5a983dSmrg if(pPriv->blitter) NVSync(pScrnInfo); 1134fc5a983dSmrg 1135fc5a983dSmrg switch(id) { 1136fc5a983dSmrg case FOURCC_YV12: 1137fc5a983dSmrg case FOURCC_I420: 1138fc5a983dSmrg left &= ~1; 1139fc5a983dSmrg npixels = ((right + 1) & ~1) - left; 1140fc5a983dSmrg top &= ~1; 1141fc5a983dSmrg nlines = ((bottom + 1) & ~1) - top; 1142fc5a983dSmrg 1143fc5a983dSmrg dst_start += (left << 1) + (top * dstPitch); 1144fc5a983dSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 1); 1145fc5a983dSmrg s2offset += tmp; 1146fc5a983dSmrg s3offset += tmp; 1147fc5a983dSmrg if(id == FOURCC_I420) { 1148fc5a983dSmrg tmp = s2offset; 1149fc5a983dSmrg s2offset = s3offset; 1150fc5a983dSmrg s3offset = tmp; 1151fc5a983dSmrg } 1152fc5a983dSmrg NVCopyData420(buf + (top * srcPitch) + left, 1153fc5a983dSmrg buf + s2offset, buf + s3offset, 1154fc5a983dSmrg dst_start, srcPitch, srcPitch2, 1155fc5a983dSmrg dstPitch, nlines, npixels); 1156fc5a983dSmrg break; 1157fc5a983dSmrg case FOURCC_UYVY: 1158fc5a983dSmrg case FOURCC_YUY2: 1159fc5a983dSmrg left &= ~1; 1160fc5a983dSmrg npixels = ((right + 1) & ~1) - left; 1161fc5a983dSmrg nlines = bottom - top; 1162fc5a983dSmrg 1163fc5a983dSmrg left <<= 1; 1164fc5a983dSmrg buf += (top * srcPitch) + left; 1165fc5a983dSmrg dst_start += left + (top * dstPitch); 1166fc5a983dSmrg 1167fc5a983dSmrg NVCopyData422(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1168fc5a983dSmrg break; 1169fc5a983dSmrg case FOURCC_RGB: 1170fc5a983dSmrg npixels = right - left; 1171fc5a983dSmrg nlines = bottom - top; 1172fc5a983dSmrg 1173fc5a983dSmrg left <<= 2; 1174fc5a983dSmrg buf += (top * srcPitch) + left; 1175fc5a983dSmrg dst_start += left + (top * dstPitch); 1176fc5a983dSmrg 1177fc5a983dSmrg NVCopyDataRGB(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 1178fc5a983dSmrg break; 1179fc5a983dSmrg default: 1180fc5a983dSmrg return BadImplementation; 1181fc5a983dSmrg } 1182fc5a983dSmrg 1183fc5a983dSmrg if(!skip) { 1184fc5a983dSmrg if(pPriv->blitter) { 1185fc5a983dSmrg NVPutBlitImage(pScrnInfo, offset, id, dstPitch, &dstBox, 1186fc5a983dSmrg xa, ya, xb, yb, 1187fc5a983dSmrg width, height, src_w, src_h, drw_w, drw_h, 1188fc5a983dSmrg clipBoxes); 1189fc5a983dSmrg } else { 1190fc5a983dSmrg NVPutOverlayImage(pScrnInfo, offset, id, dstPitch, &dstBox, 1191fc5a983dSmrg xa, ya, xb, yb, 1192fc5a983dSmrg width, height, src_w, src_h, drw_w, drw_h, 1193fc5a983dSmrg clipBoxes); 1194fc5a983dSmrg pPriv->currentBuffer ^= 1; 1195fc5a983dSmrg } 1196fc5a983dSmrg } 1197fc5a983dSmrg 1198fc5a983dSmrg return Success; 1199fc5a983dSmrg} 1200fc5a983dSmrg/* 1201fc5a983dSmrg * QueryImageAttributes 1202fc5a983dSmrg */ 1203fc5a983dSmrgstatic int NVQueryImageAttributes 1204fc5a983dSmrg( 1205fc5a983dSmrg ScrnInfoPtr pScrnInfo, 1206fc5a983dSmrg int id, 1207fc5a983dSmrg unsigned short *w, 1208fc5a983dSmrg unsigned short *h, 1209fc5a983dSmrg int *pitches, 1210fc5a983dSmrg int *offsets 1211fc5a983dSmrg) 1212fc5a983dSmrg{ 1213fc5a983dSmrg int size, tmp; 1214fc5a983dSmrg 1215fc5a983dSmrg if(*w > 2046) 1216fc5a983dSmrg *w = 2046; 1217fc5a983dSmrg if(*h > 2046) 1218fc5a983dSmrg *h = 2046; 1219fc5a983dSmrg 1220fc5a983dSmrg *w = (*w + 1) & ~1; 1221fc5a983dSmrg if (offsets) 1222fc5a983dSmrg offsets[0] = 0; 1223fc5a983dSmrg 1224fc5a983dSmrg switch (id) 1225fc5a983dSmrg { 1226fc5a983dSmrg case FOURCC_YV12: 1227fc5a983dSmrg case FOURCC_I420: 1228fc5a983dSmrg *h = (*h + 1) & ~1; 1229fc5a983dSmrg size = (*w + 3) & ~3; 1230fc5a983dSmrg if (pitches) 1231fc5a983dSmrg pitches[0] = size; 1232fc5a983dSmrg size *= *h; 1233fc5a983dSmrg if (offsets) 1234fc5a983dSmrg offsets[1] = size; 1235fc5a983dSmrg tmp = ((*w >> 1) + 3) & ~3; 1236fc5a983dSmrg if (pitches) 1237fc5a983dSmrg pitches[1] = pitches[2] = tmp; 1238fc5a983dSmrg tmp *= (*h >> 1); 1239fc5a983dSmrg size += tmp; 1240fc5a983dSmrg if (offsets) 1241fc5a983dSmrg offsets[2] = size; 1242fc5a983dSmrg size += tmp; 1243fc5a983dSmrg break; 1244fc5a983dSmrg case FOURCC_UYVY: 1245fc5a983dSmrg case FOURCC_YUY2: 1246fc5a983dSmrg size = *w << 1; 1247fc5a983dSmrg if (pitches) 1248fc5a983dSmrg pitches[0] = size; 1249fc5a983dSmrg size *= *h; 1250fc5a983dSmrg break; 1251fc5a983dSmrg case FOURCC_RGB: 1252fc5a983dSmrg size = *w << 2; 1253fc5a983dSmrg if(pitches) 1254fc5a983dSmrg pitches[0] = size; 1255fc5a983dSmrg size *= *h; 1256fc5a983dSmrg break; 1257fc5a983dSmrg default: 1258fc5a983dSmrg *w = *h = size = 0; 1259fc5a983dSmrg break; 1260fc5a983dSmrg } 1261fc5a983dSmrg return size; 1262fc5a983dSmrg} 1263fc5a983dSmrg 1264fc5a983dSmrgstatic void NVVideoTimerCallback 1265fc5a983dSmrg( 1266fc5a983dSmrg ScrnInfoPtr pScrnInfo, 1267fc5a983dSmrg Time currentTime 1268fc5a983dSmrg) 1269fc5a983dSmrg{ 1270fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 1271fc5a983dSmrg NVPortPrivPtr pOverPriv = NULL; 1272fc5a983dSmrg NVPortPrivPtr pBlitPriv = NULL; 1273fc5a983dSmrg Bool needCallback = FALSE; 1274fc5a983dSmrg 1275fc5a983dSmrg if(!pScrnInfo->vtSema) return; 1276fc5a983dSmrg 1277fc5a983dSmrg if(pNv->overlayAdaptor) { 1278fc5a983dSmrg pOverPriv = GET_OVERLAY_PRIVATE(pNv); 1279fc5a983dSmrg if(!pOverPriv->videoStatus) 1280fc5a983dSmrg pOverPriv = NULL; 1281fc5a983dSmrg } 1282fc5a983dSmrg 1283fc5a983dSmrg if(pNv->blitAdaptor) { 1284fc5a983dSmrg pBlitPriv = GET_BLIT_PRIVATE(pNv); 1285fc5a983dSmrg if(!pBlitPriv->videoStatus) 1286fc5a983dSmrg pBlitPriv = NULL; 1287fc5a983dSmrg } 1288fc5a983dSmrg 1289fc5a983dSmrg if(pOverPriv) { 1290fc5a983dSmrg if(pOverPriv->videoTime < currentTime) { 1291fc5a983dSmrg if(pOverPriv->videoStatus & OFF_TIMER) { 1292fc5a983dSmrg NVStopOverlay(pScrnInfo); 1293fc5a983dSmrg pOverPriv->videoStatus = FREE_TIMER; 1294fc5a983dSmrg pOverPriv->videoTime = currentTime + FREE_DELAY; 1295fc5a983dSmrg needCallback = TRUE; 1296fc5a983dSmrg } else 1297fc5a983dSmrg if(pOverPriv->videoStatus & FREE_TIMER) { 1298fc5a983dSmrg NVFreeOverlayMemory(pScrnInfo); 1299fc5a983dSmrg pOverPriv->videoStatus = 0; 1300fc5a983dSmrg } 1301fc5a983dSmrg } else { 1302fc5a983dSmrg needCallback = TRUE; 1303fc5a983dSmrg } 1304fc5a983dSmrg } 1305fc5a983dSmrg 1306fc5a983dSmrg if(pBlitPriv) { 1307fc5a983dSmrg if(pBlitPriv->videoTime < currentTime) { 1308fc5a983dSmrg NVFreeBlitMemory(pScrnInfo); 1309fc5a983dSmrg pBlitPriv->videoStatus = 0; 1310fc5a983dSmrg } else { 1311fc5a983dSmrg needCallback = TRUE; 1312fc5a983dSmrg } 1313fc5a983dSmrg } 1314fc5a983dSmrg 1315fc5a983dSmrg pNv->VideoTimerCallback = needCallback ? NVVideoTimerCallback : NULL; 1316fc5a983dSmrg} 1317fc5a983dSmrg 1318fc5a983dSmrg 1319fc5a983dSmrg/***** Exported offscreen surface stuff ****/ 1320fc5a983dSmrg 1321fc5a983dSmrg 1322fc5a983dSmrgstatic int 1323fc5a983dSmrgNVAllocSurface ( 1324fc5a983dSmrg ScrnInfoPtr pScrnInfo, 1325fc5a983dSmrg int id, 1326fc5a983dSmrg unsigned short w, 1327fc5a983dSmrg unsigned short h, 1328fc5a983dSmrg XF86SurfacePtr surface 1329fc5a983dSmrg) 1330fc5a983dSmrg{ 1331fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 1332fc5a983dSmrg NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 1333fc5a983dSmrg int size, bpp; 1334fc5a983dSmrg 1335fc5a983dSmrg bpp = pScrnInfo->bitsPerPixel >> 3; 1336fc5a983dSmrg 1337fc5a983dSmrg if(pPriv->grabbedByV4L) return BadAlloc; 1338fc5a983dSmrg 1339fc5a983dSmrg if((w > 2046) || (h > 2046)) return BadValue; 1340fc5a983dSmrg 1341fc5a983dSmrg w = (w + 1) & ~1; 1342fc5a983dSmrg pPriv->pitch = ((w << 1) + 63) & ~63; 1343fc5a983dSmrg size = h * pPriv->pitch / bpp; 1344fc5a983dSmrg 1345fc5a983dSmrg pPriv->linear = NVAllocateOverlayMemory(pScrnInfo, pPriv->linear, 1346fc5a983dSmrg size); 1347fc5a983dSmrg 1348fc5a983dSmrg if(!pPriv->linear) return BadAlloc; 1349fc5a983dSmrg 1350fc5a983dSmrg pPriv->offset = pPriv->linear->offset * bpp; 1351fc5a983dSmrg 1352fc5a983dSmrg surface->width = w; 1353fc5a983dSmrg surface->height = h; 1354fc5a983dSmrg surface->pScrn = pScrnInfo; 1355fc5a983dSmrg surface->pitches = &pPriv->pitch; 1356fc5a983dSmrg surface->offsets = &pPriv->offset; 1357fc5a983dSmrg surface->devPrivate.ptr = (pointer)pPriv; 1358fc5a983dSmrg surface->id = id; 1359fc5a983dSmrg 1360fc5a983dSmrg /* grab the video */ 1361fc5a983dSmrg NVStopOverlay(pScrnInfo); 1362fc5a983dSmrg pPriv->videoStatus = 0; 1363fc5a983dSmrg REGION_EMPTY(pScrnInfo->pScreen, &pPriv->clip); 1364fc5a983dSmrg pPriv->grabbedByV4L = TRUE; 1365fc5a983dSmrg 1366fc5a983dSmrg return Success; 1367fc5a983dSmrg} 1368fc5a983dSmrg 1369fc5a983dSmrgstatic int 1370fc5a983dSmrgNVStopSurface (XF86SurfacePtr surface) 1371fc5a983dSmrg{ 1372fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr); 1373fc5a983dSmrg 1374fc5a983dSmrg if(pPriv->grabbedByV4L && pPriv->videoStatus) { 1375fc5a983dSmrg NVStopOverlay(surface->pScrn); 1376fc5a983dSmrg pPriv->videoStatus = 0; 1377fc5a983dSmrg } 1378fc5a983dSmrg 1379fc5a983dSmrg return Success; 1380fc5a983dSmrg} 1381fc5a983dSmrg 1382fc5a983dSmrgstatic int 1383fc5a983dSmrgNVFreeSurface (XF86SurfacePtr surface) 1384fc5a983dSmrg{ 1385fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr); 1386fc5a983dSmrg 1387fc5a983dSmrg if(pPriv->grabbedByV4L) { 1388fc5a983dSmrg NVStopSurface(surface); 1389fc5a983dSmrg NVFreeOverlayMemory(surface->pScrn); 1390fc5a983dSmrg pPriv->grabbedByV4L = FALSE; 1391fc5a983dSmrg } 1392fc5a983dSmrg 1393fc5a983dSmrg return Success; 1394fc5a983dSmrg} 1395fc5a983dSmrg 1396fc5a983dSmrgstatic int 1397fc5a983dSmrgNVGetSurfaceAttribute ( 1398fc5a983dSmrg ScrnInfoPtr pScrnInfo, 1399fc5a983dSmrg Atom attribute, 1400fc5a983dSmrg INT32 *value 1401fc5a983dSmrg) 1402fc5a983dSmrg{ 1403fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 1404fc5a983dSmrg NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 1405fc5a983dSmrg 1406fc5a983dSmrg return NVGetOverlayPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv); 1407fc5a983dSmrg} 1408fc5a983dSmrg 1409fc5a983dSmrgstatic int 1410fc5a983dSmrgNVSetSurfaceAttribute( 1411fc5a983dSmrg ScrnInfoPtr pScrnInfo, 1412fc5a983dSmrg Atom attribute, 1413fc5a983dSmrg INT32 value 1414fc5a983dSmrg) 1415fc5a983dSmrg{ 1416fc5a983dSmrg NVPtr pNv = NVPTR(pScrnInfo); 1417fc5a983dSmrg NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); 1418fc5a983dSmrg 1419fc5a983dSmrg return NVSetOverlayPortAttribute(pScrnInfo, attribute, value, (pointer)pPriv); 1420fc5a983dSmrg} 1421fc5a983dSmrg 1422fc5a983dSmrgstatic int 1423fc5a983dSmrgNVDisplaySurface ( 1424fc5a983dSmrg XF86SurfacePtr surface, 1425fc5a983dSmrg short src_x, short src_y, 1426fc5a983dSmrg short drw_x, short drw_y, 1427fc5a983dSmrg short src_w, short src_h, 1428fc5a983dSmrg short drw_w, short drw_h, 1429fc5a983dSmrg RegionPtr clipBoxes 1430fc5a983dSmrg) 1431fc5a983dSmrg{ 1432fc5a983dSmrg ScrnInfoPtr pScrnInfo = surface->pScrn; 1433fc5a983dSmrg NVPortPrivPtr pPriv = (NVPortPrivPtr)(surface->devPrivate.ptr); 1434fc5a983dSmrg INT32 xa, xb, ya, yb; 1435fc5a983dSmrg BoxRec dstBox; 1436fc5a983dSmrg 1437fc5a983dSmrg if(!pPriv->grabbedByV4L) return Success; 1438fc5a983dSmrg 1439fc5a983dSmrg if(src_w > (drw_w << 3)) 1440fc5a983dSmrg drw_w = src_w >> 3; 1441fc5a983dSmrg if(src_h > (drw_h << 3)) 1442fc5a983dSmrg drw_h = src_h >> 3; 1443fc5a983dSmrg 1444fc5a983dSmrg /* Clip */ 1445fc5a983dSmrg xa = src_x; 1446fc5a983dSmrg xb = src_x + src_w; 1447fc5a983dSmrg ya = src_y; 1448fc5a983dSmrg yb = src_y + src_h; 1449fc5a983dSmrg 1450fc5a983dSmrg dstBox.x1 = drw_x; 1451fc5a983dSmrg dstBox.x2 = drw_x + drw_w; 1452fc5a983dSmrg dstBox.y1 = drw_y; 1453fc5a983dSmrg dstBox.y2 = drw_y + drw_h; 1454fc5a983dSmrg 1455fc5a983dSmrg if(!xf86XVClipVideoHelper(&dstBox, &xa, &xb, &ya, &yb, clipBoxes, 1456fc5a983dSmrg surface->width, surface->height)) 1457fc5a983dSmrg { 1458fc5a983dSmrg return Success; 1459fc5a983dSmrg } 1460fc5a983dSmrg 1461fc5a983dSmrg dstBox.x1 -= pScrnInfo->frameX0; 1462fc5a983dSmrg dstBox.x2 -= pScrnInfo->frameX0; 1463fc5a983dSmrg dstBox.y1 -= pScrnInfo->frameY0; 1464fc5a983dSmrg dstBox.y2 -= pScrnInfo->frameY0; 1465fc5a983dSmrg 1466fc5a983dSmrg pPriv->currentBuffer = 0; 1467fc5a983dSmrg 1468fc5a983dSmrg NVPutOverlayImage (pScrnInfo, surface->offsets[0], surface->id, 1469fc5a983dSmrg surface->pitches[0], &dstBox, xa, ya, xb, yb, 1470fc5a983dSmrg surface->width, surface->height, src_w, src_h, 1471fc5a983dSmrg drw_w, drw_h, clipBoxes); 1472fc5a983dSmrg 1473fc5a983dSmrg return Success; 1474fc5a983dSmrg} 1475fc5a983dSmrg 1476fc5a983dSmrgXF86OffscreenImageRec NVOffscreenImages[2] = 1477fc5a983dSmrg{ 1478fc5a983dSmrg { 1479fc5a983dSmrg &NVImages[0], 1480fc5a983dSmrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 1481fc5a983dSmrg NVAllocSurface, 1482fc5a983dSmrg NVFreeSurface, 1483fc5a983dSmrg NVDisplaySurface, 1484fc5a983dSmrg NVStopSurface, 1485fc5a983dSmrg NVGetSurfaceAttribute, 1486fc5a983dSmrg NVSetSurfaceAttribute, 1487fc5a983dSmrg 2046, 2046, 1488fc5a983dSmrg NUM_OVERLAY_ATTRIBUTES - 1, 1489fc5a983dSmrg &NVOverlayAttributes[1] 1490fc5a983dSmrg }, 1491fc5a983dSmrg { 1492fc5a983dSmrg &NVImages[2], 1493fc5a983dSmrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT, 1494fc5a983dSmrg NVAllocSurface, 1495fc5a983dSmrg NVFreeSurface, 1496fc5a983dSmrg NVDisplaySurface, 1497fc5a983dSmrg NVStopSurface, 1498fc5a983dSmrg NVGetSurfaceAttribute, 1499fc5a983dSmrg NVSetSurfaceAttribute, 1500fc5a983dSmrg 2046, 2046, 1501fc5a983dSmrg NUM_OVERLAY_ATTRIBUTES - 1, 1502fc5a983dSmrg &NVOverlayAttributes[1] 1503fc5a983dSmrg }, 1504fc5a983dSmrg}; 1505fc5a983dSmrg 1506fc5a983dSmrgstatic void 1507fc5a983dSmrgNVInitOffscreenImages (ScreenPtr pScreen) 1508fc5a983dSmrg{ 1509fc5a983dSmrg xf86XVRegisterOffscreenImages(pScreen, NVOffscreenImages, 2); 1510fc5a983dSmrg} 1511