i740_video.c revision 5c69f917
1/* 2 * Copyright 2001 by Patrick LERDA 3 * Portions Copyright by Stephen Blackheath 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Patrick LERDA not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Patrick LERDA makes no representations 12 * about the suitability of this software for any purpose. It is provided 13 * "as is" without express or implied warranty. 14 * 15 * PATRICK LERDA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL PATRICK LERDA BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 * 23 * Authors: Patrick LERDA 24 * with modifications by Stephen Blackheath (Aug 2002) 25 * 26 * REVISION HISTORY: 27 * December 2001 - Patrick LERDA's original i740fb project on SourceForge. 28 * 27 August 2002 - Patrick's version would run for an hour or two on my 29 * machine, then the screen would go blank (no signal to monitor) and for 30 * some reason I sometimes couldn't even log in through the network. I had 31 * to re-boot my machine. This version fixes that and makes a few other 32 * unnecessary tweaks. I am not certain, but I think the problem is that 33 * Patrick's code was reading a value from XRX register 0xD0, and or'ing 34 * with 0x10. When I removed this from the main loop, it became reliable. 35 * I suspect the hardware (whether just my cheap clone board only I'm not 36 * sure) was sometimes returning bogus values, which were then programmed 37 * back in - but I never checked this. This register is related to 38 * powering on or off certain subsystems of the i740 chip, so that might 39 * explain the blank screen. - Stephen Blackheath 40 * 3 September 2002 - Added software scaling in the situation where the 41 * screen size is smaller than the original video size, since scaling down 42 * is not supported by the hardware. The implementation of this is not 43 * quite complete. 44 * 12 September 2002 - Better software scaling with some averaging, giving a 45 * nicer picture. 46 */ 47 48 49/* 50 * i740_video.c: i740 Xv driver. Based on the mga Xv driver by Mark Vojkovich. 51 */ 52#ifdef HAVE_CONFIG_H 53#include "config.h" 54#endif 55 56#include <stdio.h> 57#include <string.h> 58#include <unistd.h> 59 60#include "xf86.h" 61#include "xf86_OSproc.h" 62#include "compiler.h" 63#include "xf86PciInfo.h" 64#include "xf86Pci.h" 65#include "xf86fbman.h" 66#include "regionstr.h" 67 68#include "xf86xv.h" 69#include <X11/extensions/Xv.h> 70#include "dixstruct.h" 71#include "fourcc.h" 72 73#include "vgaHW.h" 74#include "i740.h" 75 76 77#define FOURCC_RV15 0x35315652 78#define FOURCC_RV16 0x36315652 79 80/*-*/ 81#define i740_wc(fb,z,r,v) (pI740->writeControl(pI740,(z),(r),(v))) 82#define i740_rc(fb,z,r) (pI740->readControl(pI740,(z),(r))) 83/*-*/ 84 85#define OFF_DELAY 250 /* milliseconds */ 86#define FREE_DELAY 15000 87 88#define OFF_TIMER 0x01 89#define FREE_TIMER 0x02 90#define CLIENT_VIDEO_ON 0x04 91 92#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 93 94 95 96 97#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 98 99static Atom xvBrightness, xvContrast, xvColorKey; 100 101 102 103#define IMAGE_MAX_PHY_WIDTH 1024 /*720*/ 104#define IMAGE_MAX_PHY_HEIGHT 1024 /*576*/ 105 106 107#define IMAGE_MAX_LOG_WIDTH 1024 /*720*/ 108#define IMAGE_MAX_LOG_HEIGHT 1024 /*576*/ 109 110 111typedef struct { 112 CARD32 YBuf0offset; 113 CARD32 YBuf1offset; 114 115 unsigned char currentBuf; 116 117 int brightness; 118 int contrast; 119 120 RegionRec clip; 121 CARD32 colorKey; 122 123 CARD32 videoStatus; 124 Time offTime; 125 Time freeTime; 126 FBLinearPtr linear; 127 128} I740PortPrivRec, *I740PortPrivPtr; 129 130typedef struct { 131 CARD32 OBUF_0Y; 132 CARD32 OBUF_1Y; 133 CARD32 OBUF_0U; 134 CARD32 OBUF_0V; 135 CARD32 OBUF_1U; 136 CARD32 OBUF_1V; 137 CARD32 OV0STRIDE; 138 CARD32 YRGB_VPH; 139 CARD32 UV_VPH; 140 CARD32 HORZ_PH; 141 CARD32 INIT_PH; 142 CARD32 DWINPOS; 143 CARD32 DWINSZ; 144 CARD32 SWID; 145 CARD32 SWIDQW; 146 CARD32 SHEIGHT; 147 CARD32 YRGBSCALE; 148 CARD32 UVSCALE; 149 CARD32 OV0CLRC0; 150 CARD32 OV0CLRC1; 151 CARD32 DCLRKV; 152 CARD32 DCLRKM; 153 CARD32 SCLRKVH; 154 CARD32 SCLRKVL; 155 CARD32 SCLRKM; 156 CARD32 OV0CONF; 157 CARD32 OV0CMD; 158} I740OverlayRegRec, *I740OverlayRegPtr; 159 160#define GET_PORT_PRIVATE(pScrn) \ 161 (I740PortPrivPtr)((I740PTR(pScrn))->adaptor->pPortPrivates[0].ptr) 162 163 164/*-----------------------------------------------------------------------------------------*/ 165__inline__ static void i740fb_overlay_off(ScrnInfoPtr pScrn) 166{ 167 I740Ptr pI740 = I740PTR(pScrn); 168 169 /* 0x3C = COL_KEY_CNTL_1 */ 170 i740_wc(fb_p, MRX, 0x3C, (i740_rc(fb_p, MRX, 0x3C) | 0x02)); 171 usleep(50000); 172 /*i740_wc(fb_p, XRX, 0xD0, (i740_rc(fb_p, XRX, 0xD0) & ~0x10)); 173 usleep(50000);*/ 174 i740_wc(fb_p, XRX, 0xD0, 0x2F); 175} 176 177__inline__ static void i740fb_overlay_set(ScrnInfoPtr pScrn, I740PortPrivPtr pPriv, unsigned long mem1,unsigned long mem2, 178 unsigned long isrc_w,unsigned long isrc_h, /* source image size */ 179 unsigned long idst_w,unsigned long idst_h, /* destination image size */ 180 unsigned long ddst_x,unsigned long ddst_y, /* destination image pos to display */ 181 unsigned long ddst_w,unsigned long ddst_h, /* destination image size to display allows trunc... */ 182 unsigned long pitch,int flip, 183 unsigned char vd_mod) 184{ 185 I740Ptr pI740 = I740PTR(pScrn); 186 const int f_dbl=pScrn->currentMode->Flags & V_DBLSCAN; 187 188 if(f_dbl) { idst_h*=2; ddst_y*=2; ddst_h*=2; } 189 190 ddst_x+=pI740->ov_offset_x; 191 ddst_y+=pI740->ov_offset_y; 192 193 /* Program the i740 overlay to use the new image dimensions. */ 194 195 i740_wc(fb_p, MRX, 0x24, mem1>>16); 196 i740_wc(fb_p, MRX, 0x23, mem1>> 8); 197 i740_wc(fb_p, MRX, 0x22, mem1>> 0); 198 199 i740_wc(fb_p, MRX, 0x27, mem2>>16); 200 i740_wc(fb_p, MRX, 0x26, mem2>> 8); 201 i740_wc(fb_p, MRX, 0x25, mem2>> 0); 202 203 i740_wc(fb_p, MRX, 0x28, (( pitch >>3)-1) ); 204 205 { unsigned short v=ddst_x; i740_wc(fb_p, MRX, 0x2B, v>> 8); i740_wc(fb_p, MRX, 0x2A, v>> 0); } 206 { unsigned short v=ddst_x+ddst_w-1; i740_wc(fb_p, MRX, 0x2D, v>> 8); i740_wc(fb_p, MRX, 0x2C, v>> 0); } 207 { unsigned short v=ddst_y; i740_wc(fb_p, MRX, 0x2F, v>> 8); i740_wc(fb_p, MRX, 0x2E, v>> 0); } 208 { unsigned short v=ddst_y+ddst_h-1; i740_wc(fb_p, MRX, 0x31, v>> 8); i740_wc(fb_p, MRX, 0x30, v>> 0); } 209 210 i740_wc(fb_p, MRX, 0x32, (isrc_w<<8)/(idst_w)); 211 i740_wc(fb_p, MRX, 0x33, (isrc_h<<8)/(idst_h)); 212 213 i740_wc(fb_p, MRX, 0x50, 0); 214 i740_wc(fb_p, MRX, 0x51, 0); 215 216 i740_wc(fb_p, MRX, 0x1E, ( idst_w > isrc_w ? 0x04 : 0x00 ) | ( idst_h > isrc_h ? 0x08 : 0x00 )); 217 i740_wc(fb_p, MRX, 0x1F, ( idst_w > isrc_w ? 0x20 : 0x00 ) | ( (idst_h > isrc_h) && (pitch <= 720*2) ? 0xC0 : 0x00 ) | (vd_mod & 0x1F)); 218 219 /*i740_wc(fb_p, MRX, 0x20, 0);*/ 220 221 i740_wc(fb_p, MRX, 0x19, 0x00); 222 223 /*i740_wc(fb_p, XRX, 0xD0, i740_rc(fb_p, XRX, 0xD0) | 0x10 );*/ 224 i740_wc(fb_p, XRX, 0xD0, 0x3F); 225 /* 0x3C = COL_KEY_CNTL_1 */ 226 i740_wc(fb_p, MRX, 0x3C, 0x05 | 0x02); 227 228 /*i740_wc(fb_p, MRX, 0x20, (flip ? 0x14 : 0x04));*/ 229 /*i740_wc(fb_p, MRX, 0x20, 0);*/ 230 /*i740_wc(fb_p, XRX, 0xD0, i740_rc(fb_p, XRX, 0xD0) | 0x10 );*/ 231 /*i740_wc(fb_p, MRX, 0x19, 0x00);*/ 232 i740_wc(fb_p, MRX, 0x20, (flip ? 0x34 : 0x24)); /*SB*/ 233} 234 235__inline__ static void i740fb_colorkey(ScrnInfoPtr pScrn,unsigned long key) 236{ 237 I740Ptr pI740 = I740PTR(pScrn); 238 unsigned char r,g,b,rm,gm,bm; 239 240 /*//xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"colorkey=%04x depth=%d\n",key,pScrn->depth);*/ 241 242 switch(pScrn->depth) 243 { 244 case 4: r=0x00; g=0x00; b=key; rm=0xFF; gm=0xFF; bm=0xF0; break; 245 case 8: r=0x00; g=0x00; b=key; rm=0xFF; gm=0xFF; bm=0x00; break; 246 case 15: r=(key&0x7C00)>>7; g=(key&0x03E0)>>2; b=(key&0x001F)<<3; rm=0x07; gm=0x07; bm=0x07; break; 247 case 16: r=(key&0xF800)>>8; g=(key&0x07E0)>>3; b=(key&0x001F)<<3; rm=0x07; gm=0x03; bm=0x07; break; 248 default: /*24*/ r=(key&0xFF00)>>8; g=(key&0xFF00)>>3; b=(key&0xFF00)<<3; rm=0x00; gm=0x00; bm=0x00; break; 249 } 250 251 i740_wc(fb_p, MRX, 0x3D, r); 252 i740_wc(fb_p, MRX, 0x3E, g); 253 i740_wc(fb_p, MRX, 0x3F, b); 254 255 i740_wc(fb_p, MRX, 0x40, rm); 256 i740_wc(fb_p, MRX, 0x41, gm); 257 i740_wc(fb_p, MRX, 0x42, bm); 258} 259 260/*-----------------------------------------------------------------------------------------*/ 261 262 263 264static void I740ResetVideo(ScrnInfoPtr pScrn) 265{ 266 I740Ptr pI740 = I740PTR(pScrn); 267 I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 268 269 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740ResetVideo entered\n"); /* ### */ 270 271 /* 272 * Enable destination color keying 273 */ 274 275 i740fb_colorkey(pScrn,pPriv->colorKey); 276} 277 278 279 280/* I740ClipVideo - 281 282 Takes the dst box in standard X BoxRec form (top and left 283 edges inclusive, bottom and right exclusive). The new dst 284 box is returned. The source boundaries are given (x1, y1 285 inclusive, x2, y2 exclusive) and returned are the new source 286 boundaries in 16.16 fixed point. 287*/ 288 289static void I740ClipVideo( 290 BoxPtr dst, 291 INT32 *x1, 292 INT32 *x2, 293 INT32 *y1, 294 INT32 *y2, 295 BoxPtr extents, /* extents of the clip region */ 296 INT32 width, 297 INT32 height 298){ 299 INT32 vscale, hscale, delta; 300 int diff; 301 302 hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); 303 vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); 304 305 *x1 <<= 16; *x2 <<= 16; 306 *y1 <<= 16; *y2 <<= 16; 307 308 diff = extents->x1 - dst->x1; 309 if(diff > 0) { 310 dst->x1 = extents->x1; 311 *x1 += diff * hscale; 312 } 313 diff = dst->x2 - extents->x2; 314 if(diff > 0) { 315 dst->x2 = extents->x2; 316 *x2 -= diff * hscale; 317 } 318 diff = extents->y1 - dst->y1; 319 if(diff > 0) { 320 dst->y1 = extents->y1; 321 *y1 += diff * vscale; 322 } 323 diff = dst->y2 - extents->y2; 324 if(diff > 0) { 325 dst->y2 = extents->y2; 326 *y2 -= diff * vscale; 327 } 328 329 if(*x1 < 0) { 330 diff = (- *x1 + hscale - 1)/ hscale; 331 dst->x1 += diff; 332 *x1 += diff * hscale; 333 } 334 delta = *x2 - (width << 16); 335 if(delta > 0) { 336 diff = (delta + hscale - 1)/ hscale; 337 dst->x2 -= diff; 338 *x2 -= diff * hscale; 339 } 340 if(*y1 < 0) { 341 diff = (- *y1 + vscale - 1)/ vscale; 342 dst->y1 += diff; 343 *y1 += diff * vscale; 344 } 345 delta = *y2 - (height << 16); 346 if(delta > 0) { 347 diff = (delta + vscale - 1)/ vscale; 348 dst->y2 -= diff; 349 *y2 -= diff * vscale; 350 } 351} 352 353static void I740StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) 354{ 355 I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 356 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740StopVideo entered %p %d\n", (void*)data, (int)exit);*/ /* ### */ 357 358 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 359 360 if(exit) 361 { 362 if(pPriv->videoStatus & CLIENT_VIDEO_ON) 363 i740fb_overlay_off(pScrn); 364 365 if(pPriv->linear) 366 { 367 xf86FreeOffscreenLinear(pPriv->linear); 368 pPriv->linear = NULL; 369 } 370 pPriv->videoStatus = 0; 371 } 372 else 373 { 374 if(pPriv->videoStatus & CLIENT_VIDEO_ON) 375 { 376 pPriv->videoStatus |= OFF_TIMER; 377 pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 378 } 379 } 380 381} 382 383static int I740SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) 384{ 385 I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 386 I740Ptr pI740 = I740PTR(pScrn); 387 I740OverlayRegPtr overlay = (I740OverlayRegPtr) (pI740->FbBase + pI740->OverlayStart); 388 389 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740SetPortAttribute entered %d\n", (int) value);*/ /* ### */ 390 391 if(attribute == xvBrightness) 392 { 393 if((value < -128) || (value > 127)) 394 return BadValue; 395 pPriv->brightness = value; 396 overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); 397 /*//OVERLAY_UPDATE(pI740->OverlayPhysical);*/ 398 } 399 else 400 if(attribute == xvContrast) 401 { 402 if((value < 0) || (value > 255)) 403 return BadValue; 404 pPriv->contrast = value; 405 overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); 406 /*//OVERLAY_UPDATE(pI740->OverlayPhysical);*/ 407 } 408 else 409 if(attribute == xvColorKey) 410 { 411 pPriv->colorKey = value; 412 413 i740fb_colorkey(pScrn,pPriv->colorKey); 414 415 /*//OVERLAY_UPDATE(pI740->OverlayPhysical);*/ 416 REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 417 } 418 else 419 return BadMatch; 420 421 return Success; 422} 423 424static int I740GetPortAttribute( 425 ScrnInfoPtr pScrn, 426 Atom attribute, 427 INT32 *value, 428 pointer data 429){ 430 I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 431 432 if(attribute == xvBrightness) { 433 *value = pPriv->brightness; 434 } else 435 if(attribute == xvContrast) { 436 *value = pPriv->contrast; 437 } else 438 if(attribute == xvColorKey) { 439 *value = pPriv->colorKey; 440 } else return BadMatch; 441 442 return Success; 443} 444 445static void I740QueryBestSize( 446 ScrnInfoPtr pScrn, 447 Bool motion, 448 short vid_w, short vid_h, 449 short drw_w, short drw_h, 450 unsigned int *p_w, unsigned int *p_h, 451 pointer data 452){ 453 if(vid_w > (drw_w << 1)) drw_w = vid_w >> 1; 454 if(vid_h > (drw_h << 1)) drw_h = vid_h >> 1; 455 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740QueryBestSize entered %d %d %d %d\n", (int) vid_w, (int) vid_h, (int) drw_w, (int) drw_h); /* ### */ 456 fprintf(stderr, "fprintf - I740QueryBestSize entered %d %d %d %d\n", (int) vid_w, (int) vid_h, (int) drw_w, (int) drw_h); /* ### */ 457 458 *p_w = drw_w; 459 *p_h = drw_h; 460} 461 462static void I740CopyMungedData(ScrnInfoPtr pScrn, 463 unsigned char *src1, unsigned char *src2, unsigned char *src3, 464 int srcPitch, 465 int srcPitch2, 466 int dstPitch, 467 int h, 468 int w, 469 long scalex, 470 long scaley) 471{ 472 I740Ptr pI740 = I740PTR(pScrn); 473 I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 474 CARD32 *dst; 475 int i, j; 476 477 if (pPriv->currentBuf == 0) 478 dst = (CARD32 *)(pI740->FbBase + pPriv->YBuf0offset); 479 else 480 dst = (CARD32 *)(pI740->FbBase + pPriv->YBuf1offset); 481 482 dstPitch >>= 2; 483 w >>= 1; 484 485 /* If the space on the screen is smaller than the source image, then we use 486 * software scaling to make it smaller. */ 487 if (scalex > 0x10000 || scaley > 0x10000) { 488 int dsth = ((long) h * 0x10000L + scaley - 1) / scaley; 489 long halfx = scalex/2; 490 long dstj = 0; 491 for(j = 0; j < dsth; j++) { 492 int dstj_rnd = dstj >> 16; 493 unsigned char* src1_ = src1 + (dstj_rnd * srcPitch); 494 unsigned char* src2_ = src2 + ((dstj_rnd/2) * srcPitch2); 495 unsigned char* src3_ = src3 + ((dstj_rnd/2) * srcPitch2); 496 int dstw = ((long) w * 0x10000L + halfx - 1) / scalex; 497 long srci = 0; 498 for(i = 0; i < dstw; i++) { 499 long srci_rnd = srci >> 16; 500 long srci2_rnd = (srci + halfx) >> 16; 501 dst[i] = 502 (((src1_[srci_rnd << 1] | (src1_[(srci_rnd << 1) + 1] << 16) | 503 (src3_[srci_rnd] << 8) | (src2_[srci_rnd] << 24))) >> 1 & 0x7F7F7F7FL) 504 + 505 (((src1_[srci2_rnd << 1] | (src1_[(srci2_rnd << 1) + 1] << 16) | 506 (src3_[srci2_rnd] << 8) | (src2_[srci2_rnd] << 24))) >> 1 & 0x7F7F7F7FL); 507 srci += scalex; 508 } 509 dst += dstPitch; 510 dstj += scaley; 511 } 512 } 513 else { 514 for(j = 0; j < h; j++) { 515 for(i = 0; i < w; i++) { 516 dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | 517 (src3[i] << 8) | (src2[i] << 24); 518 } 519 dst += dstPitch; 520 src1 += srcPitch; 521 if(j & 1) { 522 src2 += srcPitch2; 523 src3 += srcPitch2; 524 } 525 } 526 } 527} 528 529 530__inline__ static void I740CopyPackedData(ScrnInfoPtr pScrn, 531 unsigned char *buf, 532 int srcPitch, 533 int dstPitch, 534 int top, 535 int left, 536 int h, 537 int w 538 ) 539{ 540 I740Ptr pI740 = I740PTR(pScrn); 541 I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 542 unsigned char *src, *dst; 543 544 src = buf + (top*srcPitch) + (left<<1); 545 546 if (pPriv->currentBuf == 0) 547 dst = pI740->FbBase + pPriv->YBuf0offset; 548 else 549 dst = pI740->FbBase + pPriv->YBuf1offset; 550 551 w <<= 1; 552 while(h--) { 553 memcpy(dst, src, w); 554 src += srcPitch; 555 dst += dstPitch; 556 } 557} 558 559 560__inline__ static void I740DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, 561 int dstPitch, /* of chroma for 4:2:0 */ 562 int x1, int y1, int x2, int y2, 563 BoxPtr dstBox, 564 short src_w, short src_h, short drw_w, short drw_h, 565 unsigned char vd_mod 566 ) 567{ 568 I740Ptr pI740 = I740PTR(pScrn); 569 I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 570 571 i740fb_overlay_set(pScrn,pPriv,pPriv->YBuf0offset,pPriv->YBuf1offset, 572 src_w,src_h, /* source image size */ 573 drw_w,drw_h, /* destination image size */ 574 dstBox->x1,dstBox->y1, /* destination image pos to display */ 575 dstBox->x2 - dstBox->x1,dstBox->y2 - dstBox->y1, /* destination image size to display allows trunc... */ 576 dstPitch,(pPriv->currentBuf != 0), 577 vd_mod); 578 579 i740fb_colorkey(pScrn,pPriv->colorKey); /* needed to reset properly the i740 board after switching from framebuffer */ 580} 581 582static FBLinearPtr I740AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) 583{ 584 ScreenPtr pScreen; 585 FBLinearPtr new_linear; 586 587 if(linear) 588 { 589 if(linear->size >= size) 590 return linear; 591 592 if(xf86ResizeOffscreenLinear(linear, size)) { 593 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory resized to %d - %p\n", (int) size, (void *)linear); /* ### */ 594 return linear; 595 } 596 597 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory free %p - %d < %d\n", (void *)linear, (int) linear->size, (int) size); /* ### */ 598 xf86FreeOffscreenLinear(linear); 599 } 600 601 pScreen = xf86ScrnToScreen(pScrn); 602 603 new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, NULL, NULL, NULL); 604 605 if(!new_linear) 606 { 607 int max_size; 608 609 xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, PRIORITY_EXTREME); 610 611 if(max_size < size) { 612 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory can't purge %d < %d\n", (int) max_size, (int) size); /* ### */ 613 return NULL; 614 } 615 616 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory purged %d\n", (int) max_size); /* ### */ 617 xf86PurgeUnlockedOffscreenAreas(pScreen); 618 new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, 619 NULL, NULL, NULL); 620 } 621 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory allocated %d - %p\n", (int) size, (void *)new_linear); /* ### */ 622 623 return new_linear; 624} 625 626static int I740PutImage(ScrnInfoPtr pScrn, 627 short src_x, short src_y, short drw_x, short drw_y, 628 short src_w, short src_h, short drw_w, short drw_h, 629 int id, unsigned char* buf, 630 short width, short height, 631 Bool sync, RegionPtr clipBoxes, pointer data, 632 DrawablePtr pDraw 633 ) 634{ 635 ScreenPtr pScreen = pScrn->pScreen; 636 I740Ptr pI740 = I740PTR(pScrn); 637 I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 638 INT32 x1, x2, y1, y2; 639 int srcPitch, dstPitch, srcPitch2=0; 640 int top, left, npixels, nlines, size; 641 BoxRec dstBox; 642 int offset2=0, offset3=0; 643 644 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740PutImage entered %d %d\n", (int) width, (int) height, id);*/ /* ### */ 645 646 /* Clip */ 647 x1 = src_x; 648 x2 = src_x + src_w; 649 y1 = src_y; 650 y2 = src_y + src_h; 651 652 dstBox.x1 = drw_x; 653 dstBox.x2 = drw_x + drw_w; 654 dstBox.y1 = drw_y; 655 dstBox.y2 = drw_y + drw_h; 656 657 I740ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 658 REGION_EXTENTS(pScreen, clipBoxes), width, height); 659 660 if((x1 >= x2) || (y1 >= y2)) { 661 return Success; 662 } 663 664 dstBox.x1 -= pScrn->frameX0; 665 dstBox.x2 -= pScrn->frameX0; 666 dstBox.y1 -= pScrn->frameY0; 667 dstBox.y2 -= pScrn->frameY0; 668 669 switch(id) 670 { 671 case FOURCC_YV12: 672 case FOURCC_I420: 673 srcPitch = (width + 3) & ~3; 674 offset2 = srcPitch * height; 675 srcPitch2 = ((width >> 1) + 3) & ~3; 676 offset3 = (srcPitch2 * (height >> 1)) + offset2; 677 dstPitch = ((width << 1) + 15) & ~15; 678 size = dstPitch * height; 679 break; 680 case FOURCC_UYVY: 681 case FOURCC_YUY2: 682 default: 683 srcPitch = (width << 1); 684 dstPitch = (srcPitch + 7) & ~7; 685 size = dstPitch * height; 686 break; 687 } 688 689 { 690 FBLinearPtr new_linear = I740AllocateMemory(pScrn, pPriv->linear, size); 691 if (new_linear != pPriv->linear) { 692 pPriv->linear = new_linear; 693 } 694 } 695 if(!pPriv->linear) 696 return BadAlloc; 697 698 /* fixup pointers */ 699 pPriv->YBuf0offset = pPriv->linear->offset*pI740->cpp; 700 pPriv->YBuf1offset = (pPriv->linear->offset*pI740->cpp) + size; 701 702 703#if 0 /*???*/ 704 /* wait for the last rendered buffer to be flipped in */ 705 while (((INREG(DOV0STA)&0x00100000)>>20) != pPriv->currentBuf); 706#endif 707 708 /* buffer swap */ 709 pPriv->currentBuf ^= 1; 710 711 /* copy data */ 712 top = y1 >> 16; 713 left = (x1 >> 16) & ~1; 714 npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 715 716 switch(id) { 717 case FOURCC_YV12: 718 case FOURCC_I420: 719 { 720 CARD32 tmp; 721 722 top &= ~1; 723 tmp = ((top >> 1) * srcPitch2) + (left >> 1); 724 offset2 += tmp; 725 offset3 += tmp; 726 727 if(id == FOURCC_I420) 728 { 729 tmp = offset2; 730 offset2 = offset3; 731 offset3 = tmp; 732 } 733 734 nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 735 736 /* If the screen image size is smaller than the video image size, then 737 * we use software scaling to make it smaller. The hardware takes care 738 * of scaling up - see i740fb_overlay_set. 739 */ 740 { 741 long scalex = 0x10000, scaley = 0x10000; 742 if (drw_w < src_w) 743 scalex = (0x10000L * (long) src_w) / (long) drw_w; 744 if (drw_h < src_h) 745 scaley = (0x10000L * (long) src_h) / (long) drw_h; 746 747 I740CopyMungedData(pScrn, buf + (top * srcPitch) + left, 748 buf + offset2, buf + offset3, 749 srcPitch, srcPitch2, dstPitch, nlines, npixels, scalex, scaley); 750 } 751 } 752 break; 753 754 case FOURCC_UYVY: case FOURCC_YUY2: default: 755 { 756 nlines = ((y2 + 0xffff) >> 16) - top; 757 /* Add software scaling as above. */ 758 I740CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines, 759 npixels); 760 } 761 break; 762 } 763 764 /* update cliplist */ 765 if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) 766 { 767 REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 768 /* draw these */ 769 xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes); 770 } 771 772 { 773 unsigned char vd_mod; 774 775 switch(id) 776 { 777 case FOURCC_RV15: vd_mod=0x09; break; 778 case FOURCC_RV16: vd_mod=0x08; break; 779 default: vd_mod=0x00; break; 780 } 781 782 I740DisplayVideo(pScrn, id, width, height, dstPitch, 783 x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h, 784 vd_mod); 785 } 786 787 pPriv->videoStatus = CLIENT_VIDEO_ON; 788 789 return Success; 790} 791 792 793static int I740QueryImageAttributes(ScrnInfoPtr pScrn, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets ) 794{ 795 int size,tmp; 796 797 if(*w > IMAGE_MAX_PHY_WIDTH) *w = IMAGE_MAX_PHY_WIDTH; 798 if(*h > IMAGE_MAX_PHY_HEIGHT) *h = IMAGE_MAX_PHY_HEIGHT; 799 800 *w = (*w + 1) & ~1; 801 if(offsets) offsets[0] = 0; 802 803 switch(id) 804 { 805 case FOURCC_YV12: 806 case FOURCC_I420: 807 *h = (*h + 1) & ~1; 808 size = (*w + 3) & ~3; 809 if(pitches) pitches[0] = size; 810 size *= *h; 811 if(offsets) offsets[1] = size; 812 tmp = ((*w >> 1) + 3) & ~3; 813 if(pitches) pitches[1] = pitches[2] = tmp; 814 tmp *= (*h >> 1); 815 size += tmp; 816 if(offsets) offsets[2] = size; 817 size += tmp; 818 break; 819 case FOURCC_UYVY: 820 case FOURCC_YUY2: 821 default: 822 size = *w << 1; 823 if(pitches) pitches[0] = size; 824 size *= *h; 825 break; 826 } 827 828 return size; 829} 830 831static void I740BlockHandler(BLOCKHANDLER_ARGS_DECL) 832{ 833 SCREEN_PTR(arg); 834 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 835 I740Ptr pI740 = I740PTR(pScrn); 836 I740PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 837 838 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740BlockHandler entered\n"); */ /* ### */ 839 840 pScreen->BlockHandler = pI740->BlockHandler; 841 842 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 843 844 pScreen->BlockHandler = I740BlockHandler; 845 846 if(pPriv->videoStatus & TIMER_MASK) 847 { 848 UpdateCurrentTime(); 849 if(pPriv->videoStatus & OFF_TIMER) 850 { 851 if(pPriv->offTime < currentTime.milliseconds) 852 { 853 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740BlockHandler: OFF_TIMER expired\n");*/ /* ### */ 854 /* Turn off the overlay */ 855 i740fb_overlay_off(pScrn); 856 857 pPriv->videoStatus = FREE_TIMER; 858 pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 859 } 860 } 861 else 862 { /* FREE_TIMER */ 863 if(pPriv->freeTime < currentTime.milliseconds) 864 { 865 if(pPriv->linear) 866 { 867 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740BlockHandler: FREE_TIMER expired\n");*/ /* ### */ 868 xf86FreeOffscreenLinear(pPriv->linear); 869 pPriv->linear = NULL; 870 } 871 pPriv->videoStatus = 0; 872 } 873 } 874 } 875} 876 877 878/*************************************************************************** 879 * Offscreen Images 880 ***************************************************************************/ 881 882typedef struct { 883 FBLinearPtr linear; 884 Bool isOn; 885} OffscreenPrivRec, * OffscreenPrivPtr; 886 887static int I740AllocateSurface( 888 ScrnInfoPtr pScrn, 889 int id, 890 unsigned short w, 891 unsigned short h, 892 XF86SurfacePtr surface 893){ 894 FBLinearPtr linear; 895 int pitch, size; 896 OffscreenPrivPtr pPriv; 897 I740Ptr pI740 = I740PTR(pScrn); 898 899 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateSurface entered %d %d\n", (int) w, (int) h); /* ### */ 900 901 if((w > IMAGE_MAX_LOG_WIDTH) || (h > IMAGE_MAX_LOG_HEIGHT)) 902 return BadAlloc; 903 904 w = (w + 1) & ~1; 905 pitch = ((w << 1) + 15) & ~15; 906 size = pitch * h; 907 908 if(!(linear = I740AllocateMemory(pScrn, NULL, size))) 909 return BadAlloc; 910 911 surface->width = w; 912 surface->height = h; 913 914 if(!(surface->pitches = malloc(sizeof(int)))) { 915 xf86FreeOffscreenLinear(linear); 916 return BadAlloc; 917 } 918 if(!(surface->offsets = malloc(sizeof(int)))) { 919 free(surface->pitches); 920 xf86FreeOffscreenLinear(linear); 921 return BadAlloc; 922 } 923 if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 924 free(surface->pitches); 925 free(surface->offsets); 926 xf86FreeOffscreenLinear(linear); 927 return BadAlloc; 928 } 929 930 pPriv->linear = linear; 931 pPriv->isOn = FALSE; 932 933 surface->pScrn = pScrn; 934 surface->id = id; 935 surface->pitches[0] = pitch; 936 surface->offsets[0] = linear->offset*pI740->cpp; 937 surface->devPrivate.ptr = (pointer)pPriv; 938 939 /*//memset(pI740->FbBase + surface->offsets[0],0,size);*/ 940 941 return Success; 942} 943 944static int I740StopSurface(XF86SurfacePtr surface) 945{ 946 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 947 948 if(pPriv->isOn) 949 { 950 /*//i740fb_overlay_off(pScrn);*/ 951 952 pPriv->isOn = FALSE; 953 } 954 955 return Success; 956} 957 958 959static int I740FreeSurface(XF86SurfacePtr surface) 960{ 961 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 962 963 if(pPriv->isOn) 964 { 965 I740StopSurface(surface); 966 } 967 968 xf86FreeOffscreenLinear(pPriv->linear); 969 free(surface->pitches); 970 free(surface->offsets); 971 free(surface->devPrivate.ptr); 972 973 return Success; 974} 975 976static int I740GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value) 977{ 978 return I740GetPortAttribute(pScrn, attribute, value, 0); 979} 980 981static int I740SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value) 982{ 983 return I740SetPortAttribute(pScrn, attribute, value, 0); 984} 985 986 987static int I740DisplaySurface(XF86SurfacePtr surface, short src_x, short src_y, 988 short drw_x, short drw_y, 989 short src_w, short src_h, 990 short drw_w, short drw_h, 991 RegionPtr clipBoxes) 992{ 993 OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 994 ScrnInfoPtr pScrn = surface->pScrn; 995 I740PortPrivPtr pI740Priv = GET_PORT_PRIVATE(pScrn); 996 997 INT32 x1, y1, x2, y2; 998 BoxRec dstBox; 999 1000 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740DisplaySurface entered\n"); /* ### */ 1001 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"I740DisplaySurface-----------------------------------\n");*/ 1002 /*//fprintf(stderr, "I740DisplaySurface-----------------------------------\n");*/ 1003 1004 1005 x1 = src_x; 1006 x2 = src_x + src_w; 1007 y1 = src_y; 1008 y2 = src_y + src_h; 1009 1010 dstBox.x1 = drw_x; 1011 dstBox.x2 = drw_x + drw_w; 1012 dstBox.y1 = drw_y; 1013 dstBox.y2 = drw_y + drw_h; 1014 1015 I740ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 1016 REGION_EXTENTS(screenInfo.screens[0], clipBoxes), 1017 surface->width, surface->height); 1018 1019 dstBox.x1 -= pScrn->frameX0; 1020 dstBox.x2 -= pScrn->frameX0; 1021 dstBox.y1 -= pScrn->frameY0; 1022 dstBox.y2 -= pScrn->frameY0; 1023 1024 /* fixup pointers */ 1025 pI740Priv->YBuf0offset = surface->offsets[0]; 1026 pI740Priv->YBuf1offset = pI740Priv->YBuf0offset; 1027 1028#if 0 /*???*/ 1029 /* wait for the last rendered buffer to be flipped in */ 1030 while (((INREG(DOV0STA)&0x00100000)>>20) != pI740Priv->currentBuf) { 1031 if(loops == 200000) { 1032 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n"); 1033 break; 1034 } 1035 loops++; 1036 } 1037#endif 1038 1039 /* buffer swap */ 1040 if (pI740Priv->currentBuf == 0) 1041 pI740Priv->currentBuf = 1; 1042 else 1043 pI740Priv->currentBuf = 0; 1044 1045 I740ResetVideo(pScrn); 1046 1047 I740DisplayVideo(pScrn, surface->id, surface->width, surface->height, 1048 surface->pitches[0], x1, y1, x2, y2, &dstBox, 1049 src_w, src_h, drw_w, drw_h, 1050 0x00); 1051 1052 xf86XVFillKeyHelper(pScrn->pScreen, pI740Priv->colorKey, clipBoxes); 1053 1054 pPriv->isOn = TRUE; 1055 /* we've prempted the XvImage stream so set its free timer */ 1056 if(pI740Priv->videoStatus & CLIENT_VIDEO_ON) { 1057 REGION_EMPTY(pScrn->pScreen, & pI740Priv->clip); 1058 UpdateCurrentTime(); 1059 pI740Priv->videoStatus = FREE_TIMER; 1060 pI740Priv->freeTime = currentTime.milliseconds + FREE_DELAY; 1061 pScrn->pScreen->BlockHandler = I740BlockHandler; 1062 } 1063 1064 return Success; 1065} 1066 1067/*-------------------------------------------------------------------------------------------*/ 1068#define NUM_IMAGES (sizeof(i740vid_Images)/sizeof(XF86ImageRec)) 1069static XF86ImageRec i740vid_Images[] = 1070{ 1071 XVIMAGE_YUY2, 1072 XVIMAGE_UYVY, 1073 XVIMAGE_YV12, /* converted to YUV2 while copying */ 1074 XVIMAGE_I420, /* converted to YUV2 while copying */ 1075 { 1076 FOURCC_RV15, 1077 XvRGB, 1078 LSBFirst, 1079 {'R','V','1','5', 1080 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 1081 16, 1082 XvPacked, 1083 1, 1084 15, 0x001F, 0x03E0, 0x7C00, 1085 0, 0, 0, 1086 0, 0, 0, 1087 0, 0, 0, 1088 {'R','V','B',0, 1089 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}, 1090 XvTopToBottom 1091 }, 1092 { 1093 FOURCC_RV16, 1094 XvRGB, 1095 LSBFirst, 1096 {'R','V','1','6', 1097 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 1098 16, 1099 XvPacked, 1100 1, 1101 16, 0x001F, 0x07E0, 0xF800, 1102 0, 0, 0, 1103 0, 0, 0, 1104 0, 0, 0, 1105 {'R','V','B',0, 1106 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}, 1107 XvTopToBottom 1108 }, 1109}; 1110 1111#define NUM_ATTRIBUTES (sizeof(i740vid_Attributes)/sizeof(XF86AttributeRec)) 1112 1113static XF86AttributeRec i740vid_Attributes[] = 1114{ 1115 {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 1116 {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 1117 {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} 1118}; 1119 1120 1121static void I740InitOffscreenImages(ScreenPtr pScreen) 1122{ 1123 XF86OffscreenImagePtr offscreenImages; 1124 { 1125 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1126 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740InitOffscreenImages entered\n"); /* ### */ 1127 } 1128 1129 /* need to free this someplace */ 1130 if(!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 1131 { 1132 return; 1133 } 1134 1135 offscreenImages[0].image = &i740vid_Images[0]; 1136 offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1137 offscreenImages[0].alloc_surface = I740AllocateSurface; 1138 offscreenImages[0].free_surface = I740FreeSurface; 1139 offscreenImages[0].display = I740DisplaySurface; 1140 offscreenImages[0].stop = I740StopSurface; 1141 offscreenImages[0].setAttribute = I740SetSurfaceAttribute; 1142 offscreenImages[0].getAttribute = I740GetSurfaceAttribute; 1143 offscreenImages[0].max_width = IMAGE_MAX_LOG_WIDTH; 1144 offscreenImages[0].max_height = IMAGE_MAX_LOG_HEIGHT; 1145 offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1146 offscreenImages[0].attributes = i740vid_Attributes; 1147 1148 xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1149} 1150 1151 1152 1153static XF86VideoAdaptorPtr I740SetupImageVideo(ScreenPtr pScreen) 1154{ 1155 /* client libraries expect an encoding */ 1156 static XF86VideoEncodingRec DummyEncoding[1] = 1157 { 1158 { 1159 0, 1160 "XV_IMAGE", 1161 IMAGE_MAX_PHY_WIDTH, IMAGE_MAX_PHY_HEIGHT, 1162 {1, 1} 1163 } 1164 }; 1165 1166#define NUM_FORMATS (sizeof(i740vid_Formats)/sizeof(XF86VideoFormatRec)) 1167 static XF86VideoFormatRec i740vid_Formats[] = 1168 { 1169 {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, {8, PseudoColor} 1170 }; 1171 1172 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1173 I740Ptr pI740 = I740PTR(pScrn); 1174 XF86VideoAdaptorPtr adapt; 1175 I740PortPrivPtr pPriv; 1176 1177 /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740SetupImageVideo entered\n");*/ /* ### */ 1178 { 1179 const int n=sizeof(XF86VideoAdaptorRec)+sizeof(I740PortPrivRec)+sizeof(DevUnion); 1180 1181 if(!(adapt = calloc(1, n))) 1182 return NULL; 1183 1184 /*//memset(adapt,0,n);*/ 1185 } 1186 1187 adapt->type = XvWindowMask | XvInputMask | XvImageMask; 1188 adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1189 adapt->name = "I740 Video Overlay"; 1190 adapt->nEncodings = 1; 1191 adapt->pEncodings = DummyEncoding; 1192 adapt->nFormats = NUM_FORMATS; 1193 adapt->pFormats = i740vid_Formats; 1194 adapt->nPorts = 1; 1195 adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 1196 1197 pPriv = (I740PortPrivPtr)((unsigned char *)(&adapt[1])+sizeof(sizeof(DevUnion))); 1198 1199 adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 1200 adapt->pAttributes = i740vid_Attributes; 1201 adapt->nImages = NUM_IMAGES; 1202 adapt->nAttributes = NUM_ATTRIBUTES; 1203 adapt->pImages = i740vid_Images; 1204 adapt->PutVideo = NULL; 1205 adapt->PutStill = NULL; 1206 adapt->GetVideo = NULL; 1207 adapt->GetStill = NULL; 1208 adapt->StopVideo = I740StopVideo; 1209 adapt->SetPortAttribute = I740SetPortAttribute; 1210 adapt->GetPortAttribute = I740GetPortAttribute; 1211 adapt->QueryBestSize = I740QueryBestSize; 1212 adapt->PutImage = I740PutImage; 1213 adapt->QueryImageAttributes = I740QueryImageAttributes; 1214 1215 pPriv->colorKey = pI740->colorKey & ((1 << pScrn->depth) - 1); 1216 pPriv->videoStatus = 0; 1217 pPriv->brightness = 0; 1218 pPriv->contrast = 64; 1219 pPriv->linear = NULL; 1220 pPriv->currentBuf = 0; 1221 1222 /* gotta uninit this someplace */ 1223 REGION_NULL(pScreen, &pPriv->clip); 1224 1225 pI740->adaptor = adapt; 1226 1227 pI740->BlockHandler = pScreen->BlockHandler; 1228 pScreen->BlockHandler = I740BlockHandler; 1229 1230 xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 1231 xvContrast = MAKE_ATOM("XV_CONTRAST"); 1232 xvColorKey = MAKE_ATOM("XV_COLORKEY"); 1233 1234 I740ResetVideo(pScrn); 1235 1236 return adapt; 1237} 1238 1239void I740InitVideo(ScreenPtr pScreen) 1240{ 1241 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1242 XF86VideoAdaptorPtr newAdaptor = NULL; 1243 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740InitVideo entered\n"); /* ### */ 1244 1245#if 0 /*disable!*/ 1246 { 1247 XF86VideoAdaptorPtr *ptr; 1248 int n; 1249 1250 n = xf86XVListGenericAdaptors(pScrn,&ptr); 1251 if (n) { 1252 xf86XVScreenInit(pScreen, ptr, n); 1253 } 1254 1255 return; 1256 } 1257#endif 1258 1259 { 1260 newAdaptor = I740SetupImageVideo(pScreen); 1261 I740InitOffscreenImages(pScreen); 1262 } 1263 1264 { 1265 XF86VideoAdaptorPtr *adaptors_oldptrs, *adaptors_newptrs = NULL; 1266 int num_adaptors; 1267 1268 num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors_oldptrs); 1269 1270 if(newAdaptor) 1271 { 1272 if(!num_adaptors) 1273 { 1274 xf86XVScreenInit(pScreen, &newAdaptor, 1); 1275 } 1276 else 1277 { 1278 if((adaptors_newptrs = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr)))) 1279 { 1280 memcpy(adaptors_newptrs, adaptors_oldptrs, num_adaptors * sizeof(XF86VideoAdaptorPtr)); 1281 adaptors_newptrs[num_adaptors] = newAdaptor; 1282 1283 /*//xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"num--- %d [%d] %08x %08x\n",num_adaptors,num_adaptors * sizeof(XF86VideoAdaptorPtr),*/ 1284 /*// adaptors_newptrs[0],adaptors_newptrs[1]);*/ 1285 1286 1287 xf86XVScreenInit(pScreen, adaptors_newptrs, num_adaptors+1); 1288 free(adaptors_newptrs); 1289 } 1290 } 1291 } 1292 1293 } 1294} 1295