pm3_video.c revision 1fb744b4
1c35d236eSmrg/* 2c35d236eSmrg * Copyright 2001 by Alan Hourihane, Sychdyn, North Wales. 3c35d236eSmrg * 4c35d236eSmrg * Permission to use, copy, modify, distribute, and sell this software and its 5c35d236eSmrg * documentation for any purpose is hereby granted without fee, provided that 6c35d236eSmrg * the above copyright notice appear in all copies and that both that 7c35d236eSmrg * copyright notice and this permission notice appear in supporting 8c35d236eSmrg * documentation, and that the name of Alan Hourihane not be used in 9c35d236eSmrg * advertising or publicity pertaining to distribution of the software without 10c35d236eSmrg * specific, written prior permission. Alan Hourihane makes no representations 11c35d236eSmrg * about the suitability of this software for any purpose. It is provided 12c35d236eSmrg * "as is" without express or implied warranty. 13c35d236eSmrg * 14c35d236eSmrg * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15c35d236eSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16c35d236eSmrg * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17c35d236eSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18c35d236eSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19c35d236eSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20c35d236eSmrg * PERFORMANCE OF THIS SOFTWARE. 21c35d236eSmrg * 22c35d236eSmrg * Authors: Alan Hourihane, alanh@fairlite.demon.co.uk 23c35d236eSmrg * Sven Luther <luther@dpt-info.u-strasbg.fr> 24c35d236eSmrg */ 25c35d236eSmrg 26c35d236eSmrg#ifdef HAVE_CONFIG_H 27c35d236eSmrg#include "config.h" 28c35d236eSmrg#endif 29c35d236eSmrg 30c35d236eSmrg#include "xf86.h" 31c35d236eSmrg#include "xf86_OSproc.h" 32c35d236eSmrg#include "compiler.h" 33c35d236eSmrg#include "xf86Pci.h" 34c35d236eSmrg#include "xf86fbman.h" 35c35d236eSmrg#include "regionstr.h" 36c35d236eSmrg 37c35d236eSmrg#include "glint.h" 38c35d236eSmrg#include "glint_regs.h" 39c35d236eSmrg#include "pm3_regs.h" 40c35d236eSmrg#include <X11/extensions/Xv.h> 41c35d236eSmrg#include "dixstruct.h" 42c35d236eSmrg#include "fourcc.h" 43c35d236eSmrg 44c35d236eSmrg#define OFF_DELAY 200 /* milliseconds */ 45c35d236eSmrg#define FREE_DELAY 60000 46c35d236eSmrg 47c35d236eSmrg#define OFF_TIMER 0x01 48c35d236eSmrg#define FREE_TIMER 0x02 49c35d236eSmrg#define CLIENT_VIDEO_ON 0x04 50c35d236eSmrg 51c35d236eSmrg#define TIMER_MASK (OFF_TIMER | FREE_TIMER) 52c35d236eSmrg 53c35d236eSmrgstatic XF86VideoAdaptorPtr Permedia3SetupImageVideo(ScreenPtr); 54c35d236eSmrgstatic void Permedia3InitOffscreenImages(ScreenPtr); 55c35d236eSmrgstatic void Permedia3StopVideo(ScrnInfoPtr, pointer, Bool); 56c35d236eSmrgstatic int Permedia3SetPortAttribute(ScrnInfoPtr, Atom, INT32, pointer); 57c35d236eSmrgstatic int Permedia3GetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 58c35d236eSmrgstatic void Permedia3QueryBestSize(ScrnInfoPtr, Bool, 59c35d236eSmrg short, short, short, short, unsigned int *, unsigned int *, pointer); 60c35d236eSmrgstatic int Permedia3PutImage( ScrnInfoPtr, 61c35d236eSmrg short, short, short, short, short, short, short, short, 62c35d236eSmrg int, unsigned char*, short, short, Bool, RegionPtr, pointer, 63c35d236eSmrg DrawablePtr); 64c35d236eSmrgstatic int Permedia3QueryImageAttributes(ScrnInfoPtr, 65c35d236eSmrg int, unsigned short *, unsigned short *, int *, int *); 66c35d236eSmrgstatic void Permedia3VideoTimerCallback(ScrnInfoPtr pScrn, Time time); 67c35d236eSmrg 68c35d236eSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 69c35d236eSmrg 70c35d236eSmrgstatic Atom xvColorKey, xvDoubleBuffer, xvAutopaintColorKey, xvFilter; 71c35d236eSmrg 72c35d236eSmrgvoid Permedia3InitVideo(ScreenPtr pScreen) 73c35d236eSmrg{ 741fb744b4Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 75c35d236eSmrg XF86VideoAdaptorPtr *adaptors, *newAdaptors = NULL; 76c35d236eSmrg XF86VideoAdaptorPtr newAdaptor = NULL; 77c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 78c35d236eSmrg int num_adaptors; 79c35d236eSmrg 80c35d236eSmrg /* Because of bugs in the PM3 when uploading images via the 81c35d236eSmrg * bypass to the framebuffer, we always have to use the accelerator. 82c35d236eSmrg */ 83c35d236eSmrg if (pGlint->NoAccel) 84c35d236eSmrg return; 85c35d236eSmrg 86c35d236eSmrg newAdaptor = Permedia3SetupImageVideo(pScreen); 87c35d236eSmrg Permedia3InitOffscreenImages(pScreen); 88c35d236eSmrg 89c35d236eSmrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 90c35d236eSmrg 91c35d236eSmrg if(newAdaptor) { 92c35d236eSmrg if(!num_adaptors) { 93c35d236eSmrg num_adaptors = 1; 94c35d236eSmrg adaptors = &newAdaptor; 95c35d236eSmrg } else { 96c35d236eSmrg newAdaptors = /* need to free this someplace */ 971fb744b4Smrg malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *)); 98c35d236eSmrg if(newAdaptors) { 99c35d236eSmrg memcpy(newAdaptors, adaptors, num_adaptors * 100c35d236eSmrg sizeof(XF86VideoAdaptorPtr)); 101c35d236eSmrg newAdaptors[num_adaptors] = newAdaptor; 102c35d236eSmrg adaptors = newAdaptors; 103c35d236eSmrg num_adaptors++; 104c35d236eSmrg } 105c35d236eSmrg } 106c35d236eSmrg } 107c35d236eSmrg 108c35d236eSmrg if(num_adaptors) 109c35d236eSmrg xf86XVScreenInit(pScreen, adaptors, num_adaptors); 110c35d236eSmrg 1111fb744b4Smrg free(newAdaptors); 112c35d236eSmrg} 113c35d236eSmrg 114c35d236eSmrg/* client libraries expect an encoding */ 115c35d236eSmrgstatic XF86VideoEncodingRec DummyEncoding[1] = 116c35d236eSmrg{ 117c35d236eSmrg { 118c35d236eSmrg 0, 119c35d236eSmrg "XV_IMAGE", 120c35d236eSmrg 2047, 2047, 121c35d236eSmrg {1, 1} 122c35d236eSmrg } 123c35d236eSmrg}; 124c35d236eSmrg 125c35d236eSmrg#define NUM_FORMATS 4 126c35d236eSmrg 127c35d236eSmrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = 128c35d236eSmrg{ 129c35d236eSmrg {8, PseudoColor}, {15, TrueColor}, {16, TrueColor}, {24, TrueColor} 130c35d236eSmrg}; 131c35d236eSmrg 132c35d236eSmrg#define NUM_ATTRIBUTES 4 133c35d236eSmrg 134c35d236eSmrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 135c35d236eSmrg{ 136c35d236eSmrg {XvSettable | XvGettable, 0, 1, "XV_DOUBLE_BUFFER"}, 137c35d236eSmrg {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"}, 138c35d236eSmrg {XvSettable | XvGettable, 0, 1, "XV_AUTOPAINT_COLORKEY"}, 139c35d236eSmrg {XvSettable | XvGettable, 0, 2, "XV_FILTER"}, 140c35d236eSmrg}; 141c35d236eSmrg 142c35d236eSmrg/* 143c35d236eSmrg * FOURCC from http://www.webartz.com/fourcc 144c35d236eSmrg * Generic GUID for legacy FOURCC XXXXXXXX-0000-0010-8000-00AA00389B71 145c35d236eSmrg */ 146c35d236eSmrg#define LE4CC(a,b,c,d) (((CARD32)(a)&0xFF)|(((CARD32)(b)&0xFF)<<8)|(((CARD32)(c)&0xFF)<<16)|(((CARD32)(d)&0xFF)<<24)) 147c35d236eSmrg#define GUID4CC(a,b,c,d) { a,b,c,d,0,0,0,0x10,0x80,0,0,0xAA,0,0x38,0x9B,0x71 } 148c35d236eSmrg 149c35d236eSmrg#define NoOrder LSBFirst 150c35d236eSmrg 151c35d236eSmrg#define NUM_IMAGES 15 152c35d236eSmrg 153c35d236eSmrgstatic XF86ImageRec Images[NUM_IMAGES] = 154c35d236eSmrg{ 155c35d236eSmrg /* Planar YVU 4:2:0 (emulated) */ 156c35d236eSmrg { LE4CC('Y','V','1','2'), XvYUV, NoOrder, GUID4CC('Y','V','1','2'), 157c35d236eSmrg 12, XvPlanar, 3, 0, 0, 0, 0, 158c35d236eSmrg 8, 8, 8, 1, 2, 2, 1, 2, 2, "YVU", XvTopToBottom }, 159c35d236eSmrg 160c35d236eSmrg /* Packed YUYV 4:2:2 */ 161c35d236eSmrg { LE4CC('Y','U','Y','2'), XvYUV, NoOrder, GUID4CC('Y','U','Y','2'), 162c35d236eSmrg 16, XvPacked, 1, 0, 0, 0, 0, 163c35d236eSmrg 8, 8, 8, 1, 2, 2, 1, 1, 1, "YUYV", XvTopToBottom }, 164c35d236eSmrg 165c35d236eSmrg /* Packed UYVY 4:2:2 */ 166c35d236eSmrg { LE4CC('U','Y','V','Y'), XvYUV, NoOrder, GUID4CC('U','Y','V','Y'), 167c35d236eSmrg 16, XvPacked, 1, 0, 0, 0, 0, 168c35d236eSmrg 8, 8, 8, 1, 2, 2, 1, 1, 1, "UYVY", XvTopToBottom }, 169c35d236eSmrg 170c35d236eSmrg /* Packed YUVA 4:4:4 */ 171c35d236eSmrg { LE4CC('Y','U','V','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, 172c35d236eSmrg 32, XvPacked, 1, 0, 0, 0, 0, 173c35d236eSmrg 8, 8, 8, 1, 1, 1, 1, 1, 1, "YUVA", XvTopToBottom }, 174c35d236eSmrg 175c35d236eSmrg /* Packed VUYA 4:4:4 */ 176c35d236eSmrg { LE4CC('V','U','Y','A') /* XXX not registered */, XvYUV, LSBFirst, { 0 }, 177c35d236eSmrg 32, XvPacked, 1, 0, 0, 0, 0, 178c35d236eSmrg 8, 8, 8, 1, 1, 1, 1, 1, 1, "VUYA", XvTopToBottom }, 179c35d236eSmrg 180c35d236eSmrg /* RGBA 8:8:8:8 */ 181c35d236eSmrg { 0x41, XvRGB, LSBFirst, { 0 }, 182c35d236eSmrg 32, XvPacked, 1, 24, 0x0000FF, 0x00FF00, 0xFF0000, 183c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 184c35d236eSmrg 185c35d236eSmrg /* RGB 5:6:5 */ 186c35d236eSmrg { 0x42, XvRGB, LSBFirst, { 0 }, 187c35d236eSmrg 16, XvPacked, 1, 16, 0x001F, 0x07E0, 0xF800, 188c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, 189c35d236eSmrg 190c35d236eSmrg /* RGBA 5:5:5:1 */ 191c35d236eSmrg { 0x43, XvRGB, LSBFirst, { 0 }, 192c35d236eSmrg 16, XvPacked, 1, 15, 0x001F, 0x03E0, 0x7C00, 193c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 194c35d236eSmrg 195c35d236eSmrg /* RGBA 4:4:4:4 */ 196c35d236eSmrg { 0x44, XvRGB, LSBFirst, { 0 }, 197c35d236eSmrg 16, XvPacked, 1, 12, 0x000F, 0x00F0, 0x0F00, 198c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGBA", XvTopToBottom }, 199c35d236eSmrg 200c35d236eSmrg /* RGB 3:3:2 */ 201c35d236eSmrg { 0x46, XvRGB, NoOrder, { 0 }, 202c35d236eSmrg 8, XvPacked, 1, 8, 0x07, 0x38, 0xC0, 203c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "RGB", XvTopToBottom }, 204c35d236eSmrg 205c35d236eSmrg /* BGRA 8:8:8:8 */ 206c35d236eSmrg { 0x47, XvRGB, LSBFirst, { 0 }, 207c35d236eSmrg 32, XvPacked, 1, 24, 0xFF0000, 0x00FF00, 0x0000FF, 208c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 209c35d236eSmrg 210c35d236eSmrg /* BGR 5:6:5 */ 211c35d236eSmrg { 0x48, XvRGB, LSBFirst, { 0 }, 212c35d236eSmrg 16, XvPacked, 1, 16, 0xF800, 0x07E0, 0x001F, 213c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, 214c35d236eSmrg 215c35d236eSmrg /* BGRA 5:5:5:1 */ 216c35d236eSmrg { 0x49, XvRGB, LSBFirst, { 0 }, 217c35d236eSmrg 16, XvPacked, 1, 15, 0x7C00, 0x03E0, 0x001F, 218c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 219c35d236eSmrg 220c35d236eSmrg /* BGRA 4:4:4:4 */ 221c35d236eSmrg { 0x4A, XvRGB, LSBFirst, { 0 }, 222c35d236eSmrg 16, XvPacked, 1, 12, 0x0F00, 0x00F0, 0x000F, 223c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGRA", XvTopToBottom }, 224c35d236eSmrg 225c35d236eSmrg /* BGR 2:3:3 */ 226c35d236eSmrg { 0x4C, XvRGB, NoOrder, { 0 }, 227c35d236eSmrg 8, XvPacked, 1, 8, 0xC0, 0x38, 0x07, 228c35d236eSmrg 0, 0, 0, 0, 0, 0, 0, 0, 0, "BGR", XvTopToBottom }, 229c35d236eSmrg}; 230c35d236eSmrg 231c35d236eSmrg#define MAX_BUFFERS 2 232c35d236eSmrg 233c35d236eSmrgtypedef struct { 234c35d236eSmrg FBAreaPtr area[MAX_BUFFERS]; 235c35d236eSmrg RegionRec clip; 236c35d236eSmrg CARD32 colorKey; 237c35d236eSmrg CARD32 videoStatus; 238c35d236eSmrg Time offTime; 239c35d236eSmrg Time freeTime; 240c35d236eSmrg int Video_Shift; 241c35d236eSmrg int Format; 242c35d236eSmrg Bool ramdacOn; 243c35d236eSmrg Bool doubleBuffer; 244c35d236eSmrg Bool autopaintColorKey; 245c35d236eSmrg int Filter; 246c35d236eSmrg int sx, sy; 247c35d236eSmrg int offset[MAX_BUFFERS]; 248c35d236eSmrg int buffer; 249c35d236eSmrg} GLINTPortPrivRec, *GLINTPortPrivPtr; 250c35d236eSmrg 251c35d236eSmrg#define GET_PORT_PRIVATE(pScrn) \ 252c35d236eSmrg (GLINTPortPrivPtr)((GLINTPTR(pScrn))->adaptor->pPortPrivates[0].ptr) 253c35d236eSmrg 254c35d236eSmrg#define RAMDAC_WRITE(data,index) \ 255c35d236eSmrgdo{ \ 256c35d236eSmrg GLINT_WRITE_REG(((index)>>8)&0xff, PM3RD_IndexHigh); \ 257c35d236eSmrg GLINT_WRITE_REG((index)&0xff, PM3RD_IndexLow); \ 258c35d236eSmrg GLINT_WRITE_REG(data, PM3RD_IndexedData); \ 259c35d236eSmrg}while(0) 260c35d236eSmrg 261c35d236eSmrgvoid Permedia3ResetVideo(ScrnInfoPtr pScrn) 262c35d236eSmrg{ 263c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 264c35d236eSmrg GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; 265c35d236eSmrg 266c35d236eSmrg GLINT_WAIT(15); 267c35d236eSmrg GLINT_WRITE_REG(0xfff0|(0xffff<<16), PM3VideoOverlayFifoControl); 268c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, PM3VideoOverlayMode); 269c35d236eSmrg pPriv->ramdacOn = FALSE; 270c35d236eSmrg RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, PM3RD_VideoOverlayControl); 271c35d236eSmrg RAMDAC_WRITE((pPriv->colorKey&0xff0000)>>16, PM3RD_VideoOverlayKeyR); 272c35d236eSmrg RAMDAC_WRITE((pPriv->colorKey&0x00ff00)>>8, PM3RD_VideoOverlayKeyG); 273c35d236eSmrg RAMDAC_WRITE(pPriv->colorKey&0x0000ff, PM3RD_VideoOverlayKeyB); 274c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, PM3VideoOverlayUpdate); 275c35d236eSmrg} 276c35d236eSmrg 277c35d236eSmrg 278c35d236eSmrgstatic XF86VideoAdaptorPtr 279c35d236eSmrgPermedia3SetupImageVideo(ScreenPtr pScreen) 280c35d236eSmrg{ 2811fb744b4Smrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 282c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 283c35d236eSmrg XF86VideoAdaptorPtr adapt; 284c35d236eSmrg GLINTPortPrivPtr pPriv; 285c35d236eSmrg 2861fb744b4Smrg if(!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec) + 287c35d236eSmrg sizeof(GLINTPortPrivRec) + 288c35d236eSmrg sizeof(DevUnion)))) 289c35d236eSmrg return NULL; 290c35d236eSmrg 291c35d236eSmrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 292c35d236eSmrg adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 293c35d236eSmrg adapt->name = "Permedia3 Backend Scaler"; 294c35d236eSmrg adapt->nEncodings = 1; 295c35d236eSmrg adapt->pEncodings = DummyEncoding; 296c35d236eSmrg adapt->nFormats = NUM_FORMATS; 297c35d236eSmrg adapt->pFormats = Formats; 298c35d236eSmrg adapt->nPorts = 1; 299c35d236eSmrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 300c35d236eSmrg pPriv = (GLINTPortPrivPtr)(&adapt->pPortPrivates[1]); 301c35d236eSmrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 302c35d236eSmrg adapt->pAttributes = Attributes; 303c35d236eSmrg adapt->nImages = NUM_IMAGES; 304c35d236eSmrg adapt->nAttributes = NUM_ATTRIBUTES; 305c35d236eSmrg adapt->pImages = Images; 306c35d236eSmrg adapt->PutVideo = NULL; 307c35d236eSmrg adapt->PutStill = NULL; 308c35d236eSmrg adapt->GetVideo = NULL; 309c35d236eSmrg adapt->GetStill = NULL; 310c35d236eSmrg adapt->StopVideo = Permedia3StopVideo; 311c35d236eSmrg adapt->SetPortAttribute = Permedia3SetPortAttribute; 312c35d236eSmrg adapt->GetPortAttribute = Permedia3GetPortAttribute; 313c35d236eSmrg adapt->QueryBestSize = Permedia3QueryBestSize; 314c35d236eSmrg adapt->PutImage = Permedia3PutImage; 315c35d236eSmrg adapt->QueryImageAttributes = Permedia3QueryImageAttributes; 316c35d236eSmrg 317c35d236eSmrg /* FIXME : depth 15 and 16 doesn't work here */ 318c35d236eSmrg pPriv->colorKey = pGlint->videoKey; 319c35d236eSmrg pPriv->videoStatus = 0; 320c35d236eSmrg pPriv->buffer = 0; /* double buffer (or maybe triple later) */ 321c35d236eSmrg pPriv->doubleBuffer = TRUE; 322c35d236eSmrg pPriv->autopaintColorKey = TRUE; 323c35d236eSmrg pPriv->Filter = PM3VideoOverlayMode_FILTER_FULL; 324c35d236eSmrg 325c35d236eSmrg /* gotta uninit this someplace */ 326c35d236eSmrg REGION_NULL(pScreen, &pPriv->clip); 327c35d236eSmrg 328c35d236eSmrg pGlint->adaptor = adapt; 329c35d236eSmrg 330c35d236eSmrg xvDoubleBuffer = MAKE_ATOM("XV_DOUBLE_BUFFER"); 331c35d236eSmrg xvColorKey = MAKE_ATOM("XV_COLORKEY"); 332c35d236eSmrg xvAutopaintColorKey = MAKE_ATOM("XV_AUTOPAINT_COLORKEY"); 333c35d236eSmrg xvFilter = MAKE_ATOM("XV_FILTER"); 334c35d236eSmrg 335c35d236eSmrg Permedia3ResetVideo(pScrn); 336c35d236eSmrg 337c35d236eSmrg return adapt; 338c35d236eSmrg} 339c35d236eSmrg 340c35d236eSmrg 341c35d236eSmrgstatic void 342c35d236eSmrgPermedia3StopVideo(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 343c35d236eSmrg{ 344c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 345c35d236eSmrg GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; 346c35d236eSmrg int i; 347c35d236eSmrg 348c35d236eSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 349c35d236eSmrg 350c35d236eSmrg if(shutdown) { 351c35d236eSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 352c35d236eSmrg pPriv->ramdacOn = FALSE; 353c35d236eSmrg GLINT_WAIT(4); 354c35d236eSmrg RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, 355c35d236eSmrg PM3RD_VideoOverlayControl); 356c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, 357c35d236eSmrg PM3VideoOverlayMode); 358c35d236eSmrg } 359c35d236eSmrg for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { 360c35d236eSmrg if(pPriv->area[i]) { 361c35d236eSmrg xf86FreeOffscreenArea(pPriv->area[i]); 362c35d236eSmrg pPriv->area[i] = NULL; 363c35d236eSmrg } 364c35d236eSmrg } 365c35d236eSmrg pPriv->videoStatus = 0; 366c35d236eSmrg } else { 367c35d236eSmrg if(pPriv->videoStatus & CLIENT_VIDEO_ON) { 368c35d236eSmrg pPriv->videoStatus |= OFF_TIMER; 369c35d236eSmrg pPriv->offTime = currentTime.milliseconds + OFF_DELAY; 370c35d236eSmrg } 371c35d236eSmrg } 372c35d236eSmrg} 373c35d236eSmrg 374c35d236eSmrgstatic int 375c35d236eSmrgPermedia3SetPortAttribute( 376c35d236eSmrg ScrnInfoPtr pScrn, 377c35d236eSmrg Atom attribute, 378c35d236eSmrg INT32 value, 379c35d236eSmrg pointer data 380c35d236eSmrg){ 381c35d236eSmrg GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; 382c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 383c35d236eSmrg 384c35d236eSmrg if (attribute == xvDoubleBuffer) 385c35d236eSmrg { 386c35d236eSmrg if ((value < 0) || (value > 1)) 387c35d236eSmrg return BadValue; 388c35d236eSmrg pPriv->doubleBuffer = value; 389c35d236eSmrg } 390c35d236eSmrg else if (attribute == xvColorKey) 391c35d236eSmrg { 392c35d236eSmrg pPriv->colorKey = value; 393c35d236eSmrg GLINT_WAIT(9); 394c35d236eSmrg RAMDAC_WRITE((value & 0xff0000)>>16, PM3RD_VideoOverlayKeyR); 395c35d236eSmrg RAMDAC_WRITE((value & 0x00ff00)>>8, PM3RD_VideoOverlayKeyG); 396c35d236eSmrg RAMDAC_WRITE((value & 0x0000ff), PM3RD_VideoOverlayKeyB); 397c35d236eSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 398c35d236eSmrg } 399c35d236eSmrg else if (attribute == xvAutopaintColorKey) 400c35d236eSmrg { 401c35d236eSmrg if ((value < 0) || (value > 1)) 402c35d236eSmrg return BadValue; 403c35d236eSmrg pPriv->autopaintColorKey = value; 404c35d236eSmrg } 405c35d236eSmrg else if (attribute == xvFilter) 406c35d236eSmrg { 407c35d236eSmrg if ((value < 0) || (value > 2)) 408c35d236eSmrg return BadValue; 409c35d236eSmrg switch (value) { 410c35d236eSmrg case 0: 411c35d236eSmrg pPriv->Filter = PM3VideoOverlayMode_FILTER_OFF; 412c35d236eSmrg break; 413c35d236eSmrg case 1: 414c35d236eSmrg pPriv->Filter = PM3VideoOverlayMode_FILTER_FULL; 415c35d236eSmrg break; 416c35d236eSmrg case 2: 417c35d236eSmrg pPriv->Filter = PM3VideoOverlayMode_FILTER_PARTIAL; 418c35d236eSmrg break; 419c35d236eSmrg } 420c35d236eSmrg } 421c35d236eSmrg else 422c35d236eSmrg return BadMatch; 423c35d236eSmrg 424c35d236eSmrg return Success; 425c35d236eSmrg} 426c35d236eSmrg 427c35d236eSmrgstatic int 428c35d236eSmrgPermedia3GetPortAttribute( 429c35d236eSmrg ScrnInfoPtr pScrn, 430c35d236eSmrg Atom attribute, 431c35d236eSmrg INT32 *value, 432c35d236eSmrg pointer data 433c35d236eSmrg){ 434c35d236eSmrg GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; 435c35d236eSmrg 436c35d236eSmrg if (attribute == xvDoubleBuffer) 437c35d236eSmrg *value = (pPriv->doubleBuffer) ? 1 : 0; 438c35d236eSmrg else if (attribute == xvColorKey) 439c35d236eSmrg *value = pPriv->colorKey; 440c35d236eSmrg else if (attribute == xvAutopaintColorKey) 441c35d236eSmrg *value = (pPriv->autopaintColorKey) ? 1 : 0; 442c35d236eSmrg else if (attribute == xvFilter) 443c35d236eSmrg *value = pPriv->Filter >> 14; 444c35d236eSmrg else 445c35d236eSmrg return BadMatch; 446c35d236eSmrg 447c35d236eSmrg return Success; 448c35d236eSmrg} 449c35d236eSmrg 450c35d236eSmrgstatic void 451c35d236eSmrgPermedia3QueryBestSize( 452c35d236eSmrg ScrnInfoPtr pScrn, 453c35d236eSmrg Bool motion, 454c35d236eSmrg short vid_w, short vid_h, 455c35d236eSmrg short drw_w, short drw_h, 456c35d236eSmrg unsigned int *p_w, unsigned int *p_h, 457c35d236eSmrg pointer data 458c35d236eSmrg){ 459c35d236eSmrg if(vid_w > (drw_w << 3)) 460c35d236eSmrg drw_w = vid_w >> 3; 461c35d236eSmrg if(vid_h > (drw_h << 3)) 462c35d236eSmrg drw_h = vid_h >> 3; 463c35d236eSmrg 464c35d236eSmrg *p_w = drw_w; 465c35d236eSmrg *p_h = drw_h; 466c35d236eSmrg} 467c35d236eSmrg 468c35d236eSmrgstatic void 469c35d236eSmrgHWCopySetup(ScrnInfoPtr pScrn, int x, int y, int w, int h) 470c35d236eSmrg{ 471c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 472c35d236eSmrg 473c35d236eSmrg GLINT_WAIT(4); 474c35d236eSmrg GLINT_WRITE_REG(0xffffffff, FBHardwareWriteMask); 475c35d236eSmrg GLINT_WRITE_REG( 476c35d236eSmrg PM3Config2D_ForegroundROPEnable | 477c35d236eSmrg PM3Config2D_ForegroundROP(GXcopy) | 478c35d236eSmrg PM3Config2D_FBWriteEnable, 479c35d236eSmrg PM3Config2D); 480c35d236eSmrg GLINT_WRITE_REG( 481c35d236eSmrg PM3RectanglePosition_XOffset(x) | 482c35d236eSmrg PM3RectanglePosition_YOffset(y), 483c35d236eSmrg PM3RectanglePosition); 484c35d236eSmrg GLINT_WRITE_REG( 485c35d236eSmrg PM3Render2D_SpanOperation | 486c35d236eSmrg PM3Render2D_XPositive | 487c35d236eSmrg PM3Render2D_YPositive | 488c35d236eSmrg PM3Render2D_Operation_SyncOnHostData | 489c35d236eSmrg PM3Render2D_Width(w) | PM3Render2D_Height(h), 490c35d236eSmrg PM3Render2D); 491c35d236eSmrg} 492c35d236eSmrg 493c35d236eSmrgstatic void 494c35d236eSmrgHWCopyYV12(ScrnInfoPtr pScrn, CARD8 *Y, int w, int h) 495c35d236eSmrg{ 496c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 497c35d236eSmrg int size = w * h; 498c35d236eSmrg CARD8 *V = Y + size; 499c35d236eSmrg CARD8 *U = V + (size >> 2); 500c35d236eSmrg CARD32 *dst; 501c35d236eSmrg int pass2 = 0; 502c35d236eSmrg int dwords, i, x = 0; 503c35d236eSmrg 504c35d236eSmrg dwords = size >> 1; 505c35d236eSmrg 506c35d236eSmrg w >>= 1; 507c35d236eSmrg 508c35d236eSmrg while (dwords >= pGlint->FIFOSize) { 509c35d236eSmrg dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); 510c35d236eSmrg GLINT_WAIT(pGlint->FIFOSize); 511c35d236eSmrg /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ 512c35d236eSmrg GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | 513c35d236eSmrg 0x05, OutputFIFO); 514c35d236eSmrg for (i = pGlint->FIFOSize - 1; i; i--, Y += 2, x++) { 515c35d236eSmrg if (x == w) { 516c35d236eSmrg x = 0; 517c35d236eSmrg if (pass2 == 0) 518c35d236eSmrg pass2 = 1; 519c35d236eSmrg else 520c35d236eSmrg if (pass2 == 1) { 521c35d236eSmrg pass2 = 0; 522c35d236eSmrg U += w; 523c35d236eSmrg V += w; 524c35d236eSmrg } 525c35d236eSmrg } 526c35d236eSmrg *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); 527c35d236eSmrg } 528c35d236eSmrg dwords -= pGlint->FIFOSize - 1; 529c35d236eSmrg } 530c35d236eSmrg if (dwords) { 531c35d236eSmrg dst = (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4); 532c35d236eSmrg GLINT_WAIT(dwords + 1); 533c35d236eSmrg /* (0x15 << 4) | 0x05 is the TAG for FBSourceData */ 534c35d236eSmrg GLINT_WRITE_REG(((dwords - 1) << 16) | (0x15 << 4) | 535c35d236eSmrg 0x05, OutputFIFO); 536c35d236eSmrg for (i = dwords; i; i--, Y += 2, x++) { 537c35d236eSmrg if (x == w) { 538c35d236eSmrg x = 0; 539c35d236eSmrg if (pass2 == 0) 540c35d236eSmrg pass2 = 1; 541c35d236eSmrg else 542c35d236eSmrg if (pass2 == 1) { 543c35d236eSmrg pass2 = 0; 544c35d236eSmrg U += w; 545c35d236eSmrg V += w; 546c35d236eSmrg } 547c35d236eSmrg } 548c35d236eSmrg *dst++ = Y[0] + (U[x] << 8) + (Y[1] << 16) + (V[x] << 24); 549c35d236eSmrg } 550c35d236eSmrg } 551c35d236eSmrg} 552c35d236eSmrg 553c35d236eSmrgstatic void 554c35d236eSmrgHWCopyFlat(ScrnInfoPtr pScrn, CARD8 *src, int w, int h) 555c35d236eSmrg{ 556c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 557c35d236eSmrg GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; 558c35d236eSmrg int pitch = pScrn->displayWidth; 559c35d236eSmrg CARD8 *tmp_src; 560c35d236eSmrg int dwords; 561c35d236eSmrg 562c35d236eSmrg if (w == pitch) { 563c35d236eSmrg dwords = (w * h) >> (2 - pPriv->Video_Shift); 564c35d236eSmrg while(dwords >= pGlint->FIFOSize) { 565c35d236eSmrg GLINT_WAIT(pGlint->FIFOSize); 566c35d236eSmrg GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | 567c35d236eSmrg 0x05, OutputFIFO); 568c35d236eSmrg GLINT_MoveDWORDS( 569c35d236eSmrg (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 570c35d236eSmrg (CARD32*)src, pGlint->FIFOSize - 1); 571c35d236eSmrg dwords -= (pGlint->FIFOSize - 1); 572c35d236eSmrg src += (pGlint->FIFOSize << 2) - 4; 573c35d236eSmrg } 574c35d236eSmrg if(dwords) { 575c35d236eSmrg GLINT_WAIT(dwords + 1); 576c35d236eSmrg GLINT_WRITE_REG(((dwords - 1) << 16)|(0x15 << 4) |0x05, OutputFIFO); 577c35d236eSmrg GLINT_MoveDWORDS( 578c35d236eSmrg (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 579c35d236eSmrg (CARD32*)src, dwords); 580c35d236eSmrg } 581c35d236eSmrg } else { 582c35d236eSmrg while (h--) { 583c35d236eSmrg tmp_src = src; 584c35d236eSmrg dwords = w >> (2 - pPriv->Video_Shift); 585c35d236eSmrg while(dwords >= pGlint->FIFOSize) { 586c35d236eSmrg GLINT_WAIT(pGlint->FIFOSize); 587c35d236eSmrg GLINT_WRITE_REG(((pGlint->FIFOSize - 2) << 16) | (0x15 << 4) | 588c35d236eSmrg 0x05, OutputFIFO); 589c35d236eSmrg GLINT_MoveDWORDS( 590c35d236eSmrg (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 591c35d236eSmrg (CARD32*)src, pGlint->FIFOSize - 1); 592c35d236eSmrg dwords -= (pGlint->FIFOSize - 1); 593c35d236eSmrg src += (pGlint->FIFOSize << 2) - 4; 594c35d236eSmrg } 595c35d236eSmrg if(dwords) { 596c35d236eSmrg GLINT_WAIT(dwords + 1); 597c35d236eSmrg GLINT_WRITE_REG(((dwords-1)<<16)|(0x15<<4) | 0x05, OutputFIFO); 598c35d236eSmrg GLINT_MoveDWORDS( 599c35d236eSmrg (CARD32*)((char*)pGlint->IOBase + OutputFIFO + 4), 600c35d236eSmrg (CARD32*)src, dwords); 601c35d236eSmrg } 602c35d236eSmrg src = tmp_src + (w << pPriv->Video_Shift); 603c35d236eSmrg } 604c35d236eSmrg } 605c35d236eSmrg} 606c35d236eSmrg 607c35d236eSmrgstatic FBAreaPtr 608c35d236eSmrgPermedia3AllocateMemory(ScrnInfoPtr pScrn, FBAreaPtr area, int width, int height) 609c35d236eSmrg{ 610c35d236eSmrg ScreenPtr pScreen; 611c35d236eSmrg FBAreaPtr new_area; 612c35d236eSmrg 613c35d236eSmrg if (area) { 614c35d236eSmrg if ((area->box.x2 - area->box.x1 >= width) && 615c35d236eSmrg (area->box.y2 - area->box.y1 >= height)) 616c35d236eSmrg return area; 617c35d236eSmrg 618c35d236eSmrg if (xf86ResizeOffscreenArea(area, width, height)) 619c35d236eSmrg return area; 620c35d236eSmrg 621c35d236eSmrg xf86FreeOffscreenArea(area); 622c35d236eSmrg } 623c35d236eSmrg 6241fb744b4Smrg pScreen = xf86ScrnToScreen(pScrn); 625c35d236eSmrg 626c35d236eSmrg new_area = xf86AllocateOffscreenArea(pScreen, width, height, pScrn->bitsPerPixel / 8, NULL, NULL, NULL); 627c35d236eSmrg 628c35d236eSmrg if (!new_area) { 629c35d236eSmrg int max_width, max_height; 630c35d236eSmrg 631c35d236eSmrg xf86QueryLargestOffscreenArea(pScreen, &max_width, &max_height, pScrn->bitsPerPixel / 8, 0, PRIORITY_EXTREME); 632c35d236eSmrg 633c35d236eSmrg if (max_width < width || max_height < height) 634c35d236eSmrg return NULL; 635c35d236eSmrg 636c35d236eSmrg xf86PurgeUnlockedOffscreenAreas(pScreen); 637c35d236eSmrg new_area = xf86AllocateOffscreenArea(pScreen, width, height, pScrn->bitsPerPixel / 8, NULL, NULL, NULL); 638c35d236eSmrg } 639c35d236eSmrg 640c35d236eSmrg return new_area; 641c35d236eSmrg} 642c35d236eSmrg 643c35d236eSmrg#define FORMAT_RGB8888 PM3VideoOverlayMode_COLORFORMAT_RGB8888 644c35d236eSmrg#define FORMAT_RGB4444 PM3VideoOverlayMode_COLORFORMAT_RGB4444 645c35d236eSmrg#define FORMAT_RGB5551 PM3VideoOverlayMode_COLORFORMAT_RGB5551 646c35d236eSmrg#define FORMAT_RGB565 PM3VideoOverlayMode_COLORFORMAT_RGB565 647c35d236eSmrg#define FORMAT_RGB332 PM3VideoOverlayMode_COLORFORMAT_RGB332 648c35d236eSmrg#define FORMAT_BGR8888 PM3VideoOverlayMode_COLORFORMAT_BGR8888 649c35d236eSmrg#define FORMAT_BGR4444 PM3VideoOverlayMode_COLORFORMAT_BGR4444 650c35d236eSmrg#define FORMAT_BGR5551 PM3VideoOverlayMode_COLORFORMAT_BGR5551 651c35d236eSmrg#define FORMAT_BGR565 PM3VideoOverlayMode_COLORFORMAT_BGR565 652c35d236eSmrg#define FORMAT_BGR332 PM3VideoOverlayMode_COLORFORMAT_BGR332 653c35d236eSmrg#define FORMAT_CI8 PM3VideoOverlayMode_COLORFORMAT_CI8 654c35d236eSmrg#define FORMAT_VUY444 PM3VideoOverlayMode_COLORFORMAT_VUY444 655c35d236eSmrg#define FORMAT_YUV444 PM3VideoOverlayMode_COLORFORMAT_YUV444 656c35d236eSmrg#define FORMAT_VUY422 PM3VideoOverlayMode_COLORFORMAT_VUY422 657c35d236eSmrg#define FORMAT_YUV422 PM3VideoOverlayMode_COLORFORMAT_YUV422 658c35d236eSmrg 659c35d236eSmrg/* Notice, have to check that we dont overflow the deltas here ... */ 660c35d236eSmrgstatic void 661c35d236eSmrgcompute_scale_factor( 662c35d236eSmrg short* src_w, short* dst_w, 663c35d236eSmrg unsigned int* shrink_delta, unsigned int* zoom_delta) 664c35d236eSmrg{ 665c35d236eSmrg /* NOTE: If we don't return reasonable values here then the video 666c35d236eSmrg * unit can potential shut off and won't display an image until re-enabled. 667c35d236eSmrg * Seems as though the zoom_delta is o.k, and I've not had the problem. 668c35d236eSmrg * The 'shrink_delta' is prone to this the most - FIXME ! */ 669c35d236eSmrg 670c35d236eSmrg if (*src_w >= *dst_w) { 671c35d236eSmrg *src_w &= ~0x3; 672c35d236eSmrg *dst_w &= ~0x3; 673c35d236eSmrg *shrink_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0ffffff0; 674c35d236eSmrg *zoom_delta = 1<<16; 675c35d236eSmrg if ( ((*shrink_delta * *dst_w) >> 16) & 0x03 ) 676c35d236eSmrg *shrink_delta += 0x10; 677c35d236eSmrg } else { 678c35d236eSmrg *src_w &= ~0x3; 679c35d236eSmrg *dst_w &= ~0x3; 680c35d236eSmrg *zoom_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0001fff0; 681c35d236eSmrg *shrink_delta = 1<<16; 682c35d236eSmrg if ( ((*zoom_delta * *dst_w) >> 16) & 0x03 ) 683c35d236eSmrg *zoom_delta += 0x10; 684c35d236eSmrg } 685c35d236eSmrg} 686c35d236eSmrg 687c35d236eSmrgstatic void 688c35d236eSmrgPermedia3DisplayVideo( 689c35d236eSmrg ScrnInfoPtr pScrn, 690c35d236eSmrg int id, 691c35d236eSmrg int offset, 692c35d236eSmrg short width, short height, 693c35d236eSmrg int x1, int y1, int x2, int y2, 694c35d236eSmrg BoxPtr dstBox, 695c35d236eSmrg short src_w, short src_h, 696c35d236eSmrg short drw_w, short drw_h 697c35d236eSmrg){ 698c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 699c35d236eSmrg GLINTPortPrivPtr portPriv = pGlint->adaptor->pPortPrivates[0].ptr; 700c35d236eSmrg unsigned int shrink, zoom; 701c35d236eSmrg unsigned int newx2; 702c35d236eSmrg 703c35d236eSmrg /* Let's overlay only to visible parts of the screen */ 704c35d236eSmrg if (dstBox->x1 == 0) { 705c35d236eSmrg x1 = drw_w - dstBox->x2; 706c35d236eSmrg drw_w = dstBox->x2; 707c35d236eSmrg } 708c35d236eSmrg if (dstBox->x2 == pScrn->frameX1) { 709c35d236eSmrg x2 = drw_w - (dstBox->x2 - dstBox->x1); 710c35d236eSmrg drw_w = (dstBox->x2 - dstBox->x1); 711c35d236eSmrg } 712c35d236eSmrg 713c35d236eSmrg /* Avoid divide by zero in compute_scale_factor. */ 714c35d236eSmrg if (drw_w < 8) 715c35d236eSmrg return; 716c35d236eSmrg 717c35d236eSmrg /* Let's adjust the width of source and dest to be compliant with 718c35d236eSmrg * the Permedia3 overlay unit requirement, and compute the X deltas. */ 719c35d236eSmrg newx2 = drw_w; 720c35d236eSmrg compute_scale_factor(&src_w, &drw_w, &shrink, &zoom); 721c35d236eSmrg dstBox->x2 -= (newx2 - drw_w); 722c35d236eSmrg 723c35d236eSmrg /* We do a long wait here - for everything that needs to be written */ 724c35d236eSmrg GLINT_WAIT(39); 725c35d236eSmrg GLINT_WRITE_REG(offset>>portPriv->Video_Shift, 726c35d236eSmrg portPriv->buffer ? PM3VideoOverlayBase1 : PM3VideoOverlayBase0); 727c35d236eSmrg /* Let's set the source pitch. */ 728c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayStride_STRIDE(pScrn->displayWidth<< 729c35d236eSmrg (pScrn->bitsPerPixel>>4) >>portPriv->Video_Shift), 730c35d236eSmrg PM3VideoOverlayStride); 731c35d236eSmrg /* Let's set the position and size of the visible part of the source. */ 732c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayWidth_WIDTH(src_w), 733c35d236eSmrg PM3VideoOverlayWidth); 734c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayHeight_HEIGHT(src_h), 735c35d236eSmrg PM3VideoOverlayHeight); 736c35d236eSmrg GLINT_WRITE_REG( 737c35d236eSmrg PM3VideoOverlayOrigin_XORIGIN(x1) | 738c35d236eSmrg PM3VideoOverlayOrigin_YORIGIN(y1), 739c35d236eSmrg PM3VideoOverlayOrigin); 740c35d236eSmrg /* Scale the source to the destinationsize */ 741c35d236eSmrg if (src_h == drw_h) { 742c35d236eSmrg GLINT_WRITE_REG( 743c35d236eSmrg PM3VideoOverlayYDelta_NONE, 744c35d236eSmrg PM3VideoOverlayYDelta); 745c35d236eSmrg } else { 746c35d236eSmrg GLINT_WRITE_REG( 747c35d236eSmrg PM3VideoOverlayYDelta_DELTA(src_h,drw_h), 748c35d236eSmrg PM3VideoOverlayYDelta); 749c35d236eSmrg } 750c35d236eSmrg if (src_w == drw_w) { 751c35d236eSmrg GLINT_WRITE_REG(1<<16, PM3VideoOverlayShrinkXDelta); 752c35d236eSmrg GLINT_WRITE_REG(1<<16, PM3VideoOverlayZoomXDelta); 753c35d236eSmrg } else { 754c35d236eSmrg GLINT_WRITE_REG(shrink, PM3VideoOverlayShrinkXDelta); 755c35d236eSmrg GLINT_WRITE_REG(zoom, PM3VideoOverlayZoomXDelta); 756c35d236eSmrg } 757c35d236eSmrg GLINT_WRITE_REG(portPriv->buffer, PM3VideoOverlayIndex); 758c35d236eSmrg 759c35d236eSmrg /* Now set the ramdac video overlay region and mode */ 760c35d236eSmrg RAMDAC_WRITE((dstBox->x1&0xff), PM3RD_VideoOverlayXStartLow); 761c35d236eSmrg RAMDAC_WRITE((dstBox->x1&0xf00)>>8, PM3RD_VideoOverlayXStartHigh); 762c35d236eSmrg RAMDAC_WRITE((dstBox->x2&0xff), PM3RD_VideoOverlayXEndLow); 763c35d236eSmrg RAMDAC_WRITE((dstBox->x2&0xf00)>>8,PM3RD_VideoOverlayXEndHigh); 764c35d236eSmrg RAMDAC_WRITE((dstBox->y1&0xff), PM3RD_VideoOverlayYStartLow); 765c35d236eSmrg RAMDAC_WRITE((dstBox->y1&0xf00)>>8, PM3RD_VideoOverlayYStartHigh); 766c35d236eSmrg RAMDAC_WRITE((dstBox->y2&0xff), PM3RD_VideoOverlayYEndLow); 767c35d236eSmrg RAMDAC_WRITE((dstBox->y2&0xf00)>>8,PM3RD_VideoOverlayYEndHigh); 768c35d236eSmrg 769c35d236eSmrg GLINT_WRITE_REG(portPriv->Video_Shift << 5 | 770c35d236eSmrg portPriv->Format | 771c35d236eSmrg portPriv->Filter | 772c35d236eSmrg PM3VideoOverlayMode_BUFFERSYNC_MANUAL | 773c35d236eSmrg PM3VideoOverlayMode_FLIP_VIDEO | 774c35d236eSmrg PM3VideoOverlayMode_ENABLE, 775c35d236eSmrg PM3VideoOverlayMode); 776c35d236eSmrg 777c35d236eSmrg if (!portPriv->ramdacOn) { 778c35d236eSmrg RAMDAC_WRITE(PM3RD_VideoOverlayControl_ENABLE | 779c35d236eSmrg PM3RD_VideoOverlayControl_KEY_COLOR | 780c35d236eSmrg PM3RD_VideoOverlayControl_MODE_MAINKEY | 781c35d236eSmrg PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED, 782c35d236eSmrg PM3RD_VideoOverlayControl); 783c35d236eSmrg portPriv->ramdacOn = TRUE; 784c35d236eSmrg } 785c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayUpdate_ENABLE, 786c35d236eSmrg PM3VideoOverlayUpdate); 787c35d236eSmrg} 788c35d236eSmrg 789c35d236eSmrgstatic int 790c35d236eSmrgPermedia3PutImage( 791c35d236eSmrg ScrnInfoPtr pScrn, 792c35d236eSmrg short src_x, short src_y, 793c35d236eSmrg short drw_x, short drw_y, 794c35d236eSmrg short src_w, short src_h, 795c35d236eSmrg short drw_w, short drw_h, 796c35d236eSmrg int id, unsigned char* buf, 797c35d236eSmrg short width, short height, 798c35d236eSmrg Bool sync, 799c35d236eSmrg RegionPtr clipBoxes, pointer data, 800c35d236eSmrg DrawablePtr pDraw 801c35d236eSmrg){ 802c35d236eSmrg#if 0 803c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 804c35d236eSmrg#endif 805c35d236eSmrg GLINTPortPrivPtr pPriv = (GLINTPortPrivPtr)data; 806c35d236eSmrg INT32 x1, x2, y1, y2; 807c35d236eSmrg int pitch; 808c35d236eSmrg int i; 809c35d236eSmrg int w_bpp, bpp; 810c35d236eSmrg Bool copy_flat = TRUE; 811c35d236eSmrg BoxRec dstBox; 812c35d236eSmrg 813c35d236eSmrg /* Let's find the image format and Video_Shift values */ 814c35d236eSmrg switch (id) { 815c35d236eSmrg case LE4CC('Y','V','1','2'): 816c35d236eSmrg pPriv->Format = FORMAT_YUV422; 817c35d236eSmrg pPriv->Video_Shift = 1; 818c35d236eSmrg copy_flat = FALSE; 819c35d236eSmrg break; 820c35d236eSmrg case LE4CC('Y','U','Y','2'): 821c35d236eSmrg pPriv->Format = FORMAT_YUV422; 822c35d236eSmrg pPriv->Video_Shift = 1; 823c35d236eSmrg break; 824c35d236eSmrg case LE4CC('U','Y','V','Y'): 825c35d236eSmrg pPriv->Format = FORMAT_VUY422; 826c35d236eSmrg pPriv->Video_Shift = 1; 827c35d236eSmrg break; 828c35d236eSmrg case LE4CC('Y','U','V','A'): 829c35d236eSmrg pPriv->Format = FORMAT_YUV444; 830c35d236eSmrg pPriv->Video_Shift = 2; 831c35d236eSmrg break; 832c35d236eSmrg case LE4CC('V','U','Y','A'): 833c35d236eSmrg pPriv->Format = FORMAT_VUY444; 834c35d236eSmrg pPriv->Video_Shift = 2; 835c35d236eSmrg break; 836c35d236eSmrg case 0x41: /* RGBA 8:8:8:8 */ 837c35d236eSmrg pPriv->Format = FORMAT_RGB8888; 838c35d236eSmrg pPriv->Video_Shift = 2; 839c35d236eSmrg break; 840c35d236eSmrg case 0x42: /* RGB 5:6:5 */ 841c35d236eSmrg pPriv->Format = FORMAT_RGB565; 842c35d236eSmrg pPriv->Video_Shift = 1; 843c35d236eSmrg break; 844c35d236eSmrg case 0x43: /* RGB 1:5:5:5 */ 845c35d236eSmrg pPriv->Format = FORMAT_RGB5551; 846c35d236eSmrg pPriv->Video_Shift = 1; 847c35d236eSmrg break; 848c35d236eSmrg case 0x44: /* RGB 4:4:4:4 */ 849c35d236eSmrg pPriv->Format = FORMAT_RGB4444; 850c35d236eSmrg pPriv->Video_Shift = 1; 851c35d236eSmrg break; 852c35d236eSmrg case 0x46: /* RGB 2:3:3 */ 853c35d236eSmrg pPriv->Format = FORMAT_RGB332; 854c35d236eSmrg pPriv->Video_Shift = 0; 855c35d236eSmrg break; 856c35d236eSmrg case 0x47: /* BGRA 8:8:8:8 */ 857c35d236eSmrg pPriv->Format = FORMAT_BGR8888; 858c35d236eSmrg pPriv->Video_Shift = 2; 859c35d236eSmrg break; 860c35d236eSmrg case 0x48: /* BGR 5:6:5 */ 861c35d236eSmrg pPriv->Format = FORMAT_BGR565; 862c35d236eSmrg pPriv->Video_Shift = 1; 863c35d236eSmrg break; 864c35d236eSmrg case 0x49: /* BGR 1:5:5:5 */ 865c35d236eSmrg pPriv->Format = FORMAT_BGR5551; 866c35d236eSmrg pPriv->Video_Shift = 1; 867c35d236eSmrg break; 868c35d236eSmrg case 0x4A: /* BGR 4:4:4:4 */ 869c35d236eSmrg pPriv->Format = FORMAT_BGR4444; 870c35d236eSmrg pPriv->Video_Shift = 1; 871c35d236eSmrg break; 872c35d236eSmrg case 0x4C: /* BGR 2:3:3 */ 873c35d236eSmrg pPriv->Format = FORMAT_BGR332; 874c35d236eSmrg pPriv->Video_Shift = 0; 875c35d236eSmrg break; 876c35d236eSmrg default: 877c35d236eSmrg return XvBadAlloc; 878c35d236eSmrg } 879c35d236eSmrg 880c35d236eSmrg /* Clip */ 881c35d236eSmrg x1 = src_x; 882c35d236eSmrg x2 = src_x + src_w; 883c35d236eSmrg y1 = src_y; 884c35d236eSmrg y2 = src_y + src_h; 885c35d236eSmrg 886c35d236eSmrg dstBox.x1 = drw_x; 887c35d236eSmrg dstBox.x2 = drw_x + drw_w; 888c35d236eSmrg dstBox.y1 = drw_y; 889c35d236eSmrg dstBox.y2 = drw_y + drw_h; 890c35d236eSmrg 891c35d236eSmrg if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, 892c35d236eSmrg width, height)) 893c35d236eSmrg return Success; 894c35d236eSmrg 895c35d236eSmrg dstBox.x1 -= pScrn->frameX0; 896c35d236eSmrg dstBox.x2 -= pScrn->frameX0; 897c35d236eSmrg dstBox.y1 -= pScrn->frameY0; 898c35d236eSmrg dstBox.y2 -= pScrn->frameY0; 899c35d236eSmrg 900c35d236eSmrg bpp = pScrn->bitsPerPixel >> 3; 901c35d236eSmrg pitch = bpp * pScrn->displayWidth; 902c35d236eSmrg 903c35d236eSmrg w_bpp = (width << pPriv->Video_Shift) >> (pScrn->bitsPerPixel >> 4); 904c35d236eSmrg 905c35d236eSmrg for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { 906c35d236eSmrg if (!(pPriv->area[i] = 907c35d236eSmrg Permedia3AllocateMemory(pScrn,pPriv->area[i],w_bpp,src_h))) 908c35d236eSmrg return BadAlloc; 909c35d236eSmrg 910c35d236eSmrg pPriv->offset[i] = (pPriv->area[i]->box.x1 * bpp) + 911c35d236eSmrg (pPriv->area[i]->box.y1 * pitch); 912c35d236eSmrg } 913c35d236eSmrg 914c35d236eSmrg HWCopySetup(pScrn, pPriv->area[pPriv->buffer]->box.x1, 915c35d236eSmrg pPriv->area[pPriv->buffer]->box.y1, w_bpp, height); 916c35d236eSmrg 917c35d236eSmrg if (copy_flat) 918c35d236eSmrg HWCopyFlat(pScrn, buf, width, height); 919c35d236eSmrg else 920c35d236eSmrg HWCopyYV12(pScrn, buf, width, height); 921c35d236eSmrg 922c35d236eSmrg /* paint the color key */ 923c35d236eSmrg if(pPriv->autopaintColorKey && 924c35d236eSmrg !REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { 925c35d236eSmrg /* update cliplist */ 926c35d236eSmrg REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); 927c35d236eSmrg#if 0 928c35d236eSmrg GLINT_WAIT(1); 929c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, 930c35d236eSmrg PM3VideoOverlayMode); 931c35d236eSmrg pPriv->ramdacOn = FALSE; 932c35d236eSmrg#endif 933c35d236eSmrg xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); 934c35d236eSmrg } 935c35d236eSmrg 936c35d236eSmrg Permedia3Sync(pScrn); 937c35d236eSmrg 938c35d236eSmrg Permedia3DisplayVideo(pScrn, id, pPriv->offset[pPriv->buffer], width,height, 939c35d236eSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 940c35d236eSmrg 941c35d236eSmrg /* Switch buffer on next run - double buffer */ 942c35d236eSmrg if (pPriv->doubleBuffer) { 943c35d236eSmrg if (!pPriv->buffer) 944c35d236eSmrg pPriv->buffer = 1; 945c35d236eSmrg else 946c35d236eSmrg pPriv->buffer = 0; 947c35d236eSmrg } 948c35d236eSmrg 949c35d236eSmrg pPriv->videoStatus = CLIENT_VIDEO_ON; 950c35d236eSmrg 951c35d236eSmrg return Success; 952c35d236eSmrg} 953c35d236eSmrg 954c35d236eSmrgstatic int 955c35d236eSmrgPermedia3QueryImageAttributes( 956c35d236eSmrg ScrnInfoPtr pScrn, 957c35d236eSmrg int id, 958c35d236eSmrg unsigned short *w, unsigned short *h, 959c35d236eSmrg int *pitches, int *offsets 960c35d236eSmrg){ 961c35d236eSmrg int size, tmp; 962c35d236eSmrg 963c35d236eSmrg if(*w > 2047) *w = 2047; 964c35d236eSmrg if(*h > 2047) *h = 2047; 965c35d236eSmrg 966c35d236eSmrg *w = (*w + 1) & ~1; 967c35d236eSmrg if(offsets) offsets[0] = 0; 968c35d236eSmrg 969c35d236eSmrg switch(id) { 970c35d236eSmrg case FOURCC_YV12: /* YV12 */ 971c35d236eSmrg *h = (*h + 1) & ~1; 972c35d236eSmrg size = (*w + 3) & ~3; 973c35d236eSmrg if(pitches) pitches[0] = size; 974c35d236eSmrg size *= *h; 975c35d236eSmrg if(offsets) offsets[1] = size; 976c35d236eSmrg tmp = ((*w >> 1) + 3) & ~3; 977c35d236eSmrg if(pitches) pitches[1] = pitches[2] = tmp; 978c35d236eSmrg tmp *= (*h >> 1); 979c35d236eSmrg size += tmp; 980c35d236eSmrg if(offsets) offsets[2] = size; 981c35d236eSmrg size += tmp; 982c35d236eSmrg break; 983c35d236eSmrg default: /* RGB15, RGB16, YUY2 */ 984c35d236eSmrg size = *w << 1; 985c35d236eSmrg if(pitches) pitches[0] = size; 986c35d236eSmrg size *= *h; 987c35d236eSmrg break; 988c35d236eSmrg } 989c35d236eSmrg 990c35d236eSmrg return size; 991c35d236eSmrg} 992c35d236eSmrg 993c35d236eSmrg/****************** Offscreen stuff ***************/ 994c35d236eSmrg 995c35d236eSmrgtypedef struct { 996c35d236eSmrg FBAreaPtr area; 997c35d236eSmrg Bool isOn; 998c35d236eSmrg int Video_Shift; 999c35d236eSmrg int Format; 1000c35d236eSmrg Bool ramdacOn; 1001c35d236eSmrg} OffscreenPrivRec, * OffscreenPrivPtr; 1002c35d236eSmrg 1003c35d236eSmrgstatic int 1004c35d236eSmrgPermedia3AllocateSurface( 1005c35d236eSmrg ScrnInfoPtr pScrn, 1006c35d236eSmrg int id, 1007c35d236eSmrg unsigned short w, 1008c35d236eSmrg unsigned short h, 1009c35d236eSmrg XF86SurfacePtr surface 1010c35d236eSmrg){ 1011c35d236eSmrg FBAreaPtr area; 1012c35d236eSmrg int fbpitch, bpp; 1013c35d236eSmrg OffscreenPrivPtr pPriv; 1014c35d236eSmrg 1015c35d236eSmrg if((w > 2047) || (h > 2047)) 1016c35d236eSmrg return BadAlloc; 1017c35d236eSmrg 1018c35d236eSmrg w = (w + 1) & ~1; 1019c35d236eSmrg bpp = pScrn->bitsPerPixel >> 3; 1020c35d236eSmrg fbpitch = bpp * pScrn->displayWidth; 1021c35d236eSmrg 1022c35d236eSmrg if(!(area = Permedia3AllocateMemory(pScrn, NULL, w, h))) 1023c35d236eSmrg return BadAlloc; 1024c35d236eSmrg 1025c35d236eSmrg surface->width = w; 1026c35d236eSmrg surface->height = h; 1027c35d236eSmrg 10281fb744b4Smrg if(!(surface->offsets = malloc(sizeof(int)))) { 1029c35d236eSmrg xf86FreeOffscreenArea(area); 1030c35d236eSmrg return BadAlloc; 1031c35d236eSmrg } 10321fb744b4Smrg if(!(pPriv = malloc(sizeof(OffscreenPrivRec)))) { 10331fb744b4Smrg free(surface->offsets); 1034c35d236eSmrg xf86FreeOffscreenArea(area); 1035c35d236eSmrg return BadAlloc; 1036c35d236eSmrg } 1037c35d236eSmrg 1038c35d236eSmrg pPriv->area = area; 1039c35d236eSmrg pPriv->isOn = FALSE; 1040c35d236eSmrg 1041c35d236eSmrg surface->pScrn = pScrn; 1042c35d236eSmrg surface->id = id; 1043c35d236eSmrg surface->offsets[0] = (area->box.x1 * bpp) + (area->box.y1 * fbpitch); 1044c35d236eSmrg surface->devPrivate.ptr = (pointer)pPriv; 1045c35d236eSmrg 1046c35d236eSmrg return Success; 1047c35d236eSmrg} 1048c35d236eSmrg 1049c35d236eSmrgstatic int 1050c35d236eSmrgPermedia3StopSurface( 1051c35d236eSmrg XF86SurfacePtr surface 1052c35d236eSmrg){ 1053c35d236eSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 1054c35d236eSmrg 1055c35d236eSmrg if(pPriv->isOn) { 1056c35d236eSmrg GLINTPtr pGlint = GLINTPTR(surface->pScrn); 1057c35d236eSmrg pPriv->ramdacOn = FALSE; 1058c35d236eSmrg GLINT_WAIT(4); 1059c35d236eSmrg RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, 1060c35d236eSmrg PM3RD_VideoOverlayControl); 1061c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, 1062c35d236eSmrg PM3VideoOverlayMode); 1063c35d236eSmrg pPriv->isOn = FALSE; 1064c35d236eSmrg } 1065c35d236eSmrg 1066c35d236eSmrg return Success; 1067c35d236eSmrg} 1068c35d236eSmrg 1069c35d236eSmrgstatic int 1070c35d236eSmrgPermedia3FreeSurface( 1071c35d236eSmrg XF86SurfacePtr surface 1072c35d236eSmrg){ 1073c35d236eSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 1074c35d236eSmrg 1075c35d236eSmrg if(pPriv->isOn) 1076c35d236eSmrg Permedia3StopSurface(surface); 1077c35d236eSmrg xf86FreeOffscreenArea(pPriv->area); 10781fb744b4Smrg free(surface->pitches); 10791fb744b4Smrg free(surface->offsets); 10801fb744b4Smrg free(surface->devPrivate.ptr); 1081c35d236eSmrg 1082c35d236eSmrg return Success; 1083c35d236eSmrg} 1084c35d236eSmrg 1085c35d236eSmrgstatic int 1086c35d236eSmrgPermedia3GetSurfaceAttribute( 1087c35d236eSmrg ScrnInfoPtr pScrn, 1088c35d236eSmrg Atom attribute, 1089c35d236eSmrg INT32 *value 1090c35d236eSmrg){ 1091c35d236eSmrg return Permedia3GetPortAttribute(pScrn, attribute, value, 1092c35d236eSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 1093c35d236eSmrg} 1094c35d236eSmrg 1095c35d236eSmrgstatic int 1096c35d236eSmrgPermedia3SetSurfaceAttribute( 1097c35d236eSmrg ScrnInfoPtr pScrn, 1098c35d236eSmrg Atom attribute, 1099c35d236eSmrg INT32 value 1100c35d236eSmrg){ 1101c35d236eSmrg return Permedia3SetPortAttribute(pScrn, attribute, value, 1102c35d236eSmrg (pointer)(GET_PORT_PRIVATE(pScrn))); 1103c35d236eSmrg} 1104c35d236eSmrg 1105c35d236eSmrgstatic int 1106c35d236eSmrgPermedia3DisplaySurface( 1107c35d236eSmrg XF86SurfacePtr surface, 1108c35d236eSmrg short src_x, short src_y, 1109c35d236eSmrg short drw_x, short drw_y, 1110c35d236eSmrg short src_w, short src_h, 1111c35d236eSmrg short drw_w, short drw_h, 1112c35d236eSmrg RegionPtr clipBoxes 1113c35d236eSmrg){ 1114c35d236eSmrg OffscreenPrivPtr pPriv = (OffscreenPrivPtr)surface->devPrivate.ptr; 1115c35d236eSmrg ScrnInfoPtr pScrn = surface->pScrn; 1116c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 1117c35d236eSmrg GLINTPortPrivPtr portPriv = pGlint->adaptor->pPortPrivates[0].ptr; 1118c35d236eSmrg INT32 x1, y1, x2, y2; 1119c35d236eSmrg BoxRec dstBox; 1120c35d236eSmrg 1121c35d236eSmrg x1 = src_x; 1122c35d236eSmrg x2 = src_x + src_w; 1123c35d236eSmrg y1 = src_y; 1124c35d236eSmrg y2 = src_y + src_h; 1125c35d236eSmrg 1126c35d236eSmrg dstBox.x1 = drw_x; 1127c35d236eSmrg dstBox.x2 = drw_x + drw_w; 1128c35d236eSmrg dstBox.y1 = drw_y; 1129c35d236eSmrg dstBox.y2 = drw_y + drw_h; 1130c35d236eSmrg 1131c35d236eSmrg if(!xf86XVClipVideoHelper(&dstBox, &x1, &x2, &y1, &y2, clipBoxes, 1132c35d236eSmrg surface->width, surface->height)) 1133c35d236eSmrg { 1134c35d236eSmrg return Success; 1135c35d236eSmrg } 1136c35d236eSmrg 1137c35d236eSmrg dstBox.x1 -= pScrn->frameX0; 1138c35d236eSmrg dstBox.x2 -= pScrn->frameX0; 1139c35d236eSmrg dstBox.y1 -= pScrn->frameY0; 1140c35d236eSmrg dstBox.y2 -= pScrn->frameY0; 1141c35d236eSmrg 1142c35d236eSmrg /* Let's find the image format and Video_Shift values */ 1143c35d236eSmrg switch (surface->id) { 1144c35d236eSmrg case LE4CC('Y','V','1','2'): 1145c35d236eSmrg pPriv->Format = FORMAT_YUV422; 1146c35d236eSmrg pPriv->Video_Shift = 1; 1147c35d236eSmrg break; 1148c35d236eSmrg case LE4CC('Y','U','Y','2'): 1149c35d236eSmrg pPriv->Format = FORMAT_YUV422; 1150c35d236eSmrg pPriv->Video_Shift = 1; 1151c35d236eSmrg break; 1152c35d236eSmrg case LE4CC('U','Y','V','Y'): 1153c35d236eSmrg pPriv->Format = FORMAT_VUY422; 1154c35d236eSmrg pPriv->Video_Shift = 1; 1155c35d236eSmrg break; 1156c35d236eSmrg case LE4CC('Y','U','V','A'): 1157c35d236eSmrg pPriv->Format = FORMAT_YUV444; 1158c35d236eSmrg pPriv->Video_Shift = 2; 1159c35d236eSmrg break; 1160c35d236eSmrg case LE4CC('V','U','Y','A'): 1161c35d236eSmrg pPriv->Format = FORMAT_VUY444; 1162c35d236eSmrg pPriv->Video_Shift = 2; 1163c35d236eSmrg break; 1164c35d236eSmrg case 0x41: /* RGBA 8:8:8:8 */ 1165c35d236eSmrg pPriv->Format = FORMAT_RGB8888; 1166c35d236eSmrg pPriv->Video_Shift = 2; 1167c35d236eSmrg break; 1168c35d236eSmrg case 0x42: /* RGB 5:6:5 */ 1169c35d236eSmrg pPriv->Format = FORMAT_RGB565; 1170c35d236eSmrg pPriv->Video_Shift = 1; 1171c35d236eSmrg break; 1172c35d236eSmrg case 0x43: /* RGB 1:5:5:5 */ 1173c35d236eSmrg pPriv->Format = FORMAT_RGB5551; 1174c35d236eSmrg pPriv->Video_Shift = 1; 1175c35d236eSmrg break; 1176c35d236eSmrg case 0x44: /* RGB 4:4:4:4 */ 1177c35d236eSmrg pPriv->Format = FORMAT_RGB4444; 1178c35d236eSmrg pPriv->Video_Shift = 1; 1179c35d236eSmrg break; 1180c35d236eSmrg case 0x46: /* RGB 2:3:3 */ 1181c35d236eSmrg pPriv->Format = FORMAT_RGB332; 1182c35d236eSmrg pPriv->Video_Shift = 0; 1183c35d236eSmrg break; 1184c35d236eSmrg case 0x47: /* BGRA 8:8:8:8 */ 1185c35d236eSmrg pPriv->Format = FORMAT_BGR8888; 1186c35d236eSmrg pPriv->Video_Shift = 2; 1187c35d236eSmrg break; 1188c35d236eSmrg case 0x48: /* BGR 5:6:5 */ 1189c35d236eSmrg pPriv->Format = FORMAT_BGR565; 1190c35d236eSmrg pPriv->Video_Shift = 1; 1191c35d236eSmrg break; 1192c35d236eSmrg case 0x49: /* BGR 1:5:5:5 */ 1193c35d236eSmrg pPriv->Format = FORMAT_BGR5551; 1194c35d236eSmrg pPriv->Video_Shift = 1; 1195c35d236eSmrg break; 1196c35d236eSmrg case 0x4A: /* BGR 4:4:4:4 */ 1197c35d236eSmrg pPriv->Format = FORMAT_BGR4444; 1198c35d236eSmrg pPriv->Video_Shift = 1; 1199c35d236eSmrg break; 1200c35d236eSmrg case 0x4C: /* BGR 2:3:3 */ 1201c35d236eSmrg pPriv->Format = FORMAT_BGR332; 1202c35d236eSmrg pPriv->Video_Shift = 0; 1203c35d236eSmrg break; 1204c35d236eSmrg default: 1205c35d236eSmrg return XvBadAlloc; 1206c35d236eSmrg } 1207c35d236eSmrg 1208c35d236eSmrg Permedia3DisplayVideo(pScrn, surface->id, surface->offsets[0], 1209c35d236eSmrg surface->width, surface->height, 1210c35d236eSmrg x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); 1211c35d236eSmrg 1212c35d236eSmrg xf86XVFillKeyHelper(pScrn->pScreen, portPriv->colorKey, clipBoxes); 1213c35d236eSmrg 1214c35d236eSmrg pPriv->isOn = TRUE; 1215c35d236eSmrg /* we've prempted the XvImage stream so set its free timer */ 1216c35d236eSmrg if(portPriv->videoStatus & CLIENT_VIDEO_ON) { 1217c35d236eSmrg REGION_EMPTY(pScrn->pScreen, &portPriv->clip); 1218c35d236eSmrg UpdateCurrentTime(); 1219c35d236eSmrg portPriv->videoStatus = FREE_TIMER; 1220c35d236eSmrg portPriv->freeTime = currentTime.milliseconds + FREE_DELAY; 1221c35d236eSmrg pGlint->VideoTimerCallback = Permedia3VideoTimerCallback; 1222c35d236eSmrg } 1223c35d236eSmrg 1224c35d236eSmrg return Success; 1225c35d236eSmrg} 1226c35d236eSmrg 1227c35d236eSmrgstatic void 1228c35d236eSmrgPermedia3InitOffscreenImages(ScreenPtr pScreen) 1229c35d236eSmrg{ 1230c35d236eSmrg XF86OffscreenImagePtr offscreenImages; 1231c35d236eSmrg 1232c35d236eSmrg /* need to free this someplace */ 12331fb744b4Smrg if(!(offscreenImages = malloc(sizeof(XF86OffscreenImageRec)))) 1234c35d236eSmrg return; 1235c35d236eSmrg 1236c35d236eSmrg offscreenImages[0].image = &Images[0]; 1237c35d236eSmrg offscreenImages[0].flags = VIDEO_OVERLAID_IMAGES | 1238c35d236eSmrg VIDEO_CLIP_TO_VIEWPORT; 1239c35d236eSmrg offscreenImages[0].alloc_surface = Permedia3AllocateSurface; 1240c35d236eSmrg offscreenImages[0].free_surface = Permedia3FreeSurface; 1241c35d236eSmrg offscreenImages[0].display = Permedia3DisplaySurface; 1242c35d236eSmrg offscreenImages[0].stop = Permedia3StopSurface; 1243c35d236eSmrg offscreenImages[0].setAttribute = Permedia3SetSurfaceAttribute; 1244c35d236eSmrg offscreenImages[0].getAttribute = Permedia3GetSurfaceAttribute; 1245c35d236eSmrg offscreenImages[0].max_width = 2047; 1246c35d236eSmrg offscreenImages[0].max_height = 2047; 1247c35d236eSmrg offscreenImages[0].num_attributes = NUM_ATTRIBUTES; 1248c35d236eSmrg offscreenImages[0].attributes = Attributes; 1249c35d236eSmrg 1250c35d236eSmrg xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); 1251c35d236eSmrg} 1252c35d236eSmrg 1253c35d236eSmrgstatic void 1254c35d236eSmrgPermedia3VideoTimerCallback(ScrnInfoPtr pScrn, Time time) 1255c35d236eSmrg{ 1256c35d236eSmrg GLINTPtr pGlint = GLINTPTR(pScrn); 1257c35d236eSmrg GLINTPortPrivPtr pPriv = pGlint->adaptor->pPortPrivates[0].ptr; 1258c35d236eSmrg int i; 1259c35d236eSmrg 1260c35d236eSmrg if(pPriv->videoStatus & TIMER_MASK) { 1261c35d236eSmrg if(pPriv->videoStatus & OFF_TIMER) { 1262c35d236eSmrg if(pPriv->offTime < time) { 1263c35d236eSmrg pPriv->ramdacOn = FALSE; 1264c35d236eSmrg GLINT_WAIT(4); 1265c35d236eSmrg RAMDAC_WRITE(PM3RD_VideoOverlayControl_DISABLE, 1266c35d236eSmrg PM3RD_VideoOverlayControl); 1267c35d236eSmrg GLINT_WRITE_REG(PM3VideoOverlayMode_DISABLE, 1268c35d236eSmrg PM3VideoOverlayMode); 1269c35d236eSmrg pPriv->videoStatus = FREE_TIMER; 1270c35d236eSmrg pPriv->freeTime = time + FREE_DELAY; 1271c35d236eSmrg } 1272c35d236eSmrg } else { /* FREE_TIMER */ 1273c35d236eSmrg if(pPriv->freeTime < time) { 1274c35d236eSmrg for (i = 0; i < (pPriv->doubleBuffer ? 2 : 1); i++) { 1275c35d236eSmrg if(pPriv->area[i]) { 1276c35d236eSmrg xf86FreeOffscreenArea(pPriv->area[i]); 1277c35d236eSmrg pPriv->area[i] = NULL; 1278c35d236eSmrg } 1279c35d236eSmrg } 1280c35d236eSmrg pPriv->videoStatus = 0; 1281c35d236eSmrg pGlint->VideoTimerCallback = NULL; 1282c35d236eSmrg } 1283c35d236eSmrg } 1284c35d236eSmrg } else /* shouldn't get here */ 1285c35d236eSmrg pGlint->VideoTimerCallback = NULL; 1286c35d236eSmrg} 1287