apm_video.c revision 8e0ed500
1 2#ifdef HAVE_CONFIG_H 3#include "config.h" 4#endif 5 6#if PSZ != 24 7#include "dixstruct.h" 8#include "fourcc.h" 9 10/* 11 * Ported from mga_video.c by Loïc Grenié 12 */ 13 14#ifndef OFF_DELAY 15#define OFF_DELAY 200 16#endif 17 18static XF86VideoAdaptorPtr A(SetupImageVideo)(ScreenPtr); 19 20static void A(StopVideo)(ScrnInfoPtr, pointer, Bool); 21static int A(SetPortAttribute)(ScrnInfoPtr, Atom, INT32, pointer); 22#ifndef IOP_ACCESS 23static int ApmGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 24static void ApmQueryBestSize(ScrnInfoPtr, Bool, short, short, short, 25 short, unsigned int *, unsigned int *, 26 pointer); 27static int ApmQueryImageAttributes(ScrnInfoPtr, int, 28 unsigned short *, unsigned short *, 29 int *, int *); 30#endif 31static int A(ReputImage)(ScrnInfoPtr, short, short, RegionPtr, pointer, 32 DrawablePtr); 33static int A(PutImage)(ScrnInfoPtr, short, short, short, short, short, 34 short, short, short, int, unsigned char*, 35 short, short, Bool, RegionPtr, pointer, 36 DrawablePtr); 37 38static void A(ResetVideo)(ScrnInfoPtr); 39static void A(XvMoveCB)(FBAreaPtr, FBAreaPtr); 40static void A(XvRemoveCB)(FBAreaPtr); 41 42#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 43 44void A(InitVideo)(ScreenPtr pScreen) 45{ 46 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 47 XF86VideoAdaptorPtr *adaptors, *newAdaptors; 48 XF86VideoAdaptorPtr newAdaptor; 49 APMDECL(pScrn); 50 int num_adaptors; 51 Bool freeAdaptors = FALSE; 52 53 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 54 55 if (pApm->Chipset >= AT24) { 56 if ((newAdaptor = A(SetupImageVideo)(pScreen))) { 57 58 newAdaptors = xalloc((num_adaptors + 1) * 59 sizeof(XF86VideoAdaptorPtr*)); 60 if(newAdaptors) { 61 if(num_adaptors) 62 memcpy(newAdaptors, adaptors, num_adaptors * 63 sizeof(XF86VideoAdaptorPtr)); 64 newAdaptors[num_adaptors] = newAdaptor; 65 adaptors = newAdaptors; 66 num_adaptors++; 67 freeAdaptors = TRUE; 68 } 69 } 70 } 71 72 if(num_adaptors) 73 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 74 75 if(freeAdaptors) 76 xfree(adaptors); 77} 78 79#ifndef APM_VIDEO_DEFINES 80#define APM_VIDEO_DEFINES 81 82static Atom xvBrightness, xvContrast; 83 84/* client libraries expect an encoding */ 85static XF86VideoEncodingRec DummyEncoding[1] = 86{ 87 { 88 0, 89 "XV_IMAGE", 90 1024, 1024, 91 {1, 1} 92 } 93}; 94 95#define NUM_FORMATS 24 96 97static XF86VideoFormatRec Formats[NUM_FORMATS] = 98{ 99 { 8, PseudoColor}, 100 {15, PseudoColor}, 101 {16, PseudoColor}, 102 {24, PseudoColor}, 103 {32, PseudoColor}, 104 { 8, DirectColor}, 105 {15, DirectColor}, 106 {16, DirectColor}, 107 {24, DirectColor}, 108 {32, DirectColor}, 109 { 8, TrueColor}, 110 {15, TrueColor}, 111 {16, TrueColor}, 112 {24, TrueColor}, 113 {32, TrueColor} 114}; 115 116#define NUM_ATTRIBUTES 2 117 118static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 119{ 120 {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 121 {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} 122}; 123 124#define NUM_IMAGES 9 125typedef char c8; 126 127static XF86ImageRec Images[NUM_IMAGES] = 128{ 129 { 130 0x35315652, 131 XvRGB, 132 LSBFirst, 133 {'R','V','1','5', 134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 135 16, 136 XvPacked, 137 1, 138 15, 0x001F, 0x03E0, 0x7C00, 139 0, 0, 0, 140 0, 0, 0, 141 0, 0, 0, 142 {'R','V','B',0, 143 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}, 144 XvTopToBottom 145 }, 146 { 147 0x36315652, 148 XvRGB, 149 LSBFirst, 150 {'R','V','1','6', 151 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 152 16, 153 XvPacked, 154 1, 155 16, 0x001F, 0x07E0, 0xF800, 156 0, 0, 0, 157 0, 0, 0, 158 0, 0, 0, 159 {'R','V','B',0, 160 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}, 161 XvTopToBottom 162 }, 163 { 164 0x32335652, 165 XvRGB, 166 LSBFirst, 167 {'R','V','3','2', 168 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 169 32, 170 XvPacked, 171 1, 172 24, 0x0000FF, 0x00FF00, 0xFF0000, 173 0, 0, 0, 174 0, 0, 0, 175 0, 0, 0, 176 {'R','V','B',0, 177 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}, 178 XvTopToBottom 179 }, 180 XVIMAGE_YUY2, 181 { 182 0x59595959, 183 XvYUV, 184 LSBFirst, 185 {0x00,0x00,0x00,0x00, 186 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 187 8, 188 XvPacked, 189 1, 190 0, 0, 0, 0, 191 8, 0, 0, 192 1, 1, 1, 193 1, 1, 1, 194 {'Y','Y','Y','Y', 195 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}, 196 XvTopToBottom 197 }, 198 { 199 0x32315659, 200 XvYUV, 201 LSBFirst, 202 {'Y','V','1','2', 203 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 204 12, 205 XvPlanar, 206 3, 207 0, 0, 0, 0 , 208 8, 8, 8, 209 1, 2, 2, 210 1, 2, 2, 211 {'Y','V','U', 212 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,0}, 213 XvTopToBottom 214 }, 215 { 216 0x59565955, 217 XvYUV, 218 LSBFirst, 219 {'U','Y','V','Y', 220 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 221 16, 222 XvPlanar, 223 1, 224 0, 0, 0, 0, 225 8, 8, 8, 226 1, 2, 2, 227 1, 1, 1, 228 {'U','Y','V','Y', 229 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}, 230 XvTopToBottom 231 }, 232 { 233 0x55595659, 234 XvYUV, 235 LSBFirst, 236 {'Y','V','Y','U', 237 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 238 16, 239 XvPlanar, 240 1, 241 0, 0, 0, 0, 242 8, 8, 8, 243 1, 2, 2, 244 1, 1, 1, 245 {'Y','V','Y','U', 246 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}, 247 XvTopToBottom 248 }, 249 { 250 0x59555956, 251 XvYUV, 252 LSBFirst, 253 {'V','Y','U','Y', 254 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 255 16, 256 XvPlanar, 257 1, 258 0, 0, 0, 0, 259 8, 8, 8, 260 1, 2, 2, 261 1, 1, 1, 262 {'V','Y','U','Y', 263 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}, 264 XvTopToBottom 265 } 266}; 267 268typedef struct { 269 Bool on; 270 unsigned char brightness; 271 unsigned char contrast; 272 unsigned short reg, val; 273 ApmPtr pApm; 274 int x1, x10, y1, drw_x, drw_y, Bpp, Bps; 275 FBAreaPtr area; 276 RegionRec clip; 277 int xnum, xden, ynum, yden; 278 CARD32 scalex, scaley; 279 CARD32 data; 280} ApmPortPrivRec, *ApmPortPrivPtr; 281#endif 282 283 284static void 285A(ResetVideo)(ScrnInfoPtr pScrn) 286{ 287 APMDECL(pScrn); 288 289 A(WaitForFifo)(pApm, 2); 290 ((ApmPortPrivPtr)pApm->adaptor->pPortPrivates[0].ptr)->on = 0; 291 ((ApmPortPrivPtr)pApm->adaptor->pPortPrivates[1].ptr)->on = 0; 292 WRXW(0x82, 0); 293 WRXW(0x92, 0); 294} 295 296 297static XF86VideoAdaptorPtr 298A(SetupImageVideo)(ScreenPtr pScreen) 299{ 300 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 301 APMDECL(pScrn); 302 XF86VideoAdaptorPtr adapt; 303 ApmPortPrivPtr pPriv; 304 305 if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 306 2 * sizeof(ApmPortPrivRec) + 307 2 * sizeof(DevUnion)))) 308 return NULL; 309 310 adapt->type = XvWindowMask | XvInputMask | XvImageMask; 311 adapt->flags = VIDEO_OVERLAID_IMAGES; 312 adapt->name = "Alliance Pro Motion video engine"; 313 adapt->nEncodings = 1; 314 adapt->pEncodings = DummyEncoding; 315 adapt->nFormats = NUM_FORMATS; 316 adapt->pFormats = Formats; 317 adapt->nPorts = 2; 318 adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 319 pPriv = (ApmPortPrivPtr)(&adapt->pPortPrivates[2]); 320 pPriv->pApm = pApm; 321 pPriv[1].pApm = pApm; 322 pPriv->reg = 0x82; 323 pPriv[1].reg = 0x92; 324 adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 325 adapt->pPortPrivates[1].ptr = (pointer)(pPriv + 1); 326 adapt->nAttributes = NUM_ATTRIBUTES; 327 adapt->pAttributes = Attributes; 328 adapt->nImages = NUM_IMAGES; 329 adapt->pImages = Images; 330 adapt->PutVideo = NULL; 331 adapt->PutStill = NULL; 332 adapt->GetVideo = NULL; 333 adapt->GetStill = NULL; 334 adapt->StopVideo = A(StopVideo); 335 adapt->SetPortAttribute = A(SetPortAttribute); 336 adapt->GetPortAttribute = ApmGetPortAttribute; 337 adapt->QueryBestSize = ApmQueryBestSize; 338 adapt->PutImage = A(PutImage); 339 adapt->ReputImage = A(ReputImage); 340 adapt->QueryImageAttributes = ApmQueryImageAttributes; 341 342 pPriv->brightness = 0; 343 pPriv->contrast = 128; 344 pPriv[1].brightness = 0; 345 pPriv[1].contrast = 128; 346 347 /* gotta uninit this someplace */ 348 REGION_NULL(pScreen, &pPriv->clip); 349 REGION_NULL(pScreen, &(pPriv + 1)->clip); 350 351 pApm->adaptor = adapt; 352 353 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 354 xvContrast = MAKE_ATOM("XV_CONTRAST"); 355 356 A(ResetVideo)(pScrn); 357 358 return adapt; 359} 360 361#ifndef IOP_ACCESS 362/* ApmClipVideo - 363 364 Takes the dst box in standard X BoxRec form (top and left 365 edges inclusive, bottom and right exclusive). The new dst 366 box is returned. The source boundaries are given (x1, y1 367 inclusive, x2, y2 exclusive) and returned are the new source 368 boundaries in 16.16 fixed point. 369 370 extents is the extents of the clip region 371*/ 372 373static void 374ApmClipVideo(BoxPtr dst, INT32 *x1, INT32 *x2, INT32 *y1, INT32 *y2, 375 BoxPtr extents, INT32 width, INT32 height, 376 CARD32 *scalex, CARD32 *scaley, INT32 mask) 377{ 378 INT32 vscale, hscale; 379 int diff; 380 381 if (dst->x2 - dst->x1 < *x2 - *x1) 382 dst->x2 = dst->x1 + *x2 - *x1; 383 384 if (dst->y2 - dst->y1 < *y2 - *y1) 385 dst->y2 = dst->y1 + *y2 - *y1; 386 387 *x1 <<= 12; *x2 <<= 16; 388 *y1 <<= 12; *y2 <<= 16; 389 390 hscale = (*x2 - *x1) / (dst->x2 - dst->x1); 391 vscale = (*y2 - *y1) / (dst->y2 - dst->y1); 392 393 diff = extents->x1 - dst->x1; 394 if(diff > 0) { 395 dst->x1 = extents->x1; 396 *x1 += diff * hscale; 397 } 398 diff = dst->x2 - extents->x2; 399 if(diff > 0) { 400 dst->x2 = extents->x2; 401 *x2 -= diff * hscale; 402 } 403 diff = extents->y1 - dst->y1; 404 if(diff > 0) { 405 dst->y1 = extents->y1; 406 *y1 += diff * vscale; 407 } 408 diff = dst->y2 - extents->y2; 409 if(diff > 0) { 410 dst->y2 = extents->y2; 411 *y2 -= diff * vscale; 412 } 413 414 if (*x2 - *x1 == 0x10000 * (dst->x2 - dst->x1)) /* Shrinking */ 415 *scalex = 0; 416 else 417 *scalex = ((*x2 - *x1) / (dst->x2 - dst->x1)) >> 4; 418 if (*y2 - *y1 == 0x10000 * (dst->y2 - dst->y1)) /* Shrinking */ 419 *scaley = 0; 420 else 421 *scaley = ((*y2 - *y1) / (dst->y2 - dst->y1)) >> 4; 422} 423#endif 424 425static void 426A(StopVideo)(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 427{ 428 ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 429 APMDECL(pScrn); 430 431 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 432 433 pPriv->on = 0; 434 A(WaitForFifo)(pApm, 1); 435 WRXB(pPriv->reg, 0); 436} 437 438static int 439A(SetPortAttribute)(ScrnInfoPtr pScrn, Atom attribute, INT32 value, 440 pointer data) 441{ 442 ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 443 /*APMDECL(pScrn);*/ 444 445 if(attribute == xvBrightness) { 446 if((value < -128) || (value > 127)) 447 return BadValue; 448 pPriv->brightness = value; 449 /* TODO : enable */ 450 } else if(attribute == xvContrast) { 451 if((value < 0) || (value > 255)) 452 return BadValue; 453 pPriv->contrast = value; 454 /* TODO : enable */ 455 } 456 457 return Success; 458} 459 460#ifndef IOP_ACCESS 461static int 462ApmGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, 463 pointer data) 464{ 465 ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 466 467 if(attribute == xvBrightness) { 468 *value = pPriv->brightness; 469 } else 470 if(attribute == xvContrast) { 471 *value = pPriv->contrast; 472 } 473 474 return Success; 475} 476 477static void 478ApmQueryBestSize(ScrnInfoPtr pScrn, Bool motion, short vid_w, short vid_h, 479 short drw_w, short drw_h, 480 unsigned int *p_w, unsigned int *p_h, pointer data) 481{ 482 APMDECL(pScrn); 483 unsigned short round = ~pApm->CurrentLayout.mask32; 484 485 *p_w = drw_w & round; 486 *p_h = drw_h & round; 487} 488#endif 489 490static void A(XvMoveCB)(FBAreaPtr area1, FBAreaPtr area2) 491{ 492 ApmPortPrivPtr pPriv = (ApmPortPrivPtr)area1->devPrivate.ptr; 493 ApmPtr pApm = pPriv->pApm; 494 495 pPriv->on = 0; 496 A(WaitForFifo)(pApm, 1); 497 WRXB(pPriv->reg, 0); /* Stop video for this port */ 498 pPriv->area = area2; 499} 500 501static void A(XvRemoveCB)(FBAreaPtr area) 502{ 503 ApmPortPrivPtr pPriv = (ApmPortPrivPtr)area->devPrivate.ptr; 504 ApmPtr pApm = pPriv->pApm; 505 506 pPriv->on = 0; 507 A(WaitForFifo)(pApm, 1); 508 WRXB(pPriv->reg, 0); /* Stop video for this port */ 509 pPriv->area = NULL; 510} 511 512static int 513A(ReputImage)(ScrnInfoPtr pScrn, short drw_x, short drw_y, 514 RegionPtr clipBoxes, pointer pdata, DrawablePtr pDraw) 515{ 516 ScreenPtr pScreen = pScrn->pScreen; 517 APMDECL(pScrn); 518 ApmPortPrivPtr pPriv = pdata, pPriv0, pPriv1; 519 register int fx, fy; 520 CARD32 mask; 521 RegionRec Union; 522 RegionPtr reg0; 523 int nrects, CurrY, tile; 524 int X1, X2, Y1, y2, xmax, ymax; 525 BoxPtr rects; 526 Bool didit = 0; 527 528 mask = pApm->CurrentLayout.mask32; 529 fx = pScrn->frameX0 & ~mask; 530 fy = pScrn->frameY0 + 1; 531 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 532 pPriv->x1 += drw_x - pPriv->drw_x; 533 pPriv->x10 = ((pPriv->x1 + mask) & ~mask) - fx; 534 pPriv->y1 += drw_y - pPriv->drw_y; 535 pPriv->drw_x = drw_x; 536 pPriv->drw_y = drw_y; 537 A(WaitForFifo)(pApm, 2); 538 WRXW(pPriv->reg + 0x06, 0xFFF - ((pPriv->scalex * pPriv->x10) & 0xFFF)); 539 WRXW(pPriv->reg + 0x0A, 0xFFF - ((pPriv->scaley * pPriv->y1) & 0xFFF)); 540 pPriv0 = (ApmPortPrivPtr)pApm->adaptor->pPortPrivates[0].ptr; 541 pPriv1 = (ApmPortPrivPtr)pApm->adaptor->pPortPrivates[1].ptr; 542 reg0 = &pPriv0->clip; 543 bzero(&Union, sizeof Union); 544 REGION_EMPTY(pScreen, &Union); 545 REGION_NULL(pScreen, &Union); 546 REGION_UNION(pScreen, &Union, reg0, &pPriv1->clip); 547 nrects = REGION_NUM_RECTS(&Union); 548 rects = REGION_RECTS(&Union); 549 tile = 0x200; 550 xmax = pScrn->frameX1 - pScrn->frameX0 + 1; 551 ymax = pScrn->frameY1 - pScrn->frameY0; 552 CurrY = -1; 553 goto BEGIN_LOOP_1; 554 do { 555 rects++; 556BEGIN_LOOP_1: 557 X1 = ((rects->x1 + mask) & ~mask) - fx; 558 if (X1 < 0) 559 X1 = 0; 560 X2 = (rects->x2 & ~mask) - fx; 561 if (X2 > xmax) 562 X2 = xmax; 563 y2 = rects->y2 - fy; 564 } while ((X2 <= X1 || y2 < -1) && --nrects > 0); 565 Y1 = rects->y1 - fy; 566 567 while (!(STATUS() & 0x800)); 568 while (STATUS() & 0x800); 569 while (nrects-- > 0) { 570 CARD32 reg, data; 571 int x1, x2, y1; 572 573 x1 = X1; 574 x2 = X2; 575 y1 = Y1; 576 if (y1 < -1) y1 = -1; 577 if (y1 > ymax) 578 break; 579 didit = 1; 580 if (y1 > CurrY) { 581 A(WaitForFifo)(pApm, 3); 582 WRXL(tile + 0x00, 0xFFF0011); 583 WRXL(tile + 0x04, y1 << 16); 584 WRXL(tile + 0x08, 0); 585 tile += 16; 586 } 587 if (RECT_IN_REGION(pScreen, reg0, rects)) { 588 pPriv = pPriv0; 589 reg = (x1 << 16) | 1; 590 } 591 else { 592 pPriv = pPriv1; 593 reg = (x1 << 16) | 2; 594 } 595 CurrY = y2; 596 if (nrects <= 0) 597 goto BEGIN_LOOP_2; 598 do { 599 rects++; 600BEGIN_LOOP_2: 601 X1 = ((rects->x1 + mask) & ~mask) - fx; 602 if (X1 < 0) 603 X1 = 0; 604 X2 = (rects->x2 & ~mask) - fx; 605 if (X2 > xmax) 606 X2 = xmax; 607 } while (X2 <= X1 && --nrects > 0); 608 Y1 = rects->y1 - fy; 609 y2 = rects->y2 - fy; 610 data = pPriv->data + (((x1 - pPriv->x10) 611 * pPriv->xden) / pPriv->xnum) * pPriv->Bpp + 612 (((y1 - pPriv->y1 + fy) * pPriv->yden) / pPriv->ynum) * pPriv->Bps; 613 A(WaitForFifo)(pApm, 4); 614 if (!nrects || tile == 0x2B0 || y1 < Y1) { 615 WRXL(tile , 0x10 | reg); 616 } 617 else { 618 WRXL(tile , reg); 619 } 620 WRXL(tile + 0x04, x2 | (CurrY << 16)); 621 WRXL(tile + 0x08, (((x2-x1)*pPriv->xden+pPriv->xnum-1) / pPriv->xnum) | 622 (data << 16)); 623 WRXB(tile + 0x0C, data >> 16); 624 tile += 16; 625 if (tile == 0x2C0) { 626 tile = 0x200; 627 break; 628 } 629 } 630 REGION_UNINIT(pScreen, &Union); 631 632 if (didit) { 633 A(WaitForFifo)(pApm, 1); 634 WRXW(0x8E, tile - 0x200); 635 } 636 637 if (didit ^ ((pPriv0->val | pPriv1->val) & 1)) { 638 if (didit) { 639 pPriv0->val |= 1; 640 pPriv1->val |= 1; 641 } 642 else { 643 pPriv0->val &= 0xFFFE; 644 pPriv1->val &= 0xFFFE; 645 } 646 if (pPriv0->on) { 647 A(WaitForFifo)(pApm, 1); 648 WRXW(0x82, pPriv0->val); 649 } 650 if (pPriv1->on) { 651 A(WaitForFifo)(pApm, 1); 652 WRXW(0x92, pPriv1->val); 653 } 654 } 655 656 return Success; 657} 658 659static int 660A(PutImage)(ScrnInfoPtr pScrn, short src_x, short src_y, 661 short drw_x, short drw_y, short src_w, short src_h, 662 short drw_w, short drw_h, int id, unsigned char* buf, 663 short width, short height, Bool sync, RegionPtr clipBoxes, 664 pointer data, DrawablePtr pDraw) 665{ 666 ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 667 ScreenPtr pScreen = pScrn->pScreen; 668 APMDECL(pScrn); 669 INT32 x1, x2, y1, y2; 670 unsigned char *dst_start; 671 int pitch, Bpp, new_h, offset = 0, offset2 = 0, offset3 = 0; 672 CARD32 mask; 673 FBAreaPtr area; 674 int srcPitch, dstPitch, srcPitch2 = 0; 675 int top, left, npixels, nlines; 676 BoxRec dstBox; 677 CARD32 scalex, scaley, scale; 678 CARD32 tmp; 679 Bool offscreen; 680 681 offscreen = (buf < (unsigned char *)pApm->FbBase || 682 buf > (unsigned char *)pApm->FbBase + 0x400000); 683 684 if(drw_w > 16384) drw_w = 16384; 685 686 /* Clip */ 687 x1 = src_x; 688 x2 = src_x + src_w; 689 y1 = src_y; 690 y2 = src_y + src_h; 691 692 dstBox.x1 = drw_x; 693 dstBox.x2 = drw_x + drw_w; 694 dstBox.y1 = drw_y; 695 dstBox.y2 = drw_y + drw_h; 696 697 mask = pApm->CurrentLayout.mask32; 698 699 ApmClipVideo(&dstBox, &x1, &x2, &y1, &y2, 700 REGION_EXTENTS(pScreen, clipBoxes), width, height, 701 &scalex, &scaley, mask); 702 703 pPriv->drw_x = drw_x; 704 pPriv->drw_y = drw_y; 705 pPriv->xnum = drw_w; 706 if (scalex) 707 pPriv->xden = src_w; 708 else 709 pPriv->xden = drw_w; /* If image is larger than window */ 710 pPriv->ynum = drw_h; 711 if (scaley) 712 pPriv->yden = src_h; 713 else 714 pPriv->yden = drw_h; 715 if((x1 - x2 >= 0xFFFF) || (y1 - y2 >= 0xFFFF)) 716 return Success; 717 718 Bpp = pScrn->bitsPerPixel >> 3; 719 pitch = Bpp * pScrn->displayWidth; 720 721 switch(id) { 722 case 0x32315659: 723 dstPitch = ((width << 1) + 3) & ~3; 724 srcPitch = (width + 3) & ~3; 725 offset2 = srcPitch * height; 726 srcPitch2 = ((width >> 1) + 3) & ~3; 727 offset = srcPitch2 * (height >> 1); 728 offset3 = offset + offset2; 729 new_h = (2 * offset2 + pitch - 1) / pitch; 730 break; 731 case 0x59595959: 732 srcPitch = width; 733 dstPitch = (srcPitch + 3) & ~3; 734 offset = dstPitch * height; 735 new_h = (offset + pitch - 1) / pitch; 736 break; 737 case 0x32335652: 738 srcPitch = (width << 2); 739 dstPitch = (srcPitch + 3) & ~3; 740 offset = dstPitch * height; 741 new_h = (offset + pitch - 1) / pitch; 742 break; 743 default: 744 if (pApm->PutImageStride) 745 srcPitch = pApm->PutImageStride; 746 else 747 srcPitch = (width << 1); 748 dstPitch = (srcPitch + 3) & ~3; 749 offset = dstPitch * height; 750 new_h = (offset + pitch - 1) / pitch; 751 break; 752 } 753 754 area = pPriv->area; 755 756 /* Allocate offscreen memory */ 757 if (offscreen && (!area || ((area->box.y2 - area->box.y1) < new_h))) { 758 Bool nukeMem = FALSE; 759 int max_w, max_h; 760 761 xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, 762 FAVOR_WIDTH_THEN_AREA, PRIORITY_LOW); 763 if (max_w == pScrn->displayWidth && max_h >= new_h) { 764 area = xf86AllocateOffscreenArea(pScreen, 765 pScrn->displayWidth, new_h, 766 4, A(XvMoveCB), A(XvRemoveCB), pPriv); 767 if (area) { 768 if (pPriv->area) 769 xf86FreeOffscreenArea(pPriv->area); 770 } 771 else 772 area = pPriv->area; /* Should not happen */ 773 } 774 if(!area) { 775 if(!(area = xf86AllocateOffscreenArea(pScreen, 776 pScrn->displayWidth, new_h, 4, 777 A(XvMoveCB), A(XvRemoveCB), pPriv))) 778 { 779 nukeMem = TRUE; 780 } 781 } else { 782 if(!xf86ResizeOffscreenArea(area, pScrn->displayWidth, new_h)) { 783 xf86FreeOffscreenArea(area); 784 pPriv->area = area = NULL; 785 nukeMem = TRUE; 786 } 787 } 788 if(nukeMem) { 789 xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, 790 FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); 791 792 if((max_w < pScrn->displayWidth) || (max_h < new_h)) 793 return BadAlloc; 794 795 xf86PurgeUnlockedOffscreenAreas(pScreen); 796 797 area = xf86AllocateOffscreenArea(pScreen, 798 pScrn->displayWidth, new_h, 4, 799 A(XvMoveCB), A(XvRemoveCB), pPriv); 800 } 801 802 pPriv->area = area; 803 } 804 805 /* copy data */ 806 pPriv->x1 = dstBox.x1 /*drw_x*/; 807 pPriv->y1 = dstBox.y1 /*drw_y*/; 808 top = y1 >> 16; 809 left = (x1 >> 16) & ~1; 810 npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 811 812 switch(id) { 813 case 0x59595959: 814 pPriv->Bpp = 1; 815 break; 816 default: 817 pPriv->Bpp = 2; 818 left <<= 1; 819 break; 820 case 0x32335652: 821 pPriv->Bpp = 4; 822 left <<= 2; 823 break; 824 } 825 pPriv->Bps = pPriv->Bpp * pPriv->xden; 826 if (offscreen) { 827 offset = (area->box.y1 * pitch) + (top * dstPitch); 828 dst_start = ((unsigned char *)pApm->FbBase) + 829 (pPriv->data = offset + left); 830 switch(id) { 831 case 0x32315659: 832 top &= ~1; 833 tmp = ((top >> 1) * srcPitch2) + (left >> 2); 834 offset2 += tmp; 835 offset3 += tmp; 836 nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 837 xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), 838 buf + offset2, buf + offset3, dst_start, 839 srcPitch, srcPitch2, dstPitch, 840 nlines, npixels); 841 break; 842 default: 843 if (id == 0x32335652) 844 npixels <<= 1; 845 else if (id == 0x59595959) 846 npixels >>= 1; 847 buf += (top * srcPitch) + left; 848 nlines = ((y2 + 0xffff) >> 16) - top; 849 if (offscreen) 850 xf86XVCopyPacked(buf, dst_start, srcPitch, dstPitch, 851 nlines, npixels); 852 break; 853 } 854 } 855 else 856 pPriv->data = buf - (unsigned char *)pApm->FbBase; 857 pPriv->on = 1; 858 A(WaitForFifo)(pApm, 3); 859 WRXW(pPriv->reg + 0x02, dstPitch >> 2); 860 WRXW(pPriv->reg + 0x04, scalex); 861 WRXW(pPriv->reg + 0x08, scaley); 862 pPriv->scalex = scalex; 863 pPriv->scaley = scaley; 864 if (scalex && scaley) 865 scale = 0x0E00; 866 else if (scalex) 867 scale = 0x0600; 868 else if (scaley) 869 scale = 0x0A00; 870 else 871 scale = 0; 872 switch(id) { 873 case 0x59595959: 874 pPriv->val = 0x017B | scale; 875 break; 876 case 0x32335652: 877 pPriv->val = 0x002F | (scale & 0xF7FF);/*Smoothing filter doesn't work*/ 878 break; 879 case 0x36315652: 880 pPriv->val = 0x002B | (scale & 0xF7FF); 881 break; 882 case 0x35315652: 883 pPriv->val = 0x0029 | (scale & 0xF7FF); 884 break; 885 case 0x59555956: 886 pPriv->val = 0x013B | scale; 887 break; 888 case 0x55595659: 889 pPriv->val = 0x014B | scale; 890 break; 891 case 0x32315659: 892 case 0x59565955: 893 default: 894 pPriv->val = 0x016B | scale; 895 break; 896 } 897 898 (void) A(ReputImage)(pScrn, drw_x, drw_y, clipBoxes, data, pDraw); 899 900 A(WaitForFifo)(pApm, 1); 901 WRXW(pPriv->reg, pPriv->val); 902 903 return Success; 904} 905 906#ifndef IOP_ACCESS 907static int 908ApmQueryImageAttributes(ScrnInfoPtr pScrn, int id, 909 unsigned short *w, unsigned short *h, 910 int *pitches, int *offsets) 911{ 912 int size, tmp; 913 914 if(*w > 1024) *w = 1024; 915 if(*h > 1024) *h = 1024; 916 917 *w = (*w + 1) & ~1; 918 if(offsets) offsets[0] = 0; 919 920 switch(id) { 921 case 0x32315659: 922 *h = (*h + 1) & ~1; 923 size = (*w + 3) & ~3; 924 if(pitches) pitches[0] = size; 925 size *= *h; 926 if(offsets) offsets[1] = size; 927 tmp = ((*w >> 1) + 3) & ~3; 928 if(pitches) pitches[1] = pitches[2] = tmp; 929 tmp *= (*h >> 1); 930 size += tmp; 931 if(offsets) offsets[2] = size; 932 size += tmp; 933 break; 934 case 0x59565955: 935 case 0x55595659: 936 case 0x59555956: 937 case 0x32595559: 938 size = *w << 1; 939 goto common; 940 case 0x59595959: 941 default: 942 size = *w; 943common: 944 if (pitches) 945 pitches[0] = size; 946 size *= *h; 947 break; 948 } 949 950 return size; 951} 952#endif 953#endif 954