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