1fa225cbcSrjs/*************************************************************************** 2fa225cbcSrjs 3fa225cbcSrjsCopyright 2000 Intel Corporation. All Rights Reserved. 4fa225cbcSrjs 5fa225cbcSrjsPermission is hereby granted, free of charge, to any person obtaining a 6fa225cbcSrjscopy of this software and associated documentation files (the 7fa225cbcSrjs"Software"), to deal in the Software without restriction, including 8fa225cbcSrjswithout limitation the rights to use, copy, modify, merge, publish, 9fa225cbcSrjsdistribute, sub license, and/or sell copies of the Software, and to 10fa225cbcSrjspermit persons to whom the Software is furnished to do so, subject to 11fa225cbcSrjsthe following conditions: 12fa225cbcSrjs 13fa225cbcSrjsThe above copyright notice and this permission notice (including the 14fa225cbcSrjsnext paragraph) shall be included in all copies or substantial portions 15fa225cbcSrjsof the Software. 16fa225cbcSrjs 17fa225cbcSrjsTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18fa225cbcSrjsOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19fa225cbcSrjsMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20fa225cbcSrjsIN NO EVENT SHALL INTEL, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 21fa225cbcSrjsDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22fa225cbcSrjsOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR 23fa225cbcSrjsTHE USE OR OTHER DEALINGS IN THE SOFTWARE. 24fa225cbcSrjs 25fa225cbcSrjs**************************************************************************/ 26fa225cbcSrjs 27fa225cbcSrjs/* 28fa225cbcSrjs * i810_video.c: i810 Xv driver. Based on the mga Xv driver by Mark Vojkovich. 29fa225cbcSrjs * 30fa225cbcSrjs * Authors: 31fa225cbcSrjs * Jonathan Bian <jonathan.bian@intel.com> 32fa225cbcSrjs * Offscreen Images: 33fa225cbcSrjs * Matt Sottek <matthew.j.sottek@intel.com> 34fa225cbcSrjs */ 35fa225cbcSrjs 36fa225cbcSrjs#ifdef HAVE_CONFIG_H 37fa225cbcSrjs#include "config.h" 38fa225cbcSrjs#endif 39fa225cbcSrjs 40fa225cbcSrjs#include <string.h> 41fa225cbcSrjs 42fa225cbcSrjs#include "xf86.h" 43fa225cbcSrjs#include "xf86_OSproc.h" 44fa225cbcSrjs#include "compiler.h" 45fa225cbcSrjs#include "xf86PciInfo.h" 46fa225cbcSrjs#include "xf86Pci.h" 47fa225cbcSrjs#include "xf86fbman.h" 48fa225cbcSrjs#include "regionstr.h" 49fa225cbcSrjs 50fa225cbcSrjs#include "i810.h" 51fa225cbcSrjs#include "xf86xv.h" 52fa225cbcSrjs#include <X11/extensions/Xv.h> 53fa225cbcSrjs#include "xaa.h" 54fa225cbcSrjs#include "xaalocal.h" 55fa225cbcSrjs#include "dixstruct.h" 56fa225cbcSrjs#include "fourcc.h" 57fa225cbcSrjs 58fa225cbcSrjs#define OFF_DELAY 250 /* milliseconds */ 59fa225cbcSrjs#define FREE_DELAY 15000 60fa225cbcSrjs 61fa225cbcSrjs#define OFF_TIMER 0x01 62fa225cbcSrjs#define FREE_TIMER 0x02 63fa225cbcSrjs#define CLIENT_VIDEO_ON 0x04 64fa225cbcSrjs 65fa225cbcSrjs#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 66fa225cbcSrjs 67fa225cbcSrjsstatic void I810InitOffscreenImages(ScreenPtr); 68fa225cbcSrjs 69fa225cbcSrjsstatic XF86VideoAdaptorPtr I810SetupImageVideo(ScreenPtr); 70fa225cbcSrjsstatic void I810StopVideo(ScrnInfoPtr, pointer, Bool); 71fa225cbcSrjsstatic int I810SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 72fa225cbcSrjsstatic int I810GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 73fa225cbcSrjsstatic void I810QueryBestSize(ScrnInfoPtr, Bool, 74fa225cbcSrjs short, short, short, short, unsigned int *, unsigned int *, pointer); 75fa225cbcSrjsstatic int I810PutImage( ScrnInfoPtr, 76fa225cbcSrjs short, short, short, short, short, short, short, short, 77fa225cbcSrjs int, unsigned char*, short, short, Bool, RegionPtr, pointer, 78fa225cbcSrjs DrawablePtr); 79fa225cbcSrjsstatic int I810QueryImageAttributes(ScrnInfoPtr, 80fa225cbcSrjs int, unsigned short *, unsigned short *, int *, int *); 81fa225cbcSrjs 82fa225cbcSrjsstatic void I810BlockHandler(int, pointer, pointer, pointer); 83fa225cbcSrjs 84fa225cbcSrjs#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 85fa225cbcSrjs 86fa225cbcSrjsstatic Atom xvBrightness, xvContrast, xvColorKey; 87fa225cbcSrjs 88fa225cbcSrjs#define IMAGE_MAX_WIDTH 1440 89fa225cbcSrjs#define IMAGE_FAST_WIDTH 720 90fa225cbcSrjs#define IMAGE_MAX_HEIGHT 1080 91fa225cbcSrjs#define Y_BUF_SIZE (IMAGE_MAX_WIDTH * IMAGE_MAX_HEIGHT) 92fa225cbcSrjs 93fa225cbcSrjs#define OVERLAY_UPDATE(p) OUTREG(0x30000, p | 0x80000000); 94fa225cbcSrjs 95fa225cbcSrjs/* 96fa225cbcSrjs * OV0CMD - Overlay Command Register 97fa225cbcSrjs */ 98fa225cbcSrjs#define VERTICAL_CHROMINANCE_FILTER 0x70000000 99fa225cbcSrjs#define VC_SCALING_OFF 0x00000000 100fa225cbcSrjs#define VC_LINE_REPLICATION 0x10000000 101fa225cbcSrjs#define VC_UP_INTERPOLATION 0x20000000 102fa225cbcSrjs#define VC_PIXEL_DROPPING 0x50000000 103fa225cbcSrjs#define VC_DOWN_INTERPOLATION 0x60000000 104fa225cbcSrjs#define VERTICAL_LUMINANCE_FILTER 0x0E000000 105fa225cbcSrjs#define VL_SCALING_OFF 0x00000000 106fa225cbcSrjs#define VL_LINE_REPLICATION 0x02000000 107fa225cbcSrjs#define VL_UP_INTERPOLATION 0x04000000 108fa225cbcSrjs#define VL_PIXEL_DROPPING 0x0A000000 109fa225cbcSrjs#define VL_DOWN_INTERPOLATION 0x0C000000 110fa225cbcSrjs#define HORIZONTAL_CHROMINANCE_FILTER 0x01C00000 111fa225cbcSrjs#define HC_SCALING_OFF 0x00000000 112fa225cbcSrjs#define HC_LINE_REPLICATION 0x00400000 113fa225cbcSrjs#define HC_UP_INTERPOLATION 0x00800000 114fa225cbcSrjs#define HC_PIXEL_DROPPING 0x01400000 115fa225cbcSrjs#define HC_DOWN_INTERPOLATION 0x01800000 116fa225cbcSrjs#define HORIZONTAL_LUMINANCE_FILTER 0x00380000 117fa225cbcSrjs#define HL_SCALING_OFF 0x00000000 118fa225cbcSrjs#define HL_LINE_REPLICATION 0x00080000 119fa225cbcSrjs#define HL_UP_INTERPOLATION 0x00100000 120fa225cbcSrjs#define HL_PIXEL_DROPPING 0x00280000 121fa225cbcSrjs#define HL_DOWN_INTERPOLATION 0x00300000 122fa225cbcSrjs 123fa225cbcSrjs#define Y_ADJUST 0x00010000 124fa225cbcSrjs#define OV_BYTE_ORDER 0x0000C000 125fa225cbcSrjs#define UV_SWAP 0x00004000 126fa225cbcSrjs#define Y_SWAP 0x00008000 127fa225cbcSrjs#define Y_AND_UV_SWAP 0x0000C000 128fa225cbcSrjs#define SOURCE_FORMAT 0x00003C00 129fa225cbcSrjs#define RGB_555 0x00000800 130fa225cbcSrjs#define RGB_565 0x00000C00 131fa225cbcSrjs#define YUV_422 0x00002000 132fa225cbcSrjs#define YUV_411 0x00002400 133fa225cbcSrjs#define YUV_420 0x00003000 134fa225cbcSrjs#define YUV_410 0x00003800 135fa225cbcSrjs#define BUFFER_AND_FIELD 0x00000006 136fa225cbcSrjs#define BUFFER0_FIELD0 0x00000000 137fa225cbcSrjs#define BUFFER1_FIELD0 0x00000004 138fa225cbcSrjs#define OVERLAY_ENABLE 0x00000001 139fa225cbcSrjs 140fa225cbcSrjs#define UV_VERT_BUF1 0x02 141fa225cbcSrjs#define UV_VERT_BUF0 0x04 142fa225cbcSrjs 143fa225cbcSrjs/* 144fa225cbcSrjs * DOV0STA - Display/Overlay 0 Status Register 145fa225cbcSrjs */ 146fa225cbcSrjs#define DOV0STA 0x30008 147fa225cbcSrjs 148fa225cbcSrjs#define MINUV_SCALE 0x1 149fa225cbcSrjs 150fa225cbcSrjs#define RGB16ToColorKey(c) \ 151fa225cbcSrjs (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) 152fa225cbcSrjs 153fa225cbcSrjs#define RGB15ToColorKey(c) \ 154fa225cbcSrjs (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3)) 155fa225cbcSrjs 156fa225cbcSrjsvoid I810InitVideo(ScreenPtr pScreen) 157fa225cbcSrjs{ 158fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 159fa225cbcSrjs XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 160fa225cbcSrjs XF86VideoAdaptorPtr newAdaptor = NULL; 161fa225cbcSrjs int num_adaptors; 162fa225cbcSrjs 163fa225cbcSrjs if (pScrn->bitsPerPixel != 8) 164fa225cbcSrjs { 165fa225cbcSrjs newAdaptor = I810SetupImageVideo(pScreen); 166fa225cbcSrjs I810InitOffscreenImages(pScreen); 167fa225cbcSrjs } 168fa225cbcSrjs 169fa225cbcSrjs num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 170fa225cbcSrjs 171fa225cbcSrjs if(newAdaptor) { 172fa225cbcSrjs if(!num_adaptors) { 173fa225cbcSrjs num_adaptors = 1; 174fa225cbcSrjs adaptors = &newAdaptor; 175fa225cbcSrjs } else { 176fa225cbcSrjs newAdaptors = /* need to free this someplace */ 177fa225cbcSrjs xalloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr*)); 178fa225cbcSrjs if(newAdaptors) { 179fa225cbcSrjs memcpy(newAdaptors, adaptors, num_adaptors * 180fa225cbcSrjs sizeof(XF86VideoAdaptorPtr)); 181fa225cbcSrjs newAdaptors[num_adaptors] = newAdaptor; 182fa225cbcSrjs adaptors = newAdaptors; 183fa225cbcSrjs num_adaptors++; 184fa225cbcSrjs } 185fa225cbcSrjs } 186fa225cbcSrjs } 187fa225cbcSrjs 188fa225cbcSrjs if(num_adaptors) 189fa225cbcSrjs xf86XVScreenInit(pScreen, adaptors, num_adaptors); 190fa225cbcSrjs 191fa225cbcSrjs if(newAdaptors) 192fa225cbcSrjs xfree(newAdaptors); 193fa225cbcSrjs} 194fa225cbcSrjs 195fa225cbcSrjs/* *INDENT-OFF* */ 196fa225cbcSrjs/* client libraries expect an encoding */ 197fa225cbcSrjsstatic XF86VideoEncodingRec DummyEncoding[1] = 198fa225cbcSrjs{ 199fa225cbcSrjs { 200fa225cbcSrjs 0, 201fa225cbcSrjs "XV_IMAGE", 202fa225cbcSrjs IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT, 203fa225cbcSrjs {1, 1} 204fa225cbcSrjs } 205fa225cbcSrjs}; 206fa225cbcSrjs 207fa225cbcSrjs#define NUM_FORMATS 3 208fa225cbcSrjs 209fa225cbcSrjsstatic XF86VideoFormatRec Formats[NUM_FORMATS] = 210fa225cbcSrjs{ 211fa225cbcSrjs {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 212fa225cbcSrjs}; 213fa225cbcSrjs 214fa225cbcSrjs#define NUM_ATTRIBUTES 3 215fa225cbcSrjs 216fa225cbcSrjsstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 217fa225cbcSrjs{ 218fa225cbcSrjs {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 219fa225cbcSrjs {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 220fa225cbcSrjs {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} 221fa225cbcSrjs}; 222fa225cbcSrjs 223fa225cbcSrjs#define NUM_IMAGES 6 224fa225cbcSrjs 225fa225cbcSrjs#define I810_RV15 0x35315652 226fa225cbcSrjs#define I810_RV16 0x36315652 227fa225cbcSrjs 228fa225cbcSrjsstatic XF86ImageRec Images[NUM_IMAGES] = 229fa225cbcSrjs{ 230fa225cbcSrjs { 231fa225cbcSrjs I810_RV15, 232fa225cbcSrjs XvRGB, 233fa225cbcSrjs LSBFirst, 234fa225cbcSrjs {'R','V','1','5', 235fa225cbcSrjs 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 236fa225cbcSrjs 16, 237fa225cbcSrjs XvPacked, 238fa225cbcSrjs 1, 239fa225cbcSrjs 15, 0x7C00, 0x03E0, 0x001F, 240fa225cbcSrjs 0, 0, 0, 241fa225cbcSrjs 0, 0, 0, 242fa225cbcSrjs 0, 0, 0, 243fa225cbcSrjs {'R','V','B',0, 244fa225cbcSrjs 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}, 245fa225cbcSrjs XvTopToBottom 246fa225cbcSrjs }, 247fa225cbcSrjs { 248fa225cbcSrjs I810_RV16, 249fa225cbcSrjs XvRGB, 250fa225cbcSrjs LSBFirst, 251fa225cbcSrjs {'R','V','1','6', 252fa225cbcSrjs 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 253fa225cbcSrjs 16, 254fa225cbcSrjs XvPacked, 255fa225cbcSrjs 1, 256fa225cbcSrjs 16, 0xF800, 0x07E0, 0x001F, 257fa225cbcSrjs 0, 0, 0, 258fa225cbcSrjs 0, 0, 0, 259fa225cbcSrjs 0, 0, 0, 260fa225cbcSrjs {'R','V','B',0, 261fa225cbcSrjs 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}, 262fa225cbcSrjs XvTopToBottom 263fa225cbcSrjs }, 264fa225cbcSrjs XVIMAGE_YUY2, 265fa225cbcSrjs XVIMAGE_YV12, 266fa225cbcSrjs XVIMAGE_I420, 267fa225cbcSrjs XVIMAGE_UYVY 268fa225cbcSrjs}; 269fa225cbcSrjs/* *INDENT-ON* */ 270fa225cbcSrjs 271fa225cbcSrjstypedef struct { 272fa225cbcSrjs uint32_t OBUF_0Y; 273fa225cbcSrjs uint32_t OBUF_1Y; 274fa225cbcSrjs uint32_t OBUF_0U; 275fa225cbcSrjs uint32_t OBUF_0V; 276fa225cbcSrjs uint32_t OBUF_1U; 277fa225cbcSrjs uint32_t OBUF_1V; 278fa225cbcSrjs uint32_t OV0STRIDE; 279fa225cbcSrjs uint32_t YRGB_VPH; 280fa225cbcSrjs uint32_t UV_VPH; 281fa225cbcSrjs uint32_t HORZ_PH; 282fa225cbcSrjs uint32_t INIT_PH; 283fa225cbcSrjs uint32_t DWINPOS; 284fa225cbcSrjs uint32_t DWINSZ; 285fa225cbcSrjs uint32_t SWID; 286fa225cbcSrjs uint32_t SWIDQW; 287fa225cbcSrjs uint32_t SHEIGHT; 288fa225cbcSrjs uint32_t YRGBSCALE; 289fa225cbcSrjs uint32_t UVSCALE; 290fa225cbcSrjs uint32_t OV0CLRC0; 291fa225cbcSrjs uint32_t OV0CLRC1; 292fa225cbcSrjs uint32_t DCLRKV; 293fa225cbcSrjs uint32_t DCLRKM; 294fa225cbcSrjs uint32_t SCLRKVH; 295fa225cbcSrjs uint32_t SCLRKVL; 296fa225cbcSrjs uint32_t SCLRKM; 297fa225cbcSrjs uint32_t OV0CONF; 298fa225cbcSrjs uint32_t OV0CMD; 299fa225cbcSrjs} I810OverlayRegRec, *I810OverlayRegPtr; 300fa225cbcSrjs 301fa225cbcSrjstypedef struct { 302fa225cbcSrjs uint32_t YBuf0offset; 303fa225cbcSrjs uint32_t UBuf0offset; 304fa225cbcSrjs uint32_t VBuf0offset; 305fa225cbcSrjs 306fa225cbcSrjs uint32_t YBuf1offset; 307fa225cbcSrjs uint32_t UBuf1offset; 308fa225cbcSrjs uint32_t VBuf1offset; 309fa225cbcSrjs 310fa225cbcSrjs unsigned char currentBuf; 311fa225cbcSrjs 312fa225cbcSrjs int brightness; 313fa225cbcSrjs int contrast; 314fa225cbcSrjs 315fa225cbcSrjs RegionRec clip; 316fa225cbcSrjs uint32_t colorKey; 317fa225cbcSrjs 318fa225cbcSrjs uint32_t videoStatus; 319fa225cbcSrjs Time offTime; 320fa225cbcSrjs Time freeTime; 321fa225cbcSrjs FBLinearPtr linear; 322fa225cbcSrjs} I810PortPrivRec, *I810PortPrivPtr; 323fa225cbcSrjs 324fa225cbcSrjs#define GET_PORT_PRIVATE(pScrn) \ 325fa225cbcSrjs (I810PortPrivPtr)((I810PTR(pScrn))->adaptor->pPortPrivates[0].ptr) 326fa225cbcSrjs 327fa225cbcSrjsstatic void I810ResetVideo(ScrnInfoPtr pScrn) 328fa225cbcSrjs{ 329fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 330fa225cbcSrjs I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; 331fa225cbcSrjs I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); 332fa225cbcSrjs 333fa225cbcSrjs /* 334fa225cbcSrjs * Default to maximum image size in YV12 335fa225cbcSrjs */ 336fa225cbcSrjs 337fa225cbcSrjs overlay->YRGB_VPH = 0; 338fa225cbcSrjs overlay->UV_VPH = 0; 339fa225cbcSrjs overlay->HORZ_PH = 0; 340fa225cbcSrjs overlay->INIT_PH = 0; 341fa225cbcSrjs overlay->DWINPOS = 0; 342fa225cbcSrjs overlay->DWINSZ = (IMAGE_MAX_HEIGHT << 16) | IMAGE_MAX_WIDTH; 343fa225cbcSrjs overlay->SWID = IMAGE_MAX_WIDTH | (IMAGE_MAX_WIDTH << 15); 344fa225cbcSrjs overlay->SWIDQW = (IMAGE_MAX_WIDTH >> 3) | (IMAGE_MAX_WIDTH << 12); 345fa225cbcSrjs overlay->SHEIGHT = IMAGE_MAX_HEIGHT | (IMAGE_MAX_HEIGHT << 15); 346fa225cbcSrjs overlay->YRGBSCALE = 0x80004000; /* scale factor 1 */ 347fa225cbcSrjs overlay->UVSCALE = 0x80004000; /* scale factor 1 */ 348fa225cbcSrjs overlay->OV0CLRC0 = 0x4000; /* brightness: 0 contrast: 1.0 */ 349fa225cbcSrjs overlay->OV0CLRC1 = 0x80; /* saturation: bypass */ 350fa225cbcSrjs 351fa225cbcSrjs /* 352fa225cbcSrjs * Enable destination color keying 353fa225cbcSrjs */ 354fa225cbcSrjs switch(pScrn->depth) { 355fa225cbcSrjs case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); 356fa225cbcSrjs overlay->DCLRKM = 0x80070307; 357fa225cbcSrjs break; 358fa225cbcSrjs case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey); 359fa225cbcSrjs overlay->DCLRKM = 0x80070707; 360fa225cbcSrjs break; 361fa225cbcSrjs default: overlay->DCLRKV = pPriv->colorKey; 362fa225cbcSrjs overlay->DCLRKM = 0x80000000; 363fa225cbcSrjs break; 364fa225cbcSrjs } 365fa225cbcSrjs 366fa225cbcSrjs overlay->SCLRKVH = 0; 367fa225cbcSrjs overlay->SCLRKVL = 0; 368fa225cbcSrjs overlay->SCLRKM = 0; /* source color key disable */ 369fa225cbcSrjs overlay->OV0CONF = 0; /* two 720 pixel line buffers */ 370fa225cbcSrjs 371fa225cbcSrjs overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | 372fa225cbcSrjs YUV_420; 373fa225cbcSrjs 374fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 375fa225cbcSrjs} 376fa225cbcSrjs 377fa225cbcSrjs 378fa225cbcSrjsstatic XF86VideoAdaptorPtr 379fa225cbcSrjsI810SetupImageVideo(ScreenPtr pScreen) 380fa225cbcSrjs{ 381fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 382fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 383fa225cbcSrjs XF86VideoAdaptorPtr adapt; 384fa225cbcSrjs I810PortPrivPtr pPriv; 385fa225cbcSrjs 386fa225cbcSrjs if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 387fa225cbcSrjs sizeof(I810PortPrivRec) + 388fa225cbcSrjs sizeof(DevUnion)))) 389fa225cbcSrjs return NULL; 390fa225cbcSrjs 391fa225cbcSrjs adapt->type = XvWindowMask | XvInputMask | XvImageMask; 392fa225cbcSrjs adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 393fa225cbcSrjs adapt->name = "I810 Video Overlay"; 394fa225cbcSrjs adapt->nEncodings = 1; 395fa225cbcSrjs adapt->pEncodings = DummyEncoding; 396fa225cbcSrjs adapt->nFormats = NUM_FORMATS; 397fa225cbcSrjs adapt->pFormats = Formats; 398fa225cbcSrjs adapt->nPorts = 1; 399fa225cbcSrjs adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 400fa225cbcSrjs 401fa225cbcSrjs pPriv = (I810PortPrivPtr)(&adapt->pPortPrivates[1]); 402fa225cbcSrjs 403fa225cbcSrjs adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 404fa225cbcSrjs adapt->pAttributes = Attributes; 405fa225cbcSrjs adapt->nImages = NUM_IMAGES; 406fa225cbcSrjs adapt->nAttributes = NUM_ATTRIBUTES; 407fa225cbcSrjs adapt->pImages = Images; 408fa225cbcSrjs adapt->PutVideo = NULL; 409fa225cbcSrjs adapt->PutStill = NULL; 410fa225cbcSrjs adapt->GetVideo = NULL; 411fa225cbcSrjs adapt->GetStill = NULL; 412fa225cbcSrjs adapt->StopVideo = I810StopVideo; 413fa225cbcSrjs adapt->SetPortAttribute = I810SetPortAttribute; 414fa225cbcSrjs adapt->GetPortAttribute = I810GetPortAttribute; 415fa225cbcSrjs adapt->QueryBestSize = I810QueryBestSize; 416fa225cbcSrjs adapt->PutImage = I810PutImage; 417fa225cbcSrjs adapt->QueryImageAttributes = I810QueryImageAttributes; 418fa225cbcSrjs 419fa225cbcSrjs pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1); 420fa225cbcSrjs pPriv->videoStatus = 0; 421fa225cbcSrjs pPriv->brightness = 0; 422fa225cbcSrjs pPriv->contrast = 64; 423fa225cbcSrjs pPriv->linear = NULL; 424fa225cbcSrjs pPriv->currentBuf = 0; 425fa225cbcSrjs 426fa225cbcSrjs /* gotta uninit this someplace */ 427fa225cbcSrjs REGION_NULL(pScreen, &pPriv->clip); 428fa225cbcSrjs 429fa225cbcSrjs pI810->adaptor = adapt; 430fa225cbcSrjs 431fa225cbcSrjs pI810->BlockHandler = pScreen->BlockHandler; 432fa225cbcSrjs pScreen->BlockHandler = I810BlockHandler; 433fa225cbcSrjs 434fa225cbcSrjs xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 435fa225cbcSrjs xvContrast = MAKE_ATOM("XV_CONTRAST"); 436fa225cbcSrjs xvColorKey = MAKE_ATOM("XV_COLORKEY"); 437fa225cbcSrjs 438fa225cbcSrjs I810ResetVideo(pScrn); 439fa225cbcSrjs 440fa225cbcSrjs return adapt; 441fa225cbcSrjs} 442fa225cbcSrjs 443fa225cbcSrjs 444fa225cbcSrjs/* I810ClipVideo - 445fa225cbcSrjs 446fa225cbcSrjs Takes the dst box in standard X BoxRec form (top and left 447fa225cbcSrjs edges inclusive, bottom and right exclusive). The new dst 448fa225cbcSrjs box is returned. The source boundaries are given (x1, y1 449fa225cbcSrjs inclusive, x2, y2 exclusive) and returned are the new source 450fa225cbcSrjs boundaries in 16.16 fixed point. 451fa225cbcSrjs*/ 452fa225cbcSrjs 453fa225cbcSrjsstatic void 454fa225cbcSrjsI810ClipVideo( 455fa225cbcSrjs BoxPtr dst, 456fa225cbcSrjs INT32 *x1, 457fa225cbcSrjs INT32 *x2, 458fa225cbcSrjs INT32 *y1, 459fa225cbcSrjs INT32 *y2, 460fa225cbcSrjs BoxPtr extents, /* extents of the clip region */ 461fa225cbcSrjs INT32 width, 462fa225cbcSrjs INT32 height 463fa225cbcSrjs){ 464fa225cbcSrjs INT32 vscale, hscale, delta; 465fa225cbcSrjs int diff; 466fa225cbcSrjs 467fa225cbcSrjs hscale = ((*x2 - *x1) << 16) / (dst->x2 - dst->x1); 468fa225cbcSrjs vscale = ((*y2 - *y1) << 16) / (dst->y2 - dst->y1); 469fa225cbcSrjs 470fa225cbcSrjs *x1 <<= 16; *x2 <<= 16; 471fa225cbcSrjs *y1 <<= 16; *y2 <<= 16; 472fa225cbcSrjs 473fa225cbcSrjs diff = extents->x1 - dst->x1; 474fa225cbcSrjs if(diff > 0) { 475fa225cbcSrjs dst->x1 = extents->x1; 476fa225cbcSrjs *x1 += diff * hscale; 477fa225cbcSrjs } 478fa225cbcSrjs diff = dst->x2 - extents->x2; 479fa225cbcSrjs if(diff > 0) { 480fa225cbcSrjs dst->x2 = extents->x2; 481fa225cbcSrjs *x2 -= diff * hscale; 482fa225cbcSrjs } 483fa225cbcSrjs diff = extents->y1 - dst->y1; 484fa225cbcSrjs if(diff > 0) { 485fa225cbcSrjs dst->y1 = extents->y1; 486fa225cbcSrjs *y1 += diff * vscale; 487fa225cbcSrjs } 488fa225cbcSrjs diff = dst->y2 - extents->y2; 489fa225cbcSrjs if(diff > 0) { 490fa225cbcSrjs dst->y2 = extents->y2; 491fa225cbcSrjs *y2 -= diff * vscale; 492fa225cbcSrjs } 493fa225cbcSrjs 494fa225cbcSrjs if(*x1 < 0) { 495fa225cbcSrjs diff = (- *x1 + hscale - 1)/ hscale; 496fa225cbcSrjs dst->x1 += diff; 497fa225cbcSrjs *x1 += diff * hscale; 498fa225cbcSrjs } 499fa225cbcSrjs delta = *x2 - (width << 16); 500fa225cbcSrjs if(delta > 0) { 501fa225cbcSrjs diff = (delta + hscale - 1)/ hscale; 502fa225cbcSrjs dst->x2 -= diff; 503fa225cbcSrjs *x2 -= diff * hscale; 504fa225cbcSrjs } 505fa225cbcSrjs if(*y1 < 0) { 506fa225cbcSrjs diff = (- *y1 + vscale - 1)/ vscale; 507fa225cbcSrjs dst->y1 += diff; 508fa225cbcSrjs *y1 += diff * vscale; 509fa225cbcSrjs } 510fa225cbcSrjs delta = *y2 - (height << 16); 511fa225cbcSrjs if(delta > 0) { 512fa225cbcSrjs diff = (delta + vscale - 1)/ vscale; 513fa225cbcSrjs dst->y2 -= diff; 514fa225cbcSrjs *y2 -= diff * vscale; 515fa225cbcSrjs } 516fa225cbcSrjs} 517fa225cbcSrjs 518fa225cbcSrjsstatic void 519fa225cbcSrjsI810StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 520fa225cbcSrjs{ 521fa225cbcSrjs I810PortPrivPtr pPriv = (I810PortPrivPtr)data; 522fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 523fa225cbcSrjs 524fa225cbcSrjs I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); 525fa225cbcSrjs 526fa225cbcSrjs REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 527fa225cbcSrjs 528fa225cbcSrjs if(shutdown) { 529fa225cbcSrjs if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 530fa225cbcSrjs overlay->OV0CMD &= 0xFFFFFFFE; 531fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 532fa225cbcSrjs } 533fa225cbcSrjs if(pPriv->linear) { 534fa225cbcSrjs xf86FreeOffscreenLinear(pPriv->linear); 535fa225cbcSrjs pPriv->linear = NULL; 536fa225cbcSrjs } 537fa225cbcSrjs pPriv->videoStatus = 0; 538fa225cbcSrjs } else { 539fa225cbcSrjs if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 540fa225cbcSrjs pPriv->videoStatus |= OFF_TIMER; 541fa225cbcSrjs pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 542fa225cbcSrjs } 543fa225cbcSrjs } 544fa225cbcSrjs 545fa225cbcSrjs} 546fa225cbcSrjs 547fa225cbcSrjsstatic int 548fa225cbcSrjsI810SetPortAttribute( 549fa225cbcSrjs ScrnInfoPtr pScrn, 550fa225cbcSrjs Atom attribute, 551fa225cbcSrjs INT32 value, 552fa225cbcSrjs pointer data 553fa225cbcSrjs){ 554fa225cbcSrjs I810PortPrivPtr pPriv = (I810PortPrivPtr)data; 555fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 556fa225cbcSrjs I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); 557fa225cbcSrjs 558fa225cbcSrjs if(attribute == xvBrightness) { 559fa225cbcSrjs if((value < -128) || (value > 127)) 560fa225cbcSrjs return BadValue; 561fa225cbcSrjs pPriv->brightness = value; 562fa225cbcSrjs overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); 563fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 564fa225cbcSrjs } else 565fa225cbcSrjs if(attribute == xvContrast) { 566fa225cbcSrjs if((value < 0) || (value > 255)) 567fa225cbcSrjs return BadValue; 568fa225cbcSrjs pPriv->contrast = value; 569fa225cbcSrjs overlay->OV0CLRC0 = (pPriv->contrast << 8) | (pPriv->brightness & 0xff); 570fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 571fa225cbcSrjs } else 572fa225cbcSrjs if(attribute == xvColorKey) { 573fa225cbcSrjs pPriv->colorKey = value; 574fa225cbcSrjs switch(pScrn->depth) { 575fa225cbcSrjs case 16: overlay->DCLRKV = RGB16ToColorKey(pPriv->colorKey); 576fa225cbcSrjs break; 577fa225cbcSrjs case 15: overlay->DCLRKV = RGB15ToColorKey(pPriv->colorKey); 578fa225cbcSrjs break; 579fa225cbcSrjs default: overlay->DCLRKV = pPriv->colorKey; 580fa225cbcSrjs break; 581fa225cbcSrjs } 582fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 583fa225cbcSrjs REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 584fa225cbcSrjs } else return BadMatch; 585fa225cbcSrjs 586fa225cbcSrjs return Success; 587fa225cbcSrjs} 588fa225cbcSrjs 589fa225cbcSrjsstatic int 590fa225cbcSrjsI810GetPortAttribute( 591fa225cbcSrjs ScrnInfoPtr pScrn, 592fa225cbcSrjs Atom attribute, 593fa225cbcSrjs INT32 *value, 594fa225cbcSrjs pointer data 595fa225cbcSrjs){ 596fa225cbcSrjs I810PortPrivPtr pPriv = (I810PortPrivPtr)data; 597fa225cbcSrjs 598fa225cbcSrjs if(attribute == xvBrightness) { 599fa225cbcSrjs *value = pPriv->brightness; 600fa225cbcSrjs } else 601fa225cbcSrjs if(attribute == xvContrast) { 602fa225cbcSrjs *value = pPriv->contrast; 603fa225cbcSrjs } else 604fa225cbcSrjs if(attribute == xvColorKey) { 605fa225cbcSrjs *value = pPriv->colorKey; 606fa225cbcSrjs } else return BadMatch; 607fa225cbcSrjs 608fa225cbcSrjs return Success; 609fa225cbcSrjs} 610fa225cbcSrjs 611fa225cbcSrjsstatic void 612fa225cbcSrjsI810QueryBestSize( 613fa225cbcSrjs ScrnInfoPtr pScrn, 614fa225cbcSrjs Bool motion, 615fa225cbcSrjs short vid_w, short vid_h, 616fa225cbcSrjs short drw_w, short drw_h, 617fa225cbcSrjs unsigned int *p_w, unsigned int *p_h, 618fa225cbcSrjs pointer data 619fa225cbcSrjs){ 620fa225cbcSrjs if(vid_w > (drw_w << 1)) drw_w = vid_w >> 1; 621fa225cbcSrjs if(vid_h > (drw_h << 1)) drw_h = vid_h >> 1; 622fa225cbcSrjs 623fa225cbcSrjs *p_w = drw_w; 624fa225cbcSrjs *p_h = drw_h; 625fa225cbcSrjs} 626fa225cbcSrjs 627fa225cbcSrjs 628fa225cbcSrjsstatic void 629fa225cbcSrjsI810CopyPackedData( 630fa225cbcSrjs ScrnInfoPtr pScrn, 631fa225cbcSrjs unsigned char *buf, 632fa225cbcSrjs int srcPitch, 633fa225cbcSrjs int dstPitch, 634fa225cbcSrjs int top, 635fa225cbcSrjs int left, 636fa225cbcSrjs int h, 637fa225cbcSrjs int w 638fa225cbcSrjs ) 639fa225cbcSrjs{ 640fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 641fa225cbcSrjs I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; 642fa225cbcSrjs unsigned char *src, *dst; 643fa225cbcSrjs 644fa225cbcSrjs src = buf + (top*srcPitch) + (left<<1); 645fa225cbcSrjs 646fa225cbcSrjs if (pPriv->currentBuf == 0) 647fa225cbcSrjs dst = pI810->FbBase + pPriv->YBuf0offset; 648fa225cbcSrjs else 649fa225cbcSrjs dst = pI810->FbBase + pPriv->YBuf1offset; 650fa225cbcSrjs 651fa225cbcSrjs w <<= 1; 652fa225cbcSrjs while(h--) { 653fa225cbcSrjs memcpy(dst, src, w); 654fa225cbcSrjs src += srcPitch; 655fa225cbcSrjs dst += dstPitch; 656fa225cbcSrjs } 657fa225cbcSrjs} 658fa225cbcSrjs 659fa225cbcSrjsstatic void 660fa225cbcSrjsI810CopyPlanarData( 661fa225cbcSrjs ScrnInfoPtr pScrn, 662fa225cbcSrjs unsigned char *buf, 663fa225cbcSrjs int srcPitch, 664fa225cbcSrjs int dstPitch, /* of chroma */ 665fa225cbcSrjs int srcH, 666fa225cbcSrjs int top, 667fa225cbcSrjs int left, 668fa225cbcSrjs int h, 669fa225cbcSrjs int w, 670fa225cbcSrjs int id 671fa225cbcSrjs ) 672fa225cbcSrjs{ 673fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 674fa225cbcSrjs I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; 675fa225cbcSrjs int i; 676fa225cbcSrjs unsigned char *src1, *src2, *src3, *dst1, *dst2, *dst3; 677fa225cbcSrjs 678fa225cbcSrjs /* Copy Y data */ 679fa225cbcSrjs src1 = buf + (top*srcPitch) + left; 680fa225cbcSrjs if (pPriv->currentBuf == 0) 681fa225cbcSrjs dst1 = pI810->FbBase + pPriv->YBuf0offset; 682fa225cbcSrjs else 683fa225cbcSrjs dst1 = pI810->FbBase + pPriv->YBuf1offset; 684fa225cbcSrjs 685fa225cbcSrjs for (i = 0; i < h; i++) { 686fa225cbcSrjs memcpy(dst1, src1, w); 687fa225cbcSrjs src1 += srcPitch; 688fa225cbcSrjs dst1 += dstPitch << 1; 689fa225cbcSrjs } 690fa225cbcSrjs 691fa225cbcSrjs /* Copy V data for YV12, or U data for I420 */ 692fa225cbcSrjs src2 = buf + (srcH*srcPitch) + ((top*srcPitch)>>2) + (left>>1); 693fa225cbcSrjs if (pPriv->currentBuf == 0) { 694fa225cbcSrjs if (id == FOURCC_I420) 695fa225cbcSrjs dst2 = pI810->FbBase + pPriv->UBuf0offset; 696fa225cbcSrjs else 697fa225cbcSrjs dst2 = pI810->FbBase + pPriv->VBuf0offset; 698fa225cbcSrjs } else { 699fa225cbcSrjs if (id == FOURCC_I420) 700fa225cbcSrjs dst2 = pI810->FbBase + pPriv->UBuf1offset; 701fa225cbcSrjs else 702fa225cbcSrjs dst2 = pI810->FbBase + pPriv->VBuf1offset; 703fa225cbcSrjs } 704fa225cbcSrjs 705fa225cbcSrjs for (i = 0; i < h/2; i++) { 706fa225cbcSrjs memcpy(dst2, src2, w/2); 707fa225cbcSrjs src2 += srcPitch>>1; 708fa225cbcSrjs dst2 += dstPitch; 709fa225cbcSrjs } 710fa225cbcSrjs 711fa225cbcSrjs /* Copy U data for YV12, or V data for I420 */ 712fa225cbcSrjs src3 = buf + (srcH*srcPitch) + ((srcH*srcPitch)>>2) + ((top*srcPitch)>>2) + (left>>1); 713fa225cbcSrjs if (pPriv->currentBuf == 0) { 714fa225cbcSrjs if (id == FOURCC_I420) 715fa225cbcSrjs dst3 = pI810->FbBase + pPriv->VBuf0offset; 716fa225cbcSrjs else 717fa225cbcSrjs dst3 = pI810->FbBase + pPriv->UBuf0offset; 718fa225cbcSrjs } else { 719fa225cbcSrjs if (id == FOURCC_I420) 720fa225cbcSrjs dst3 = pI810->FbBase + pPriv->VBuf1offset; 721fa225cbcSrjs else 722fa225cbcSrjs dst3 = pI810->FbBase + pPriv->UBuf1offset; 723fa225cbcSrjs } 724fa225cbcSrjs 725fa225cbcSrjs for (i = 0; i < h/2; i++) { 726fa225cbcSrjs memcpy(dst3, src3, w/2); 727fa225cbcSrjs src3 += srcPitch>>1; 728fa225cbcSrjs dst3 += dstPitch; 729fa225cbcSrjs } 730fa225cbcSrjs} 731fa225cbcSrjs 732fa225cbcSrjsstatic void 733fa225cbcSrjsI810DisplayVideo( 734fa225cbcSrjs ScrnInfoPtr pScrn, 735fa225cbcSrjs int id, 736fa225cbcSrjs short width, short height, 737fa225cbcSrjs int dstPitch, /* of chroma for 4:2:0 */ 738fa225cbcSrjs int x1, int y1, int x2, int y2, 739fa225cbcSrjs BoxPtr dstBox, 740fa225cbcSrjs short src_w, short src_h, 741fa225cbcSrjs short drw_w, short drw_h 742fa225cbcSrjs){ 743fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 744fa225cbcSrjs I810PortPrivPtr pPriv = pI810->adaptor->pPortPrivates[0].ptr; 745fa225cbcSrjs I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); 746fa225cbcSrjs int xscaleInt, xscaleFract, yscaleInt, yscaleFract; 747fa225cbcSrjs int xscaleIntUV = 0, xscaleFractUV = 0, yscaleIntUV = 0, yscaleFractUV = 0; 748fa225cbcSrjs unsigned int swidth; 749fa225cbcSrjs 750fa225cbcSrjs switch(id) { 751fa225cbcSrjs case FOURCC_YV12: 752fa225cbcSrjs case FOURCC_I420: 753fa225cbcSrjs swidth = (width + 7) & ~7; 754fa225cbcSrjs overlay->SWID = (swidth << 15) | swidth; 755fa225cbcSrjs overlay->SWIDQW = (swidth << 12) | (swidth >> 3); 756fa225cbcSrjs break; 757fa225cbcSrjs case FOURCC_UYVY: 758fa225cbcSrjs case FOURCC_YUY2: 759fa225cbcSrjs default: 760fa225cbcSrjs swidth = ((width + 3) & ~3) << 1; 761fa225cbcSrjs overlay->SWID = swidth; 762fa225cbcSrjs overlay->SWIDQW = swidth >> 3; 763fa225cbcSrjs break; 764fa225cbcSrjs } 765fa225cbcSrjs 766fa225cbcSrjs /* wide video formats (>720 pixels) are special */ 767fa225cbcSrjs if( swidth > IMAGE_FAST_WIDTH ) { 768fa225cbcSrjs overlay->OV0CONF = 1; /* one 1440 pixel line buffer */ 769fa225cbcSrjs } else { 770fa225cbcSrjs overlay->OV0CONF = 0; /* two 720 pixel line buffers */ 771fa225cbcSrjs } 772fa225cbcSrjs 773fa225cbcSrjs overlay->SHEIGHT = height | (height << 15); 774fa225cbcSrjs overlay->DWINPOS = (dstBox->y1 << 16) | (dstBox->x1); 775fa225cbcSrjs overlay->DWINSZ = ((dstBox->y2 - dstBox->y1) << 16) | 776fa225cbcSrjs (dstBox->x2 - dstBox->x1); 777fa225cbcSrjs 778fa225cbcSrjs /* buffer locations */ 779fa225cbcSrjs overlay->OBUF_0Y = pPriv->YBuf0offset; 780fa225cbcSrjs overlay->OBUF_1Y = pPriv->YBuf1offset; 781fa225cbcSrjs overlay->OBUF_0U = pPriv->UBuf0offset; 782fa225cbcSrjs overlay->OBUF_0V = pPriv->VBuf0offset; 783fa225cbcSrjs overlay->OBUF_1U = pPriv->UBuf1offset; 784fa225cbcSrjs overlay->OBUF_1V = pPriv->VBuf1offset; 785fa225cbcSrjs 786fa225cbcSrjs /* 787fa225cbcSrjs * Calculate horizontal and vertical scaling factors, default to 1:1 788fa225cbcSrjs */ 789fa225cbcSrjs overlay->YRGBSCALE = 0x80004000; 790fa225cbcSrjs overlay->UVSCALE = 0x80004000; 791fa225cbcSrjs 792fa225cbcSrjs /* 793fa225cbcSrjs * Initially, YCbCr and Overlay Enable and 794fa225cbcSrjs * vertical chrominance up interpolation and horozontal chrominance 795fa225cbcSrjs * up interpolation 796fa225cbcSrjs */ 797fa225cbcSrjs overlay->OV0CMD = VC_UP_INTERPOLATION | HC_UP_INTERPOLATION | Y_ADJUST | 798fa225cbcSrjs OVERLAY_ENABLE; 799fa225cbcSrjs 800fa225cbcSrjs if ((drw_w != src_w) || (drw_h != src_h)) 801fa225cbcSrjs { 802fa225cbcSrjs xscaleInt = (src_w / drw_w) & 0x3; 803fa225cbcSrjs xscaleFract = (src_w << 12) / drw_w; 804fa225cbcSrjs yscaleInt = (src_h / drw_h) & 0x3; 805fa225cbcSrjs yscaleFract = (src_h << 12) / drw_h; 806fa225cbcSrjs 807fa225cbcSrjs overlay->YRGBSCALE = (xscaleInt << 15) | 808fa225cbcSrjs ((xscaleFract & 0xFFF) << 3) | 809fa225cbcSrjs (yscaleInt) | 810fa225cbcSrjs ((yscaleFract & 0xFFF) << 20); 811fa225cbcSrjs 812fa225cbcSrjs if (drw_w > src_w) 813fa225cbcSrjs { 814fa225cbcSrjs /* horizontal up-scaling */ 815fa225cbcSrjs overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER; 816fa225cbcSrjs overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER; 817fa225cbcSrjs overlay->OV0CMD |= (HC_UP_INTERPOLATION | HL_UP_INTERPOLATION); 818fa225cbcSrjs } 819fa225cbcSrjs 820fa225cbcSrjs if (drw_h > src_h) 821fa225cbcSrjs { 822fa225cbcSrjs /* vertical up-scaling */ 823fa225cbcSrjs overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER; 824fa225cbcSrjs overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER; 825fa225cbcSrjs overlay->OV0CMD |= (VC_UP_INTERPOLATION | VL_UP_INTERPOLATION); 826fa225cbcSrjs } 827fa225cbcSrjs 828fa225cbcSrjs if (drw_w < src_w) 829fa225cbcSrjs { 830fa225cbcSrjs /* horizontal down-scaling */ 831fa225cbcSrjs overlay->OV0CMD &= ~HORIZONTAL_CHROMINANCE_FILTER; 832fa225cbcSrjs overlay->OV0CMD &= ~HORIZONTAL_LUMINANCE_FILTER; 833fa225cbcSrjs overlay->OV0CMD |= (HC_DOWN_INTERPOLATION | HL_DOWN_INTERPOLATION); 834fa225cbcSrjs } 835fa225cbcSrjs 836fa225cbcSrjs if (drw_h < src_h) 837fa225cbcSrjs { 838fa225cbcSrjs /* vertical down-scaling */ 839fa225cbcSrjs overlay->OV0CMD &= ~VERTICAL_CHROMINANCE_FILTER; 840fa225cbcSrjs overlay->OV0CMD &= ~VERTICAL_LUMINANCE_FILTER; 841fa225cbcSrjs overlay->OV0CMD |= (VC_DOWN_INTERPOLATION | VL_DOWN_INTERPOLATION); 842fa225cbcSrjs } 843fa225cbcSrjs 844fa225cbcSrjs /* now calculate the UV scaling factor */ 845fa225cbcSrjs 846fa225cbcSrjs if (xscaleFract) 847fa225cbcSrjs { 848fa225cbcSrjs xscaleFractUV = xscaleFract >> MINUV_SCALE; 849fa225cbcSrjs overlay->OV0CMD &= ~HC_DOWN_INTERPOLATION; 850fa225cbcSrjs overlay->OV0CMD |= HC_UP_INTERPOLATION; 851fa225cbcSrjs } 852fa225cbcSrjs 853fa225cbcSrjs if (xscaleInt) 854fa225cbcSrjs { 855fa225cbcSrjs xscaleIntUV = xscaleInt >> MINUV_SCALE; 856fa225cbcSrjs if (xscaleIntUV) 857fa225cbcSrjs { 858fa225cbcSrjs overlay->OV0CMD &= ~HC_UP_INTERPOLATION; 859fa225cbcSrjs } 860fa225cbcSrjs } 861fa225cbcSrjs 862fa225cbcSrjs if (yscaleFract) 863fa225cbcSrjs { 864fa225cbcSrjs yscaleFractUV = yscaleFract >> MINUV_SCALE; 865fa225cbcSrjs overlay->OV0CMD &= ~VC_DOWN_INTERPOLATION; 866fa225cbcSrjs overlay->OV0CMD |= VC_UP_INTERPOLATION; 867fa225cbcSrjs } 868fa225cbcSrjs 869fa225cbcSrjs if (yscaleInt) 870fa225cbcSrjs { 871fa225cbcSrjs yscaleIntUV = yscaleInt >> MINUV_SCALE; 872fa225cbcSrjs if (yscaleIntUV) 873fa225cbcSrjs { 874fa225cbcSrjs overlay->OV0CMD &= ~VC_UP_INTERPOLATION; 875fa225cbcSrjs overlay->OV0CMD |= VC_DOWN_INTERPOLATION; 876fa225cbcSrjs } 877fa225cbcSrjs } 878fa225cbcSrjs 879fa225cbcSrjs overlay->UVSCALE = yscaleIntUV | ((xscaleFractUV & 0xFFF) << 3) | 880fa225cbcSrjs ((yscaleFractUV & 0xFFF) << 20); 881fa225cbcSrjs } 882fa225cbcSrjs 883fa225cbcSrjs switch(id) { 884fa225cbcSrjs case FOURCC_YV12: 885fa225cbcSrjs case FOURCC_I420: 886fa225cbcSrjs /* set UV vertical phase to -0.25 */ 887fa225cbcSrjs overlay->UV_VPH = 0x30003000; 888fa225cbcSrjs overlay->INIT_PH = UV_VERT_BUF0 | UV_VERT_BUF1; 889fa225cbcSrjs overlay->OV0STRIDE = (dstPitch << 1) | (dstPitch << 16); 890fa225cbcSrjs overlay->OV0CMD &= ~SOURCE_FORMAT; 891fa225cbcSrjs overlay->OV0CMD |= YUV_420; 892fa225cbcSrjs break; 893fa225cbcSrjs case I810_RV15: 894fa225cbcSrjs case I810_RV16: 895fa225cbcSrjs overlay->UV_VPH = 0; 896fa225cbcSrjs overlay->INIT_PH = 0; 897fa225cbcSrjs overlay->OV0STRIDE = dstPitch; 898fa225cbcSrjs overlay->OV0CMD &= ~SOURCE_FORMAT; 899fa225cbcSrjs overlay->OV0CMD |= (id==I810_RV15 ? RGB_555 : RGB_565); 900fa225cbcSrjs overlay->OV0CMD &= ~OV_BYTE_ORDER; 901fa225cbcSrjs break; 902fa225cbcSrjs case FOURCC_UYVY: 903fa225cbcSrjs case FOURCC_YUY2: 904fa225cbcSrjs default: 905fa225cbcSrjs overlay->UV_VPH = 0; 906fa225cbcSrjs overlay->INIT_PH = 0; 907fa225cbcSrjs overlay->OV0STRIDE = dstPitch; 908fa225cbcSrjs overlay->OV0CMD &= ~SOURCE_FORMAT; 909fa225cbcSrjs overlay->OV0CMD |= YUV_422; 910fa225cbcSrjs overlay->OV0CMD &= ~OV_BYTE_ORDER; 911fa225cbcSrjs if (id == FOURCC_UYVY) 912fa225cbcSrjs overlay->OV0CMD |= Y_SWAP; 913fa225cbcSrjs break; 914fa225cbcSrjs } 915fa225cbcSrjs 916fa225cbcSrjs overlay->OV0CMD &= ~BUFFER_AND_FIELD; 917fa225cbcSrjs if (pPriv->currentBuf == 0) 918fa225cbcSrjs overlay->OV0CMD |= BUFFER0_FIELD0; 919fa225cbcSrjs else 920fa225cbcSrjs overlay->OV0CMD |= BUFFER1_FIELD0; 921fa225cbcSrjs 922fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 923fa225cbcSrjs 924fa225cbcSrjs} 925fa225cbcSrjs 926fa225cbcSrjsstatic FBLinearPtr 927fa225cbcSrjsI810AllocateMemory( 928fa225cbcSrjs ScrnInfoPtr pScrn, 929fa225cbcSrjs FBLinearPtr linear, 930fa225cbcSrjs int size 931fa225cbcSrjs){ 932fa225cbcSrjs ScreenPtr pScreen; 933fa225cbcSrjs FBLinearPtr new_linear; 934fa225cbcSrjs 935fa225cbcSrjs if(linear) { 936fa225cbcSrjs if(linear->size >= size) 937fa225cbcSrjs return linear; 938fa225cbcSrjs 939fa225cbcSrjs if(xf86ResizeOffscreenLinear(linear, size)) 940fa225cbcSrjs return linear; 941fa225cbcSrjs 942fa225cbcSrjs xf86FreeOffscreenLinear(linear); 943fa225cbcSrjs } 944fa225cbcSrjs 945fa225cbcSrjs pScreen = screenInfo.screens[pScrn->scrnIndex]; 946fa225cbcSrjs 947fa225cbcSrjs new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, 948fa225cbcSrjs NULL, NULL, NULL); 949fa225cbcSrjs 950fa225cbcSrjs if(!new_linear) { 951fa225cbcSrjs int max_size; 952fa225cbcSrjs 953fa225cbcSrjs xf86QueryLargestOffscreenLinear(pScreen, &max_size, 4, 954fa225cbcSrjs PRIORITY_EXTREME); 955fa225cbcSrjs 956fa225cbcSrjs if(max_size < size) return NULL; 957fa225cbcSrjs 958fa225cbcSrjs xf86PurgeUnlockedOffscreenAreas(pScreen); 959fa225cbcSrjs new_linear = xf86AllocateOffscreenLinear(pScreen, size, 4, 960fa225cbcSrjs NULL, NULL, NULL); 961fa225cbcSrjs } 962fa225cbcSrjs 963fa225cbcSrjs return new_linear; 964fa225cbcSrjs} 965fa225cbcSrjs 966fa225cbcSrjsstatic int 967fa225cbcSrjsI810PutImage( 968fa225cbcSrjs ScrnInfoPtr pScrn, 969fa225cbcSrjs short src_x, short src_y, 970fa225cbcSrjs short drw_x, short drw_y, 971fa225cbcSrjs short src_w, short src_h, 972fa225cbcSrjs short drw_w, short drw_h, 973fa225cbcSrjs int id, unsigned char* buf, 974fa225cbcSrjs short width, short height, 975fa225cbcSrjs Bool sync, 976fa225cbcSrjs RegionPtr clipBoxes, pointer data, 977fa225cbcSrjs DrawablePtr pDraw 978fa225cbcSrjs){ 979fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 980fa225cbcSrjs I810PortPrivPtr pPriv = (I810PortPrivPtr)data; 981fa225cbcSrjs INT32 x1, x2, y1, y2; 982fa225cbcSrjs int srcPitch, dstPitch; 983fa225cbcSrjs int top, left, npixels, nlines, size, loops; 984fa225cbcSrjs BoxRec dstBox; 985fa225cbcSrjs 986fa225cbcSrjs 987fa225cbcSrjs /* Clip */ 988fa225cbcSrjs x1 = src_x; 989fa225cbcSrjs x2 = src_x + src_w; 990fa225cbcSrjs y1 = src_y; 991fa225cbcSrjs y2 = src_y + src_h; 992fa225cbcSrjs 993fa225cbcSrjs dstBox.x1 = drw_x; 994fa225cbcSrjs dstBox.x2 = drw_x + drw_w; 995fa225cbcSrjs dstBox.y1 = drw_y; 996fa225cbcSrjs dstBox.y2 = drw_y + drw_h; 997fa225cbcSrjs 998fa225cbcSrjs I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 999fa225cbcSrjs REGION_EXTENTS(pScrn->pScreen, clipBoxes), width, height); 1000fa225cbcSrjs 1001fa225cbcSrjs if((x1 >= x2) || (y1 >= y2)) 1002fa225cbcSrjs return Success; 1003fa225cbcSrjs /* 1004fa225cbcSrjs * Fix for 4 pixel granularity of AdjustFrame 1005fa225cbcSrjs * unless boarder is clipped by frame 1006fa225cbcSrjs */ 1007fa225cbcSrjs dstBox.x1 -= (pScrn->frameX0 & 1008fa225cbcSrjs ((dstBox.x1 == pScrn->frameX0) ? ~0x0UL : ~0x3UL)); 1009fa225cbcSrjs dstBox.x2 -= (pScrn->frameX0 & ~0x3); 1010fa225cbcSrjs dstBox.y1 -= pScrn->frameY0; 1011fa225cbcSrjs dstBox.y2 -= pScrn->frameY0; 1012fa225cbcSrjs 1013fa225cbcSrjs switch(id) { 1014fa225cbcSrjs case FOURCC_YV12: 1015fa225cbcSrjs case FOURCC_I420: 1016fa225cbcSrjs srcPitch = (width + 3) & ~3; 1017fa225cbcSrjs dstPitch = ((width >> 1) + 7) & ~7; /* of chroma */ 1018fa225cbcSrjs size = dstPitch * height * 3; 1019fa225cbcSrjs break; 1020fa225cbcSrjs case FOURCC_UYVY: 1021fa225cbcSrjs case FOURCC_YUY2: 1022fa225cbcSrjs default: 1023fa225cbcSrjs srcPitch = (width << 1); 1024fa225cbcSrjs dstPitch = (srcPitch + 7) & ~7; 1025fa225cbcSrjs size = dstPitch * height; 1026fa225cbcSrjs break; 1027fa225cbcSrjs } 1028fa225cbcSrjs 1029fa225cbcSrjs if(!(pPriv->linear = I810AllocateMemory(pScrn, pPriv->linear, 1030fa225cbcSrjs (pScrn->bitsPerPixel == 16) ? size : (size >> 1)))) 1031fa225cbcSrjs return BadAlloc; 1032fa225cbcSrjs 1033fa225cbcSrjs /* fixup pointers */ 1034fa225cbcSrjs pPriv->YBuf0offset = pPriv->linear->offset * pI810->cpp; 1035fa225cbcSrjs pPriv->UBuf0offset = pPriv->YBuf0offset + (dstPitch * 2 * height); 1036fa225cbcSrjs pPriv->VBuf0offset = pPriv->UBuf0offset + (dstPitch * height >> 1); 1037fa225cbcSrjs 1038fa225cbcSrjs pPriv->YBuf1offset = (pPriv->linear->offset * pI810->cpp) + size; 1039fa225cbcSrjs pPriv->UBuf1offset = pPriv->YBuf1offset + (dstPitch * 2 * height); 1040fa225cbcSrjs pPriv->VBuf1offset = pPriv->UBuf1offset + (dstPitch * height >> 1); 1041fa225cbcSrjs 1042fa225cbcSrjs 1043fa225cbcSrjs /* Make sure this buffer isn't in use */ 1044fa225cbcSrjs loops = 0; 1045fa225cbcSrjs while (loops < 1000000) { 1046fa225cbcSrjs if(((INREG(DOV0STA)&0x00100000)>>20) == pPriv->currentBuf) { 1047fa225cbcSrjs break; 1048fa225cbcSrjs } 1049fa225cbcSrjs loops++; 1050fa225cbcSrjs } 1051fa225cbcSrjs if(loops >= 1000000) { 1052fa225cbcSrjs pPriv->currentBuf = !pPriv->currentBuf; 1053fa225cbcSrjs } 1054fa225cbcSrjs 1055fa225cbcSrjs 1056fa225cbcSrjs /* buffer swap */ 1057fa225cbcSrjs if (pPriv->currentBuf == 0) 1058fa225cbcSrjs pPriv->currentBuf = 1; 1059fa225cbcSrjs else 1060fa225cbcSrjs pPriv->currentBuf = 0; 1061fa225cbcSrjs 1062fa225cbcSrjs /* copy data */ 1063fa225cbcSrjs top = y1 >> 16; 1064fa225cbcSrjs left = (x1 >> 16) & ~1; 1065fa225cbcSrjs npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 1066fa225cbcSrjs 1067fa225cbcSrjs switch(id) { 1068fa225cbcSrjs case FOURCC_YV12: 1069fa225cbcSrjs case FOURCC_I420: 1070fa225cbcSrjs top &= ~1; 1071fa225cbcSrjs nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 1072fa225cbcSrjs I810CopyPlanarData(pScrn, buf, srcPitch, dstPitch, height, top, left, 1073fa225cbcSrjs nlines, npixels, id); 1074fa225cbcSrjs break; 1075fa225cbcSrjs case FOURCC_UYVY: 1076fa225cbcSrjs case FOURCC_YUY2: 1077fa225cbcSrjs default: 1078fa225cbcSrjs nlines = ((y2 + 0xffff) >> 16) - top; 1079fa225cbcSrjs I810CopyPackedData(pScrn, buf, srcPitch, dstPitch, top, left, nlines, 1080fa225cbcSrjs npixels); 1081fa225cbcSrjs break; 1082fa225cbcSrjs } 1083fa225cbcSrjs 1084fa225cbcSrjs /* update cliplist */ 1085fa225cbcSrjs if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 1086fa225cbcSrjs REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 1087fa225cbcSrjs /* draw these */ 1088fa225cbcSrjs xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 1089fa225cbcSrjs } 1090fa225cbcSrjs 1091fa225cbcSrjs I810DisplayVideo(pScrn, id, width, height, dstPitch, 1092fa225cbcSrjs x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1093fa225cbcSrjs 1094fa225cbcSrjs pPriv->videoStatus = CLIENT_VIDEO_ON; 1095fa225cbcSrjs 1096fa225cbcSrjs return Success; 1097fa225cbcSrjs} 1098fa225cbcSrjs 1099fa225cbcSrjs 1100fa225cbcSrjsstatic int 1101fa225cbcSrjsI810QueryImageAttributes( 1102fa225cbcSrjs ScrnInfoPtr pScrn, 1103fa225cbcSrjs int id, 1104fa225cbcSrjs unsigned short *w, unsigned short *h, 1105fa225cbcSrjs int *pitches, int *offsets 1106fa225cbcSrjs){ 1107fa225cbcSrjs int size, tmp; 1108fa225cbcSrjs 1109fa225cbcSrjs if(*w > IMAGE_MAX_WIDTH) *w = IMAGE_MAX_WIDTH; 1110fa225cbcSrjs if(*h > IMAGE_MAX_HEIGHT) *h = IMAGE_MAX_HEIGHT; 1111fa225cbcSrjs 1112fa225cbcSrjs *w = (*w + 1) & ~1; 1113fa225cbcSrjs if(offsets) offsets[0] = 0; 1114fa225cbcSrjs 1115fa225cbcSrjs switch(id) { 1116fa225cbcSrjs /* IA44 is for XvMC only */ 1117fa225cbcSrjs case FOURCC_IA44: 1118fa225cbcSrjs case FOURCC_AI44: 1119fa225cbcSrjs if(pitches) pitches[0] = *w; 1120fa225cbcSrjs size = *w * *h; 1121fa225cbcSrjs break; 1122fa225cbcSrjs case FOURCC_YV12: 1123fa225cbcSrjs case FOURCC_I420: 1124fa225cbcSrjs *h = (*h + 1) & ~1; 1125fa225cbcSrjs size = (*w + 3) & ~3; 1126fa225cbcSrjs if(pitches) pitches[0] = size; 1127fa225cbcSrjs size *= *h; 1128fa225cbcSrjs if(offsets) offsets[1] = size; 1129fa225cbcSrjs tmp = ((*w >> 1) + 3) & ~3; 1130fa225cbcSrjs if(pitches) pitches[1] = pitches[2] = tmp; 1131fa225cbcSrjs tmp *= (*h >> 1); 1132fa225cbcSrjs size += tmp; 1133fa225cbcSrjs if(offsets) offsets[2] = size; 1134fa225cbcSrjs size += tmp; 1135fa225cbcSrjs break; 1136fa225cbcSrjs case FOURCC_UYVY: 1137fa225cbcSrjs case FOURCC_YUY2: 1138fa225cbcSrjs default: 1139fa225cbcSrjs size = *w << 1; 1140fa225cbcSrjs if(pitches) pitches[0] = size; 1141fa225cbcSrjs size *= *h; 1142fa225cbcSrjs break; 1143fa225cbcSrjs } 1144fa225cbcSrjs 1145fa225cbcSrjs return size; 1146fa225cbcSrjs} 1147fa225cbcSrjs 1148fa225cbcSrjsstatic void 1149fa225cbcSrjsI810BlockHandler ( 1150fa225cbcSrjs int i, 1151fa225cbcSrjs pointer blockData, 1152fa225cbcSrjs pointer pTimeout, 1153fa225cbcSrjs pointer pReadmask 1154fa225cbcSrjs){ 1155fa225cbcSrjs ScreenPtr pScreen = screenInfo.screens[i]; 1156fa225cbcSrjs ScrnInfoPtr pScrn = xf86Screens[i]; 1157fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 1158fa225cbcSrjs I810PortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); 1159fa225cbcSrjs I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); 1160fa225cbcSrjs 1161fa225cbcSrjs pScreen->BlockHandler = pI810->BlockHandler; 1162fa225cbcSrjs 1163fa225cbcSrjs (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 1164fa225cbcSrjs 1165fa225cbcSrjs pScreen->BlockHandler = I810BlockHandler; 1166fa225cbcSrjs 1167fa225cbcSrjs if(pPriv->videoStatus & TIMER_MASK) { 1168fa225cbcSrjs UpdateCurrentTime(); 1169fa225cbcSrjs if(pPriv->videoStatus & OFF_TIMER) { 1170fa225cbcSrjs if(pPriv->offTime < currentTime.milliseconds) { 1171fa225cbcSrjs /* Turn off the overlay */ 1172fa225cbcSrjs overlay->OV0CMD &= 0xFFFFFFFE; 1173fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 1174fa225cbcSrjs 1175fa225cbcSrjs pPriv->videoStatus = FREE_TIMER; 1176fa225cbcSrjs pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1177fa225cbcSrjs } 1178fa225cbcSrjs } else { /* FREE_TIMER */ 1179fa225cbcSrjs if(pPriv->freeTime < currentTime.milliseconds) { 1180fa225cbcSrjs if(pPriv->linear) { 1181fa225cbcSrjs xf86FreeOffscreenLinear(pPriv->linear); 1182fa225cbcSrjs pPriv->linear = NULL; 1183fa225cbcSrjs } 1184fa225cbcSrjs pPriv->videoStatus = 0; 1185fa225cbcSrjs } 1186fa225cbcSrjs } 1187fa225cbcSrjs } 1188fa225cbcSrjs} 1189fa225cbcSrjs 1190fa225cbcSrjs 1191fa225cbcSrjs/*************************************************************************** 1192fa225cbcSrjs * Offscreen Images 1193fa225cbcSrjs ***************************************************************************/ 1194fa225cbcSrjs 1195fa225cbcSrjstypedef struct { 1196fa225cbcSrjs FBLinearPtr linear; 1197fa225cbcSrjs Bool isOn; 1198fa225cbcSrjs} OffscreenPrivRec, * OffscreenPrivPtr; 1199fa225cbcSrjs 1200fa225cbcSrjsstatic int 1201fa225cbcSrjsI810AllocateSurface( 1202fa225cbcSrjs ScrnInfoPtr pScrn, 1203fa225cbcSrjs int id, 1204fa225cbcSrjs unsigned short w, 1205fa225cbcSrjs unsigned short h, 1206fa225cbcSrjs XF86SurfacePtr surface 1207fa225cbcSrjs){ 1208fa225cbcSrjs FBLinearPtr linear; 1209fa225cbcSrjs int pitch, fbpitch, size, bpp; 1210fa225cbcSrjs OffscreenPrivPtr pPriv; 1211fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 1212fa225cbcSrjs 1213fa225cbcSrjs if((w > 1024) || (h > 1024)) 1214fa225cbcSrjs return BadAlloc; 1215fa225cbcSrjs 1216fa225cbcSrjs w = (w + 1) & ~1; 1217fa225cbcSrjs pitch = ((w << 1) + 15) & ~15; 1218fa225cbcSrjs bpp = pScrn->bitsPerPixel >> 3; 1219fa225cbcSrjs fbpitch = bpp * pScrn->displayWidth; 1220fa225cbcSrjs size = ((pitch * h) + bpp - 1) / bpp; 1221fa225cbcSrjs 1222fa225cbcSrjs if(!(linear = I810AllocateMemory(pScrn, NULL, size))) 1223fa225cbcSrjs return BadAlloc; 1224fa225cbcSrjs 1225fa225cbcSrjs surface->width = w; 1226fa225cbcSrjs surface->height = h; 1227fa225cbcSrjs 1228fa225cbcSrjs if(!(surface->pitches = xalloc(sizeof(int)))) { 1229fa225cbcSrjs xf86FreeOffscreenLinear(linear); 1230fa225cbcSrjs return BadAlloc; 1231fa225cbcSrjs } 1232fa225cbcSrjs if(!(surface->offsets = xalloc(sizeof(int)))) { 1233fa225cbcSrjs xfree(surface->pitches); 1234fa225cbcSrjs xf86FreeOffscreenLinear(linear); 1235fa225cbcSrjs return BadAlloc; 1236fa225cbcSrjs } 1237fa225cbcSrjs if(!(pPriv = xalloc(sizeof(OffscreenPrivRec)))) { 1238fa225cbcSrjs xfree(surface->pitches); 1239fa225cbcSrjs xfree(surface->offsets); 1240fa225cbcSrjs xf86FreeOffscreenLinear(linear); 1241fa225cbcSrjs return BadAlloc; 1242fa225cbcSrjs } 1243fa225cbcSrjs 1244fa225cbcSrjs pPriv->linear = linear; 1245fa225cbcSrjs pPriv->isOn = FALSE; 1246fa225cbcSrjs 1247fa225cbcSrjs surface->pScrn = pScrn; 1248fa225cbcSrjs surface->id = id; 1249fa225cbcSrjs surface->pitches[0] = pitch; 1250fa225cbcSrjs surface->offsets[0] = linear->offset * bpp; 1251fa225cbcSrjs surface->devPrivate.ptr = (pointer)pPriv; 1252fa225cbcSrjs 1253fa225cbcSrjs memset(pI810->FbBase + surface->offsets[0],0,size); 1254fa225cbcSrjs 1255fa225cbcSrjs return Success; 1256fa225cbcSrjs} 1257fa225cbcSrjs 1258fa225cbcSrjsstatic int 1259fa225cbcSrjsI810StopSurface( 1260fa225cbcSrjs XF86SurfacePtr surface 1261fa225cbcSrjs){ 1262fa225cbcSrjs OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 1263fa225cbcSrjs 1264fa225cbcSrjs if(pPriv->isOn) { 1265fa225cbcSrjs I810Ptr pI810 = I810PTR(surface->pScrn); 1266fa225cbcSrjs 1267fa225cbcSrjs I810OverlayRegPtr overlay = (I810OverlayRegPtr) (pI810->FbBase + pI810->OverlayStart); 1268fa225cbcSrjs 1269fa225cbcSrjs overlay->OV0CMD &= 0xFFFFFFFE; 1270fa225cbcSrjs OVERLAY_UPDATE(pI810->OverlayPhysical); 1271fa225cbcSrjs 1272fa225cbcSrjs pPriv->isOn = FALSE; 1273fa225cbcSrjs } 1274fa225cbcSrjs 1275fa225cbcSrjs return Success; 1276fa225cbcSrjs} 1277fa225cbcSrjs 1278fa225cbcSrjs 1279fa225cbcSrjsstatic int 1280fa225cbcSrjsI810FreeSurface( 1281fa225cbcSrjs XF86SurfacePtr surface 1282fa225cbcSrjs){ 1283fa225cbcSrjs OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 1284fa225cbcSrjs 1285fa225cbcSrjs if(pPriv->isOn) { 1286fa225cbcSrjs I810StopSurface(surface); 1287fa225cbcSrjs } 1288fa225cbcSrjs xf86FreeOffscreenLinear(pPriv->linear); 1289fa225cbcSrjs xfree(surface->pitches); 1290fa225cbcSrjs xfree(surface->offsets); 1291fa225cbcSrjs xfree(surface->devPrivate.ptr); 1292fa225cbcSrjs 1293fa225cbcSrjs return Success; 1294fa225cbcSrjs} 1295fa225cbcSrjs 1296fa225cbcSrjsstatic int 1297fa225cbcSrjsI810GetSurfaceAttribute( 1298fa225cbcSrjs ScrnInfoPtr pScrn, 1299fa225cbcSrjs Atom attribute, 1300fa225cbcSrjs INT32 *value 1301fa225cbcSrjs){ 1302fa225cbcSrjs return I810GetPortAttribute(pScrn, attribute, value, NULL); 1303fa225cbcSrjs} 1304fa225cbcSrjs 1305fa225cbcSrjsstatic int 1306fa225cbcSrjsI810SetSurfaceAttribute( 1307fa225cbcSrjs ScrnInfoPtr pScrn, 1308fa225cbcSrjs Atom attribute, 1309fa225cbcSrjs INT32 value 1310fa225cbcSrjs){ 1311fa225cbcSrjs return I810SetPortAttribute(pScrn, attribute, value, NULL); 1312fa225cbcSrjs} 1313fa225cbcSrjs 1314fa225cbcSrjs 1315fa225cbcSrjsstatic int 1316fa225cbcSrjsI810DisplaySurface( 1317fa225cbcSrjs XF86SurfacePtr surface, 1318fa225cbcSrjs short src_x, short src_y, 1319fa225cbcSrjs short drw_x, short drw_y, 1320fa225cbcSrjs short src_w, short src_h, 1321fa225cbcSrjs short drw_w, short drw_h, 1322fa225cbcSrjs RegionPtr clipBoxes 1323fa225cbcSrjs){ 1324fa225cbcSrjs OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 1325fa225cbcSrjs ScrnInfoPtr pScrn = surface->pScrn; 1326fa225cbcSrjs I810Ptr pI810 = I810PTR(pScrn); 1327fa225cbcSrjs I810PortPrivPtr pI810Priv = GET_PORT_PRIVATE(pScrn); 1328fa225cbcSrjs 1329fa225cbcSrjs INT32 x1, y1, x2, y2; 1330fa225cbcSrjs INT32 loops = 0; 1331fa225cbcSrjs BoxRec dstBox; 1332fa225cbcSrjs 1333fa225cbcSrjs x1 = src_x; 1334fa225cbcSrjs x2 = src_x + src_w; 1335fa225cbcSrjs y1 = src_y; 1336fa225cbcSrjs y2 = src_y + src_h; 1337fa225cbcSrjs 1338fa225cbcSrjs dstBox.x1 = drw_x; 1339fa225cbcSrjs dstBox.x2 = drw_x + drw_w; 1340fa225cbcSrjs dstBox.y1 = drw_y; 1341fa225cbcSrjs dstBox.y2 = drw_y + drw_h; 1342fa225cbcSrjs 1343fa225cbcSrjs I810ClipVideo(&dstBox, &x1, &x2, &y1, &y2, 1344fa225cbcSrjs REGION_EXTENTS(screenInfo.screens[0], clipBoxes), 1345fa225cbcSrjs surface->width, surface->height); 1346fa225cbcSrjs 1347fa225cbcSrjs /* 1348fa225cbcSrjs * Fix for 4 pixel granularity of AdjustFrame 1349fa225cbcSrjs * unless boarder is clipped by frame 1350fa225cbcSrjs */ 1351fa225cbcSrjs dstBox.x1 -= (pScrn->frameX0 & 1352fa225cbcSrjs ((dstBox.x1 == pScrn->frameX0) ? ~0x0UL : ~0x3UL)); 1353fa225cbcSrjs dstBox.x2 -= (pScrn->frameX0 & ~0x3); 1354fa225cbcSrjs dstBox.y1 -= pScrn->frameY0; 1355fa225cbcSrjs dstBox.y2 -= pScrn->frameY0; 1356fa225cbcSrjs 1357fa225cbcSrjs /* fixup pointers */ 1358fa225cbcSrjs pI810Priv->YBuf0offset = surface->offsets[0]; 1359fa225cbcSrjs pI810Priv->YBuf1offset = pI810Priv->YBuf0offset; 1360fa225cbcSrjs 1361fa225cbcSrjs /* wait for the last rendered buffer to be flipped in */ 1362fa225cbcSrjs while (((INREG(DOV0STA)&0x00100000)>>20) != pI810Priv->currentBuf) { 1363fa225cbcSrjs if(loops == 200000) { 1364fa225cbcSrjs xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overlay Lockup\n"); 1365fa225cbcSrjs break; 1366fa225cbcSrjs } 1367fa225cbcSrjs loops++; 1368fa225cbcSrjs } 1369fa225cbcSrjs 1370fa225cbcSrjs /* buffer swap */ 1371fa225cbcSrjs if (pI810Priv->currentBuf == 0) 1372fa225cbcSrjs pI810Priv->currentBuf = 1; 1373fa225cbcSrjs else 1374fa225cbcSrjs pI810Priv->currentBuf = 0; 1375fa225cbcSrjs 1376fa225cbcSrjs I810ResetVideo(pScrn); 1377fa225cbcSrjs 1378fa225cbcSrjs I810DisplayVideo(pScrn, surface->id, surface->width, surface->height, 1379fa225cbcSrjs surface->pitches[0], x1, y1, x2, y2, &dstBox, 1380fa225cbcSrjs src_w, src_h, drw_w, drw_h); 1381fa225cbcSrjs 1382fa225cbcSrjs xf86XVFillKeyHelper(pScrn->pScreen, pI810Priv->colorKey, clipBoxes); 1383fa225cbcSrjs 1384fa225cbcSrjs pPriv->isOn = TRUE; 1385fa225cbcSrjs /* we've prempted the XvImage stream so set its free timer */ 1386fa225cbcSrjs if(pI810Priv->videoStatus & CLIENT_VIDEO_ON) { 1387fa225cbcSrjs REGION_EMPTY(pScrn->pScreen, & pI810Priv->clip); 1388fa225cbcSrjs UpdateCurrentTime(); 1389fa225cbcSrjs pI810Priv->videoStatus = FREE_TIMER; 1390fa225cbcSrjs pI810Priv->freeTime = currentTime.milliseconds + FREE_DELAY; 1391fa225cbcSrjs pScrn->pScreen->BlockHandler = I810BlockHandler; 1392fa225cbcSrjs } 1393fa225cbcSrjs 1394fa225cbcSrjs return Success; 1395fa225cbcSrjs} 1396fa225cbcSrjs 1397fa225cbcSrjs 1398fa225cbcSrjsstatic void 1399fa225cbcSrjsI810InitOffscreenImages(ScreenPtr pScreen) 1400fa225cbcSrjs{ 1401fa225cbcSrjs XF86OffscreenImagePtr offscreenImages; 1402fa225cbcSrjs 1403fa225cbcSrjs /* need to free this someplace */ 1404fa225cbcSrjs if(!(offscreenImages = xalloc(sizeof(XF86OffscreenImageRec)))) { 1405fa225cbcSrjs return; 1406fa225cbcSrjs } 1407fa225cbcSrjs 1408fa225cbcSrjs offscreenImages[0].image = &Images[0]; 1409fa225cbcSrjs offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | 1410fa225cbcSrjs VIDEO_CLIP_TO_VIEWPORT; 1411fa225cbcSrjs offscreenImages[0].alloc_surface = I810AllocateSurface; 1412fa225cbcSrjs offscreenImages[0].free_surface = I810FreeSurface; 1413fa225cbcSrjs offscreenImages[0].display = I810DisplaySurface; 1414fa225cbcSrjs offscreenImages[0].stop = I810StopSurface; 1415fa225cbcSrjs offscreenImages[0].setAttribute = I810SetSurfaceAttribute; 1416fa225cbcSrjs offscreenImages[0].getAttribute = I810GetSurfaceAttribute; 1417fa225cbcSrjs offscreenImages[0].max_width = 1024; 1418fa225cbcSrjs offscreenImages[0].max_height = 1024; 1419fa225cbcSrjs offscreenImages[0].num_attributes = 1; 1420fa225cbcSrjs offscreenImages[0].attributes = Attributes; 1421fa225cbcSrjs 1422fa225cbcSrjs xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1423fa225cbcSrjs} 1424fa225cbcSrjs 1425