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