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