savage_video.c revision 6aec45a7
1/* 2 * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. 3 * Copyright (c) 2003-2006, X.Org Foundation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Except as contained in this notice, the name of the copyright holder(s) 24 * and author(s) shall not be used in advertising or otherwise to promote 25 * the sale, use or other dealings in this Software without prior written 26 * authorization from the copyright holder(s) and author(s). 27 */ 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32 33#include <X11/extensions/Xv.h> 34#include "dix.h" 35#include "dixstruct.h" 36#include "fourcc.h" 37 38#include "savage_driver.h" 39#include "savage_streams.h" 40#include "savage_regs.h" 41#include "savage_bci.h" 42 43#define OFF_DELAY 200 /* milliseconds */ 44#define FREE_DELAY 60000 45 46#define OFF_TIMER 0x01 47#define FREE_TIMER 0x02 48#define CLIENT_VIDEO_ON 0x04 49 50#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 51 52void savageOUTREG( SavagePtr psav, unsigned long offset, unsigned long value ); 53 54static XF86VideoAdaptorPtr SavageSetupImageVideo(ScreenPtr); 55static void SavageInitOffscreenImages(ScreenPtr); 56static void SavageStopVideo(ScrnInfoPtr, pointer, Bool); 57static int SavageSetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 58static int SavageGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 59static void SavageQueryBestSize(ScrnInfoPtr, Bool, 60 short, short, short, short, unsigned int *, unsigned int *, pointer); 61static int SavagePutImage( ScrnInfoPtr, 62 short, short, short, short, short, short, short, short, 63 int, unsigned char*, short, short, Bool, RegionPtr, pointer, 64 DrawablePtr); 65static int SavageQueryImageAttributes(ScrnInfoPtr, 66 int, unsigned short *, unsigned short *, int *, int *); 67static void SavageFreeMemory(ScrnInfoPtr pScrn, void *mem_struct); 68 69void SavageResetVideo(ScrnInfoPtr pScrn); 70 71static void SavageSetColorKeyOld(ScrnInfoPtr pScrn); 72static void SavageSetColorKeyNew(ScrnInfoPtr pScrn); 73static void SavageSetColorKey2000(ScrnInfoPtr pScrn); 74static void (*SavageSetColorKey)(ScrnInfoPtr pScrn) = NULL; 75 76static void SavageSetColorOld(ScrnInfoPtr pScrn ); 77static void SavageSetColorNew(ScrnInfoPtr pScrn ); 78static void SavageSetColor2000(ScrnInfoPtr pScrn ); 79static void (*SavageSetColor)(ScrnInfoPtr pScrn ) = NULL; 80 81static void (*SavageInitStreams)(ScrnInfoPtr pScrn) = NULL; 82 83static void SavageDisplayVideoOld( 84 ScrnInfoPtr pScrn, int id, int offset, 85 short width, short height, int pitch, 86 int x1, int y1, int x2, int y2, 87 BoxPtr dstBox, 88 short src_w, short src_h, 89 short drw_w, short drw_h 90); 91static void SavageDisplayVideoNew( 92 ScrnInfoPtr pScrn, int id, int offset, 93 short width, short height, int pitch, 94 int x1, int y1, int x2, int y2, 95 BoxPtr dstBox, 96 short src_w, short src_h, 97 short drw_w, short drw_h 98); 99static void SavageDisplayVideo2000( 100 ScrnInfoPtr pScrn, int id, int offset, 101 short width, short height, int pitch, 102 int x1, int y1, int x2, int y2, 103 BoxPtr dstBox, 104 short src_w, short src_h, 105 short drw_w, short drw_h 106); 107static void (*SavageDisplayVideo)( 108 ScrnInfoPtr pScrn, int id, int offset, 109 short width, short height, int pitch, 110 int x1, int y1, int x2, int y2, 111 BoxPtr dstBox, 112 short src_w, short src_h, 113 short drw_w, short drw_h 114) = NULL; 115 116/*static void SavageBlockHandler(int, pointer, pointer, pointer);*/ 117 118#define XVTRACE 4 119 120#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 121 122static Atom xvColorKey, xvBrightness, xvContrast, xvSaturation, xvHue, xvInterpolation; 123 124/* client libraries expect an encoding */ 125static XF86VideoEncodingRec DummyEncoding[1] = 126{ 127 { 128 0, 129 "XV_IMAGE", 130 1024, 1024, 131 {1, 1} 132 } 133}; 134 135#define NUM_FORMATS 5 136 137static XF86VideoFormatRec Formats[NUM_FORMATS] = 138{ 139 {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 140}; 141 142#define NUM_ATTRIBUTES 6 143 144static XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 145{ 146 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 147 {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 148 {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}, 149 {XvSettable | XvGettable, 0, 255, "XV_SATURATION"}, 150 {XvSettable | XvGettable, -180, 180, "XV_HUE"}, 151 {XvSettable | XvGettable, 0, 1, "XV_VERTICAL_INTERPOLATION"} 152}; 153 154#define FOURCC_RV16 0x36315652 155#define FOURCC_RV15 0x35315652 156#define FOURCC_Y211 0x31313259 157 158/* 159 * For completeness sake, here is a cracking of the fourcc's I support. 160 * 161 * YUY2, packed 4:2:2, byte order: Y0 U0 Y1 V0 Y2 U2 Y3 V2 162 * Y211, packed 2:1:1, byte order: Y0 U0 Y2 V0 Y4 U2 Y6 V2 163 * YV12, planar 4:1:1, Y plane HxW, V plane H/2xW/2, U plane H/2xW/2 164 * I420, planar 4:1:1, Y plane HxW, U plane H/2xW/2, V plane H/2xW/2 165 * (I420 is also known as IYUV) 166 */ 167 168 169static XF86ImageRec Images[] = 170{ 171 XVIMAGE_YUY2, 172 XVIMAGE_YV12, 173 XVIMAGE_I420, 174 { 175 FOURCC_RV15, 176 XvRGB, 177 LSBFirst, 178 {'R','V','1','5', 179 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 180 16, 181 XvPacked, 182 1, 183 15, 0x001F, 0x03E0, 0x7C00, 184 0, 0, 0, 185 0, 0, 0, 186 0, 0, 0, 187 {'R','V','B',0, 188 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}, 189 XvTopToBottom 190 }, 191 { 192 FOURCC_RV16, 193 XvRGB, 194 LSBFirst, 195 {'R','V','1','6', 196 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 197 16, 198 XvPacked, 199 1, 200 16, 0x001F, 0x07E0, 0xF800, 201 0, 0, 0, 202 0, 0, 0, 203 0, 0, 0, 204 {'R','V','B',0, 205 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}, 206 XvTopToBottom 207 }, 208 { 209 FOURCC_Y211, 210 XvYUV, 211 LSBFirst, 212 {'Y','2','1','1', 213 0x00,0x00,0x00,0x10,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71}, 214 6, 215 XvPacked, 216 3, 217 0, 0, 0, 0 , 218 8, 8, 8, 219 2, 4, 4, 220 1, 1, 1, 221 {'Y','U','Y','V', 222 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}, 223 XvTopToBottom 224 } 225}; 226 227#define NUM_IMAGES (sizeof(Images)/sizeof(Images[0])) 228 229typedef struct { 230 int brightness; /* -128 .. 127 */ 231 CARD32 contrast; /* 0 .. 255 */ 232 CARD32 saturation; /* 0 .. 255 */ 233 int hue; /* -128 .. 127 */ 234 Bool interpolation; /* on/off */ 235 236 /*FBAreaPtr area;*/ 237 RegionRec clip; 238 CARD32 colorKey; 239 CARD32 videoStatus; 240 Time offTime; 241 Time freeTime; 242 int lastKnownPitch; 243 244 void *video_memory; /* opaque memory management information structure */ 245 CARD32 video_offset; /* offset in video memory of packed YUV buffer */ 246 247 void *video_planarmem; /* opaque memory management information structure */ 248 CARD32 video_planarbuf; /* offset in video memory of planar YV12 buffer */ 249 250#ifdef XF86DRI 251 Bool tried_agp; /* TRUE if AGP allocation has been tried */ 252 CARD32 agpBase; /* Physical address of aperture base */ 253 CARD32 agpBufferOffset; /* Offset of buffer in AGP memory, or 0 if unavailable */ 254 drmAddress agpBufferMap; /* Mapping of AGP buffer in process memory, or NULL */ 255#endif 256 257} SavagePortPrivRec, *SavagePortPrivPtr; 258 259 260#define GET_PORT_PRIVATE(pScrn) \ 261 (SavagePortPrivPtr)((SAVPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 262 263static 264unsigned int GetBlendForFourCC( int id ) 265{ 266 switch( id ) { 267 case FOURCC_YUY2: 268 case FOURCC_YV12: /* shouldn't this be 4? */ 269 case FOURCC_I420: /* shouldn't this be 4? */ 270 return 1; 271 case FOURCC_Y211: 272 return 4; 273 case FOURCC_RV15: 274 return 3; 275 case FOURCC_RV16: 276 return 5; 277 default: 278 return 0; 279 } 280} 281 282static 283unsigned int GetBlendForFourCC2000( int id ) 284{ 285 switch( id ) { 286 case FOURCC_YUY2: 287 return 1; 288 case FOURCC_I420: 289 return 1; /* was 4 */ 290 case FOURCC_YV12: 291 return 1; /* was 4 */ 292 case FOURCC_Y211: 293 return 4; 294 case FOURCC_RV15: 295 return 3; 296 case FOURCC_RV16: 297 return 5; 298 default: 299 return 0; 300 } 301} 302 303 304void savageOUTREG( SavagePtr psav, unsigned long offset, unsigned long value ) 305{ 306 ErrorF( "MMIO %08lx, was %08lx, want %08lx,", 307 offset, (CARD32)MMIO_IN32( psav->MapBase, offset ), value ); 308 MMIO_OUT32( psav->MapBase, offset, value ); 309 ErrorF( " now %08lx\n", (CARD32)MMIO_IN32( psav->MapBase, offset ) ); 310} 311 312#if 0 313static void 314SavageClipVWindow(ScrnInfoPtr pScrn) 315{ 316 SavagePtr psav = SAVPTR(pScrn); 317 318 if( (psav->Chipset == S3_SAVAGE_MX) || 319 (psav->Chipset == S3_SUPERSAVAGE) ) { 320 if (psav->IsSecondary) { 321 OUTREG(SEC_STREAM2_WINDOW_SZ, 0); 322 } else if (psav->IsPrimary) { 323 OUTREG(SEC_STREAM_WINDOW_SZ, 0); 324 } else { 325 OUTREG(SEC_STREAM_WINDOW_SZ, 0); 326#if 0 327 OUTREG(SEC_STREAM2_WINDOW_SZ, 0); 328#endif 329 } 330 } else if (psav->Chipset == S3_SAVAGE2000) { 331 OUTREG(SEC_STREAM_WINDOW_SZ, 0); 332 } else { 333 OUTREG( SSTREAM_WINDOW_SIZE_REG, 1); 334 OUTREG( SSTREAM_WINDOW_START_REG, 0x03ff03ff); 335 } 336} 337#endif 338 339void SavageInitVideo(ScreenPtr pScreen) 340{ 341 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 342 XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 343 XF86VideoAdaptorPtr newAdaptor = NULL; 344 SavagePtr psav = SAVPTR(pScrn); 345 int num_adaptors; 346 347 xf86ErrorFVerb(XVTRACE,"SavageInitVideo\n"); 348 if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset)) 349 { 350 newAdaptor = SavageSetupImageVideo(pScreen); 351 SavageInitOffscreenImages(pScreen); 352 353 SavageInitStreams = SavageInitStreamsNew; 354 SavageSetColor = SavageSetColorNew; 355 SavageSetColorKey = SavageSetColorKeyNew; 356 SavageDisplayVideo = SavageDisplayVideoNew; 357 } 358 else if (psav->Chipset == S3_SAVAGE2000) 359 { 360 newAdaptor = SavageSetupImageVideo(pScreen); 361 SavageInitOffscreenImages(pScreen); 362 363 SavageInitStreams = SavageInitStreams2000; 364 SavageSetColor = SavageSetColor2000; 365 SavageSetColorKey = SavageSetColorKey2000; 366 SavageDisplayVideo = SavageDisplayVideo2000; 367 } 368 else 369 { 370 newAdaptor = SavageSetupImageVideo(pScreen); 371 SavageInitOffscreenImages(pScreen); 372 373 SavageInitStreams = SavageInitStreamsOld; 374 SavageSetColor = SavageSetColorOld; 375 SavageSetColorKey = SavageSetColorKeyOld; 376 SavageDisplayVideo = SavageDisplayVideoOld; 377 } 378 379 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 380 381 if(newAdaptor) { 382 if(!num_adaptors) { 383 num_adaptors = 1; 384 adaptors = &newAdaptor; 385 } else { 386 newAdaptors = /* need to free this someplace */ 387 xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 388 if(newAdaptors) { 389 memcpy(newAdaptors, adaptors, num_adaptors * 390 sizeof(XF86VideoAdaptorPtr)); 391 newAdaptors[num_adaptors] = newAdaptor; 392 adaptors = newAdaptors; 393 num_adaptors++; 394 } 395 } 396 } 397 398 if(num_adaptors) 399 xf86XVScreenInit(pScreen, adaptors, num_adaptors); 400 401 if(newAdaptors) 402 xfree(newAdaptors); 403 404 if( newAdaptor ) 405 { 406 psav->videoFourCC = 0; 407 } 408} 409 410 411void SavageSetColorKeyOld(ScrnInfoPtr pScrn) 412{ 413 SavagePtr psav = SAVPTR(pScrn); 414 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 415 int red, green, blue; 416 417 /* Here, we reset the colorkey and all the controls. */ 418 419 red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 420 green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 421 blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 422 423 if( !pPriv->colorKey ) { 424 OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0 ); 425 OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0 ); 426 OUTREG( BLEND_CONTROL_REG, 0 ); 427 } 428 else { 429 switch (pScrn->depth) { 430 case 8: 431 OUTREG( COL_CHROMA_KEY_CONTROL_REG, 432 0x37000000 | (pPriv->colorKey & 0xFF) ); 433 OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 434 0x00000000 | (pPriv->colorKey & 0xFF) ); 435 break; 436 case 15: 437 OUTREG( COL_CHROMA_KEY_CONTROL_REG, 438 0x05000000 | (red<<19) | (green<<11) | (blue<<3) ); 439 OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 440 0x00000000 | (red<<19) | (green<<11) | (blue<<3) ); 441 break; 442 case 16: 443 OUTREG( COL_CHROMA_KEY_CONTROL_REG, 444 0x16000000 | (red<<19) | (green<<10) | (blue<<3) ); 445 OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 446 0x00020002 | (red<<19) | (green<<10) | (blue<<3) ); 447 break; 448 case 24: 449 OUTREG( COL_CHROMA_KEY_CONTROL_REG, 450 0x17000000 | (red<<16) | (green<<8) | (blue) ); 451 OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 452 0x00000000 | (red<<16) | (green<<8) | (blue) ); 453 break; 454 } 455 456 /* We use destination colorkey */ 457 OUTREG( BLEND_CONTROL_REG, 0x05000000 ); 458 } 459} 460 461void SavageSetColorKeyNew(ScrnInfoPtr pScrn) 462{ 463 SavagePtr psav = SAVPTR(pScrn); 464 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 465 int red, green, blue; 466 467 /* Here, we reset the colorkey and all the controls. */ 468 469 red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 470 green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 471 blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 472 473 if( !pPriv->colorKey ) { 474 if (psav->IsSecondary) { 475 OUTREG( SEC_STREAM2_CKEY_LOW, 0 ); 476 OUTREG( SEC_STREAM2_CKEY_UPPER, 0 ); 477 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 478 } else if (psav->IsPrimary) { 479 OUTREG( SEC_STREAM_CKEY_LOW, 0 ); 480 OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 481 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 482 } else { 483 OUTREG( SEC_STREAM_CKEY_LOW, 0 ); 484 OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); 485 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 486#if 0 487 sleep(1); 488 OUTREG( SEC_STREAM2_CKEY_LOW, 0 ); 489 OUTREG( SEC_STREAM2_CKEY_UPPER, 0 ); 490 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 491#endif 492 } 493 } 494 else { 495 switch (pScrn->depth) { 496 case 8: 497 if (psav->IsSecondary) { 498 OUTREG( SEC_STREAM2_CKEY_LOW, 499 0x47000000 | (pPriv->colorKey & 0xFF) ); 500 OUTREG( SEC_STREAM2_CKEY_UPPER, 501 0x47000000 | (pPriv->colorKey & 0xFF) ); 502 } else if (psav->IsPrimary) { 503 OUTREG( SEC_STREAM_CKEY_LOW, 504 0x47000000 | (pPriv->colorKey & 0xFF) ); 505 OUTREG( SEC_STREAM_CKEY_UPPER, 506 0x47000000 | (pPriv->colorKey & 0xFF) ); 507 } else { 508 OUTREG( SEC_STREAM_CKEY_LOW, 509 0x47000000 | (pPriv->colorKey & 0xFF) ); 510 OUTREG( SEC_STREAM_CKEY_UPPER, 511 0x47000000 | (pPriv->colorKey & 0xFF) ); 512#if 0 513 OUTREG( SEC_STREAM2_CKEY_LOW, 514 0x47000000 | (pPriv->colorKey & 0xFF) ); 515 OUTREG( SEC_STREAM2_CKEY_UPPER, 516 0x47000000 | (pPriv->colorKey & 0xFF) ); 517#endif 518 } 519 break; 520 case 15: 521 if (psav->IsSecondary) { 522 OUTREG( SEC_STREAM2_CKEY_LOW, 523 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 524 OUTREG( SEC_STREAM2_CKEY_UPPER, 525 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 526 } else if (psav->IsPrimary) { 527 OUTREG( SEC_STREAM_CKEY_LOW, 528 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 529 OUTREG( SEC_STREAM_CKEY_UPPER, 530 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 531 } else { 532 OUTREG( SEC_STREAM_CKEY_LOW, 533 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 534 OUTREG( SEC_STREAM_CKEY_UPPER, 535 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 536#if 0 537 OUTREG( SEC_STREAM2_CKEY_LOW, 538 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 539 OUTREG( SEC_STREAM2_CKEY_UPPER, 540 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 541#endif 542 } 543 break; 544 case 16: 545 if (psav->IsSecondary) { 546 OUTREG( SEC_STREAM2_CKEY_LOW, 547 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 548 OUTREG( SEC_STREAM2_CKEY_UPPER, 549 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 550 } else if (psav->IsPrimary) { 551 OUTREG( SEC_STREAM_CKEY_LOW, 552 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 553 OUTREG( SEC_STREAM_CKEY_UPPER, 554 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 555 } else { 556 OUTREG( SEC_STREAM_CKEY_LOW, 557 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 558 OUTREG( SEC_STREAM_CKEY_UPPER, 559 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 560#if 0 561 OUTREG( SEC_STREAM2_CKEY_LOW, 562 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 563 OUTREG( SEC_STREAM2_CKEY_UPPER, 564 0x46020002 | (red<<19) | (green<<10) | (blue<<3) ); 565#endif 566 } 567 break; 568 case 24: 569 if (psav->IsSecondary) { 570 OUTREG( SEC_STREAM2_CKEY_LOW, 571 0x47000000 | (red<<16) | (green<<8) | (blue) ); 572 OUTREG( SEC_STREAM2_CKEY_UPPER, 573 0x47000000 | (red<<16) | (green<<8) | (blue) ); 574 } else if (psav->IsPrimary) { 575 OUTREG( SEC_STREAM_CKEY_LOW, 576 0x47000000 | (red<<16) | (green<<8) | (blue) ); 577 OUTREG( SEC_STREAM_CKEY_UPPER, 578 0x47000000 | (red<<16) | (green<<8) | (blue) ); 579 } else { 580 OUTREG( SEC_STREAM_CKEY_LOW, 581 0x47000000 | (red<<16) | (green<<8) | (blue) ); 582 OUTREG( SEC_STREAM_CKEY_UPPER, 583 0x47000000 | (red<<16) | (green<<8) | (blue) ); 584#if 0 585 OUTREG( SEC_STREAM2_CKEY_LOW, 586 0x47000000 | (red<<16) | (green<<8) | (blue) ); 587 OUTREG( SEC_STREAM2_CKEY_UPPER, 588 0x47000000 | (red<<16) | (green<<8) | (blue) ); 589#endif 590 } 591 break; 592 } 593 594 /* We assume destination colorkey */ 595 if (psav->IsSecondary) { 596 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 597 } else if (psav->IsPrimary) { 598 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 599 } else { 600 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 601#if 0 602 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 603#endif 604 } 605 } 606} 607 608void SavageSetColorKey2000(ScrnInfoPtr pScrn) 609{ 610 SavagePtr psav = SAVPTR(pScrn); 611 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 612 int red, green, blue; 613 614 /* Here, we reset the colorkey and all the controls. */ 615 616 red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red; 617 green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green; 618 blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue; 619 620 if( !pPriv->colorKey ) { 621 OUTREG( SEC_STREAM_CKEY_LOW, 0); 622 OUTREG( SEC_STREAM_CKEY_UPPER, 0); 623 OUTREG( BLEND_CONTROL, (8 << 2)); 624 } 625 else { 626 switch (pScrn->depth) { 627 case 8: 628 OUTREG( SEC_STREAM_CKEY_LOW, 629 0x47000000 | (pPriv->colorKey & 0xFF) ); 630 OUTREG( SEC_STREAM_CKEY_UPPER, 631 (pPriv->colorKey & 0xFF) ); 632 break; 633 case 15: 634 OUTREG( SEC_STREAM_CKEY_LOW, 635 0x45000000 | (red<<19) | (green<<11) | (blue<<3) ); 636 OUTREG( SEC_STREAM_CKEY_UPPER, 637 (red<<19) | (green<<11) | (blue<<3) ); 638 break; 639 case 16: 640 OUTREG( SEC_STREAM_CKEY_LOW, 641 0x46000000 | (red<<19) | (green<<10) | (blue<<3) ); 642 OUTREG( SEC_STREAM_CKEY_UPPER, 643 (red<<19) | (green<<10) | (blue<<3) ); 644 break; 645 case 24: 646 OUTREG( SEC_STREAM_CKEY_LOW, 647 0x47000000 | (red<<16) | (green<<8) | (blue) ); 648 OUTREG( SEC_STREAM_CKEY_UPPER, 649 (red<<16) | (green<<8) | (blue) ); 650 break; 651 } 652 653 /* We assume destination colorkey */ 654 OUTREG( BLEND_CONTROL, INREG(BLEND_CONTROL) | (8 << 2)); 655 } 656} 657 658void SavageSetColorOld( ScrnInfoPtr pScrn ) 659{ 660 SavagePtr psav = SAVPTR(pScrn); 661 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 662 663 xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n", 664 pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue ); 665 666 if( 667 (psav->videoFourCC == FOURCC_RV15) || 668 (psav->videoFourCC == FOURCC_RV16) 669 ) 670 { 671 OUTREG( COLOR_ADJUSTMENT_REG, 0 ); 672 } 673 else 674 { 675 /* Change 0..255 into 0..15 */ 676 long sat = pPriv->saturation * 16 / 256; 677 double hue = pPriv->hue * 0.017453292; 678 unsigned long hs1 = ((long)(sat * cos(hue))) & 0x1f; 679 unsigned long hs2 = ((long)(sat * sin(hue))) & 0x1f; 680 681 OUTREG( COLOR_ADJUSTMENT_REG, 682 0x80008000 | 683 (pPriv->brightness + 128) | 684 ((pPriv->contrast & 0xf8) << (12-7)) | 685 (hs1 << 16) | 686 (hs2 << 24) 687 ); 688 689 } 690} 691 692void SavageSetColorNew( ScrnInfoPtr pScrn ) 693{ 694 SavagePtr psav = SAVPTR(pScrn); 695 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 696 697 /* Brightness/contrast/saturation/hue computations. */ 698 699 double k, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb; 700 int k1, k2, k3, k4, k5, k6, k7, kb; 701 double s = pPriv->saturation / 128.0; 702 double h = pPriv->hue * 0.017453292; 703 unsigned long assembly1, assembly2, assembly3; 704 705 xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n", 706 pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue ); 707 708 if( psav->videoFourCC == FOURCC_Y211 ) 709 k = 1.0; /* YUV */ 710 else 711 k = 1.14; /* YCrCb */ 712 713 /* 714 * The S3 documentation must be wrong for k4 and k5. Their default 715 * values, which they hardcode in their Windows driver, have the 716 * opposite sign from the results in the register spec. 717 */ 718 719 dk1 = k * pPriv->contrast; 720 dk2 = 64.0 * 1.371 * k * s * cos(h); 721 dk3 = -64.0 * 1.371 * k * s * sin(h); 722 dk4 = -128.0 * k * s * (0.698 * cos(h) - 0.336 * sin(h)); 723 dk5 = -128.0 * k * s * (0.698 * sin(h) + 0.336 * cos(h)); 724 dk6 = 64.0 * 1.732 * k * s * sin(h); /* == k3 / 1.26331, right? */ 725 dk7 = 64.0 * 1.732 * k * s * cos(h); /* == k2 / -1.26331, right? */ 726 dkb = 128.0 * pPriv->brightness + 64.0; 727 if( psav->videoFourCC != FOURCC_Y211 ) 728 dkb -= dk1 * 14.0; 729 730 k1 = (int)(dk1+0.5) & 0x1ff; 731 k2 = (int)(dk2+0.5) & 0x1ff; 732 k3 = (int)(dk3+0.5) & 0x1ff; 733 assembly1 = (k3<<18) | (k2<<9) | k1; 734 xf86ErrorFVerb(XVTRACE+1, "CC1 = %08lx ", assembly1 ); 735 736 k4 = (int)(dk4+0.5) & 0x1ff; 737 k5 = (int)(dk5+0.5) & 0x1ff; 738 k6 = (int)(dk6+0.5) & 0x1ff; 739 assembly2 = (k6<<18) | (k5<<9) | k4; 740 xf86ErrorFVerb(XVTRACE+1, "CC2 = %08lx ", assembly2 ); 741 742 k7 = (int)(dk7+0.5) & 0x1ff; 743 kb = (int)(dkb+0.5) & 0xffff; 744 assembly3 = (kb<<9) | k7; 745 xf86ErrorFVerb(XVTRACE+1, "CC3 = %08lx\n", assembly3 ); 746 747 if (psav->IsSecondary) { 748 OUTREG( SEC_STREAM2_COLOR_CONVERT1, assembly1 ); 749 OUTREG( SEC_STREAM2_COLOR_CONVERT2, assembly2 ); 750 OUTREG( SEC_STREAM2_COLOR_CONVERT3, assembly3 ); 751 } else if (psav->IsPrimary) { 752 OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly1 ); 753 OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly2 ); 754 OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly3 ); 755 } else { 756 OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly1 ); 757 OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly2 ); 758 OUTREG( SEC_STREAM_COLOR_CONVERT3, assembly3 ); 759#if 0 760 sleep(1); 761 OUTREG( SEC_STREAM2_COLOR_CONVERT1, assembly1 ); 762 OUTREG( SEC_STREAM2_COLOR_CONVERT2, assembly2 ); 763 OUTREG( SEC_STREAM2_COLOR_CONVERT3, assembly3 ); 764#endif 765 } 766} 767 768void SavageSetColor2000( ScrnInfoPtr pScrn ) 769{ 770 SavagePtr psav = SAVPTR(pScrn); 771 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 772 773 /* Brightness/contrast/saturation/hue computations. */ 774 775 double k, yb, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb; 776 int k1, k2, k3, k4, k5, k6, k7, kb; 777 double s = pPriv->saturation / 10000.0; 778 double h = pPriv->hue * 0.017453292; 779 unsigned long assembly1, assembly2, assembly3, assembly4; 780 unsigned long brightness = pPriv->brightness; 781 782 xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n", 783 pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue ); 784 785 if( psav->videoFourCC == FOURCC_Y211 ) { 786 k = 1.0;/* YUV */ 787 yb = 0.0; 788 } else { 789 k = 1.1;/* YCrCb */ 790 yb = 14.0; 791 } 792 793 dk1 = 128 * k * (pPriv->contrast / 10000.0); 794 if (dk1 < 0) 795 dk1 -= 0.5; 796 else 797 dk1 += 0.5; 798 dk2 = 64.0 * 1.371 * k * s * cos(h); 799 if (dk2 < 0) 800 dk2 -= 0.5; 801 else 802 dk2 += 0.5; 803 dk3 = -64.0 * 1.371 * k * s * sin(h); 804 if (dk3 < 0) 805 dk3 -= 0.5; 806 else 807 dk3 += 0.5; 808 dk4 = -128.0 * k * s * (0.698 * cos(h) + 0.336 * sin(h)); 809 if (dk4 < 0) 810 dk4 -= 0.5; 811 else 812 dk4 += 0.5; 813 dk5 = 128.0 * k * s * (0.698 * sin(h) - 0.336 * cos(h)); 814 if (dk5 < 0) 815 dk5 -= 0.5; 816 else 817 dk5 += 0.5; 818 dk6 = 64.0 * 1.732 * k * s * sin(h); 819 if (dk6 < 0) 820 dk6 -= 0.5; 821 else 822 dk6 += 0.5; 823 dk7 = 64.0 * 1.732 * k * s * cos(h); 824 if (dk7 < 0) 825 dk7 -= 0.5; 826 else 827 dk7 += 0.5; 828 829 if (pPriv->brightness <= 0) 830 brightness = pPriv->brightness * 200 / 750 - 200; 831 else 832 brightness = (pPriv->brightness - 750) * 200 / (10000 - 750); 833 dkb = 128 * (brightness - (k * pPriv->contrast * yb / 10000.0) + 0.5); 834 if (dkb < 0) 835 dkb -= 0.5; 836 else 837 dkb += 0.5; 838 839 k1 = (int)(dk1 /*+0.5*/) & 0x1ff; 840 k2 = (int)(dk2 /*+0.5*/) & 0x1ff; 841 assembly1 = (k2<<16) | k1; 842 843 k3 = (int)(dk3 /*+0.5*/) & 0x1ff; 844 k4 = (int)(dk4 /*+0.5*/) & 0x1ff; 845 assembly2 = (k4<<16) | k3; 846 847 k5 = (int)(dk5 /*+0.5*/) & 0x1ff; 848 k6 = (int)(dk6 /*+0.5*/) & 0x1ff; 849 assembly3 = (k6<<16) | k5; 850 851 k7 = (int)(dk7 /*+0.5*/) & 0x1ff; 852 kb = (int)(dkb /*+0.5*/) & 0xffff; 853 assembly4 = (kb<<16) | k7; 854 855#if 0 856 assembly1 = 0x640092; 857 assembly2 = 0x19a0000; 858 assembly3 = 0x001cf; 859 assembly4 = 0xf8ca007e; 860#endif 861 862 OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, assembly1 ); 863 OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, assembly2 ); 864 OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, assembly3 ); 865 OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, assembly4 ); 866 867} 868 869void SavageResetVideo(ScrnInfoPtr pScrn) 870{ 871 xf86ErrorFVerb(XVTRACE,"SavageResetVideo\n"); 872 SavageSetColor( pScrn ); 873 SavageSetColorKey( pScrn ); 874} 875 876 877static XF86VideoAdaptorPtr 878SavageSetupImageVideo(ScreenPtr pScreen) 879{ 880 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 881 SavagePtr psav = SAVPTR(pScrn); 882 XF86VideoAdaptorPtr adapt; 883 SavagePortPrivPtr pPriv; 884 885 xf86ErrorFVerb(XVTRACE,"SavageSetupImageVideo\n"); 886 887 if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 888 sizeof(SavagePortPrivRec) + 889 sizeof(DevUnion)))) 890 return NULL; 891 892 adapt->type = XvWindowMask | XvInputMask | XvImageMask; 893 adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 894 adapt->name = "Savage Streams Engine"; 895 adapt->nEncodings = 1; 896 adapt->pEncodings = DummyEncoding; 897 adapt->nFormats = NUM_FORMATS; 898 adapt->pFormats = Formats; 899 adapt->nPorts = 1; 900 adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 901 pPriv = (SavagePortPrivPtr)(&adapt->pPortPrivates[1]); 902 adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 903 adapt->pAttributes = Attributes; 904 adapt->nImages = NUM_IMAGES; 905 adapt->nAttributes = NUM_ATTRIBUTES; 906 adapt->pImages = Images; 907 adapt->PutVideo = NULL; 908 adapt->PutStill = NULL; 909 adapt->GetVideo = NULL; 910 adapt->GetStill = NULL; 911 adapt->StopVideo = SavageStopVideo; 912 adapt->SetPortAttribute = SavageSetPortAttribute; 913 adapt->GetPortAttribute = SavageGetPortAttribute; 914 adapt->QueryBestSize = SavageQueryBestSize; 915 adapt->PutImage = SavagePutImage; 916 adapt->QueryImageAttributes = SavageQueryImageAttributes; 917 918 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 919 xvContrast = MAKE_ATOM("XV_CONTRAST"); 920 xvColorKey = MAKE_ATOM("XV_COLORKEY"); 921 xvHue = MAKE_ATOM("XV_HUE"); 922 xvSaturation = MAKE_ATOM("XV_SATURATION"); 923 /* interpolation option only available on "old" streams */ 924 xvInterpolation = MAKE_ATOM("XV_VERTICAL_INTERPOLATION"); 925 926 pPriv->colorKey = 927 (1 << pScrn->offset.red) | 928 (1 << pScrn->offset.green) | 929 (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); 930 pPriv->videoStatus = 0; 931 pPriv->brightness = 0; 932 pPriv->contrast = 128; 933 pPriv->saturation = 128; 934#if 0 935 /* 936 * The S3 driver has these values for some of the chips. I have yet 937 * to find any Savage where these make sense. 938 */ 939 pPriv->brightness = 64; 940 pPriv->contrast = 16; 941 pPriv->saturation = 128; 942#endif 943 pPriv->hue = 0; 944 pPriv->lastKnownPitch = 0; 945 946 pPriv->interpolation = FALSE; 947 948 /* gotta uninit this someplace */ 949 REGION_NULL(pScreen, &pPriv->clip); 950 951 psav->adaptor = adapt; 952 953 #if 0 954 psav->BlockHandler = pScreen->BlockHandler; 955 pScreen->BlockHandler = SavageBlockHandler; 956 #endif 957 958 return adapt; 959} 960 961 962/* SavageClipVideo - 963 964 Takes the dst box in standard X BoxRec form (top and left 965 edges inclusive, bottom and right exclusive). The new dst 966 box is returned. The source boundaries are given (x1, y1 967 inclusive, x2, y2 exclusive) and returned are the new source 968 boundaries in 16.16 fixed point. 969*/ 970 971static void 972SavageClipVideo( 973 BoxPtr dst, 974 INT32 *x1, 975 INT32 *x2, 976 INT32 *y1, 977 INT32 *y2, 978 BoxPtr extents, /* extents of the clip region */ 979 INT32 width, 980 INT32 height 981){ 982 INT32 vscale, hscale, delta; 983 int diff; 984 985 hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); 986 vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); 987 988 *x1 <<= 16; *x2 <<= 16; 989 *y1 <<= 16; *y2 <<= 16; 990 991 diff = extents->x1 - dst->x1; 992 if(diff > 0) { 993 dst->x1 = extents->x1; 994 *x1 += diff * hscale; 995 } 996 diff = dst->x2 - extents->x2; 997 if(diff > 0) { 998 dst->x2 = extents->x2; 999 *x2 -= diff * hscale; 1000 } 1001 diff = extents->y1 - dst->y1; 1002 if(diff > 0) { 1003 dst->y1 = extents->y1; 1004 *y1 += diff * vscale; 1005 } 1006 diff = dst->y2 - extents->y2; 1007 if(diff > 0) { 1008 dst->y2 = extents->y2; 1009 *y2 -= diff * vscale; 1010 } 1011 1012 if(*x1 < 0) { 1013 diff = (- *x1 + hscale - 1)/ hscale; 1014 dst->x1 += diff; 1015 *x1 += diff * hscale; 1016 } 1017 delta = *x2 - (width << 16); 1018 if(delta > 0) { 1019 diff = (delta + hscale - 1)/ hscale; 1020 dst->x2 -= diff; 1021 *x2 -= diff * hscale; 1022 } 1023 if(*y1 < 0) { 1024 diff = (- *y1 + vscale - 1)/ vscale; 1025 dst->y1 += diff; 1026 *y1 += diff * vscale; 1027 } 1028 delta = *y2 - (height << 16); 1029 if(delta > 0) { 1030 diff = (delta + vscale - 1)/ vscale; 1031 dst->y2 -= diff; 1032 *y2 -= diff * vscale; 1033 } 1034} 1035 1036static void 1037SavageStopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 1038{ 1039 SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1040 SavagePtr psav = SAVPTR(pScrn); 1041 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 1042 1043 xf86ErrorFVerb(XVTRACE,"SavageStopVideo\n"); 1044 1045 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1046 1047 if(shutdown) { 1048 /*SavageClipVWindow(pScrn);*/ 1049 SavageStreamsOff( pScrn ); 1050 1051#ifdef XF86DRI 1052 if (pPriv->agpBufferMap != NULL) { 1053 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 1054 1055 /* agpXVideo is reused to implement UploadToScreen in EXA */ 1056 if (!psav->useEXA) { 1057 drmUnmap(pPriv->agpBufferMap, pSAVAGEDRIServer->agpXVideo.size); 1058 pSAVAGEDRIServer->agpXVideo.map = NULL; 1059 } 1060 pPriv->agpBufferMap = NULL; 1061 pPriv->agpBufferOffset = 0; 1062 } 1063 pPriv->tried_agp = FALSE; 1064#endif 1065 1066 if (pPriv->video_memory != NULL) { 1067 SavageFreeMemory(pScrn, pPriv->video_memory); 1068 pPriv->video_memory = NULL; 1069 } 1070 if (pPriv->video_planarmem != NULL) { 1071 SavageFreeMemory(pScrn, pPriv->video_planarmem); 1072 pPriv->video_planarmem = NULL; 1073 } 1074 pPriv->videoStatus = 0; 1075 } else { 1076 if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 1077 pPriv->videoStatus |= OFF_TIMER; 1078 pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 1079 } 1080 } 1081} 1082 1083 1084static int 1085SavageSetPortAttribute( 1086 ScrnInfoPtr pScrn, 1087 Atom attribute, 1088 INT32 value, 1089 pointer data 1090){ 1091 SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1092 SavagePtr psav = SAVPTR(pScrn); 1093 1094 if(attribute == xvColorKey) { 1095 pPriv->colorKey = value; 1096 if( psav->videoFlags & VF_STREAMS_ON) 1097 SavageSetColorKey( pScrn ); 1098 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 1099 } 1100 else if( attribute == xvBrightness) { 1101 if((value < -128) || (value > 127)) 1102 return BadValue; 1103 pPriv->brightness = value; 1104 if( psav->videoFlags & VF_STREAMS_ON) 1105 SavageSetColor( pScrn ); 1106 } 1107 else if( attribute == xvContrast) { 1108 if((value < 0) || (value > 255)) 1109 return BadValue; 1110 pPriv->contrast = value; 1111 if( psav->videoFlags & VF_STREAMS_ON) 1112 SavageSetColor( pScrn ); 1113 } 1114 else if( attribute == xvSaturation) { 1115 if((value < 0) || (value > 255)) 1116 return BadValue; 1117 pPriv->saturation = value; 1118 if( psav->videoFlags & VF_STREAMS_ON) 1119 SavageSetColor( pScrn ); 1120 } 1121 else if( attribute == xvHue) { 1122 if((value < -180) || (value > 180)) 1123 return BadValue; 1124 pPriv->hue = value; 1125 if( psav->videoFlags & VF_STREAMS_ON) 1126 SavageSetColor( pScrn ); 1127 } 1128 else if( attribute == xvInterpolation) { 1129 if((value < 0) || (value > 1)) 1130 return BadValue; 1131 if (value == 1) 1132 pPriv->interpolation = TRUE; 1133 else 1134 pPriv->interpolation = FALSE; 1135 } 1136 else 1137 return BadMatch; 1138 1139 return Success; 1140} 1141 1142 1143static int 1144SavageGetPortAttribute( 1145 ScrnInfoPtr pScrn, 1146 Atom attribute, 1147 INT32 *value, 1148 pointer data 1149){ 1150 SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1151 1152 if(attribute == xvColorKey) { 1153 *value = pPriv->colorKey; 1154 } 1155 else if( attribute == xvBrightness ) { 1156 *value = pPriv->brightness; 1157 } 1158 else if( attribute == xvContrast ) { 1159 *value = pPriv->contrast; 1160 } 1161 else if( attribute == xvHue ) { 1162 *value = pPriv->hue; 1163 } 1164 else if( attribute == xvSaturation ) { 1165 *value = pPriv->saturation; 1166 } 1167 else if( attribute == xvInterpolation ) { 1168 *value = pPriv->interpolation; 1169 } 1170 else return BadMatch; 1171 1172 return Success; 1173} 1174 1175static void 1176SavageQueryBestSize( 1177 ScrnInfoPtr pScrn, 1178 Bool motion, 1179 short vid_w, short vid_h, 1180 short drw_w, short drw_h, 1181 unsigned int *p_w, unsigned int *p_h, 1182 pointer data 1183){ 1184 /* What are the real limits for the Savage? */ 1185 1186 *p_w = drw_w; 1187 *p_h = drw_h; 1188 1189 if(*p_w > 16384) *p_w = 16384; 1190} 1191 1192/* SavageCopyPlanarDataBCI() causes artifacts on the screen when used on savage4. 1193 * It's probably something with the BCI. Maybe we need a waitforidle() or 1194 * something... 1195 */ 1196static void 1197SavageCopyPlanarDataBCI( 1198 ScrnInfoPtr pScrn, 1199 unsigned char *srcY, /* Y */ 1200 unsigned char *srcV, /* V */ 1201 unsigned char *srcU, /* U */ 1202 unsigned char *dst, 1203 unsigned char * planarPtr, 1204 unsigned long planarOffset, 1205 int srcPitch, int srcPitch2, 1206 int dstPitch, 1207 int h,int w, 1208 Bool isAGP) 1209{ 1210 SavagePtr psav = SAVPTR(pScrn); 1211 1212 /* for pixel transfer */ 1213 unsigned long offsetY = planarOffset; 1214 unsigned long offsetV = offsetY + srcPitch * h; 1215 unsigned long offsetU = offsetV + srcPitch2 * (h>>1); 1216 unsigned long dstOffset = (unsigned long)dst - (unsigned long)psav->FBBase; 1217 int i; 1218 unsigned char memType; 1219 1220 BCI_GET_PTR; 1221 1222 /* copy Y planar */ 1223 memcpy(planarPtr, srcY, srcPitch * h); 1224 1225 /* copy V planar */ 1226 planarPtr = planarPtr + srcPitch * h; 1227 memcpy(planarPtr, srcV, srcPitch2 * (h>>1)); 1228 1229 /* copy U planar */ 1230 planarPtr = planarPtr + srcPitch2 * (h>>1); 1231 memcpy(planarPtr, srcU, srcPitch2 * (h>>1)); 1232 1233 memType = isAGP ? 3 : 0; 1234 1235 /* 1236 * Transfer pixel data from one memory location to another location 1237 * and reformat the data during the transfer 1238 * a. program BCI51 to specify the source information 1239 * b. program BCI52 to specify the destination information 1240 * c. program BCI53 to specify the source dimensions 1241 * d. program BCI54 to specify the destination dimensions 1242 * e. (if the data is in YCbCr420 format)program BCI55,BCI56,BCI57 to 1243 * locations of the Y,Cb,and Cr data 1244 * f. program BCI50(command=011) to specify the formatting options and 1245 * kick off the transfer 1246 * this command can be used for color space conversion(YCbCr to RGB) 1247 * or for oversampling, but not for both simultaneously. it can also be 1248 * used to do mastered image transfer when the source is tiled 1249 */ 1250 1251 w = (w+0xf)&0xff0; 1252 psav->WaitQueue(psav,11); 1253 BCI_SEND(BCI_SET_REGISTER | BCI_SET_REGISTER_COUNT(7) | 0x51); 1254 BCI_SEND(offsetY | memType); 1255 BCI_SEND(dstOffset); 1256 BCI_SEND(((h-1)<<16)|((w-1)>>3)); 1257 BCI_SEND(dstPitch >> 3); 1258 BCI_SEND(offsetU | memType); 1259 BCI_SEND(offsetV | memType); 1260 BCI_SEND((srcPitch2 << 16)| srcPitch2); 1261 1262 BCI_SEND(BCI_SET_REGISTER | BCI_SET_REGISTER_COUNT(1) | 0x50); 1263 BCI_SEND(0x00200003 | srcPitch); 1264 1265 BCI_SEND(0xC0170000); 1266} 1267 1268static void 1269SavageCopyData( 1270 unsigned char *src, 1271 unsigned char *dst, 1272 int srcPitch, 1273 int dstPitch, 1274 int h, 1275 int w 1276){ 1277 w <<= 1; 1278 if (w == srcPitch && w == dstPitch) { 1279 memcpy(dst, src, w * h); 1280 } else 1281 while(h--) { 1282 memcpy(dst, src, w); 1283 src += srcPitch; 1284 dst += dstPitch; 1285 } 1286} 1287 1288static void 1289SavageCopyPlanarData( 1290 unsigned char *src1, /* Y */ 1291 unsigned char *src2, /* V */ 1292 unsigned char *src3, /* U */ 1293 unsigned char *dst1, 1294 int srcPitch, 1295 int srcPitch2, 1296 int dstPitch, 1297 int h, 1298 int w 1299){ 1300 CARD32 *dst = (CARD32*)dst1; 1301 int i, j; 1302 1303 dstPitch >>= 2; 1304 w >>= 1; 1305 1306 for(j = 0; j < h; j++) { 1307 for(i = 0; i < w; i++) { 1308/* Shouldn't this be 'if LITTLEENDIAN'? */ 1309#if 1 1310 dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | 1311 (src3[i] << 8) | (src2[i] << 24); 1312#else 1313 dst[i] = (src1[i << 1] << 24) | (src1[(i << 1) + 1] << 8) | 1314 (src3[i] << 0) | (src2[i] << 16); 1315#endif 1316 } 1317 dst += dstPitch; 1318 src1 += srcPitch; 1319 if(j & 1) { 1320 src2 += srcPitch2; 1321 src3 += srcPitch2; 1322 } 1323 } 1324} 1325 1326static void 1327SavageVideoSave(ScreenPtr pScreen, ExaOffscreenArea *area) 1328{ 1329 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 1330 SavagePtr psav = SAVPTR(pScrn); 1331 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1332 1333 if (pPriv->video_memory == area) 1334 pPriv->video_memory = NULL; 1335 if (pPriv->video_planarmem == area) 1336 pPriv->video_planarmem = NULL; 1337} 1338 1339static CARD32 1340SavageAllocateMemory( 1341 ScrnInfoPtr pScrn, 1342 void **mem_struct, 1343 int size 1344){ 1345 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; 1346 SavagePtr psav = SAVPTR(pScrn); 1347 int offset = 0; 1348 1349 if (psav->useEXA) { 1350 ExaOffscreenArea *area = *mem_struct; 1351 1352 if (area != NULL) { 1353 if (area->size >= size) 1354 return area->offset; 1355 1356 exaOffscreenFree(pScrn->pScreen, area); 1357 } 1358 1359 area = exaOffscreenAlloc(pScrn->pScreen, size, 64, TRUE, SavageVideoSave, 1360 NULL); 1361 *mem_struct = area; 1362 if (area == NULL) 1363 return 0; 1364 offset = area->offset; 1365 } 1366 1367 if (!psav->useEXA) { 1368 FBLinearPtr linear = *mem_struct; 1369 int cpp = pScrn->bitsPerPixel / 8; 1370 1371 /* XAA allocates in units of pixels at the screen bpp, so adjust size 1372 * appropriately. 1373 */ 1374 size = (size + cpp - 1) / cpp; 1375 1376 if (linear) { 1377 if(linear->size >= size) 1378 return linear->offset * cpp; 1379 1380 if(xf86ResizeOffscreenLinear(linear, size)) 1381 return linear->offset * cpp; 1382 1383 xf86FreeOffscreenLinear(linear); 1384 } 1385 1386 linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 1387 NULL, NULL, NULL); 1388 *mem_struct = linear; 1389 1390 if (!linear) { 1391 int max_size; 1392 1393 xf86QueryLargestOffscreenLinear(pScreen, &max_size, 16, 1394 PRIORITY_EXTREME); 1395 1396 if(max_size < size) 1397 return 0; 1398 1399 xf86PurgeUnlockedOffscreenAreas(pScreen); 1400 linear = xf86AllocateOffscreenLinear(pScreen, size, 16, 1401 NULL, NULL, NULL); 1402 *mem_struct = linear; 1403 if (!linear) 1404 return 0; 1405 } 1406 offset = linear->offset * cpp; 1407 } 1408 1409 return offset; 1410} 1411 1412static void 1413SavageFreeMemory( 1414 ScrnInfoPtr pScrn, 1415 void *mem_struct 1416){ 1417 SavagePtr psav = SAVPTR(pScrn); 1418 1419 if (psav->useEXA) { 1420 ExaOffscreenArea *area = mem_struct; 1421 1422 if (area != NULL) 1423 exaOffscreenFree(pScrn->pScreen, area); 1424 } 1425 if (!psav->useEXA) { 1426 FBLinearPtr linear = mem_struct; 1427 1428 if (linear != NULL) 1429 xf86FreeOffscreenLinear(linear); 1430 } 1431} 1432 1433static void 1434SavageSetBlend(ScrnInfoPtr pScrn, int id) 1435{ 1436 SavagePtr psav = SAVPTR(pScrn); 1437 1438 if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) 1439 { 1440 psav->blendBase = GetBlendForFourCC( id ); 1441 xf86ErrorFVerb(XVTRACE+1,"Format %4.4s, blend is %08x\n", (char*)&id, psav->blendBase ); 1442 if (psav->IsSecondary) { 1443 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 1444 } else if (psav->IsPrimary) { 1445 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 1446 } else { 1447 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 )); 1448#if 0 1449 OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 17) | (8 << 12) )); 1450#endif 1451 } 1452 } else if (psav->Chipset == S3_SAVAGE2000) { 1453 psav->blendBase = GetBlendForFourCC2000( id ); 1454 xf86ErrorFVerb(XVTRACE+1,"Format %4.4s, blend is %08x\n", (char*)&id, psav->blendBase ); 1455 if (id != FOURCC_YV12) 1456 OUTREG( BLEND_CONTROL, 1457 ((psav->blendBase << 24) | (8 << 2) /*| 0x20000000*/)); 1458 else 1459 OUTREG( BLEND_CONTROL, 1460 ((psav->blendBase << 24) | (8 << 2) /*| 0x10000000*/)); 1461 } 1462 1463 psav->videoFourCC = id; 1464} 1465 1466static void 1467SavageDisplayVideoOld( 1468 ScrnInfoPtr pScrn, 1469 int id, 1470 int offset, 1471 short width, short height, 1472 int pitch, 1473 int x1, int y1, int x2, int y2, 1474 BoxPtr dstBox, 1475 short src_w, short src_h, 1476 short drw_w, short drw_h 1477){ 1478 SavagePtr psav = SAVPTR(pScrn); 1479 vgaHWPtr hwp = VGAHWPTR(pScrn); 1480 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1481 /*DisplayModePtr mode = pScrn->currentMode;*/ 1482 int vgaCRIndex, vgaCRReg, vgaIOBase; 1483 CARD32 ssControl; 1484 int scalratio; 1485 1486 1487 vgaIOBase = hwp->IOBase; 1488 vgaCRIndex = vgaIOBase + 4; 1489 vgaCRReg = vgaIOBase + 5; 1490#if 0 1491 if ( psav->videoFourCC != id ) { 1492 SavageSetBlend(pScrn,id); 1493 SavageResetVideo(pScrn); 1494 } 1495#endif 1496 if( psav->videoFourCC != id ) 1497 SavageStreamsOff(pScrn); 1498 1499 if( !(psav->videoFlags & VF_STREAMS_ON) ) 1500 { 1501 SavageSetBlend(pScrn,id); 1502 SavageStreamsOn(pScrn); 1503 SavageResetVideo(pScrn); 1504 pPriv->lastKnownPitch = 0; 1505 } 1506 1507 if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) 1508 && psav->FPExpansion) { 1509 drw_w = (((float)(drw_w * psav->XExp1)/(float)psav->XExp2)+1); 1510 drw_h = (float)(drw_h * psav->YExp1)/(float)psav->YExp2+1; 1511 dstBox->x1 = (float)(dstBox->x1 * psav->XExp1)/(float)psav->XExp2; 1512 dstBox->y1 = (float)(dstBox->y1 * psav->YExp1)/(float)psav->YExp2; 1513 1514 dstBox->x1 += psav->displayXoffset; 1515 dstBox->y1 += psav->displayYoffset; 1516 } 1517 1518 /* 1519 * Process horizontal scaling 1520 * upscaling and downscaling smaller than 2:1 controled by MM8198 1521 * MM8190 controls downscaling mode larger than 2:1 1522 * Together MM8190 and MM8198 can set arbitrary downscale up to 64:1 1523 */ 1524 scalratio = 0; 1525 ssControl = 0; 1526 1527 if (src_w >= (drw_w * 2)) { 1528 if (src_w < (drw_w * 4)) { 1529 ssControl |= HDSCALE_4; 1530 scalratio = HSCALING(src_w,(drw_w*4)); 1531 } else if (src_w < (drw_w * 8)) { 1532 ssControl |= HDSCALE_8; 1533 scalratio = HSCALING(src_w,(drw_w*8)); 1534 } else if (src_w < (drw_w * 16)) { 1535 ssControl |= HDSCALE_16; 1536 scalratio = HSCALING(src_w,(drw_w*16)); 1537 } else if (src_w < (drw_w * 32)) { 1538 ssControl |= HDSCALE_32; 1539 scalratio = HSCALING(src_w,(drw_w*32)); 1540 } else if (src_w < (drw_w * 64)) { 1541 ssControl |= HDSCALE_64; 1542 scalratio = HSCALING(src_w,(drw_w*64)); 1543 } else { 1544 /* Request beyond maximum downscale! */ 1545 ssControl |= HDSCALE_64; 1546 scalratio = HSCALING(2,1); 1547 } 1548 } else 1549 scalratio = HSCALING(src_w,drw_w); 1550 1551 ssControl |= src_w; 1552 /*ssControl |= (1 << 24);*/ 1553 ssControl |= (GetBlendForFourCC(psav->videoFourCC) << 24); 1554#if 0 1555 /* Wait for VBLANK. */ 1556 VerticalRetraceWait(); 1557#endif 1558 OUTREG(SSTREAM_CONTROL_REG, ssControl); 1559 if (scalratio) 1560 OUTREG(SSTREAM_STRETCH_REG,scalratio); 1561 1562 /* Calculate vertical scale factor. */ 1563 OUTREG(SSTREAM_VINITIAL_REG, 0 ); 1564 /*OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );*/ 1565 OUTREG(SSTREAM_VSCALE_REG, VSCALING(src_h,drw_h)); 1566 1567 /* Set surface location and stride. */ 1568 OUTREG(SSTREAM_FBADDR0_REG, (offset + (x1>>15)) & (0x1ffffff & ~BASE_PAD) ); 1569 OUTREG(SSTREAM_FBADDR1_REG, 0); 1570 OUTREG(SSTREAM_STRIDE_REG, pitch & 0xfff ); 1571 1572 OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(dstBox->x1, dstBox->y1) ); 1573 OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(dstBox->x2-dstBox->x1, 1574 dstBox->y2-dstBox->y1)); 1575 1576 /* 1577 * MM81E8:Secondary Stream Source Line Count 1578 * bit_0~10: # of lines in the source image (before scaling) 1579 * bit_15 = 1: Enable vertical interpolation 1580 * 0: Line duplicaion 1581 */ 1582 /* 1583 * Vertical Interpolation is very bandwidth intensive. Some savages can't 1584 * seem to handle it. Default is line doubling. --AGD 1585 */ 1586 if (pPriv->interpolation) { 1587 if (src_w * 16 <= 0x3300) { 1588 OUTREG(SSTREAM_LINES_REG, 0x8000 | src_h ); 1589 OUTREG(FIFO_CONTROL, (INREG(FIFO_CONTROL) + 1)); 1590 } else { 1591 OUTREG(SSTREAM_LINES_REG, src_h ); 1592 } 1593 } else { 1594 OUTREG(SSTREAM_LINES_REG, src_h ); 1595 } 1596 1597#if 0 1598 /* Set color key on primary. */ 1599 1600 SavageSetColorKey( pScrn ); 1601#endif 1602 1603 /* Set FIFO L2 on second stream. */ 1604 1605 if( pPriv->lastKnownPitch != pitch ) 1606 { 1607 unsigned char cr92; 1608 1609 pPriv->lastKnownPitch = pitch; 1610 1611 pitch = (pitch + 7) / 8; 1612 VGAOUT8(vgaCRIndex, 0x92); 1613 cr92 = VGAIN8(vgaCRReg); 1614 VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1615 VGAOUT8(vgaCRIndex, 0x93); 1616 if (psav->bTiled && (( drw_h > src_h) || (drw_w > src_w))) 1617 VGAOUT8(vgaCRReg, pitch | 0xf); 1618 else 1619 VGAOUT8(vgaCRReg, pitch); 1620 } 1621} 1622 1623static void 1624SavageDisplayVideoNew( 1625 ScrnInfoPtr pScrn, 1626 int id, 1627 int offset, 1628 short width, short height, 1629 int pitch, 1630 int x1, int y1, int x2, int y2, 1631 BoxPtr dstBox, 1632 short src_w, short src_h, 1633 short drw_w, short drw_h 1634){ 1635 SavagePtr psav = SAVPTR(pScrn); 1636 vgaHWPtr hwp = VGAHWPTR(pScrn); 1637 /*DisplayModePtr mode = pScrn->currentMode;*/ 1638 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1639 int vgaCRIndex, vgaCRReg, vgaIOBase; 1640 1641 1642 vgaIOBase = hwp->IOBase; 1643 vgaCRIndex = vgaIOBase + 4; 1644 vgaCRReg = vgaIOBase + 5; 1645#if 0 1646 if ( psav->videoFourCC != id ) { 1647 SavageSetBlend(pScrn,id); 1648 SavageResetVideo(pScrn); 1649 } 1650#endif 1651 if( psav->videoFourCC != id ) 1652 SavageStreamsOff(pScrn); 1653 1654 if( !(psav->videoFlags & VF_STREAMS_ON) ) 1655 { 1656 SavageSetBlend(pScrn,id); 1657 SavageStreamsOn(pScrn); 1658 SavageResetVideo(pScrn); 1659 pPriv->lastKnownPitch = 0; 1660 } 1661 1662 /* Calculate horizontal and vertical scale factors. */ 1663 1664 if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) && 1665 (psav->DisplayType == MT_LCD) && 1666 !psav->CrtOnly && 1667 !psav->TvOn) 1668 { 1669 drw_w = (drw_w * psav->XExp1)/psav->XExp2 + 1; 1670 drw_h = (drw_h * psav->YExp1)/psav->YExp2 + 1; 1671 dstBox->x1 = (dstBox->x1 * psav->XExp1)/psav->XExp2; 1672 dstBox->y1 = (dstBox->y1 * psav->YExp1)/psav->YExp2; 1673 dstBox->x1 += psav->displayXoffset; 1674 dstBox->y1 += psav->displayYoffset; 1675 } 1676 1677 if (psav->IsSecondary) { 1678 OUTREG(SEC_STREAM2_HSCALING, 1679 ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1680 /* BUGBUG need to add 00040000 if src stride > 2048 */ 1681 OUTREG(SEC_STREAM2_VSCALING, 1682 ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1683 } else if (psav->IsPrimary) { 1684 OUTREG(SEC_STREAM_HSCALING, 1685 ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1686 /* BUGBUG need to add 00040000 if src stride > 2048 */ 1687 OUTREG(SEC_STREAM_VSCALING, 1688 ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1689 } else { 1690 OUTREG(SEC_STREAM_HSCALING, 1691 ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1692 /* BUGBUG need to add 00040000 if src stride > 2048 */ 1693 OUTREG(SEC_STREAM_VSCALING, 1694 ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1695#if 0 1696 OUTREG(SEC_STREAM2_HSCALING, 1697 ((src_w&0xfff)<<20) | ((65536 * src_w / drw_w) & 0x1FFFF )); 1698 /* BUGBUG need to add 00040000 if src stride > 2048 */ 1699 OUTREG(SEC_STREAM2_VSCALING, 1700 ((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF )); 1701#endif 1702 } 1703 1704 /* 1705 * Set surface location and stride. We use x1>>15 because all surfaces 1706 * are 2 bytes/pixel. 1707 */ 1708 1709 if (psav->IsSecondary) { 1710 OUTREG(SEC_STREAM2_FBUF_ADDR0, (offset + (x1>>15)) 1711 & (0x7ffffff & ~BASE_PAD)); 1712 OUTREG(SEC_STREAM2_STRIDE_LPB, pitch & 0xfff ); 1713 OUTREG(SEC_STREAM2_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1714 OUTREG(SEC_STREAM2_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1715 | (dstBox->x2-dstBox->x1) ); 1716 } else if (psav->IsPrimary) { 1717 OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) 1718 & (0x7ffffff & ~BASE_PAD)); 1719 OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff ); 1720 OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1721 OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1722 | (dstBox->x2-dstBox->x1) ); 1723 } else { 1724 OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15)) 1725 & (0x7ffffff & ~BASE_PAD)); 1726 OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff ); 1727 OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1728 OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1729 | (dstBox->x2-dstBox->x1) ); 1730#if 0 1731 OUTREG(SEC_STREAM2_FBUF_ADDR0, (offset + (x1>>15)) 1732 & (0x7ffffff & ~BASE_PAD)); 1733 OUTREG(SEC_STREAM2_STRIDE_LPB, pitch & 0xfff ); 1734 OUTREG(SEC_STREAM2_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) ); 1735 OUTREG(SEC_STREAM2_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16) 1736 | (dstBox->x2-dstBox->x1) ); 1737#endif 1738 } 1739 1740#if 0 1741 /* Set color key on primary. */ 1742 1743 SavageSetColorKey( pScrn ); 1744#endif 1745 1746 /* Set FIFO L2 on second stream. */ 1747 /* Is CR92 shadowed for crtc2? -- AGD */ 1748 if( pPriv->lastKnownPitch != pitch ) 1749 { 1750 unsigned char cr92; 1751 1752 pPriv->lastKnownPitch = pitch; 1753 pitch = (pitch + 7) / 8 - 4; 1754 VGAOUT8(vgaCRIndex, 0x92); 1755 cr92 = VGAIN8(vgaCRReg); 1756 VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1757 VGAOUT8(vgaCRIndex, 0x93); 1758 VGAOUT8(vgaCRReg, pitch); 1759 } 1760} 1761 1762static void 1763SavageDisplayVideo2000( 1764 ScrnInfoPtr pScrn, 1765 int id, 1766 int offset, 1767 short width, short height, 1768 int pitch, 1769 int x1, int y1, int x2, int y2, 1770 BoxPtr dstBox, 1771 short src_w, short src_h, 1772 short drw_w, short drw_h 1773){ 1774 SavagePtr psav = SAVPTR(pScrn); 1775 vgaHWPtr hwp = VGAHWPTR(pScrn); 1776 /*DisplayModePtr mode = pScrn->currentMode;*/ 1777 SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr; 1778 int vgaCRIndex, vgaCRReg, vgaIOBase; 1779 CARD32 addr0, addr1, addr2; 1780 1781 vgaIOBase = hwp->IOBase; 1782 vgaCRIndex = vgaIOBase + 4; 1783 vgaCRReg = vgaIOBase + 5; 1784 1785 1786 if( psav->videoFourCC != id ) 1787 SavageStreamsOff(pScrn); 1788 1789 if( !(psav->videoFlags & VF_STREAMS_ON) ) 1790 { 1791 SavageSetBlend(pScrn,id); 1792 SavageStreamsOn(pScrn); 1793 SavageResetVideo(pScrn); 1794 pPriv->lastKnownPitch = 0; 1795 } 1796 1797 if (src_w > drw_w) 1798 OUTREG(SEC_STREAM_SRC_START_2000, 0); 1799 else 1800 OUTREG(SEC_STREAM_SRC_START_2000, SRCSTART(x1, y1)); 1801 1802 /*OUTREG(SEC_STREAM_SRC_SIZE_2000, SRCSIZE(src_w, src_h));*/ 1803 OUTREG(SEC_STREAM_SRC_SIZE_2000, 1804 SRCSIZE((dstBox->x2-dstBox->x1), (dstBox->y2-dstBox->y1))); 1805 /* 1806 buffersize = (src_w * src_h * 2) / 4096; 1807 OUTREG(SEC_STREAM_BUFFERSIZE_2000, (buffersize & 0xffffff) << 12); 1808 */ 1809 1810 /*SavageResetVideo(pScrn);*/ 1811 1812 if( src_w > drw_w ) 1813 OUTREG(SEC_STREAM_HSCALE_NORMALIZE, HSCALING_NORMALIZE(drw_w,src_w)); 1814 else 1815 OUTREG(SEC_STREAM_HSCALE_NORMALIZE, (2048 << 16)); 1816 1817 /* Calculate horizontal and vertical scale factors. */ 1818 if ((src_w > drw_w) || (src_h > drw_h)) 1819 OUTREG(SEC_STREAM_HSCALING, (HSCALING_2000(src_w,drw_w)) | 0x01000000); 1820 else 1821 OUTREG(SEC_STREAM_HSCALING, HSCALING_2000(src_w,drw_w)); 1822 1823 OUTREG(SEC_STREAM_VSCALING, VSCALING_2000(src_h,drw_h)); 1824 1825 /* 1826 * Set surface location and stride. We use x1>>15 because all surfaces 1827 * are 2 bytes/pixel. 1828 */ 1829 1830 addr0 = offset + (x1>>15); /* Y in YCbCr420 */ 1831 addr1 = addr0 + (width * height); /* Cb in in YCbCr420 */ 1832 addr2 = addr1 + ((width * height) / 4); /* Cr in in YCbCr420 */ 1833 OUTREG(SEC_STREAM_FBUF_ADDR0, (addr0) & (0x3fffff & ~BASE_PAD)); 1834#if 0 1835 OUTREG(SEC_STREAM_FBUF_ADDR1, (addr1) & (0x3fffff & ~BASE_PAD)); 1836 OUTREG(SEC_STREAM_FBUF_ADDR2, (addr2) & (0x3fffff & ~BASE_PAD)); 1837#endif 1838 1839 OUTREG(SEC_STREAM_WINDOW_START, XY_2000(dstBox->x1,dstBox->y1)); 1840 OUTREG(SEC_STREAM_WINDOW_SZ, 1841 WH_2000((dstBox->x2-dstBox->x1),(dstBox->y2-dstBox->y1))); 1842 1843 /*pitch = width * 2;*/ 1844 OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff); 1845#if 0 1846 /* Y stride + CbCr stride in YCbCr420 */ 1847 OUTREG(SEC_STREAM_STRIDE, (pitch & 0xfff) + ((pitch & 0xfff) << 15)); 1848#endif 1849 1850#if 0 1851 /* Set color key on primary. */ 1852 1853 SavageSetColorKey2000( pScrn ); 1854#endif 1855 1856#if 0 1857 /* Set FIFO L2 on second stream. */ 1858 if( pPriv->lastKnownPitch != pitch ) 1859 { 1860 unsigned char cr92; 1861 1862 pPriv->lastKnownPitch = pitch; 1863 pitch = (pitch + 7) / 8 - 4; 1864 VGAOUT8(vgaCRIndex, 0x92); 1865 cr92 = VGAIN8(vgaCRReg); 1866 VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80); 1867 VGAOUT8(vgaCRIndex, 0x93); 1868 VGAOUT8(vgaCRReg, pitch); 1869 } 1870#endif 1871} 1872 1873static void 1874SavageFillKeyHelper(DrawablePtr pDraw, uint32_t colorKey, RegionPtr clipBoxes) 1875{ 1876#if HAVE_XV_DRAWABLE_HELPER 1877 xf86XVFillKeyHelperDrawable(pDraw, colorKey, clipBoxes); 1878#else 1879 xf86XVFillKeyHelper(pDraw->pScreen, colorKey, clipBoxes); 1880#endif 1881} 1882 1883static int 1884SavagePutImage( 1885 ScrnInfoPtr pScrn, 1886 short src_x, short src_y, 1887 short drw_x, short drw_y, 1888 short src_w, short src_h, 1889 short drw_w, short drw_h, 1890 int id, unsigned char* buf, 1891 short width, short height, 1892 Bool sync, 1893 RegionPtr clipBoxes, pointer data, 1894 DrawablePtr pDraw 1895){ 1896 SavagePortPrivPtr pPriv = (SavagePortPrivPtr)data; 1897 SavagePtr psav = SAVPTR(pScrn); 1898 ScreenPtr pScreen = pScrn->pScreen; 1899 INT32 x1, x2, y1, y2; 1900 unsigned char *dst_start; 1901 int pitch, new_size, offset, offsetV=0, offsetU=0; 1902 int srcPitch, srcPitch2=0, dstPitch; 1903 int planarFrameSize; 1904 int top, left, npixels, nlines; 1905 BoxRec dstBox; 1906 CARD32 tmp; 1907/* xf86ErrorFVerb(XVTRACE,"SavagePutImage\n"); */ 1908 if(drw_w > 16384) drw_w = 16384; 1909 1910 /* Clip */ 1911 x1 = src_x; 1912 x2 = src_x + src_w; 1913 y1 = src_y; 1914 y2 = src_y + src_h; 1915 1916 dstBox.x1 = drw_x; 1917 dstBox.x2 = drw_x + drw_w; 1918 dstBox.y1 = drw_y; 1919 dstBox.y2 = drw_y + drw_h; 1920 1921 SavageClipVideo(&dstBox, &x1, &x2, &y1, &y2, 1922 REGION_EXTENTS(pScreen, clipBoxes), width, height); 1923 1924 drw_w = dstBox.x2 - dstBox.x1; 1925 drw_h = dstBox.y2 - dstBox.y1; 1926 src_w = ( x2 - x1 ) >> 16; 1927 src_h = ( y2 - y1 ) >> 16; 1928 1929 if((x1 >= x2) || (y1 >= y2)) 1930 return Success; 1931 1932 dstBox.x1 -= pScrn->frameX0; 1933 dstBox.x2 -= pScrn->frameX0; 1934 dstBox.y1 -= pScrn->frameY0; 1935 dstBox.y2 -= pScrn->frameY0; 1936 1937 pitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 1938 1939 /* All formats directly displayable by Savage are packed and 2 bytes per pixel */ 1940 dstPitch = ((width << 1) + 15) & ~15; 1941 new_size = dstPitch * height; 1942 1943 switch(id) { 1944 case FOURCC_Y211: /* Y211 */ 1945 srcPitch = width; 1946 break; 1947 case FOURCC_YV12: /* YV12 */ 1948 srcPitch = (width + 3) & ~3; 1949 offsetV = srcPitch * height; 1950 srcPitch2 = ((width >> 1) + 3) & ~3; 1951 offsetU = (srcPitch2 * (height >> 1)) + offsetV; 1952 break; 1953 case FOURCC_I420: 1954 srcPitch = (width + 3) & ~3; 1955 offsetU = srcPitch * height; 1956 srcPitch2 = ((width >> 1) + 3) & ~3; 1957 offsetV = (srcPitch2 * (height >> 1)) + offsetU; 1958 break; 1959 case FOURCC_RV15: /* RGB15 */ 1960 case FOURCC_RV16: /* RGB16 */ 1961 case FOURCC_YUY2: /* YUY2 */ 1962 default: 1963 srcPitch = (width << 1); 1964 break; 1965 } 1966 1967 /* Calculate required memory for all planar frames */ 1968 planarFrameSize = 0; 1969 if (srcPitch2 != 0 && S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv) { 1970 new_size = ((new_size + 0xF) & ~0xF); 1971 planarFrameSize = srcPitch * height + srcPitch2 * height; 1972 } 1973 1974 /* Check whether AGP buffers can be allocated. If not, fall back to ordinary 1975 upload to framebuffer (slower) */ 1976#ifdef XF86DRI 1977 if (!pPriv->tried_agp && !psav->IsPCI && psav->drmFD > 0 && psav->DRIServerInfo != NULL) { 1978 int ret; 1979 SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo; 1980 1981 pPriv->tried_agp = TRUE; 1982 if (pSAVAGEDRIServer->agpXVideo.size >= max(new_size, planarFrameSize)) { 1983 if (pSAVAGEDRIServer->agpXVideo.map == NULL && 1984 drmMap( psav->drmFD, 1985 pSAVAGEDRIServer->agpXVideo.handle, 1986 pSAVAGEDRIServer->agpXVideo.size, 1987 &pSAVAGEDRIServer->agpXVideo.map ) < 0 ) { 1988 1989 xf86DrvMsg( pScreen->myNum, X_ERROR, "[agp] XVideo: Could not map agpXVideo \n" ); 1990 pPriv->agpBufferOffset = 0; 1991 pPriv->agpBufferMap = NULL; 1992 } else { 1993 pPriv->agpBufferMap = pSAVAGEDRIServer->agpXVideo.map; 1994 pPriv->agpBufferOffset = pSAVAGEDRIServer->agpXVideo.offset; 1995 pPriv->agpBase = drmAgpBase(psav->drmFD); 1996#if 0 1997 xf86DrvMsg( pScreen->myNum, X_INFO, 1998 "[agp] agpXVideo mapped at 0x%08lx aperture=0x%08x offset=0x%08lx\n", 1999 (unsigned long)pPriv->agpBufferMap, pPriv->agpBase, pPriv->agpBufferOffset); 2000#endif 2001 } 2002 } else { 2003 /* This situation is expected if AGPforXv is disabled, otherwise report. */ 2004 if (pSAVAGEDRIServer->agpXVideo.size > 0) { 2005 xf86DrvMsg( pScreen->myNum, X_ERROR, 2006 "[agp] XVideo: not enough space in buffer (got %ld bytes, required %ld bytes).\n", 2007 pSAVAGEDRIServer->agpXVideo.size, max(new_size, planarFrameSize)); 2008 } 2009 pPriv->agpBufferMap = NULL; 2010 pPriv->agpBufferOffset = 0; 2011 } 2012 } 2013#endif /* XF86DRI */ 2014 2015 2016 /* Buffer for final packed frame */ 2017 pPriv->video_offset = SavageAllocateMemory( 2018 pScrn, &pPriv->video_memory, 2019 new_size); 2020 if (pPriv->video_offset == 0) 2021 return BadAlloc; 2022 2023 /* Packed format cases */ 2024 if (planarFrameSize == 0) { 2025 pPriv->video_planarbuf = 0; 2026 2027 /* Planar format cases */ 2028 } else { 2029 /* Hardware-assisted planar conversion only works on 16-byte aligned addresses */ 2030 pPriv->video_planarbuf = SavageAllocateMemory( 2031 pScrn, &pPriv->video_planarmem, 2032 ((planarFrameSize + 0xF) & ~0xF)); 2033 if (pPriv->video_planarbuf != 0) { 2034 /* TODO: stop any pending conversions when buffers change... */ 2035 pPriv->video_planarbuf = ((pPriv->video_planarbuf + 0xF) & ~0xF); 2036 } else { 2037 /* Fallback using software conversion */ 2038 } 2039 } 2040 2041 /* copy data */ 2042 top = y1 >> 16; 2043 left = (x1 >> 16) & ~1; 2044 npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 2045 left <<= 1; 2046 2047 offset = (pPriv->video_offset) + (top * dstPitch); 2048 dst_start = (psav->FBBase + ((offset + left) & ~BASE_PAD)); 2049 2050 switch(id) { 2051 case FOURCC_YV12: /* YV12 */ 2052 case FOURCC_I420: 2053 top &= ~1; 2054 tmp = ((top >> 1) * srcPitch2) + (left >> 2); 2055 offsetU += tmp; 2056 offsetV += tmp; 2057 nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 2058 if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv && (npixels & 0xF) == 0 && pPriv->video_planarbuf != 0) { 2059#ifdef XF86DRI 2060 if (pPriv->agpBufferMap != NULL) { 2061 /* Using copy to AGP memory */ 2062 SavageCopyPlanarDataBCI( 2063 pScrn, 2064 buf + (top * srcPitch) + (left >> 1), 2065 buf + offsetV, 2066 buf + offsetU, 2067 dst_start, 2068 pPriv->agpBufferMap, 2069 pPriv->agpBase + pPriv->agpBufferOffset, 2070 srcPitch, srcPitch2, dstPitch, nlines, npixels, TRUE); 2071 } else 2072#endif /* XF86DRI */ 2073 { 2074 /* Using ordinary copy to framebuffer */ 2075 SavageCopyPlanarDataBCI( 2076 pScrn, 2077 buf + (top * srcPitch) + (left >> 1), 2078 buf + offsetV, 2079 buf + offsetU, 2080 dst_start, 2081 (unsigned char *)psav->FBBase + pPriv->video_planarbuf, 2082 pPriv->video_planarbuf, 2083 srcPitch, srcPitch2, dstPitch, nlines, npixels, FALSE); 2084 } 2085 } else { 2086 SavageCopyPlanarData( 2087 buf + (top * srcPitch) + (left >> 1), 2088 buf + offsetV, 2089 buf + offsetU, 2090 dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels); 2091 } 2092 break; 2093 case FOURCC_Y211: /* Y211 */ 2094 case FOURCC_RV15: /* RGB15 */ 2095 case FOURCC_RV16: /* RGB16 */ 2096 case FOURCC_YUY2: /* YUY2 */ 2097 default: 2098 buf += (top * srcPitch) + left; 2099 nlines = ((y2 + 0xffff) >> 16) - top; 2100 SavageCopyData(buf, dst_start, srcPitch, dstPitch, nlines, npixels); 2101 break; 2102 } 2103 2104 /* We need to enable the video before we draw the chroma color. 2105 Otherwise, we get blue flashes. */ 2106 2107 SavageDisplayVideo(pScrn, id, offset, width, height, dstPitch, 2108 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 2109 2110 /* update cliplist */ 2111 if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) { 2112 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 2113 /* draw these */ 2114 SavageFillKeyHelper(pDraw, pPriv->colorKey, clipBoxes); 2115 2116 } 2117 2118 pPriv->videoStatus = CLIENT_VIDEO_ON; 2119 2120 return Success; 2121} 2122 2123static int 2124SavageQueryImageAttributes( 2125 ScrnInfoPtr pScrn, 2126 int id, 2127 unsigned short *w, unsigned short *h, 2128 int *pitches, int *offsets 2129){ 2130 int size, tmp; 2131 2132 if(*w > 1024) *w = 1024; 2133 if(*h > 1024) *h = 1024; 2134 2135 *w = (*w + 1) & ~1; 2136 if(offsets) offsets[0] = 0; 2137 2138 switch(id) { 2139 case FOURCC_IA44: 2140 if (pitches) pitches[0]=*w; 2141 size=(*w)*(*h); 2142 break; 2143 case FOURCC_Y211: 2144 size = *w << 2; 2145 if(pitches) pitches[0] = size; 2146 size *= *h; 2147 break; 2148 case FOURCC_YV12: 2149 case FOURCC_I420: 2150 *h = (*h + 1) & ~1; 2151 size = (*w + 3) & ~3; 2152 if(pitches) pitches[0] = size; 2153 size *= *h; 2154 if(offsets) offsets[1] = size; 2155 tmp = ((*w >> 1) + 3) & ~3; 2156 if(pitches) pitches[1] = pitches[2] = tmp; 2157 tmp *= (*h >> 1); 2158 size += tmp; 2159 if(offsets) offsets[2] = size; 2160 size += tmp; 2161 break; 2162 case FOURCC_RV15: /* RGB15 */ 2163 case FOURCC_RV16: /* RGB16 */ 2164 case FOURCC_YUY2: 2165 default: 2166 size = *w << 1; 2167 if(pitches) pitches[0] = size; 2168 size *= *h; 2169 break; 2170 } 2171 2172 return size; 2173} 2174 2175/****************** Offscreen stuff ***************/ 2176 2177typedef struct { 2178 void *surface_memory; 2179 Bool isOn; 2180} OffscreenPrivRec, * OffscreenPrivPtr; 2181 2182static int 2183SavageAllocateSurface( 2184 ScrnInfoPtr pScrn, 2185 int id, 2186 unsigned short w, 2187 unsigned short h, 2188 XF86SurfacePtr surface 2189){ 2190 int offset, size; 2191 int pitch, fbpitch, numlines; 2192 void *surface_memory = NULL; 2193 OffscreenPrivPtr pPriv; 2194 2195 if((w > 1024) || (h > 1024)) 2196 return BadAlloc; 2197 2198 w = (w + 1) & ~1; 2199 pitch = ((w << 1) + 15) & ~15; 2200 fbpitch = pScrn->bitsPerPixel * pScrn->displayWidth >> 3; 2201 numlines = ((pitch * h) + fbpitch - 1) / fbpitch; 2202 size = pitch * h; 2203 2204 offset = SavageAllocateMemory(pScrn, &surface_memory, size); 2205 if (offset == 0) 2206 return BadAlloc; 2207 2208 surface->width = w; 2209 surface->height = h; 2210 2211 if(!(surface->pitches = xalloc(sizeof(int)))) { 2212 SavageFreeMemory(pScrn, surface_memory); 2213 return BadAlloc; 2214 } 2215 if(!(surface->offsets = xalloc(sizeof(int)))) { 2216 xfree(surface->pitches); 2217 SavageFreeMemory(pScrn, surface_memory); 2218 return BadAlloc; 2219 } 2220 if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 2221 xfree(surface->pitches); 2222 xfree(surface->offsets); 2223 SavageFreeMemory(pScrn, surface_memory); 2224 return BadAlloc; 2225 } 2226 2227 pPriv->surface_memory = surface_memory; 2228 pPriv->isOn = FALSE; 2229 2230 surface->pScrn = pScrn; 2231 surface->id = id; 2232 surface->pitches[0] = pitch; 2233 surface->offsets[0] = offset; /*area->box.y1 * fbpitch;*/ 2234 surface->devPrivate.ptr = (pointer)pPriv; 2235 2236 return Success; 2237} 2238 2239static int 2240SavageStopSurface( 2241 XF86SurfacePtr surface 2242){ 2243 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2244 xf86ErrorFVerb(XVTRACE,"SavageStopSurface\n"); 2245 2246 if(pPriv->isOn) { 2247 /*SavagePtr psav = SAVPTR(surface->pScrn);*/ 2248 /*SavageClipVWindow(surface->pScrn);*/ 2249 SavageStreamsOff( surface->pScrn ); 2250 pPriv->isOn = FALSE; 2251 } 2252 2253 return Success; 2254} 2255 2256 2257static int 2258SavageFreeSurface( 2259 XF86SurfacePtr surface 2260){ 2261 ScrnInfoPtr pScrn = surface->pScrn; 2262 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2263 2264 if(pPriv->isOn) 2265 SavageStopSurface(surface); 2266 SavageFreeMemory(pScrn, pPriv->surface_memory); 2267 xfree(surface->pitches); 2268 xfree(surface->offsets); 2269 xfree(surface->devPrivate.ptr); 2270 2271 return Success; 2272} 2273 2274static int 2275SavageGetSurfaceAttribute( 2276 ScrnInfoPtr pScrn, 2277 Atom attribute, 2278 INT32 *value 2279){ 2280 return SavageGetPortAttribute(pScrn, attribute, value, 2281 (pointer)(GET_PORT_PRIVATE(pScrn))); 2282} 2283 2284static int 2285SavageSetSurfaceAttribute( 2286 ScrnInfoPtr pScrn, 2287 Atom attribute, 2288 INT32 value 2289){ 2290 return SavageSetPortAttribute(pScrn, attribute, value, 2291 (pointer)(GET_PORT_PRIVATE(pScrn))); 2292} 2293 2294 2295static int 2296SavageDisplaySurface( 2297 XF86SurfacePtr surface, 2298 short src_x, short src_y, 2299 short drw_x, short drw_y, 2300 short src_w, short src_h, 2301 short drw_w, short drw_h, 2302 RegionPtr clipBoxes 2303){ 2304 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 2305 ScrnInfoPtr pScrn = surface->pScrn; 2306 ScreenPtr pScreen = pScrn->pScreen; 2307 SavagePortPrivPtr portPriv = GET_PORT_PRIVATE(pScrn); 2308 INT32 x1, y1, x2, y2; 2309 BoxRec dstBox; 2310 xf86ErrorFVerb(XVTRACE,"SavageDisplaySurface\n"); 2311 2312 x1 = src_x; 2313 x2 = src_x + src_w; 2314 y1 = src_y; 2315 y2 = src_y + src_h; 2316 2317 dstBox.x1 = drw_x; 2318 dstBox.x2 = drw_x + drw_w; 2319 dstBox.y1 = drw_y; 2320 dstBox.y2 = drw_y + drw_h; 2321 2322 SavageClipVideo(&dstBox, &x1, &x2, &y1, &y2, 2323 REGION_EXTENTS(pScreen, clipBoxes), 2324 surface->width, surface->height); 2325 2326 if((x1 >= x2) || (y1 >= y2)) 2327 return Success; 2328 2329 dstBox.x1 -= pScrn->frameX0; 2330 dstBox.x2 -= pScrn->frameX0; 2331 dstBox.y1 -= pScrn->frameY0; 2332 dstBox.y2 -= pScrn->frameY0; 2333 2334 SavageDisplayVideo(pScrn, surface->id, surface->offsets[0], 2335 surface->width, surface->height, surface->pitches[0], 2336 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 2337 2338 xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 2339 2340 pPriv->isOn = TRUE; 2341#if 0 2342 if(portPriv->videoStatus & CLIENT_VIDEO_ON) { 2343 REGION_EMPTY(pScreen, &portPriv->clip); 2344 UpdateCurrentTime(); 2345 portPriv->videoStatus = FREE_TIMER; 2346 portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 2347 } 2348#endif 2349 2350 return Success; 2351} 2352 2353 2354static void 2355SavageInitOffscreenImages(ScreenPtr pScreen) 2356{ 2357 XF86OffscreenImagePtr offscreenImages; 2358 SavagePtr psav = SAVPTR(xf86Screens[pScreen->myNum]); 2359 2360 /* need to free this someplace */ 2361 if (!psav->offscreenImages) { 2362 if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) 2363 return; 2364 psav->offscreenImages = offscreenImages; 2365 } else { 2366 offscreenImages = psav->offscreenImages; 2367 } 2368 2369 offscreenImages[0].image = &Images[0]; 2370 offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | 2371 VIDEO_CLIP_TO_VIEWPORT; 2372 offscreenImages[0].alloc_surface = SavageAllocateSurface; 2373 offscreenImages[0].free_surface = SavageFreeSurface; 2374 offscreenImages[0].display = SavageDisplaySurface; 2375 offscreenImages[0].stop = SavageStopSurface; 2376 offscreenImages[0].setAttribute = SavageSetSurfaceAttribute; 2377 offscreenImages[0].getAttribute = SavageGetSurfaceAttribute; 2378 offscreenImages[0].max_width = 1024; 2379 offscreenImages[0].max_height = 1024; 2380 offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 2381 offscreenImages[0].attributes = Attributes; 2382 2383 xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 2384} 2385 2386