i740_video.c revision 5c69f917
1301ea0f4Smrg/* 2301ea0f4Smrg * Copyright 2001 by Patrick LERDA 3301ea0f4Smrg * Portions Copyright by Stephen Blackheath 4301ea0f4Smrg * 5301ea0f4Smrg * Permission to use, copy, modify, distribute, and sell this software and its 6301ea0f4Smrg * documentation for any purpose is hereby granted without fee, provided that 7301ea0f4Smrg * the above copyright notice appear in all copies and that both that 8301ea0f4Smrg * copyright notice and this permission notice appear in supporting 9301ea0f4Smrg * documentation, and that the name of Patrick LERDA not be used in 10301ea0f4Smrg * advertising or publicity pertaining to distribution of the software without 11301ea0f4Smrg * specific, written prior permission. Patrick LERDA makes no representations 12301ea0f4Smrg * about the suitability of this software for any purpose. It is provided 13301ea0f4Smrg * "as is" without express or implied warranty. 14301ea0f4Smrg * 15301ea0f4Smrg * PATRICK LERDA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16301ea0f4Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17301ea0f4Smrg * EVENT SHALL PATRICK LERDA BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18301ea0f4Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19301ea0f4Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20301ea0f4Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21301ea0f4Smrg * PERFORMANCE OF THIS SOFTWARE. 22301ea0f4Smrg * 23301ea0f4Smrg * Authors: Patrick LERDA 24301ea0f4Smrg * with modifications by Stephen Blackheath (Aug 2002) 25301ea0f4Smrg * 26301ea0f4Smrg * REVISION HISTORY: 27301ea0f4Smrg * December 2001 - Patrick LERDA's original i740fb project on SourceForge. 28301ea0f4Smrg * 27 August 2002 - Patrick's version would run for an hour or two on my 29301ea0f4Smrg * machine, then the screen would go blank (no signal to monitor) and for 30301ea0f4Smrg * some reason I sometimes couldn't even log in through the network. I had 31301ea0f4Smrg * to re-boot my machine. This version fixes that and makes a few other 32301ea0f4Smrg * unnecessary tweaks. I am not certain, but I think the problem is that 33301ea0f4Smrg * Patrick's code was reading a value from XRX register 0xD0, and or'ing 34301ea0f4Smrg * with 0x10. When I removed this from the main loop, it became reliable. 35301ea0f4Smrg * I suspect the hardware (whether just my cheap clone board only I'm not 36301ea0f4Smrg * sure) was sometimes returning bogus values, which were then programmed 37301ea0f4Smrg * back in - but I never checked this. This register is related to 38301ea0f4Smrg * powering on or off certain subsystems of the i740 chip, so that might 39301ea0f4Smrg * explain the blank screen. - Stephen Blackheath 40301ea0f4Smrg * 3 September 2002 - Added software scaling in the situation where the 41301ea0f4Smrg * screen size is smaller than the original video size, since scaling down 42301ea0f4Smrg * is not supported by the hardware. The implementation of this is not 43301ea0f4Smrg * quite complete. 44301ea0f4Smrg * 12 September 2002 - Better software scaling with some averaging, giving a 45301ea0f4Smrg * nicer picture. 46301ea0f4Smrg */ 47301ea0f4Smrg 48301ea0f4Smrg 49301ea0f4Smrg/* 50301ea0f4Smrg * i740_video.c: i740 Xv driver. Based on the mga Xv driver by Mark Vojkovich. 51301ea0f4Smrg */ 52301ea0f4Smrg#ifdef HAVE_CONFIG_H 53301ea0f4Smrg#include "config.h" 54301ea0f4Smrg#endif 55301ea0f4Smrg 56301ea0f4Smrg#include <stdio.h> 57301ea0f4Smrg#include <string.h> 585c69f917Smrg#include <unistd.h> 59301ea0f4Smrg 60301ea0f4Smrg#include "xf86.h" 61301ea0f4Smrg#include "xf86_OSproc.h" 62301ea0f4Smrg#include "compiler.h" 63301ea0f4Smrg#include "xf86PciInfo.h" 64301ea0f4Smrg#include "xf86Pci.h" 65301ea0f4Smrg#include "xf86fbman.h" 66301ea0f4Smrg#include "regionstr.h" 67301ea0f4Smrg 68301ea0f4Smrg#include "xf86xv.h" 69301ea0f4Smrg#include <X11/extensions/Xv.h> 70301ea0f4Smrg#include "dixstruct.h" 71301ea0f4Smrg#include "fourcc.h" 72301ea0f4Smrg 73301ea0f4Smrg#include "vgaHW.h" 74301ea0f4Smrg#include "i740.h" 75301ea0f4Smrg 76301ea0f4Smrg 77301ea0f4Smrg#define FOURCC_RV15 0x35315652 78301ea0f4Smrg#define FOURCC_RV16 0x36315652 79301ea0f4Smrg 80301ea0f4Smrg/*-*/ 81301ea0f4Smrg#define i740_wc(fb,z,r,v) (pI740->writeControl(pI740,(z),(r),(v))) 82301ea0f4Smrg#define i740_rc(fb,z,r) (pI740->readControl(pI740,(z),(r))) 83301ea0f4Smrg/*-*/ 84301ea0f4Smrg 85301ea0f4Smrg#define OFF_DELAY 250 /* milliseconds */ 86301ea0f4Smrg#define FREE_DELAY 15000 87301ea0f4Smrg 88301ea0f4Smrg#define OFF_TIMER 0x01 89301ea0f4Smrg#define FREE_TIMER 0x02 90301ea0f4Smrg#define CLIENT_VIDEO_ON 0x04 91301ea0f4Smrg 92301ea0f4Smrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 93301ea0f4Smrg 94301ea0f4Smrg 95301ea0f4Smrg 96301ea0f4Smrg 97301ea0f4Smrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 98301ea0f4Smrg 99301ea0f4Smrgstatic Atom xvBrightness, xvContrast, xvColorKey; 100301ea0f4Smrg 101301ea0f4Smrg 102301ea0f4Smrg 103301ea0f4Smrg#define IMAGE_MAX_PHY_WIDTH 1024 /*720*/ 104301ea0f4Smrg#define IMAGE_MAX_PHY_HEIGHT 1024 /*576*/ 105301ea0f4Smrg 106301ea0f4Smrg 107301ea0f4Smrg#define IMAGE_MAX_LOG_WIDTH 1024 /*720*/ 108301ea0f4Smrg#define IMAGE_MAX_LOG_HEIGHT 1024 /*576*/ 109301ea0f4Smrg 110301ea0f4Smrg 111301ea0f4Smrgtypedef struct { 112301ea0f4Smrg CARD32 YBuf0offset; 113301ea0f4Smrg CARD32 YBuf1offset; 114301ea0f4Smrg 115301ea0f4Smrg unsigned char currentBuf; 116301ea0f4Smrg 117301ea0f4Smrg int brightness; 118301ea0f4Smrg int contrast; 119301ea0f4Smrg 120301ea0f4Smrg RegionRec clip; 121301ea0f4Smrg CARD32 colorKey; 122301ea0f4Smrg 123301ea0f4Smrg CARD32 videoStatus; 124301ea0f4Smrg Time offTime; 125301ea0f4Smrg Time freeTime; 126301ea0f4Smrg FBLinearPtr linear; 127301ea0f4Smrg 128301ea0f4Smrg} I740PortPrivRec, *I740PortPrivPtr; 129301ea0f4Smrg 130301ea0f4Smrgtypedef struct { 131301ea0f4Smrg CARD32 OBUF_0Y; 132301ea0f4Smrg CARD32 OBUF_1Y; 133301ea0f4Smrg CARD32 OBUF_0U; 134301ea0f4Smrg CARD32 OBUF_0V; 135301ea0f4Smrg CARD32 OBUF_1U; 136301ea0f4Smrg CARD32 OBUF_1V; 137301ea0f4Smrg CARD32 OV0STRIDE; 138301ea0f4Smrg CARD32 YRGB_VPH; 139301ea0f4Smrg CARD32 UV_VPH; 140301ea0f4Smrg CARD32 HORZ_PH; 141301ea0f4Smrg CARD32 INIT_PH; 142301ea0f4Smrg CARD32 DWINPOS; 143301ea0f4Smrg CARD32 DWINSZ; 144301ea0f4Smrg CARD32 SWID; 145301ea0f4Smrg CARD32 SWIDQW; 146301ea0f4Smrg CARD32 SHEIGHT; 147301ea0f4Smrg CARD32 YRGBSCALE; 148301ea0f4Smrg CARD32 UVSCALE; 149301ea0f4Smrg CARD32 OV0CLRC0; 150301ea0f4Smrg CARD32 OV0CLRC1; 151301ea0f4Smrg CARD32 DCLRKV; 152301ea0f4Smrg CARD32 DCLRKM; 153301ea0f4Smrg CARD32 SCLRKVH; 154301ea0f4Smrg CARD32 SCLRKVL; 155301ea0f4Smrg CARD32 SCLRKM; 156301ea0f4Smrg CARD32 OV0CONF; 157301ea0f4Smrg CARD32 OV0CMD; 158301ea0f4Smrg} I740OverlayRegRec, *I740OverlayRegPtr; 159301ea0f4Smrg 160301ea0f4Smrg#define GET_PORT_PRIVATE(pScrn) \ 161301ea0f4Smrg (I740PortPrivPtr)((I740PTR(pScrn))->adaptor->pPortPrivates[0].ptr) 162301ea0f4Smrg 163301ea0f4Smrg 164301ea0f4Smrg/*-----------------------------------------------------------------------------------------*/ 165301ea0f4Smrg__inline__ static void i740fb_overlay_off(ScrnInfoPtr pScrn) 166301ea0f4Smrg{ 167301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 168301ea0f4Smrg 169301ea0f4Smrg /* 0x3C = COL_KEY_CNTL_1 */ 170301ea0f4Smrg i740_wc(fb_p, MRX, 0x3C, (i740_rc(fb_p, MRX, 0x3C) | 0x02)); 171301ea0f4Smrg usleep(50000); 172301ea0f4Smrg /*i740_wc(fb_p, XRX, 0xD0, (i740_rc(fb_p, XRX, 0xD0) & ~0x10)); 173301ea0f4Smrg usleep(50000);*/ 174301ea0f4Smrg i740_wc(fb_p, XRX, 0xD0, 0x2F); 175301ea0f4Smrg} 176301ea0f4Smrg 177301ea0f4Smrg__inline__ static void i740fb_overlay_set(ScrnInfoPtr pScrn, I740PortPrivPtr pPriv, unsigned long mem1,unsigned long mem2, 178301ea0f4Smrg unsigned long isrc_w,unsigned long isrc_h, /* source image size */ 179301ea0f4Smrg unsigned long idst_w,unsigned long idst_h, /* destination image size */ 180301ea0f4Smrg unsigned long ddst_x,unsigned long ddst_y, /* destination image pos to display */ 181301ea0f4Smrg unsigned long ddst_w,unsigned long ddst_h, /* destination image size to display allows trunc... */ 182301ea0f4Smrg unsigned long pitch,int flip, 183301ea0f4Smrg unsigned char vd_mod) 184301ea0f4Smrg{ 185301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 186301ea0f4Smrg const int f_dbl=pScrn->currentMode->Flags & V_DBLSCAN; 187301ea0f4Smrg 188301ea0f4Smrg if(f_dbl) { idst_h*=2; ddst_y*=2; ddst_h*=2; } 189301ea0f4Smrg 190301ea0f4Smrg ddst_x+=pI740->ov_offset_x; 191301ea0f4Smrg ddst_y+=pI740->ov_offset_y; 192301ea0f4Smrg 193301ea0f4Smrg /* Program the i740 overlay to use the new image dimensions. */ 194301ea0f4Smrg 195301ea0f4Smrg i740_wc(fb_p, MRX, 0x24, mem1>>16); 196301ea0f4Smrg i740_wc(fb_p, MRX, 0x23, mem1>> 8); 197301ea0f4Smrg i740_wc(fb_p, MRX, 0x22, mem1>> 0); 198301ea0f4Smrg 199301ea0f4Smrg i740_wc(fb_p, MRX, 0x27, mem2>>16); 200301ea0f4Smrg i740_wc(fb_p, MRX, 0x26, mem2>> 8); 201301ea0f4Smrg i740_wc(fb_p, MRX, 0x25, mem2>> 0); 202301ea0f4Smrg 203301ea0f4Smrg i740_wc(fb_p, MRX, 0x28, (( pitch >>3)-1) ); 204301ea0f4Smrg 205301ea0f4Smrg { unsigned short v=ddst_x; i740_wc(fb_p, MRX, 0x2B, v>> 8); i740_wc(fb_p, MRX, 0x2A, v>> 0); } 206301ea0f4Smrg { unsigned short v=ddst_x+ddst_w-1; i740_wc(fb_p, MRX, 0x2D, v>> 8); i740_wc(fb_p, MRX, 0x2C, v>> 0); } 207301ea0f4Smrg { unsigned short v=ddst_y; i740_wc(fb_p, MRX, 0x2F, v>> 8); i740_wc(fb_p, MRX, 0x2E, v>> 0); } 208301ea0f4Smrg { unsigned short v=ddst_y+ddst_h-1; i740_wc(fb_p, MRX, 0x31, v>> 8); i740_wc(fb_p, MRX, 0x30, v>> 0); } 209301ea0f4Smrg 210301ea0f4Smrg i740_wc(fb_p, MRX, 0x32, (isrc_w<<8)/(idst_w)); 211301ea0f4Smrg i740_wc(fb_p, MRX, 0x33, (isrc_h<<8)/(idst_h)); 212301ea0f4Smrg 213301ea0f4Smrg i740_wc(fb_p, MRX, 0x50, 0); 214301ea0f4Smrg i740_wc(fb_p, MRX, 0x51, 0); 215301ea0f4Smrg 216301ea0f4Smrg i740_wc(fb_p, MRX, 0x1E, ( idst_w > isrc_w ? 0x04 : 0x00 ) | ( idst_h > isrc_h ? 0x08 : 0x00 )); 217301ea0f4Smrg i740_wc(fb_p, MRX, 0x1F, ( idst_w > isrc_w ? 0x20 : 0x00 ) | ( (idst_h > isrc_h) && (pitch <= 720*2) ? 0xC0 : 0x00 ) | (vd_mod & 0x1F)); 218301ea0f4Smrg 219301ea0f4Smrg /*i740_wc(fb_p, MRX, 0x20, 0);*/ 220301ea0f4Smrg 221301ea0f4Smrg i740_wc(fb_p, MRX, 0x19, 0x00); 222301ea0f4Smrg 223301ea0f4Smrg /*i740_wc(fb_p, XRX, 0xD0, i740_rc(fb_p, XRX, 0xD0) | 0x10 );*/ 224301ea0f4Smrg i740_wc(fb_p, XRX, 0xD0, 0x3F); 225301ea0f4Smrg /* 0x3C = COL_KEY_CNTL_1 */ 226301ea0f4Smrg i740_wc(fb_p, MRX, 0x3C, 0x05 | 0x02); 227301ea0f4Smrg 228301ea0f4Smrg /*i740_wc(fb_p, MRX, 0x20, (flip ? 0x14 : 0x04));*/ 229301ea0f4Smrg /*i740_wc(fb_p, MRX, 0x20, 0);*/ 230301ea0f4Smrg /*i740_wc(fb_p, XRX, 0xD0, i740_rc(fb_p, XRX, 0xD0) | 0x10 );*/ 231301ea0f4Smrg /*i740_wc(fb_p, MRX, 0x19, 0x00);*/ 232301ea0f4Smrg i740_wc(fb_p, MRX, 0x20, (flip ? 0x34 : 0x24)); /*SB*/ 233301ea0f4Smrg} 234301ea0f4Smrg 235301ea0f4Smrg__inline__ static void i740fb_colorkey(ScrnInfoPtr pScrn,unsigned long key) 236301ea0f4Smrg{ 237301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 238301ea0f4Smrg unsigned char r,g,b,rm,gm,bm; 239301ea0f4Smrg 240301ea0f4Smrg /*//xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"colorkey=%04x depth=%d\n",key,pScrn->depth);*/ 241301ea0f4Smrg 242301ea0f4Smrg switch(pScrn->depth) 243301ea0f4Smrg { 244301ea0f4Smrg case 4: r=0x00; g=0x00; b=key; rm=0xFF; gm=0xFF; bm=0xF0; break; 245301ea0f4Smrg case 8: r=0x00; g=0x00; b=key; rm=0xFF; gm=0xFF; bm=0x00; break; 246301ea0f4Smrg case 15: r=(key&0x7C00)>>7; g=(key&0x03E0)>>2; b=(key&0x001F)<<3; rm=0x07; gm=0x07; bm=0x07; break; 247301ea0f4Smrg case 16: r=(key&0xF800)>>8; g=(key&0x07E0)>>3; b=(key&0x001F)<<3; rm=0x07; gm=0x03; bm=0x07; break; 248301ea0f4Smrg default: /*24*/ r=(key&0xFF00)>>8; g=(key&0xFF00)>>3; b=(key&0xFF00)<<3; rm=0x00; gm=0x00; bm=0x00; break; 249301ea0f4Smrg } 250301ea0f4Smrg 251301ea0f4Smrg i740_wc(fb_p, MRX, 0x3D, r); 252301ea0f4Smrg i740_wc(fb_p, MRX, 0x3E, g); 253301ea0f4Smrg i740_wc(fb_p, MRX, 0x3F, b); 254301ea0f4Smrg 255301ea0f4Smrg i740_wc(fb_p, MRX, 0x40, rm); 256301ea0f4Smrg i740_wc(fb_p, MRX, 0x41, gm); 257301ea0f4Smrg i740_wc(fb_p, MRX, 0x42, bm); 258301ea0f4Smrg} 259301ea0f4Smrg 260301ea0f4Smrg/*-----------------------------------------------------------------------------------------*/ 261301ea0f4Smrg 262301ea0f4Smrg 263301ea0f4Smrg 264301ea0f4Smrgstatic void I740ResetVideo(ScrnInfoPtr pScrn) 265301ea0f4Smrg{ 266301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 267301ea0f4Smrg I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 268301ea0f4Smrg 269301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740ResetVideo entered\n"); /* ### */ 270301ea0f4Smrg 271301ea0f4Smrg /* 272301ea0f4Smrg * Enable destination color keying 273301ea0f4Smrg */ 274301ea0f4Smrg 275301ea0f4Smrg i740fb_colorkey(pScrn,pPriv->colorKey); 276301ea0f4Smrg} 277301ea0f4Smrg 278301ea0f4Smrg 279301ea0f4Smrg 280301ea0f4Smrg/* I740ClipVideo - 281301ea0f4Smrg 282301ea0f4Smrg Takes the dst box in standard X BoxRec form (top and left 283301ea0f4Smrg edges inclusive, bottom and right exclusive). The new dst 284301ea0f4Smrg box is returned. The source boundaries are given (x1, y1 285301ea0f4Smrg inclusive, x2, y2 exclusive) and returned are the new source 286301ea0f4Smrg boundaries in 16.16 fixed point. 287301ea0f4Smrg*/ 288301ea0f4Smrg 289301ea0f4Smrgstatic void I740ClipVideo( 290301ea0f4Smrg BoxPtr dst, 291301ea0f4Smrg INT32 *x1, 292301ea0f4Smrg INT32 *x2, 293301ea0f4Smrg INT32 *y1, 294301ea0f4Smrg INT32 *y2, 295301ea0f4Smrg BoxPtr extents, /* extents of the clip region */ 296301ea0f4Smrg INT32 width, 297301ea0f4Smrg INT32 height 298301ea0f4Smrg){ 299301ea0f4Smrg INT32 vscale, hscale, delta; 300301ea0f4Smrg int diff; 301301ea0f4Smrg 302301ea0f4Smrg hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); 303301ea0f4Smrg vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); 304301ea0f4Smrg 305301ea0f4Smrg *x1 <<= 16; *x2 <<= 16; 306301ea0f4Smrg *y1 <<= 16; *y2 <<= 16; 307301ea0f4Smrg 308301ea0f4Smrg diff = extents->x1 - dst->x1; 309301ea0f4Smrg if(diff > 0) { 310301ea0f4Smrg dst->x1 = extents->x1; 311301ea0f4Smrg *x1 += diff * hscale; 312301ea0f4Smrg } 313301ea0f4Smrg diff = dst->x2 - extents->x2; 314301ea0f4Smrg if(diff > 0) { 315301ea0f4Smrg dst->x2 = extents->x2; 316301ea0f4Smrg *x2 -= diff * hscale; 317301ea0f4Smrg } 318301ea0f4Smrg diff = extents->y1 - dst->y1; 319301ea0f4Smrg if(diff > 0) { 320301ea0f4Smrg dst->y1 = extents->y1; 321301ea0f4Smrg *y1 += diff * vscale; 322301ea0f4Smrg } 323301ea0f4Smrg diff = dst->y2 - extents->y2; 324301ea0f4Smrg if(diff > 0) { 325301ea0f4Smrg dst->y2 = extents->y2; 326301ea0f4Smrg *y2 -= diff * vscale; 327301ea0f4Smrg } 328301ea0f4Smrg 329301ea0f4Smrg if(*x1 < 0) { 330301ea0f4Smrg diff = (- *x1 + hscale - 1)/ hscale; 331301ea0f4Smrg dst->x1 += diff; 332301ea0f4Smrg *x1 += diff * hscale; 333301ea0f4Smrg } 334301ea0f4Smrg delta = *x2 - (width << 16); 335301ea0f4Smrg if(delta > 0) { 336301ea0f4Smrg diff = (delta + hscale - 1)/ hscale; 337301ea0f4Smrg dst->x2 -= diff; 338301ea0f4Smrg *x2 -= diff * hscale; 339301ea0f4Smrg } 340301ea0f4Smrg if(*y1 < 0) { 341301ea0f4Smrg diff = (- *y1 + vscale - 1)/ vscale; 342301ea0f4Smrg dst->y1 += diff; 343301ea0f4Smrg *y1 += diff * vscale; 344301ea0f4Smrg } 345301ea0f4Smrg delta = *y2 - (height << 16); 346301ea0f4Smrg if(delta > 0) { 347301ea0f4Smrg diff = (delta + vscale - 1)/ vscale; 348301ea0f4Smrg dst->y2 -= diff; 349301ea0f4Smrg *y2 -= diff * vscale; 350301ea0f4Smrg } 351301ea0f4Smrg} 352301ea0f4Smrg 353301ea0f4Smrgstatic void I740StopVideo(ScrnInfoPtr pScrn, pointer data, Bool exit) 354301ea0f4Smrg{ 355301ea0f4Smrg I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 356301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740StopVideo entered %p %d\n", (void*)data, (int)exit);*/ /* ### */ 357301ea0f4Smrg 358301ea0f4Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 359301ea0f4Smrg 360301ea0f4Smrg if(exit) 361301ea0f4Smrg { 362301ea0f4Smrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) 363301ea0f4Smrg i740fb_overlay_off(pScrn); 364301ea0f4Smrg 365301ea0f4Smrg if(pPriv->linear) 366301ea0f4Smrg { 367301ea0f4Smrg xf86FreeOffscreenLinear(pPriv->linear); 368301ea0f4Smrg pPriv->linear = NULL; 369301ea0f4Smrg } 370301ea0f4Smrg pPriv->videoStatus = 0; 371301ea0f4Smrg } 372301ea0f4Smrg else 373301ea0f4Smrg { 374301ea0f4Smrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) 375301ea0f4Smrg { 376301ea0f4Smrg pPriv->videoStatus |= OFF_TIMER; 377301ea0f4Smrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 378301ea0f4Smrg } 379301ea0f4Smrg } 380301ea0f4Smrg 381301ea0f4Smrg} 382301ea0f4Smrg 383301ea0f4Smrgstatic int I740SetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) 384301ea0f4Smrg{ 385301ea0f4Smrg I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 386301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 387301ea0f4Smrg I740OverlayRegPtr overlay = (I740OverlayRegPtr) (pI740->FbBase + pI740->OverlayStart); 388301ea0f4Smrg 389301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740SetPortAttribute entered %d\n", (int) value);*/ /* ### */ 390301ea0f4Smrg 391301ea0f4Smrg if(attribute == xvBrightness) 392301ea0f4Smrg { 393301ea0f4Smrg if((value < -128) || (value > 127)) 394301ea0f4Smrg return BadValue; 395301ea0f4Smrg pPriv->brightness = value; 396301ea0f4Smrg overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); 397301ea0f4Smrg /*//OVERLAY_UPDATE(pI740->OverlayPhysical);*/ 398301ea0f4Smrg } 399301ea0f4Smrg else 400301ea0f4Smrg if(attribute == xvContrast) 401301ea0f4Smrg { 402301ea0f4Smrg if((value < 0) || (value > 255)) 403301ea0f4Smrg return BadValue; 404301ea0f4Smrg pPriv->contrast = value; 405301ea0f4Smrg overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); 406301ea0f4Smrg /*//OVERLAY_UPDATE(pI740->OverlayPhysical);*/ 407301ea0f4Smrg } 408301ea0f4Smrg else 409301ea0f4Smrg if(attribute == xvColorKey) 410301ea0f4Smrg { 411301ea0f4Smrg pPriv->colorKey = value; 412301ea0f4Smrg 413301ea0f4Smrg i740fb_colorkey(pScrn,pPriv->colorKey); 414301ea0f4Smrg 415301ea0f4Smrg /*//OVERLAY_UPDATE(pI740->OverlayPhysical);*/ 416301ea0f4Smrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 417301ea0f4Smrg } 418301ea0f4Smrg else 419301ea0f4Smrg return BadMatch; 420301ea0f4Smrg 421301ea0f4Smrg return Success; 422301ea0f4Smrg} 423301ea0f4Smrg 424301ea0f4Smrgstatic int I740GetPortAttribute( 425301ea0f4Smrg ScrnInfoPtr pScrn, 426301ea0f4Smrg Atom attribute, 427301ea0f4Smrg INT32 *value, 428301ea0f4Smrg pointer data 429301ea0f4Smrg){ 430301ea0f4Smrg I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 431301ea0f4Smrg 432301ea0f4Smrg if(attribute == xvBrightness) { 433301ea0f4Smrg *value = pPriv->brightness; 434301ea0f4Smrg } else 435301ea0f4Smrg if(attribute == xvContrast) { 436301ea0f4Smrg *value = pPriv->contrast; 437301ea0f4Smrg } else 438301ea0f4Smrg if(attribute == xvColorKey) { 439301ea0f4Smrg *value = pPriv->colorKey; 440301ea0f4Smrg } else return BadMatch; 441301ea0f4Smrg 442301ea0f4Smrg return Success; 443301ea0f4Smrg} 444301ea0f4Smrg 445301ea0f4Smrgstatic void I740QueryBestSize( 446301ea0f4Smrg ScrnInfoPtr pScrn, 447301ea0f4Smrg Bool motion, 448301ea0f4Smrg short vid_w, short vid_h, 449301ea0f4Smrg short drw_w, short drw_h, 450301ea0f4Smrg unsigned int *p_w, unsigned int *p_h, 451301ea0f4Smrg pointer data 452301ea0f4Smrg){ 453301ea0f4Smrg if(vid_w > (drw_w << 1)) drw_w = vid_w >> 1; 454301ea0f4Smrg if(vid_h > (drw_h << 1)) drw_h = vid_h >> 1; 455301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740QueryBestSize entered %d %d %d %d\n", (int) vid_w, (int) vid_h, (int) drw_w, (int) drw_h); /* ### */ 456301ea0f4Smrg fprintf(stderr, "fprintf - I740QueryBestSize entered %d %d %d %d\n", (int) vid_w, (int) vid_h, (int) drw_w, (int) drw_h); /* ### */ 457301ea0f4Smrg 458301ea0f4Smrg *p_w = drw_w; 459301ea0f4Smrg *p_h = drw_h; 460301ea0f4Smrg} 461301ea0f4Smrg 462301ea0f4Smrgstatic void I740CopyMungedData(ScrnInfoPtr pScrn, 463301ea0f4Smrg unsigned char *src1, unsigned char *src2, unsigned char *src3, 464301ea0f4Smrg int srcPitch, 465301ea0f4Smrg int srcPitch2, 466301ea0f4Smrg int dstPitch, 467301ea0f4Smrg int h, 468301ea0f4Smrg int w, 469301ea0f4Smrg long scalex, 470301ea0f4Smrg long scaley) 471301ea0f4Smrg{ 472301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 473301ea0f4Smrg I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 474301ea0f4Smrg CARD32 *dst; 475301ea0f4Smrg int i, j; 476301ea0f4Smrg 477301ea0f4Smrg if (pPriv->currentBuf == 0) 478301ea0f4Smrg dst = (CARD32 *)(pI740->FbBase + pPriv->YBuf0offset); 479301ea0f4Smrg else 480301ea0f4Smrg dst = (CARD32 *)(pI740->FbBase + pPriv->YBuf1offset); 481301ea0f4Smrg 482301ea0f4Smrg dstPitch >>= 2; 483301ea0f4Smrg w >>= 1; 484301ea0f4Smrg 485301ea0f4Smrg /* If the space on the screen is smaller than the source image, then we use 486301ea0f4Smrg * software scaling to make it smaller. */ 487301ea0f4Smrg if (scalex > 0x10000 || scaley > 0x10000) { 488301ea0f4Smrg int dsth = ((long) h * 0x10000L + scaley - 1) / scaley; 489301ea0f4Smrg long halfx = scalex/2; 490301ea0f4Smrg long dstj = 0; 491301ea0f4Smrg for(j = 0; j < dsth; j++) { 492301ea0f4Smrg int dstj_rnd = dstj >> 16; 493301ea0f4Smrg unsigned char* src1_ = src1 + (dstj_rnd * srcPitch); 494301ea0f4Smrg unsigned char* src2_ = src2 + ((dstj_rnd/2) * srcPitch2); 495301ea0f4Smrg unsigned char* src3_ = src3 + ((dstj_rnd/2) * srcPitch2); 496301ea0f4Smrg int dstw = ((long) w * 0x10000L + halfx - 1) / scalex; 497301ea0f4Smrg long srci = 0; 498301ea0f4Smrg for(i = 0; i < dstw; i++) { 499301ea0f4Smrg long srci_rnd = srci >> 16; 500301ea0f4Smrg long srci2_rnd = (srci + halfx) >> 16; 501301ea0f4Smrg dst[i] = 502301ea0f4Smrg (((src1_[srci_rnd << 1] | (src1_[(srci_rnd << 1) + 1] << 16) | 503301ea0f4Smrg (src3_[srci_rnd] << 8) | (src2_[srci_rnd] << 24))) >> 1 & 0x7F7F7F7FL) 504301ea0f4Smrg + 505301ea0f4Smrg (((src1_[srci2_rnd << 1] | (src1_[(srci2_rnd << 1) + 1] << 16) | 506301ea0f4Smrg (src3_[srci2_rnd] << 8) | (src2_[srci2_rnd] << 24))) >> 1 & 0x7F7F7F7FL); 507301ea0f4Smrg srci += scalex; 508301ea0f4Smrg } 509301ea0f4Smrg dst += dstPitch; 510301ea0f4Smrg dstj += scaley; 511301ea0f4Smrg } 512301ea0f4Smrg } 513301ea0f4Smrg else { 514301ea0f4Smrg for(j = 0; j < h; j++) { 515301ea0f4Smrg for(i = 0; i < w; i++) { 516301ea0f4Smrg dst[i] = src1[i << 1] | (src1[(i << 1) + 1] << 16) | 517301ea0f4Smrg (src3[i] << 8) | (src2[i] << 24); 518301ea0f4Smrg } 519301ea0f4Smrg dst += dstPitch; 520301ea0f4Smrg src1 += srcPitch; 521301ea0f4Smrg if(j & 1) { 522301ea0f4Smrg src2 += srcPitch2; 523301ea0f4Smrg src3 += srcPitch2; 524301ea0f4Smrg } 525301ea0f4Smrg } 526301ea0f4Smrg } 527301ea0f4Smrg} 528301ea0f4Smrg 529301ea0f4Smrg 530301ea0f4Smrg__inline__ static void I740CopyPackedData(ScrnInfoPtr pScrn, 531301ea0f4Smrg unsigned char *buf, 532301ea0f4Smrg int srcPitch, 533301ea0f4Smrg int dstPitch, 534301ea0f4Smrg int top, 535301ea0f4Smrg int left, 536301ea0f4Smrg int h, 537301ea0f4Smrg int w 538301ea0f4Smrg ) 539301ea0f4Smrg{ 540301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 541301ea0f4Smrg I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 542301ea0f4Smrg unsigned char *src, *dst; 543301ea0f4Smrg 544301ea0f4Smrg src = buf + (top*srcPitch) + (left<<1); 545301ea0f4Smrg 546301ea0f4Smrg if (pPriv->currentBuf == 0) 547301ea0f4Smrg dst = pI740->FbBase + pPriv->YBuf0offset; 548301ea0f4Smrg else 549301ea0f4Smrg dst = pI740->FbBase + pPriv->YBuf1offset; 550301ea0f4Smrg 551301ea0f4Smrg w <<= 1; 552301ea0f4Smrg while(h--) { 553301ea0f4Smrg memcpy(dst, src, w); 554301ea0f4Smrg src += srcPitch; 555301ea0f4Smrg dst += dstPitch; 556301ea0f4Smrg } 557301ea0f4Smrg} 558301ea0f4Smrg 559301ea0f4Smrg 560301ea0f4Smrg__inline__ static void I740DisplayVideo(ScrnInfoPtr pScrn, int id, short width, short height, 561301ea0f4Smrg int dstPitch, /* of chroma for 4:2:0 */ 562301ea0f4Smrg int x1, int y1, int x2, int y2, 563301ea0f4Smrg BoxPtr dstBox, 564301ea0f4Smrg short src_w, short src_h, short drw_w, short drw_h, 565301ea0f4Smrg unsigned char vd_mod 566301ea0f4Smrg ) 567301ea0f4Smrg{ 568301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 569301ea0f4Smrg I740PortPrivPtr pPriv = pI740->adaptor->pPortPrivates[0].ptr; 570301ea0f4Smrg 571301ea0f4Smrg i740fb_overlay_set(pScrn,pPriv,pPriv->YBuf0offset,pPriv->YBuf1offset, 572301ea0f4Smrg src_w,src_h, /* source image size */ 573301ea0f4Smrg drw_w,drw_h, /* destination image size */ 574301ea0f4Smrg dstBox->x1,dstBox->y1, /* destination image pos to display */ 575301ea0f4Smrg dstBox->x2 - dstBox->x1,dstBox->y2 - dstBox->y1, /* destination image size to display allows trunc... */ 576301ea0f4Smrg dstPitch,(pPriv->currentBuf != 0), 577301ea0f4Smrg vd_mod); 578301ea0f4Smrg 579301ea0f4Smrg i740fb_colorkey(pScrn,pPriv->colorKey); /* needed to reset properly the i740 board after switching from framebuffer */ 580301ea0f4Smrg} 581301ea0f4Smrg 582301ea0f4Smrgstatic FBLinearPtr I740AllocateMemory(ScrnInfoPtr pScrn, FBLinearPtr linear, int size) 583301ea0f4Smrg{ 584301ea0f4Smrg ScreenPtr pScreen; 585301ea0f4Smrg FBLinearPtr new_linear; 586301ea0f4Smrg 587301ea0f4Smrg if(linear) 588301ea0f4Smrg { 589301ea0f4Smrg if(linear->size >= size) 590301ea0f4Smrg return linear; 591301ea0f4Smrg 592301ea0f4Smrg if(xf86ResizeOffscreenLinear(linear, size)) { 593301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory resized to %d - %p\n", (int) size, (void *)linear); /* ### */ 594301ea0f4Smrg return linear; 595301ea0f4Smrg } 596301ea0f4Smrg 597301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory free %p - %d < %d\n", (void *)linear, (int) linear->size, (int) size); /* ### */ 598301ea0f4Smrg xf86FreeOffscreenLinear(linear); 599301ea0f4Smrg } 600301ea0f4Smrg 6015c69f917Smrg pScreen = xf86ScrnToScreen(pScrn); 602301ea0f4Smrg 603301ea0f4Smrg new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, NULL, NULL, NULL); 604301ea0f4Smrg 605301ea0f4Smrg if(!new_linear) 606301ea0f4Smrg { 607301ea0f4Smrg int max_size; 608301ea0f4Smrg 609301ea0f4Smrg xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, PRIORITY_EXTREME); 610301ea0f4Smrg 611301ea0f4Smrg if(max_size < size) { 612301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory can't purge %d < %d\n", (int) max_size, (int) size); /* ### */ 613301ea0f4Smrg return NULL; 614301ea0f4Smrg } 615301ea0f4Smrg 616301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory purged %d\n", (int) max_size); /* ### */ 617301ea0f4Smrg xf86PurgeUnlockedOffscreenAreas(pScreen); 618301ea0f4Smrg new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, 619301ea0f4Smrg NULL, NULL, NULL); 620301ea0f4Smrg } 621301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateMemory allocated %d - %p\n", (int) size, (void *)new_linear); /* ### */ 622301ea0f4Smrg 623301ea0f4Smrg return new_linear; 624301ea0f4Smrg} 625301ea0f4Smrg 626301ea0f4Smrgstatic int I740PutImage(ScrnInfoPtr pScrn, 627301ea0f4Smrg short src_x, short src_y, short drw_x, short drw_y, 628301ea0f4Smrg short src_w, short src_h, short drw_w, short drw_h, 629301ea0f4Smrg int id, unsigned char* buf, 630301ea0f4Smrg short width, short height, 631301ea0f4Smrg Bool sync, RegionPtr clipBoxes, pointer data, 632301ea0f4Smrg DrawablePtr pDraw 633301ea0f4Smrg ) 634301ea0f4Smrg{ 635301ea0f4Smrg ScreenPtr pScreen = pScrn->pScreen; 636301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 637301ea0f4Smrg I740PortPrivPtr pPriv = (I740PortPrivPtr)data; 638301ea0f4Smrg INT32 x1, x2, y1, y2; 639301ea0f4Smrg int srcPitch, dstPitch, srcPitch2=0; 640301ea0f4Smrg int top, left, npixels, nlines, size; 641301ea0f4Smrg BoxRec dstBox; 642301ea0f4Smrg int offset2=0, offset3=0; 643301ea0f4Smrg 644301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740PutImage entered %d %d\n", (int) width, (int) height, id);*/ /* ### */ 645301ea0f4Smrg 646301ea0f4Smrg /* Clip */ 647301ea0f4Smrg x1 = src_x; 648301ea0f4Smrg x2 = src_x + src_w; 649301ea0f4Smrg y1 = src_y; 650301ea0f4Smrg y2 = src_y + src_h; 651301ea0f4Smrg 652301ea0f4Smrg dstBox.x1 = drw_x; 653301ea0f4Smrg dstBox.x2 = drw_x + drw_w; 654301ea0f4Smrg dstBox.y1 = drw_y; 655301ea0f4Smrg dstBox.y2 = drw_y + drw_h; 656301ea0f4Smrg 657301ea0f4Smrg I740ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 658301ea0f4Smrg REGION_EXTENTS(pScreen, clipBoxes), width, height); 659301ea0f4Smrg 660301ea0f4Smrg if((x1 >= x2) || (y1 >= y2)) { 661301ea0f4Smrg return Success; 662301ea0f4Smrg } 663301ea0f4Smrg 664301ea0f4Smrg dstBox.x1 -= pScrn->frameX0; 665301ea0f4Smrg dstBox.x2 -= pScrn->frameX0; 666301ea0f4Smrg dstBox.y1 -= pScrn->frameY0; 667301ea0f4Smrg dstBox.y2 -= pScrn->frameY0; 668301ea0f4Smrg 669301ea0f4Smrg switch(id) 670301ea0f4Smrg { 671301ea0f4Smrg case FOURCC_YV12: 672301ea0f4Smrg case FOURCC_I420: 673301ea0f4Smrg srcPitch = (width + 3) & ~3; 674301ea0f4Smrg offset2 = srcPitch * height; 675301ea0f4Smrg srcPitch2 = ((width >> 1) + 3) & ~3; 676301ea0f4Smrg offset3 = (srcPitch2 * (height >> 1)) + offset2; 677301ea0f4Smrg dstPitch = ((width << 1) + 15) & ~15; 678301ea0f4Smrg size = dstPitch * height; 679301ea0f4Smrg break; 680301ea0f4Smrg case FOURCC_UYVY: 681301ea0f4Smrg case FOURCC_YUY2: 682301ea0f4Smrg default: 683301ea0f4Smrg srcPitch = (width << 1); 684301ea0f4Smrg dstPitch = (srcPitch + 7) & ~7; 685301ea0f4Smrg size = dstPitch * height; 686301ea0f4Smrg break; 687301ea0f4Smrg } 688301ea0f4Smrg 689301ea0f4Smrg { 690301ea0f4Smrg FBLinearPtr new_linear = I740AllocateMemory(pScrn, pPriv->linear, size); 691301ea0f4Smrg if (new_linear != pPriv->linear) { 692301ea0f4Smrg pPriv->linear = new_linear; 693301ea0f4Smrg } 694301ea0f4Smrg } 695301ea0f4Smrg if(!pPriv->linear) 696301ea0f4Smrg return BadAlloc; 697301ea0f4Smrg 698301ea0f4Smrg /* fixup pointers */ 699301ea0f4Smrg pPriv->YBuf0offset = pPriv->linear->offset*pI740->cpp; 700301ea0f4Smrg pPriv->YBuf1offset = (pPriv->linear->offset*pI740->cpp) + size; 701301ea0f4Smrg 702301ea0f4Smrg 703301ea0f4Smrg#if 0 /*???*/ 704301ea0f4Smrg /* wait for the last rendered buffer to be flipped in */ 705301ea0f4Smrg while (((INREG(DOV0STA)&0x00100000)>>20) != pPriv->currentBuf); 706301ea0f4Smrg#endif 707301ea0f4Smrg 708301ea0f4Smrg /* buffer swap */ 709301ea0f4Smrg pPriv->currentBuf ^= 1; 710301ea0f4Smrg 711301ea0f4Smrg /* copy data */ 712301ea0f4Smrg top = y1 >> 16; 713301ea0f4Smrg left = (x1 >> 16) & ~1; 714301ea0f4Smrg npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 715301ea0f4Smrg 716301ea0f4Smrg switch(id) { 717301ea0f4Smrg case FOURCC_YV12: 718301ea0f4Smrg case FOURCC_I420: 719301ea0f4Smrg { 720301ea0f4Smrg CARD32 tmp; 721301ea0f4Smrg 722301ea0f4Smrg top &= ~1; 723301ea0f4Smrg tmp = ((top >> 1) * srcPitch2) + (left >> 1); 724301ea0f4Smrg offset2 += tmp; 725301ea0f4Smrg offset3 += tmp; 726301ea0f4Smrg 727301ea0f4Smrg if(id == FOURCC_I420) 728301ea0f4Smrg { 729301ea0f4Smrg tmp = offset2; 730301ea0f4Smrg offset2 = offset3; 731301ea0f4Smrg offset3 = tmp; 732301ea0f4Smrg } 733301ea0f4Smrg 734301ea0f4Smrg nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 735301ea0f4Smrg 736301ea0f4Smrg /* If the screen image size is smaller than the video image size, then 737301ea0f4Smrg * we use software scaling to make it smaller. The hardware takes care 738301ea0f4Smrg * of scaling up - see i740fb_overlay_set. 739301ea0f4Smrg */ 740301ea0f4Smrg { 741301ea0f4Smrg long scalex = 0x10000, scaley = 0x10000; 742301ea0f4Smrg if (drw_w < src_w) 743301ea0f4Smrg scalex = (0x10000L * (long) src_w) / (long) drw_w; 744301ea0f4Smrg if (drw_h < src_h) 745301ea0f4Smrg scaley = (0x10000L * (long) src_h) / (long) drw_h; 746301ea0f4Smrg 747301ea0f4Smrg I740CopyMungedData(pScrn, buf + (top * srcPitch) + left, 748301ea0f4Smrg buf + offset2, buf + offset3, 749301ea0f4Smrg srcPitch, srcPitch2, dstPitch, nlines, npixels, scalex, scaley); 750301ea0f4Smrg } 751301ea0f4Smrg } 752301ea0f4Smrg break; 753301ea0f4Smrg 754301ea0f4Smrg case FOURCC_UYVY: case FOURCC_YUY2: default: 755301ea0f4Smrg { 756301ea0f4Smrg nlines = ((y2 + 0xffff) >> 16) - top; 757301ea0f4Smrg /* Add software scaling as above. */ 758301ea0f4Smrg I740CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines, 759301ea0f4Smrg npixels); 760301ea0f4Smrg } 761301ea0f4Smrg break; 762301ea0f4Smrg } 763301ea0f4Smrg 764301ea0f4Smrg /* update cliplist */ 765301ea0f4Smrg if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) 766301ea0f4Smrg { 767301ea0f4Smrg REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 768301ea0f4Smrg /* draw these */ 769301ea0f4Smrg xf86XVFillKeyHelper(pScreen, pPriv->colorKey, clipBoxes); 770301ea0f4Smrg } 771301ea0f4Smrg 772301ea0f4Smrg { 773301ea0f4Smrg unsigned char vd_mod; 774301ea0f4Smrg 775301ea0f4Smrg switch(id) 776301ea0f4Smrg { 777301ea0f4Smrg case FOURCC_RV15: vd_mod=0x09; break; 778301ea0f4Smrg case FOURCC_RV16: vd_mod=0x08; break; 779301ea0f4Smrg default: vd_mod=0x00; break; 780301ea0f4Smrg } 781301ea0f4Smrg 782301ea0f4Smrg I740DisplayVideo(pScrn, id, width, height, dstPitch, 783301ea0f4Smrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h, 784301ea0f4Smrg vd_mod); 785301ea0f4Smrg } 786301ea0f4Smrg 787301ea0f4Smrg pPriv->videoStatus = CLIENT_VIDEO_ON; 788301ea0f4Smrg 789301ea0f4Smrg return Success; 790301ea0f4Smrg} 791301ea0f4Smrg 792301ea0f4Smrg 793301ea0f4Smrgstatic int I740QueryImageAttributes(ScrnInfoPtr pScrn, int id, unsigned short *w, unsigned short *h, int *pitches, int *offsets ) 794301ea0f4Smrg{ 795301ea0f4Smrg int size,tmp; 796301ea0f4Smrg 797301ea0f4Smrg if(*w > IMAGE_MAX_PHY_WIDTH) *w = IMAGE_MAX_PHY_WIDTH; 798301ea0f4Smrg if(*h > IMAGE_MAX_PHY_HEIGHT) *h = IMAGE_MAX_PHY_HEIGHT; 799301ea0f4Smrg 800301ea0f4Smrg *w = (*w + 1) & ~1; 801301ea0f4Smrg if(offsets) offsets[0] = 0; 802301ea0f4Smrg 803301ea0f4Smrg switch(id) 804301ea0f4Smrg { 805301ea0f4Smrg case FOURCC_YV12: 806301ea0f4Smrg case FOURCC_I420: 807301ea0f4Smrg *h = (*h + 1) & ~1; 808301ea0f4Smrg size = (*w + 3) & ~3; 809301ea0f4Smrg if(pitches) pitches[0] = size; 810301ea0f4Smrg size *= *h; 811301ea0f4Smrg if(offsets) offsets[1] = size; 812301ea0f4Smrg tmp = ((*w >> 1) + 3) & ~3; 813301ea0f4Smrg if(pitches) pitches[1] = pitches[2] = tmp; 814301ea0f4Smrg tmp *= (*h >> 1); 815301ea0f4Smrg size += tmp; 816301ea0f4Smrg if(offsets) offsets[2] = size; 817301ea0f4Smrg size += tmp; 818301ea0f4Smrg break; 819301ea0f4Smrg case FOURCC_UYVY: 820301ea0f4Smrg case FOURCC_YUY2: 821301ea0f4Smrg default: 822301ea0f4Smrg size = *w << 1; 823301ea0f4Smrg if(pitches) pitches[0] = size; 824301ea0f4Smrg size *= *h; 825301ea0f4Smrg break; 826301ea0f4Smrg } 827301ea0f4Smrg 828301ea0f4Smrg return size; 829301ea0f4Smrg} 830301ea0f4Smrg 8315c69f917Smrgstatic void I740BlockHandler(BLOCKHANDLER_ARGS_DECL) 832301ea0f4Smrg{ 8335c69f917Smrg SCREEN_PTR(arg); 8345c69f917Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 835301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 836301ea0f4Smrg I740PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 837301ea0f4Smrg 838301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740BlockHandler entered\n"); */ /* ### */ 839301ea0f4Smrg 840301ea0f4Smrg pScreen->BlockHandler = pI740->BlockHandler; 841301ea0f4Smrg 8425c69f917Smrg (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 843301ea0f4Smrg 844301ea0f4Smrg pScreen->BlockHandler = I740BlockHandler; 845301ea0f4Smrg 846301ea0f4Smrg if(pPriv->videoStatus & TIMER_MASK) 847301ea0f4Smrg { 848301ea0f4Smrg UpdateCurrentTime(); 849301ea0f4Smrg if(pPriv->videoStatus & OFF_TIMER) 850301ea0f4Smrg { 851301ea0f4Smrg if(pPriv->offTime < currentTime.milliseconds) 852301ea0f4Smrg { 853301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740BlockHandler: OFF_TIMER expired\n");*/ /* ### */ 854301ea0f4Smrg /* Turn off the overlay */ 855301ea0f4Smrg i740fb_overlay_off(pScrn); 856301ea0f4Smrg 857301ea0f4Smrg pPriv->videoStatus = FREE_TIMER; 858301ea0f4Smrg pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 859301ea0f4Smrg } 860301ea0f4Smrg } 861301ea0f4Smrg else 862301ea0f4Smrg { /* FREE_TIMER */ 863301ea0f4Smrg if(pPriv->freeTime < currentTime.milliseconds) 864301ea0f4Smrg { 865301ea0f4Smrg if(pPriv->linear) 866301ea0f4Smrg { 867301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740BlockHandler: FREE_TIMER expired\n");*/ /* ### */ 868301ea0f4Smrg xf86FreeOffscreenLinear(pPriv->linear); 869301ea0f4Smrg pPriv->linear = NULL; 870301ea0f4Smrg } 871301ea0f4Smrg pPriv->videoStatus = 0; 872301ea0f4Smrg } 873301ea0f4Smrg } 874301ea0f4Smrg } 875301ea0f4Smrg} 876301ea0f4Smrg 877301ea0f4Smrg 878301ea0f4Smrg/*************************************************************************** 879301ea0f4Smrg * Offscreen Images 880301ea0f4Smrg ***************************************************************************/ 881301ea0f4Smrg 882301ea0f4Smrgtypedef struct { 883301ea0f4Smrg FBLinearPtr linear; 884301ea0f4Smrg Bool isOn; 885301ea0f4Smrg} OffscreenPrivRec, * OffscreenPrivPtr; 886301ea0f4Smrg 887301ea0f4Smrgstatic int I740AllocateSurface( 888301ea0f4Smrg ScrnInfoPtr pScrn, 889301ea0f4Smrg int id, 890301ea0f4Smrg unsigned short w, 891301ea0f4Smrg unsigned short h, 892301ea0f4Smrg XF86SurfacePtr surface 893301ea0f4Smrg){ 894301ea0f4Smrg FBLinearPtr linear; 895301ea0f4Smrg int pitch, size; 896301ea0f4Smrg OffscreenPrivPtr pPriv; 897301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 898301ea0f4Smrg 899301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740AllocateSurface entered %d %d\n", (int) w, (int) h); /* ### */ 900301ea0f4Smrg 901301ea0f4Smrg if((w > IMAGE_MAX_LOG_WIDTH) || (h > IMAGE_MAX_LOG_HEIGHT)) 902301ea0f4Smrg return BadAlloc; 903301ea0f4Smrg 904301ea0f4Smrg w = (w + 1) & ~1; 905301ea0f4Smrg pitch = ((w << 1) + 15) & ~15; 906301ea0f4Smrg size = pitch * h; 907301ea0f4Smrg 908301ea0f4Smrg if(!(linear = I740AllocateMemory(pScrn, NULL, size))) 909301ea0f4Smrg return BadAlloc; 910301ea0f4Smrg 911301ea0f4Smrg surface->width = w; 912301ea0f4Smrg surface->height = h; 913301ea0f4Smrg 9145c69f917Smrg if(!(surface->pitches = malloc(sizeof(int)))) { 915301ea0f4Smrg xf86FreeOffscreenLinear(linear); 916301ea0f4Smrg return BadAlloc; 917301ea0f4Smrg } 9185c69f917Smrg if(!(surface->offsets = malloc(sizeof(int)))) { 9195c69f917Smrg free(surface->pitches); 920301ea0f4Smrg xf86FreeOffscreenLinear(linear); 921301ea0f4Smrg return BadAlloc; 922301ea0f4Smrg } 9235c69f917Smrg if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 9245c69f917Smrg free(surface->pitches); 9255c69f917Smrg free(surface->offsets); 926301ea0f4Smrg xf86FreeOffscreenLinear(linear); 927301ea0f4Smrg return BadAlloc; 928301ea0f4Smrg } 929301ea0f4Smrg 930301ea0f4Smrg pPriv->linear = linear; 931301ea0f4Smrg pPriv->isOn = FALSE; 932301ea0f4Smrg 933301ea0f4Smrg surface->pScrn = pScrn; 934301ea0f4Smrg surface->id = id; 935301ea0f4Smrg surface->pitches[0] = pitch; 936301ea0f4Smrg surface->offsets[0] = linear->offset*pI740->cpp; 937301ea0f4Smrg surface->devPrivate.ptr = (pointer)pPriv; 938301ea0f4Smrg 939301ea0f4Smrg /*//memset(pI740->FbBase + surface->offsets[0],0,size);*/ 940301ea0f4Smrg 941301ea0f4Smrg return Success; 942301ea0f4Smrg} 943301ea0f4Smrg 944301ea0f4Smrgstatic int I740StopSurface(XF86SurfacePtr surface) 945301ea0f4Smrg{ 946301ea0f4Smrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 947301ea0f4Smrg 948301ea0f4Smrg if(pPriv->isOn) 949301ea0f4Smrg { 950301ea0f4Smrg /*//i740fb_overlay_off(pScrn);*/ 951301ea0f4Smrg 952301ea0f4Smrg pPriv->isOn = FALSE; 953301ea0f4Smrg } 954301ea0f4Smrg 955301ea0f4Smrg return Success; 956301ea0f4Smrg} 957301ea0f4Smrg 958301ea0f4Smrg 959301ea0f4Smrgstatic int I740FreeSurface(XF86SurfacePtr surface) 960301ea0f4Smrg{ 961301ea0f4Smrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 962301ea0f4Smrg 963301ea0f4Smrg if(pPriv->isOn) 964301ea0f4Smrg { 965301ea0f4Smrg I740StopSurface(surface); 966301ea0f4Smrg } 967301ea0f4Smrg 968301ea0f4Smrg xf86FreeOffscreenLinear(pPriv->linear); 9695c69f917Smrg free(surface->pitches); 9705c69f917Smrg free(surface->offsets); 9715c69f917Smrg free(surface->devPrivate.ptr); 972301ea0f4Smrg 973301ea0f4Smrg return Success; 974301ea0f4Smrg} 975301ea0f4Smrg 976301ea0f4Smrgstatic int I740GetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value) 977301ea0f4Smrg{ 978301ea0f4Smrg return I740GetPortAttribute(pScrn, attribute, value, 0); 979301ea0f4Smrg} 980301ea0f4Smrg 981301ea0f4Smrgstatic int I740SetSurfaceAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value) 982301ea0f4Smrg{ 983301ea0f4Smrg return I740SetPortAttribute(pScrn, attribute, value, 0); 984301ea0f4Smrg} 985301ea0f4Smrg 986301ea0f4Smrg 987301ea0f4Smrgstatic int I740DisplaySurface(XF86SurfacePtr surface, short src_x, short src_y, 988301ea0f4Smrg short drw_x, short drw_y, 989301ea0f4Smrg short src_w, short src_h, 990301ea0f4Smrg short drw_w, short drw_h, 991301ea0f4Smrg RegionPtr clipBoxes) 992301ea0f4Smrg{ 993301ea0f4Smrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 994301ea0f4Smrg ScrnInfoPtr pScrn = surface->pScrn; 995301ea0f4Smrg I740PortPrivPtr pI740Priv = GET_PORT_PRIVATE(pScrn); 996301ea0f4Smrg 997301ea0f4Smrg INT32 x1, y1, x2, y2; 998301ea0f4Smrg BoxRec dstBox; 999301ea0f4Smrg 1000301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740DisplaySurface entered\n"); /* ### */ 1001301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"I740DisplaySurface-----------------------------------\n");*/ 1002301ea0f4Smrg /*//fprintf(stderr, "I740DisplaySurface-----------------------------------\n");*/ 1003301ea0f4Smrg 1004301ea0f4Smrg 1005301ea0f4Smrg x1 = src_x; 1006301ea0f4Smrg x2 = src_x + src_w; 1007301ea0f4Smrg y1 = src_y; 1008301ea0f4Smrg y2 = src_y + src_h; 1009301ea0f4Smrg 1010301ea0f4Smrg dstBox.x1 = drw_x; 1011301ea0f4Smrg dstBox.x2 = drw_x + drw_w; 1012301ea0f4Smrg dstBox.y1 = drw_y; 1013301ea0f4Smrg dstBox.y2 = drw_y + drw_h; 1014301ea0f4Smrg 1015301ea0f4Smrg I740ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 1016301ea0f4Smrg REGION_EXTENTS(screenInfo.screens[0], clipBoxes), 1017301ea0f4Smrg surface->width, surface->height); 1018301ea0f4Smrg 1019301ea0f4Smrg dstBox.x1 -= pScrn->frameX0; 1020301ea0f4Smrg dstBox.x2 -= pScrn->frameX0; 1021301ea0f4Smrg dstBox.y1 -= pScrn->frameY0; 1022301ea0f4Smrg dstBox.y2 -= pScrn->frameY0; 1023301ea0f4Smrg 1024301ea0f4Smrg /* fixup pointers */ 1025301ea0f4Smrg pI740Priv->YBuf0offset = surface->offsets[0]; 1026301ea0f4Smrg pI740Priv->YBuf1offset = pI740Priv->YBuf0offset; 1027301ea0f4Smrg 1028301ea0f4Smrg#if 0 /*???*/ 1029301ea0f4Smrg /* wait for the last rendered buffer to be flipped in */ 1030301ea0f4Smrg while (((INREG(DOV0STA)&0x00100000)>>20) != pI740Priv->currentBuf) { 1031301ea0f4Smrg if(loops == 200000) { 1032301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n"); 1033301ea0f4Smrg break; 1034301ea0f4Smrg } 1035301ea0f4Smrg loops++; 1036301ea0f4Smrg } 1037301ea0f4Smrg#endif 1038301ea0f4Smrg 1039301ea0f4Smrg /* buffer swap */ 1040301ea0f4Smrg if (pI740Priv->currentBuf == 0) 1041301ea0f4Smrg pI740Priv->currentBuf = 1; 1042301ea0f4Smrg else 1043301ea0f4Smrg pI740Priv->currentBuf = 0; 1044301ea0f4Smrg 1045301ea0f4Smrg I740ResetVideo(pScrn); 1046301ea0f4Smrg 1047301ea0f4Smrg I740DisplayVideo(pScrn, surface->id, surface->width, surface->height, 1048301ea0f4Smrg surface->pitches[0], x1, y1, x2, y2, &dstBox, 1049301ea0f4Smrg src_w, src_h, drw_w, drw_h, 1050301ea0f4Smrg 0x00); 1051301ea0f4Smrg 1052301ea0f4Smrg xf86XVFillKeyHelper(pScrn->pScreen, pI740Priv->colorKey, clipBoxes); 1053301ea0f4Smrg 1054301ea0f4Smrg pPriv->isOn = TRUE; 1055301ea0f4Smrg /* we've prempted the XvImage stream so set its free timer */ 1056301ea0f4Smrg if(pI740Priv->videoStatus & CLIENT_VIDEO_ON) { 1057301ea0f4Smrg REGION_EMPTY(pScrn->pScreen, & pI740Priv->clip); 1058301ea0f4Smrg UpdateCurrentTime(); 1059301ea0f4Smrg pI740Priv->videoStatus = FREE_TIMER; 1060301ea0f4Smrg pI740Priv->freeTime = currentTime.milliseconds + FREE_DELAY; 1061301ea0f4Smrg pScrn->pScreen->BlockHandler = I740BlockHandler; 1062301ea0f4Smrg } 1063301ea0f4Smrg 1064301ea0f4Smrg return Success; 1065301ea0f4Smrg} 1066301ea0f4Smrg 1067301ea0f4Smrg/*-------------------------------------------------------------------------------------------*/ 1068301ea0f4Smrg#define NUM_IMAGES (sizeof(i740vid_Images)/sizeof(XF86ImageRec)) 1069301ea0f4Smrgstatic XF86ImageRec i740vid_Images[] = 1070301ea0f4Smrg{ 1071301ea0f4Smrg XVIMAGE_YUY2, 1072301ea0f4Smrg XVIMAGE_UYVY, 1073301ea0f4Smrg XVIMAGE_YV12, /* converted to YUV2 while copying */ 1074301ea0f4Smrg XVIMAGE_I420, /* converted to YUV2 while copying */ 1075301ea0f4Smrg { 1076301ea0f4Smrg FOURCC_RV15, 1077301ea0f4Smrg XvRGB, 1078301ea0f4Smrg LSBFirst, 1079301ea0f4Smrg {'R','V','1','5', 1080301ea0f4Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 1081301ea0f4Smrg 16, 1082301ea0f4Smrg XvPacked, 1083301ea0f4Smrg 1, 1084301ea0f4Smrg 15, 0x001F, 0x03E0, 0x7C00, 1085301ea0f4Smrg 0, 0, 0, 1086301ea0f4Smrg 0, 0, 0, 1087301ea0f4Smrg 0, 0, 0, 1088301ea0f4Smrg {'R','V','B',0, 1089301ea0f4Smrg 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}, 1090301ea0f4Smrg XvTopToBottom 1091301ea0f4Smrg }, 1092301ea0f4Smrg { 1093301ea0f4Smrg FOURCC_RV16, 1094301ea0f4Smrg XvRGB, 1095301ea0f4Smrg LSBFirst, 1096301ea0f4Smrg {'R','V','1','6', 1097301ea0f4Smrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 1098301ea0f4Smrg 16, 1099301ea0f4Smrg XvPacked, 1100301ea0f4Smrg 1, 1101301ea0f4Smrg 16, 0x001F, 0x07E0, 0xF800, 1102301ea0f4Smrg 0, 0, 0, 1103301ea0f4Smrg 0, 0, 0, 1104301ea0f4Smrg 0, 0, 0, 1105301ea0f4Smrg {'R','V','B',0, 1106301ea0f4Smrg 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}, 1107301ea0f4Smrg XvTopToBottom 1108301ea0f4Smrg }, 1109301ea0f4Smrg}; 1110301ea0f4Smrg 1111301ea0f4Smrg#define NUM_ATTRIBUTES (sizeof(i740vid_Attributes)/sizeof(XF86AttributeRec)) 1112301ea0f4Smrg 1113301ea0f4Smrgstatic XF86AttributeRec i740vid_Attributes[] = 1114301ea0f4Smrg{ 1115301ea0f4Smrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 1116301ea0f4Smrg {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 1117301ea0f4Smrg {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} 1118301ea0f4Smrg}; 1119301ea0f4Smrg 1120301ea0f4Smrg 1121301ea0f4Smrgstatic void I740InitOffscreenImages(ScreenPtr pScreen) 1122301ea0f4Smrg{ 1123301ea0f4Smrg XF86OffscreenImagePtr offscreenImages; 1124301ea0f4Smrg { 11255c69f917Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1126301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740InitOffscreenImages entered\n"); /* ### */ 1127301ea0f4Smrg } 1128301ea0f4Smrg 1129301ea0f4Smrg /* need to free this someplace */ 11305c69f917Smrg if(!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 1131301ea0f4Smrg { 1132301ea0f4Smrg return; 1133301ea0f4Smrg } 1134301ea0f4Smrg 1135301ea0f4Smrg offscreenImages[0].image = &i740vid_Images[0]; 1136301ea0f4Smrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1137301ea0f4Smrg offscreenImages[0].alloc_surface = I740AllocateSurface; 1138301ea0f4Smrg offscreenImages[0].free_surface = I740FreeSurface; 1139301ea0f4Smrg offscreenImages[0].display = I740DisplaySurface; 1140301ea0f4Smrg offscreenImages[0].stop = I740StopSurface; 1141301ea0f4Smrg offscreenImages[0].setAttribute = I740SetSurfaceAttribute; 1142301ea0f4Smrg offscreenImages[0].getAttribute = I740GetSurfaceAttribute; 1143301ea0f4Smrg offscreenImages[0].max_width = IMAGE_MAX_LOG_WIDTH; 1144301ea0f4Smrg offscreenImages[0].max_height = IMAGE_MAX_LOG_HEIGHT; 1145301ea0f4Smrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1146301ea0f4Smrg offscreenImages[0].attributes = i740vid_Attributes; 1147301ea0f4Smrg 1148301ea0f4Smrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1149301ea0f4Smrg} 1150301ea0f4Smrg 1151301ea0f4Smrg 1152301ea0f4Smrg 1153301ea0f4Smrgstatic XF86VideoAdaptorPtr I740SetupImageVideo(ScreenPtr pScreen) 1154301ea0f4Smrg{ 1155301ea0f4Smrg /* client libraries expect an encoding */ 1156301ea0f4Smrg static XF86VideoEncodingRec DummyEncoding[1] = 1157301ea0f4Smrg { 1158301ea0f4Smrg { 1159301ea0f4Smrg 0, 1160301ea0f4Smrg "XV_IMAGE", 1161301ea0f4Smrg IMAGE_MAX_PHY_WIDTH, IMAGE_MAX_PHY_HEIGHT, 1162301ea0f4Smrg {1, 1} 1163301ea0f4Smrg } 1164301ea0f4Smrg }; 1165301ea0f4Smrg 1166301ea0f4Smrg#define NUM_FORMATS (sizeof(i740vid_Formats)/sizeof(XF86VideoFormatRec)) 1167301ea0f4Smrg static XF86VideoFormatRec i740vid_Formats[] = 1168301ea0f4Smrg { 1169301ea0f4Smrg {15, TrueColor}, {16, TrueColor}, {24, TrueColor}, {8, PseudoColor} 1170301ea0f4Smrg }; 1171301ea0f4Smrg 11725c69f917Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1173301ea0f4Smrg I740Ptr pI740 = I740PTR(pScrn); 1174301ea0f4Smrg XF86VideoAdaptorPtr adapt; 1175301ea0f4Smrg I740PortPrivPtr pPriv; 1176301ea0f4Smrg 1177301ea0f4Smrg /*xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740SetupImageVideo entered\n");*/ /* ### */ 1178301ea0f4Smrg { 1179301ea0f4Smrg const int n=sizeof(XF86VideoAdaptorRec)+sizeof(I740PortPrivRec)+sizeof(DevUnion); 1180301ea0f4Smrg 11815c69f917Smrg if(!(adapt = calloc(1, n))) 1182301ea0f4Smrg return NULL; 1183301ea0f4Smrg 1184301ea0f4Smrg /*//memset(adapt,0,n);*/ 1185301ea0f4Smrg } 1186301ea0f4Smrg 1187301ea0f4Smrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 1188301ea0f4Smrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 1189301ea0f4Smrg adapt->name = "I740 Video Overlay"; 1190301ea0f4Smrg adapt->nEncodings = 1; 1191301ea0f4Smrg adapt->pEncodings = DummyEncoding; 1192301ea0f4Smrg adapt->nFormats = NUM_FORMATS; 1193301ea0f4Smrg adapt->pFormats = i740vid_Formats; 1194301ea0f4Smrg adapt->nPorts = 1; 1195301ea0f4Smrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 1196301ea0f4Smrg 1197301ea0f4Smrg pPriv = (I740PortPrivPtr)((unsigned char *)(&adapt[1])+sizeof(sizeof(DevUnion))); 1198301ea0f4Smrg 1199301ea0f4Smrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 1200301ea0f4Smrg adapt->pAttributes = i740vid_Attributes; 1201301ea0f4Smrg adapt->nImages = NUM_IMAGES; 1202301ea0f4Smrg adapt->nAttributes = NUM_ATTRIBUTES; 1203301ea0f4Smrg adapt->pImages = i740vid_Images; 1204301ea0f4Smrg adapt->PutVideo = NULL; 1205301ea0f4Smrg adapt->PutStill = NULL; 1206301ea0f4Smrg adapt->GetVideo = NULL; 1207301ea0f4Smrg adapt->GetStill = NULL; 1208301ea0f4Smrg adapt->StopVideo = I740StopVideo; 1209301ea0f4Smrg adapt->SetPortAttribute = I740SetPortAttribute; 1210301ea0f4Smrg adapt->GetPortAttribute = I740GetPortAttribute; 1211301ea0f4Smrg adapt->QueryBestSize = I740QueryBestSize; 1212301ea0f4Smrg adapt->PutImage = I740PutImage; 1213301ea0f4Smrg adapt->QueryImageAttributes = I740QueryImageAttributes; 1214301ea0f4Smrg 1215301ea0f4Smrg pPriv->colorKey = pI740->colorKey & ((1 << pScrn->depth) - 1); 1216301ea0f4Smrg pPriv->videoStatus = 0; 1217301ea0f4Smrg pPriv->brightness = 0; 1218301ea0f4Smrg pPriv->contrast = 64; 1219301ea0f4Smrg pPriv->linear = NULL; 1220301ea0f4Smrg pPriv->currentBuf = 0; 1221301ea0f4Smrg 1222301ea0f4Smrg /* gotta uninit this someplace */ 1223301ea0f4Smrg REGION_NULL(pScreen, &pPriv->clip); 1224301ea0f4Smrg 1225301ea0f4Smrg pI740->adaptor = adapt; 1226301ea0f4Smrg 1227301ea0f4Smrg pI740->BlockHandler = pScreen->BlockHandler; 1228301ea0f4Smrg pScreen->BlockHandler = I740BlockHandler; 1229301ea0f4Smrg 1230301ea0f4Smrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 1231301ea0f4Smrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 1232301ea0f4Smrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 1233301ea0f4Smrg 1234301ea0f4Smrg I740ResetVideo(pScrn); 1235301ea0f4Smrg 1236301ea0f4Smrg return adapt; 1237301ea0f4Smrg} 1238301ea0f4Smrg 1239301ea0f4Smrgvoid I740InitVideo(ScreenPtr pScreen) 1240301ea0f4Smrg{ 12415c69f917Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 1242301ea0f4Smrg XF86VideoAdaptorPtr newAdaptor = NULL; 1243301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "I740InitVideo entered\n"); /* ### */ 1244301ea0f4Smrg 1245301ea0f4Smrg#if 0 /*disable!*/ 1246301ea0f4Smrg { 1247301ea0f4Smrg XF86VideoAdaptorPtr *ptr; 1248301ea0f4Smrg int n; 1249301ea0f4Smrg 1250301ea0f4Smrg n = xf86XVListGenericAdaptors(pScrn,&ptr); 1251301ea0f4Smrg if (n) { 1252301ea0f4Smrg xf86XVScreenInit(pScreen, ptr, n); 1253301ea0f4Smrg } 1254301ea0f4Smrg 1255301ea0f4Smrg return; 1256301ea0f4Smrg } 1257301ea0f4Smrg#endif 1258301ea0f4Smrg 1259301ea0f4Smrg { 1260301ea0f4Smrg newAdaptor = I740SetupImageVideo(pScreen); 1261301ea0f4Smrg I740InitOffscreenImages(pScreen); 1262301ea0f4Smrg } 1263301ea0f4Smrg 1264301ea0f4Smrg { 1265301ea0f4Smrg XF86VideoAdaptorPtr *adaptors_oldptrs, *adaptors_newptrs = NULL; 1266301ea0f4Smrg int num_adaptors; 1267301ea0f4Smrg 1268301ea0f4Smrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors_oldptrs); 1269301ea0f4Smrg 1270301ea0f4Smrg if(newAdaptor) 1271301ea0f4Smrg { 1272301ea0f4Smrg if(!num_adaptors) 1273301ea0f4Smrg { 1274301ea0f4Smrg xf86XVScreenInit(pScreen, &newAdaptor, 1); 1275301ea0f4Smrg } 1276301ea0f4Smrg else 1277301ea0f4Smrg { 12785c69f917Smrg if((adaptors_newptrs = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr)))) 1279301ea0f4Smrg { 1280301ea0f4Smrg memcpy(adaptors_newptrs, adaptors_oldptrs, num_adaptors * sizeof(XF86VideoAdaptorPtr)); 1281301ea0f4Smrg adaptors_newptrs[num_adaptors] = newAdaptor; 1282301ea0f4Smrg 1283301ea0f4Smrg /*//xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,"num--- %d [%d] %08x %08x\n",num_adaptors,num_adaptors * sizeof(XF86VideoAdaptorPtr),*/ 1284301ea0f4Smrg /*// adaptors_newptrs[0],adaptors_newptrs[1]);*/ 1285301ea0f4Smrg 1286301ea0f4Smrg 1287301ea0f4Smrg xf86XVScreenInit(pScreen, adaptors_newptrs, num_adaptors+1); 12885c69f917Smrg free(adaptors_newptrs); 1289301ea0f4Smrg } 1290301ea0f4Smrg } 1291301ea0f4Smrg } 1292301ea0f4Smrg 1293301ea0f4Smrg } 1294301ea0f4Smrg} 1295