apm_video.c revision 17a48c7c
117a48c7cSmrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_video.c,v 1.11tsi Exp $ */ 217a48c7cSmrg 317a48c7cSmrg#ifdef HAVE_CONFIG_H 417a48c7cSmrg#include "config.h" 517a48c7cSmrg#endif 617a48c7cSmrg 717a48c7cSmrg#if PSZ != 24 817a48c7cSmrg#include "dixstruct.h" 917a48c7cSmrg#include "fourcc.h" 1017a48c7cSmrg 1117a48c7cSmrg/* 1217a48c7cSmrg * Ported from mga_video.c by Loïc Grenié 1317a48c7cSmrg */ 1417a48c7cSmrg 1517a48c7cSmrg#ifndef OFF_DELAY 1617a48c7cSmrg#define OFF_DELAY 200 1717a48c7cSmrg#endif 1817a48c7cSmrg 1917a48c7cSmrgstatic XF86VideoAdaptorPtr A(SetupImageVideo)(ScreenPtr); 2017a48c7cSmrg 2117a48c7cSmrgstatic void A(StopVideo)(ScrnInfoPtr, pointer, Bool); 2217a48c7cSmrgstatic int A(SetPortAttribute)(ScrnInfoPtr, Atom, INT32, pointer); 2317a48c7cSmrg#ifndef IOP_ACCESS 2417a48c7cSmrgstatic int ApmGetPortAttribute(ScrnInfoPtr, Atom ,INT32 *, pointer); 2517a48c7cSmrgstatic void ApmQueryBestSize(ScrnInfoPtr, Bool, short, short, short, 2617a48c7cSmrg short, unsigned int *, unsigned int *, 2717a48c7cSmrg pointer); 2817a48c7cSmrgstatic int ApmQueryImageAttributes(ScrnInfoPtr, int, 2917a48c7cSmrg unsigned short *, unsigned short *, 3017a48c7cSmrg int *, int *); 3117a48c7cSmrg#endif 3217a48c7cSmrgstatic int A(ReputImage)(ScrnInfoPtr, short, short, RegionPtr, pointer, 3317a48c7cSmrg DrawablePtr); 3417a48c7cSmrgstatic int A(PutImage)(ScrnInfoPtr, short, short, short, short, short, 3517a48c7cSmrg short, short, short, int, unsigned char*, 3617a48c7cSmrg short, short, Bool, RegionPtr, pointer, 3717a48c7cSmrg DrawablePtr); 3817a48c7cSmrg 3917a48c7cSmrgstatic void A(ResetVideo)(ScrnInfoPtr); 4017a48c7cSmrgstatic void A(XvMoveCB)(FBAreaPtr, FBAreaPtr); 4117a48c7cSmrgstatic void A(XvRemoveCB)(FBAreaPtr); 4217a48c7cSmrg 4317a48c7cSmrg#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE) 4417a48c7cSmrg 4517a48c7cSmrgvoid A(InitVideo)(ScreenPtr pScreen) 4617a48c7cSmrg{ 4717a48c7cSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 4817a48c7cSmrg XF86VideoAdaptorPtr *adaptors, *newAdaptors; 4917a48c7cSmrg XF86VideoAdaptorPtr newAdaptor; 5017a48c7cSmrg APMDECL(pScrn); 5117a48c7cSmrg int num_adaptors; 5217a48c7cSmrg Bool freeAdaptors = FALSE; 5317a48c7cSmrg 5417a48c7cSmrg num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors); 5517a48c7cSmrg 5617a48c7cSmrg if (pApm->Chipset >= AT24) { 5717a48c7cSmrg if ((newAdaptor = A(SetupImageVideo)(pScreen))) { 5817a48c7cSmrg 5917a48c7cSmrg newAdaptors = xalloc((num_adaptors + 1) * 6017a48c7cSmrg sizeof(XF86VideoAdaptorPtr*)); 6117a48c7cSmrg if(newAdaptors) { 6217a48c7cSmrg if(num_adaptors) 6317a48c7cSmrg memcpy(newAdaptors, adaptors, num_adaptors * 6417a48c7cSmrg sizeof(XF86VideoAdaptorPtr)); 6517a48c7cSmrg newAdaptors[num_adaptors] = newAdaptor; 6617a48c7cSmrg adaptors = newAdaptors; 6717a48c7cSmrg num_adaptors++; 6817a48c7cSmrg freeAdaptors = TRUE; 6917a48c7cSmrg } 7017a48c7cSmrg } 7117a48c7cSmrg } 7217a48c7cSmrg 7317a48c7cSmrg if(num_adaptors) 7417a48c7cSmrg xf86XVScreenInit(pScreen, adaptors, num_adaptors); 7517a48c7cSmrg 7617a48c7cSmrg if(freeAdaptors) 7717a48c7cSmrg xfree(adaptors); 7817a48c7cSmrg} 7917a48c7cSmrg 8017a48c7cSmrg#ifndef APM_VIDEO_DEFINES 8117a48c7cSmrg#define APM_VIDEO_DEFINES 8217a48c7cSmrg 8317a48c7cSmrgstatic Atom xvBrightness, xvContrast; 8417a48c7cSmrg 8517a48c7cSmrg/* client libraries expect an encoding */ 8617a48c7cSmrgstatic XF86VideoEncodingRec DummyEncoding[1] = 8717a48c7cSmrg{ 8817a48c7cSmrg { 8917a48c7cSmrg 0, 9017a48c7cSmrg "XV_IMAGE", 9117a48c7cSmrg 1024, 1024, 9217a48c7cSmrg {1, 1} 9317a48c7cSmrg } 9417a48c7cSmrg}; 9517a48c7cSmrg 9617a48c7cSmrg#define NUM_FORMATS 24 9717a48c7cSmrg 9817a48c7cSmrgstatic XF86VideoFormatRec Formats[NUM_FORMATS] = 9917a48c7cSmrg{ 10017a48c7cSmrg { 8, PseudoColor}, 10117a48c7cSmrg {15, PseudoColor}, 10217a48c7cSmrg {16, PseudoColor}, 10317a48c7cSmrg {24, PseudoColor}, 10417a48c7cSmrg {32, PseudoColor}, 10517a48c7cSmrg { 8, DirectColor}, 10617a48c7cSmrg {15, DirectColor}, 10717a48c7cSmrg {16, DirectColor}, 10817a48c7cSmrg {24, DirectColor}, 10917a48c7cSmrg {32, DirectColor}, 11017a48c7cSmrg { 8, TrueColor}, 11117a48c7cSmrg {15, TrueColor}, 11217a48c7cSmrg {16, TrueColor}, 11317a48c7cSmrg {24, TrueColor}, 11417a48c7cSmrg {32, TrueColor} 11517a48c7cSmrg}; 11617a48c7cSmrg 11717a48c7cSmrg#define NUM_ATTRIBUTES 2 11817a48c7cSmrg 11917a48c7cSmrgstatic XF86AttributeRec Attributes[NUM_ATTRIBUTES] = 12017a48c7cSmrg{ 12117a48c7cSmrg {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"}, 12217a48c7cSmrg {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"} 12317a48c7cSmrg}; 12417a48c7cSmrg 12517a48c7cSmrg#define NUM_IMAGES 9 12617a48c7cSmrgtypedef char c8; 12717a48c7cSmrg 12817a48c7cSmrgstatic XF86ImageRec Images[NUM_IMAGES] = 12917a48c7cSmrg{ 13017a48c7cSmrg { 13117a48c7cSmrg 0x35315652, 13217a48c7cSmrg XvRGB, 13317a48c7cSmrg LSBFirst, 13417a48c7cSmrg {'R','V','1','5', 13517a48c7cSmrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 13617a48c7cSmrg 16, 13717a48c7cSmrg XvPacked, 13817a48c7cSmrg 1, 13917a48c7cSmrg 15, 0x001F, 0x03E0, 0x7C00, 14017a48c7cSmrg 0, 0, 0, 14117a48c7cSmrg 0, 0, 0, 14217a48c7cSmrg 0, 0, 0, 14317a48c7cSmrg {'R','V','B',0, 14417a48c7cSmrg 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}, 14517a48c7cSmrg XvTopToBottom 14617a48c7cSmrg }, 14717a48c7cSmrg { 14817a48c7cSmrg 0x36315652, 14917a48c7cSmrg XvRGB, 15017a48c7cSmrg LSBFirst, 15117a48c7cSmrg {'R','V','1','6', 15217a48c7cSmrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 15317a48c7cSmrg 16, 15417a48c7cSmrg XvPacked, 15517a48c7cSmrg 1, 15617a48c7cSmrg 16, 0x001F, 0x07E0, 0xF800, 15717a48c7cSmrg 0, 0, 0, 15817a48c7cSmrg 0, 0, 0, 15917a48c7cSmrg 0, 0, 0, 16017a48c7cSmrg {'R','V','B',0, 16117a48c7cSmrg 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}, 16217a48c7cSmrg XvTopToBottom 16317a48c7cSmrg }, 16417a48c7cSmrg { 16517a48c7cSmrg 0x32335652, 16617a48c7cSmrg XvRGB, 16717a48c7cSmrg LSBFirst, 16817a48c7cSmrg {'R','V','3','2', 16917a48c7cSmrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 17017a48c7cSmrg 32, 17117a48c7cSmrg XvPacked, 17217a48c7cSmrg 1, 17317a48c7cSmrg 24, 0x0000FF, 0x00FF00, 0xFF0000, 17417a48c7cSmrg 0, 0, 0, 17517a48c7cSmrg 0, 0, 0, 17617a48c7cSmrg 0, 0, 0, 17717a48c7cSmrg {'R','V','B',0, 17817a48c7cSmrg 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}, 17917a48c7cSmrg XvTopToBottom 18017a48c7cSmrg }, 18117a48c7cSmrg XVIMAGE_YUY2, 18217a48c7cSmrg { 18317a48c7cSmrg 0x59595959, 18417a48c7cSmrg XvYUV, 18517a48c7cSmrg LSBFirst, 18617a48c7cSmrg {0x00,0x00,0x00,0x00, 18717a48c7cSmrg 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, 18817a48c7cSmrg 8, 18917a48c7cSmrg XvPacked, 19017a48c7cSmrg 1, 19117a48c7cSmrg 0, 0, 0, 0, 19217a48c7cSmrg 8, 0, 0, 19317a48c7cSmrg 1, 1, 1, 19417a48c7cSmrg 1, 1, 1, 19517a48c7cSmrg {'Y','Y','Y','Y', 19617a48c7cSmrg 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}, 19717a48c7cSmrg XvTopToBottom 19817a48c7cSmrg }, 19917a48c7cSmrg { 20017a48c7cSmrg 0x32315659, 20117a48c7cSmrg XvYUV, 20217a48c7cSmrg LSBFirst, 20317a48c7cSmrg {'Y','V','1','2', 20417a48c7cSmrg 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 20517a48c7cSmrg 12, 20617a48c7cSmrg XvPlanar, 20717a48c7cSmrg 3, 20817a48c7cSmrg 0, 0, 0, 0 , 20917a48c7cSmrg 8, 8, 8, 21017a48c7cSmrg 1, 2, 2, 21117a48c7cSmrg 1, 2, 2, 21217a48c7cSmrg {'Y','V','U', 21317a48c7cSmrg 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,0}, 21417a48c7cSmrg XvTopToBottom 21517a48c7cSmrg }, 21617a48c7cSmrg { 21717a48c7cSmrg 0x59565955, 21817a48c7cSmrg XvYUV, 21917a48c7cSmrg LSBFirst, 22017a48c7cSmrg {'U','Y','V','Y', 22117a48c7cSmrg 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 22217a48c7cSmrg 16, 22317a48c7cSmrg XvPlanar, 22417a48c7cSmrg 1, 22517a48c7cSmrg 0, 0, 0, 0, 22617a48c7cSmrg 8, 8, 8, 22717a48c7cSmrg 1, 2, 2, 22817a48c7cSmrg 1, 1, 1, 22917a48c7cSmrg {'U','Y','V','Y', 23017a48c7cSmrg 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}, 23117a48c7cSmrg XvTopToBottom 23217a48c7cSmrg }, 23317a48c7cSmrg { 23417a48c7cSmrg 0x55595659, 23517a48c7cSmrg XvYUV, 23617a48c7cSmrg LSBFirst, 23717a48c7cSmrg {'Y','V','Y','U', 23817a48c7cSmrg 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 23917a48c7cSmrg 16, 24017a48c7cSmrg XvPlanar, 24117a48c7cSmrg 1, 24217a48c7cSmrg 0, 0, 0, 0, 24317a48c7cSmrg 8, 8, 8, 24417a48c7cSmrg 1, 2, 2, 24517a48c7cSmrg 1, 1, 1, 24617a48c7cSmrg {'Y','V','Y','U', 24717a48c7cSmrg 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}, 24817a48c7cSmrg XvTopToBottom 24917a48c7cSmrg }, 25017a48c7cSmrg { 25117a48c7cSmrg 0x59555956, 25217a48c7cSmrg XvYUV, 25317a48c7cSmrg LSBFirst, 25417a48c7cSmrg {'V','Y','U','Y', 25517a48c7cSmrg 0x00,0x00,0x00,0x10,(c8)0x80,0x00,0x00,(c8)0xAA,0x00,0x38,(c8)0x9B,0x71}, 25617a48c7cSmrg 16, 25717a48c7cSmrg XvPlanar, 25817a48c7cSmrg 1, 25917a48c7cSmrg 0, 0, 0, 0, 26017a48c7cSmrg 8, 8, 8, 26117a48c7cSmrg 1, 2, 2, 26217a48c7cSmrg 1, 1, 1, 26317a48c7cSmrg {'V','Y','U','Y', 26417a48c7cSmrg 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}, 26517a48c7cSmrg XvTopToBottom 26617a48c7cSmrg } 26717a48c7cSmrg}; 26817a48c7cSmrg 26917a48c7cSmrgtypedef struct { 27017a48c7cSmrg Bool on; 27117a48c7cSmrg unsigned char brightness; 27217a48c7cSmrg unsigned char contrast; 27317a48c7cSmrg unsigned short reg, val; 27417a48c7cSmrg ApmPtr pApm; 27517a48c7cSmrg int x1, x10, y1, drw_x, drw_y, Bpp, Bps; 27617a48c7cSmrg FBAreaPtr area; 27717a48c7cSmrg RegionRec clip; 27817a48c7cSmrg int xnum, xden, ynum, yden; 27917a48c7cSmrg CARD32 scalex, scaley; 28017a48c7cSmrg CARD32 data; 28117a48c7cSmrg} ApmPortPrivRec, *ApmPortPrivPtr; 28217a48c7cSmrg#endif 28317a48c7cSmrg 28417a48c7cSmrg 28517a48c7cSmrgstatic void 28617a48c7cSmrgA(ResetVideo)(ScrnInfoPtr pScrn) 28717a48c7cSmrg{ 28817a48c7cSmrg APMDECL(pScrn); 28917a48c7cSmrg 29017a48c7cSmrg A(WaitForFifo)(pApm, 2); 29117a48c7cSmrg ((ApmPortPrivPtr)pApm->adaptor->pPortPrivates[0].ptr)->on = 0; 29217a48c7cSmrg ((ApmPortPrivPtr)pApm->adaptor->pPortPrivates[1].ptr)->on = 0; 29317a48c7cSmrg WRXW(0x82, 0); 29417a48c7cSmrg WRXW(0x92, 0); 29517a48c7cSmrg} 29617a48c7cSmrg 29717a48c7cSmrg 29817a48c7cSmrgstatic XF86VideoAdaptorPtr 29917a48c7cSmrgA(SetupImageVideo)(ScreenPtr pScreen) 30017a48c7cSmrg{ 30117a48c7cSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 30217a48c7cSmrg APMDECL(pScrn); 30317a48c7cSmrg XF86VideoAdaptorPtr adapt; 30417a48c7cSmrg ApmPortPrivPtr pPriv; 30517a48c7cSmrg 30617a48c7cSmrg if(!(adapt = xcalloc(1, sizeof(XF86VideoAdaptorRec) + 30717a48c7cSmrg 2 * sizeof(ApmPortPrivRec) + 30817a48c7cSmrg 2 * sizeof(DevUnion)))) 30917a48c7cSmrg return NULL; 31017a48c7cSmrg 31117a48c7cSmrg adapt->type = XvWindowMask | XvInputMask | XvImageMask; 31217a48c7cSmrg adapt->flags = VIDEO_OVERLAID_IMAGES; 31317a48c7cSmrg adapt->name = "Alliance Pro Motion video engine"; 31417a48c7cSmrg adapt->nEncodings = 1; 31517a48c7cSmrg adapt->pEncodings = DummyEncoding; 31617a48c7cSmrg adapt->nFormats = NUM_FORMATS; 31717a48c7cSmrg adapt->pFormats = Formats; 31817a48c7cSmrg adapt->nPorts = 2; 31917a48c7cSmrg adapt->pPortPrivates = (DevUnion*)(&adapt[1]); 32017a48c7cSmrg pPriv = (ApmPortPrivPtr)(&adapt->pPortPrivates[2]); 32117a48c7cSmrg pPriv->pApm = pApm; 32217a48c7cSmrg pPriv[1].pApm = pApm; 32317a48c7cSmrg pPriv->reg = 0x82; 32417a48c7cSmrg pPriv[1].reg = 0x92; 32517a48c7cSmrg adapt->pPortPrivates[0].ptr = (pointer)(pPriv); 32617a48c7cSmrg adapt->pPortPrivates[1].ptr = (pointer)(pPriv + 1); 32717a48c7cSmrg adapt->nAttributes = NUM_ATTRIBUTES; 32817a48c7cSmrg adapt->pAttributes = Attributes; 32917a48c7cSmrg adapt->nImages = NUM_IMAGES; 33017a48c7cSmrg adapt->pImages = Images; 33117a48c7cSmrg adapt->PutVideo = NULL; 33217a48c7cSmrg adapt->PutStill = NULL; 33317a48c7cSmrg adapt->GetVideo = NULL; 33417a48c7cSmrg adapt->GetStill = NULL; 33517a48c7cSmrg adapt->StopVideo = A(StopVideo); 33617a48c7cSmrg adapt->SetPortAttribute = A(SetPortAttribute); 33717a48c7cSmrg adapt->GetPortAttribute = ApmGetPortAttribute; 33817a48c7cSmrg adapt->QueryBestSize = ApmQueryBestSize; 33917a48c7cSmrg adapt->PutImage = A(PutImage); 34017a48c7cSmrg adapt->ReputImage = A(ReputImage); 34117a48c7cSmrg adapt->QueryImageAttributes = ApmQueryImageAttributes; 34217a48c7cSmrg 34317a48c7cSmrg pPriv->brightness = 0; 34417a48c7cSmrg pPriv->contrast = 128; 34517a48c7cSmrg pPriv[1].brightness = 0; 34617a48c7cSmrg pPriv[1].contrast = 128; 34717a48c7cSmrg 34817a48c7cSmrg /* gotta uninit this someplace */ 34917a48c7cSmrg REGION_NULL(pScreen, &pPriv->clip); 35017a48c7cSmrg REGION_NULL(pScreen, &(pPriv + 1)->clip); 35117a48c7cSmrg 35217a48c7cSmrg pApm->adaptor = adapt; 35317a48c7cSmrg 35417a48c7cSmrg xvBrightness = MAKE_ATOM("XV_BRIGHTNESS"); 35517a48c7cSmrg xvContrast = MAKE_ATOM("XV_CONTRAST"); 35617a48c7cSmrg 35717a48c7cSmrg A(ResetVideo)(pScrn); 35817a48c7cSmrg 35917a48c7cSmrg return adapt; 36017a48c7cSmrg} 36117a48c7cSmrg 36217a48c7cSmrg#ifndef IOP_ACCESS 36317a48c7cSmrg/* ApmClipVideo - 36417a48c7cSmrg 36517a48c7cSmrg Takes the dst box in standard X BoxRec form (top and left 36617a48c7cSmrg edges inclusive, bottom and right exclusive). The new dst 36717a48c7cSmrg box is returned. The source boundaries are given (x1, y1 36817a48c7cSmrg inclusive, x2, y2 exclusive) and returned are the new source 36917a48c7cSmrg boundaries in 16.16 fixed point. 37017a48c7cSmrg 37117a48c7cSmrg extents is the extents of the clip region 37217a48c7cSmrg*/ 37317a48c7cSmrg 37417a48c7cSmrgstatic void 37517a48c7cSmrgApmClipVideo(BoxPtr dst, INT32 *x1, INT32 *x2, INT32 *y1, INT32 *y2, 37617a48c7cSmrg BoxPtr extents, INT32 width, INT32 height, 37717a48c7cSmrg CARD32 *scalex, CARD32 *scaley, INT32 mask) 37817a48c7cSmrg{ 37917a48c7cSmrg INT32 vscale, hscale; 38017a48c7cSmrg int diff; 38117a48c7cSmrg 38217a48c7cSmrg if (dst->x2 - dst->x1 < *x2 - *x1) 38317a48c7cSmrg dst->x2 = dst->x1 + *x2 - *x1; 38417a48c7cSmrg 38517a48c7cSmrg if (dst->y2 - dst->y1 < *y2 - *y1) 38617a48c7cSmrg dst->y2 = dst->y1 + *y2 - *y1; 38717a48c7cSmrg 38817a48c7cSmrg *x1 <<= 12; *x2 <<= 16; 38917a48c7cSmrg *y1 <<= 12; *y2 <<= 16; 39017a48c7cSmrg 39117a48c7cSmrg hscale = (*x2 - *x1) / (dst->x2 - dst->x1); 39217a48c7cSmrg vscale = (*y2 - *y1) / (dst->y2 - dst->y1); 39317a48c7cSmrg 39417a48c7cSmrg diff = extents->x1 - dst->x1; 39517a48c7cSmrg if(diff > 0) { 39617a48c7cSmrg dst->x1 = extents->x1; 39717a48c7cSmrg *x1 += diff * hscale; 39817a48c7cSmrg } 39917a48c7cSmrg diff = dst->x2 - extents->x2; 40017a48c7cSmrg if(diff > 0) { 40117a48c7cSmrg dst->x2 = extents->x2; 40217a48c7cSmrg *x2 -= diff * hscale; 40317a48c7cSmrg } 40417a48c7cSmrg diff = extents->y1 - dst->y1; 40517a48c7cSmrg if(diff > 0) { 40617a48c7cSmrg dst->y1 = extents->y1; 40717a48c7cSmrg *y1 += diff * vscale; 40817a48c7cSmrg } 40917a48c7cSmrg diff = dst->y2 - extents->y2; 41017a48c7cSmrg if(diff > 0) { 41117a48c7cSmrg dst->y2 = extents->y2; 41217a48c7cSmrg *y2 -= diff * vscale; 41317a48c7cSmrg } 41417a48c7cSmrg 41517a48c7cSmrg if (*x2 - *x1 == 0x10000 * (dst->x2 - dst->x1)) /* Shrinking */ 41617a48c7cSmrg *scalex = 0; 41717a48c7cSmrg else 41817a48c7cSmrg *scalex = ((*x2 - *x1) / (dst->x2 - dst->x1)) >> 4; 41917a48c7cSmrg if (*y2 - *y1 == 0x10000 * (dst->y2 - dst->y1)) /* Shrinking */ 42017a48c7cSmrg *scaley = 0; 42117a48c7cSmrg else 42217a48c7cSmrg *scaley = ((*y2 - *y1) / (dst->y2 - dst->y1)) >> 4; 42317a48c7cSmrg} 42417a48c7cSmrg#endif 42517a48c7cSmrg 42617a48c7cSmrgstatic void 42717a48c7cSmrgA(StopVideo)(ScrnInfoPtr pScrn, pointer data, Bool shutdown) 42817a48c7cSmrg{ 42917a48c7cSmrg ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 43017a48c7cSmrg APMDECL(pScrn); 43117a48c7cSmrg 43217a48c7cSmrg REGION_EMPTY(pScrn->pScreen, &pPriv->clip); 43317a48c7cSmrg 43417a48c7cSmrg pPriv->on = 0; 43517a48c7cSmrg A(WaitForFifo)(pApm, 1); 43617a48c7cSmrg WRXB(pPriv->reg, 0); 43717a48c7cSmrg} 43817a48c7cSmrg 43917a48c7cSmrgstatic int 44017a48c7cSmrgA(SetPortAttribute)(ScrnInfoPtr pScrn, Atom attribute, INT32 value, 44117a48c7cSmrg pointer data) 44217a48c7cSmrg{ 44317a48c7cSmrg ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 44417a48c7cSmrg /*APMDECL(pScrn);*/ 44517a48c7cSmrg 44617a48c7cSmrg if(attribute == xvBrightness) { 44717a48c7cSmrg if((value < -128) || (value > 127)) 44817a48c7cSmrg return BadValue; 44917a48c7cSmrg pPriv->brightness = value; 45017a48c7cSmrg /* TODO : enable */ 45117a48c7cSmrg } else if(attribute == xvContrast) { 45217a48c7cSmrg if((value < 0) || (value > 255)) 45317a48c7cSmrg return BadValue; 45417a48c7cSmrg pPriv->contrast = value; 45517a48c7cSmrg /* TODO : enable */ 45617a48c7cSmrg } 45717a48c7cSmrg 45817a48c7cSmrg return Success; 45917a48c7cSmrg} 46017a48c7cSmrg 46117a48c7cSmrg#ifndef IOP_ACCESS 46217a48c7cSmrgstatic int 46317a48c7cSmrgApmGetPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, 46417a48c7cSmrg pointer data) 46517a48c7cSmrg{ 46617a48c7cSmrg ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 46717a48c7cSmrg 46817a48c7cSmrg if(attribute == xvBrightness) { 46917a48c7cSmrg *value = pPriv->brightness; 47017a48c7cSmrg } else 47117a48c7cSmrg if(attribute == xvContrast) { 47217a48c7cSmrg *value = pPriv->contrast; 47317a48c7cSmrg } 47417a48c7cSmrg 47517a48c7cSmrg return Success; 47617a48c7cSmrg} 47717a48c7cSmrg 47817a48c7cSmrgstatic void 47917a48c7cSmrgApmQueryBestSize(ScrnInfoPtr pScrn, Bool motion, short vid_w, short vid_h, 48017a48c7cSmrg short drw_w, short drw_h, 48117a48c7cSmrg unsigned int *p_w, unsigned int *p_h, pointer data) 48217a48c7cSmrg{ 48317a48c7cSmrg APMDECL(pScrn); 48417a48c7cSmrg unsigned short round = ~pApm->CurrentLayout.mask32; 48517a48c7cSmrg 48617a48c7cSmrg *p_w = drw_w & round; 48717a48c7cSmrg *p_h = drw_h & round; 48817a48c7cSmrg} 48917a48c7cSmrg#endif 49017a48c7cSmrg 49117a48c7cSmrgstatic void A(XvMoveCB)(FBAreaPtr area1, FBAreaPtr area2) 49217a48c7cSmrg{ 49317a48c7cSmrg ApmPortPrivPtr pPriv = (ApmPortPrivPtr)area1->devPrivate.ptr; 49417a48c7cSmrg ApmPtr pApm = pPriv->pApm; 49517a48c7cSmrg 49617a48c7cSmrg pPriv->on = 0; 49717a48c7cSmrg A(WaitForFifo)(pApm, 1); 49817a48c7cSmrg WRXB(pPriv->reg, 0); /* Stop video for this port */ 49917a48c7cSmrg pPriv->area = area2; 50017a48c7cSmrg} 50117a48c7cSmrg 50217a48c7cSmrgstatic void A(XvRemoveCB)(FBAreaPtr area) 50317a48c7cSmrg{ 50417a48c7cSmrg ApmPortPrivPtr pPriv = (ApmPortPrivPtr)area->devPrivate.ptr; 50517a48c7cSmrg ApmPtr pApm = pPriv->pApm; 50617a48c7cSmrg 50717a48c7cSmrg pPriv->on = 0; 50817a48c7cSmrg A(WaitForFifo)(pApm, 1); 50917a48c7cSmrg WRXB(pPriv->reg, 0); /* Stop video for this port */ 51017a48c7cSmrg pPriv->area = NULL; 51117a48c7cSmrg} 51217a48c7cSmrg 51317a48c7cSmrgstatic int 51417a48c7cSmrgA(ReputImage)(ScrnInfoPtr pScrn, short drw_x, short drw_y, 51517a48c7cSmrg RegionPtr clipBoxes, pointer pdata, DrawablePtr pDraw) 51617a48c7cSmrg{ 51717a48c7cSmrg ScreenPtr pScreen = pScrn->pScreen; 51817a48c7cSmrg APMDECL(pScrn); 51917a48c7cSmrg ApmPortPrivPtr pPriv = pdata, pPriv0, pPriv1; 52017a48c7cSmrg register int fx, fy; 52117a48c7cSmrg CARD32 mask; 52217a48c7cSmrg RegionRec Union; 52317a48c7cSmrg RegionPtr reg0; 52417a48c7cSmrg int nrects, CurrY, tile; 52517a48c7cSmrg int X1, X2, Y1, y2, xmax, ymax; 52617a48c7cSmrg BoxPtr rects; 52717a48c7cSmrg Bool didit = 0; 52817a48c7cSmrg 52917a48c7cSmrg mask = pApm->CurrentLayout.mask32; 53017a48c7cSmrg fx = pScrn->frameX0 & ~mask; 53117a48c7cSmrg fy = pScrn->frameY0 + 1; 53217a48c7cSmrg REGION_COPY(pScreen, &pPriv->clip, clipBoxes); 53317a48c7cSmrg pPriv->x1 += drw_x - pPriv->drw_x; 53417a48c7cSmrg pPriv->x10 = ((pPriv->x1 + mask) & ~mask) - fx; 53517a48c7cSmrg pPriv->y1 += drw_y - pPriv->drw_y; 53617a48c7cSmrg pPriv->drw_x = drw_x; 53717a48c7cSmrg pPriv->drw_y = drw_y; 53817a48c7cSmrg A(WaitForFifo)(pApm, 2); 53917a48c7cSmrg WRXW(pPriv->reg + 0x06, 0xFFF - ((pPriv->scalex * pPriv->x10) & 0xFFF)); 54017a48c7cSmrg WRXW(pPriv->reg + 0x0A, 0xFFF - ((pPriv->scaley * pPriv->y1) & 0xFFF)); 54117a48c7cSmrg pPriv0 = (ApmPortPrivPtr)pApm->adaptor->pPortPrivates[0].ptr; 54217a48c7cSmrg pPriv1 = (ApmPortPrivPtr)pApm->adaptor->pPortPrivates[1].ptr; 54317a48c7cSmrg reg0 = &pPriv0->clip; 54417a48c7cSmrg bzero(&Union, sizeof Union); 54517a48c7cSmrg REGION_EMPTY(pScreen, &Union); 54617a48c7cSmrg REGION_NULL(pScreen, &Union); 54717a48c7cSmrg REGION_UNION(pScreen, &Union, reg0, &pPriv1->clip); 54817a48c7cSmrg nrects = REGION_NUM_RECTS(&Union); 54917a48c7cSmrg rects = REGION_RECTS(&Union); 55017a48c7cSmrg tile = 0x200; 55117a48c7cSmrg xmax = pScrn->frameX1 - pScrn->frameX0 + 1; 55217a48c7cSmrg ymax = pScrn->frameY1 - pScrn->frameY0; 55317a48c7cSmrg CurrY = -1; 55417a48c7cSmrg goto BEGIN_LOOP_1; 55517a48c7cSmrg do { 55617a48c7cSmrg rects++; 55717a48c7cSmrgBEGIN_LOOP_1: 55817a48c7cSmrg X1 = ((rects->x1 + mask) & ~mask) - fx; 55917a48c7cSmrg if (X1 < 0) 56017a48c7cSmrg X1 = 0; 56117a48c7cSmrg X2 = (rects->x2 & ~mask) - fx; 56217a48c7cSmrg if (X2 > xmax) 56317a48c7cSmrg X2 = xmax; 56417a48c7cSmrg y2 = rects->y2 - fy; 56517a48c7cSmrg } while ((X2 <= X1 || y2 < -1) && --nrects > 0); 56617a48c7cSmrg Y1 = rects->y1 - fy; 56717a48c7cSmrg 56817a48c7cSmrg while (!(STATUS() & 0x800)); 56917a48c7cSmrg while (STATUS() & 0x800); 57017a48c7cSmrg while (nrects-- > 0) { 57117a48c7cSmrg CARD32 reg, data; 57217a48c7cSmrg int x1, x2, y1; 57317a48c7cSmrg 57417a48c7cSmrg x1 = X1; 57517a48c7cSmrg x2 = X2; 57617a48c7cSmrg y1 = Y1; 57717a48c7cSmrg if (y1 < -1) y1 = -1; 57817a48c7cSmrg if (y1 > ymax) 57917a48c7cSmrg break; 58017a48c7cSmrg didit = 1; 58117a48c7cSmrg if (y1 > CurrY) { 58217a48c7cSmrg A(WaitForFifo)(pApm, 3); 58317a48c7cSmrg WRXL(tile + 0x00, 0xFFF0011); 58417a48c7cSmrg WRXL(tile + 0x04, y1 << 16); 58517a48c7cSmrg WRXL(tile + 0x08, 0); 58617a48c7cSmrg tile += 16; 58717a48c7cSmrg } 58817a48c7cSmrg if (RECT_IN_REGION(pScreen, reg0, rects)) { 58917a48c7cSmrg pPriv = pPriv0; 59017a48c7cSmrg reg = (x1 << 16) | 1; 59117a48c7cSmrg } 59217a48c7cSmrg else { 59317a48c7cSmrg pPriv = pPriv1; 59417a48c7cSmrg reg = (x1 << 16) | 2; 59517a48c7cSmrg } 59617a48c7cSmrg CurrY = y2; 59717a48c7cSmrg if (nrects <= 0) 59817a48c7cSmrg goto BEGIN_LOOP_2; 59917a48c7cSmrg do { 60017a48c7cSmrg rects++; 60117a48c7cSmrgBEGIN_LOOP_2: 60217a48c7cSmrg X1 = ((rects->x1 + mask) & ~mask) - fx; 60317a48c7cSmrg if (X1 < 0) 60417a48c7cSmrg X1 = 0; 60517a48c7cSmrg X2 = (rects->x2 & ~mask) - fx; 60617a48c7cSmrg if (X2 > xmax) 60717a48c7cSmrg X2 = xmax; 60817a48c7cSmrg } while (X2 <= X1 && --nrects > 0); 60917a48c7cSmrg Y1 = rects->y1 - fy; 61017a48c7cSmrg y2 = rects->y2 - fy; 61117a48c7cSmrg data = pPriv->data + (((x1 - pPriv->x10) 61217a48c7cSmrg * pPriv->xden) / pPriv->xnum) * pPriv->Bpp + 61317a48c7cSmrg (((y1 - pPriv->y1 + fy) * pPriv->yden) / pPriv->ynum) * pPriv->Bps; 61417a48c7cSmrg A(WaitForFifo)(pApm, 4); 61517a48c7cSmrg if (!nrects || tile == 0x2B0 || y1 < Y1) { 61617a48c7cSmrg WRXL(tile , 0x10 | reg); 61717a48c7cSmrg } 61817a48c7cSmrg else { 61917a48c7cSmrg WRXL(tile , reg); 62017a48c7cSmrg } 62117a48c7cSmrg WRXL(tile + 0x04, x2 | (CurrY << 16)); 62217a48c7cSmrg WRXL(tile + 0x08, (((x2-x1)*pPriv->xden+pPriv->xnum-1) / pPriv->xnum) | 62317a48c7cSmrg (data << 16)); 62417a48c7cSmrg WRXB(tile + 0x0C, data >> 16); 62517a48c7cSmrg tile += 16; 62617a48c7cSmrg if (tile == 0x2C0) { 62717a48c7cSmrg tile = 0x200; 62817a48c7cSmrg break; 62917a48c7cSmrg } 63017a48c7cSmrg } 63117a48c7cSmrg REGION_UNINIT(pScreen, &Union); 63217a48c7cSmrg 63317a48c7cSmrg if (didit) { 63417a48c7cSmrg A(WaitForFifo)(pApm, 1); 63517a48c7cSmrg WRXW(0x8E, tile - 0x200); 63617a48c7cSmrg } 63717a48c7cSmrg 63817a48c7cSmrg if (didit ^ ((pPriv0->val | pPriv1->val) & 1)) { 63917a48c7cSmrg if (didit) { 64017a48c7cSmrg pPriv0->val |= 1; 64117a48c7cSmrg pPriv1->val |= 1; 64217a48c7cSmrg } 64317a48c7cSmrg else { 64417a48c7cSmrg pPriv0->val &= 0xFFFE; 64517a48c7cSmrg pPriv1->val &= 0xFFFE; 64617a48c7cSmrg } 64717a48c7cSmrg if (pPriv0->on) { 64817a48c7cSmrg A(WaitForFifo)(pApm, 1); 64917a48c7cSmrg WRXW(0x82, pPriv0->val); 65017a48c7cSmrg } 65117a48c7cSmrg if (pPriv1->on) { 65217a48c7cSmrg A(WaitForFifo)(pApm, 1); 65317a48c7cSmrg WRXW(0x92, pPriv1->val); 65417a48c7cSmrg } 65517a48c7cSmrg } 65617a48c7cSmrg 65717a48c7cSmrg return Success; 65817a48c7cSmrg} 65917a48c7cSmrg 66017a48c7cSmrgstatic int 66117a48c7cSmrgA(PutImage)(ScrnInfoPtr pScrn, short src_x, short src_y, 66217a48c7cSmrg short drw_x, short drw_y, short src_w, short src_h, 66317a48c7cSmrg short drw_w, short drw_h, int id, unsigned char* buf, 66417a48c7cSmrg short width, short height, Bool sync, RegionPtr clipBoxes, 66517a48c7cSmrg pointer data, DrawablePtr pDraw) 66617a48c7cSmrg{ 66717a48c7cSmrg ApmPortPrivPtr pPriv = (ApmPortPrivPtr)data; 66817a48c7cSmrg ScreenPtr pScreen = pScrn->pScreen; 66917a48c7cSmrg APMDECL(pScrn); 67017a48c7cSmrg INT32 x1, x2, y1, y2; 67117a48c7cSmrg unsigned char *dst_start; 67217a48c7cSmrg int pitch, Bpp, new_h, offset = 0, offset2 = 0, offset3 = 0; 67317a48c7cSmrg CARD32 mask; 67417a48c7cSmrg FBAreaPtr area; 67517a48c7cSmrg int srcPitch, dstPitch, srcPitch2 = 0; 67617a48c7cSmrg int top, left, npixels, nlines; 67717a48c7cSmrg BoxRec dstBox; 67817a48c7cSmrg CARD32 scalex, scaley, scale; 67917a48c7cSmrg CARD32 tmp; 68017a48c7cSmrg Bool offscreen; 68117a48c7cSmrg 68217a48c7cSmrg offscreen = (buf < (unsigned char *)pApm->FbBase || 68317a48c7cSmrg buf > (unsigned char *)pApm->FbBase + 0x400000); 68417a48c7cSmrg 68517a48c7cSmrg if(drw_w > 16384) drw_w = 16384; 68617a48c7cSmrg 68717a48c7cSmrg /* Clip */ 68817a48c7cSmrg x1 = src_x; 68917a48c7cSmrg x2 = src_x + src_w; 69017a48c7cSmrg y1 = src_y; 69117a48c7cSmrg y2 = src_y + src_h; 69217a48c7cSmrg 69317a48c7cSmrg dstBox.x1 = drw_x; 69417a48c7cSmrg dstBox.x2 = drw_x + drw_w; 69517a48c7cSmrg dstBox.y1 = drw_y; 69617a48c7cSmrg dstBox.y2 = drw_y + drw_h; 69717a48c7cSmrg 69817a48c7cSmrg mask = pApm->CurrentLayout.mask32; 69917a48c7cSmrg 70017a48c7cSmrg ApmClipVideo(&dstBox, &x1, &x2, &y1, &y2, 70117a48c7cSmrg REGION_EXTENTS(pScreen, clipBoxes), width, height, 70217a48c7cSmrg &scalex, &scaley, mask); 70317a48c7cSmrg 70417a48c7cSmrg pPriv->drw_x = drw_x; 70517a48c7cSmrg pPriv->drw_y = drw_y; 70617a48c7cSmrg pPriv->xnum = drw_w; 70717a48c7cSmrg if (scalex) 70817a48c7cSmrg pPriv->xden = src_w; 70917a48c7cSmrg else 71017a48c7cSmrg pPriv->xden = drw_w; /* If image is larger than window */ 71117a48c7cSmrg pPriv->ynum = drw_h; 71217a48c7cSmrg if (scaley) 71317a48c7cSmrg pPriv->yden = src_h; 71417a48c7cSmrg else 71517a48c7cSmrg pPriv->yden = drw_h; 71617a48c7cSmrg if((x1 - x2 >= 0xFFFF) || (y1 - y2 >= 0xFFFF)) 71717a48c7cSmrg return Success; 71817a48c7cSmrg 71917a48c7cSmrg Bpp = pScrn->bitsPerPixel >> 3; 72017a48c7cSmrg pitch = Bpp * pScrn->displayWidth; 72117a48c7cSmrg 72217a48c7cSmrg switch(id) { 72317a48c7cSmrg case 0x32315659: 72417a48c7cSmrg dstPitch = ((width << 1) + 3) & ~3; 72517a48c7cSmrg srcPitch = (width + 3) & ~3; 72617a48c7cSmrg offset2 = srcPitch * height; 72717a48c7cSmrg srcPitch2 = ((width >> 1) + 3) & ~3; 72817a48c7cSmrg offset = srcPitch2 * (height >> 1); 72917a48c7cSmrg offset3 = offset + offset2; 73017a48c7cSmrg new_h = (2 * offset2 + pitch - 1) / pitch; 73117a48c7cSmrg break; 73217a48c7cSmrg case 0x59595959: 73317a48c7cSmrg srcPitch = width; 73417a48c7cSmrg dstPitch = (srcPitch + 3) & ~3; 73517a48c7cSmrg offset = dstPitch * height; 73617a48c7cSmrg new_h = (offset + pitch - 1) / pitch; 73717a48c7cSmrg break; 73817a48c7cSmrg case 0x32335652: 73917a48c7cSmrg srcPitch = (width << 2); 74017a48c7cSmrg dstPitch = (srcPitch + 3) & ~3; 74117a48c7cSmrg offset = dstPitch * height; 74217a48c7cSmrg new_h = (offset + pitch - 1) / pitch; 74317a48c7cSmrg break; 74417a48c7cSmrg default: 74517a48c7cSmrg if (pApm->PutImageStride) 74617a48c7cSmrg srcPitch = pApm->PutImageStride; 74717a48c7cSmrg else 74817a48c7cSmrg srcPitch = (width << 1); 74917a48c7cSmrg dstPitch = (srcPitch + 3) & ~3; 75017a48c7cSmrg offset = dstPitch * height; 75117a48c7cSmrg new_h = (offset + pitch - 1) / pitch; 75217a48c7cSmrg break; 75317a48c7cSmrg } 75417a48c7cSmrg 75517a48c7cSmrg area = pPriv->area; 75617a48c7cSmrg 75717a48c7cSmrg /* Allocate offscreen memory */ 75817a48c7cSmrg if (offscreen && (!area || ((area->box.y2 - area->box.y1) < new_h))) { 75917a48c7cSmrg Bool nukeMem = FALSE; 76017a48c7cSmrg int max_w, max_h; 76117a48c7cSmrg 76217a48c7cSmrg xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, 76317a48c7cSmrg FAVOR_WIDTH_THEN_AREA, PRIORITY_LOW); 76417a48c7cSmrg if (max_w == pScrn->displayWidth && max_h >= new_h) { 76517a48c7cSmrg area = xf86AllocateOffscreenArea(pScreen, 76617a48c7cSmrg pScrn->displayWidth, new_h, 76717a48c7cSmrg 4, A(XvMoveCB), A(XvRemoveCB), pPriv); 76817a48c7cSmrg if (area) { 76917a48c7cSmrg if (pPriv->area) 77017a48c7cSmrg xf86FreeOffscreenArea(pPriv->area); 77117a48c7cSmrg } 77217a48c7cSmrg else 77317a48c7cSmrg area = pPriv->area; /* Should not happen */ 77417a48c7cSmrg } 77517a48c7cSmrg if(!area) { 77617a48c7cSmrg if(!(area = xf86AllocateOffscreenArea(pScreen, 77717a48c7cSmrg pScrn->displayWidth, new_h, 4, 77817a48c7cSmrg A(XvMoveCB), A(XvRemoveCB), pPriv))) 77917a48c7cSmrg { 78017a48c7cSmrg nukeMem = TRUE; 78117a48c7cSmrg } 78217a48c7cSmrg } else { 78317a48c7cSmrg if(!xf86ResizeOffscreenArea(area, pScrn->displayWidth, new_h)) { 78417a48c7cSmrg xf86FreeOffscreenArea(area); 78517a48c7cSmrg pPriv->area = area = NULL; 78617a48c7cSmrg nukeMem = TRUE; 78717a48c7cSmrg } 78817a48c7cSmrg } 78917a48c7cSmrg if(nukeMem) { 79017a48c7cSmrg xf86QueryLargestOffscreenArea(pScreen, &max_w, &max_h, 0, 79117a48c7cSmrg FAVOR_WIDTH_THEN_AREA, PRIORITY_EXTREME); 79217a48c7cSmrg 79317a48c7cSmrg if((max_w < pScrn->displayWidth) || (max_h < new_h)) 79417a48c7cSmrg return BadAlloc; 79517a48c7cSmrg 79617a48c7cSmrg xf86PurgeUnlockedOffscreenAreas(pScreen); 79717a48c7cSmrg 79817a48c7cSmrg area = xf86AllocateOffscreenArea(pScreen, 79917a48c7cSmrg pScrn->displayWidth, new_h, 4, 80017a48c7cSmrg A(XvMoveCB), A(XvRemoveCB), pPriv); 80117a48c7cSmrg } 80217a48c7cSmrg 80317a48c7cSmrg pPriv->area = area; 80417a48c7cSmrg } 80517a48c7cSmrg 80617a48c7cSmrg /* copy data */ 80717a48c7cSmrg pPriv->x1 = dstBox.x1 /*drw_x*/; 80817a48c7cSmrg pPriv->y1 = dstBox.y1 /*drw_y*/; 80917a48c7cSmrg top = y1 >> 16; 81017a48c7cSmrg left = (x1 >> 16) & ~1; 81117a48c7cSmrg npixels = ((((x2 + 0xffff) >> 16) + 1) & ~1) - left; 81217a48c7cSmrg 81317a48c7cSmrg switch(id) { 81417a48c7cSmrg case 0x59595959: 81517a48c7cSmrg pPriv->Bpp = 1; 81617a48c7cSmrg break; 81717a48c7cSmrg default: 81817a48c7cSmrg pPriv->Bpp = 2; 81917a48c7cSmrg left <<= 1; 82017a48c7cSmrg break; 82117a48c7cSmrg case 0x32335652: 82217a48c7cSmrg pPriv->Bpp = 4; 82317a48c7cSmrg left <<= 2; 82417a48c7cSmrg break; 82517a48c7cSmrg } 82617a48c7cSmrg pPriv->Bps = pPriv->Bpp * pPriv->xden; 82717a48c7cSmrg if (offscreen) { 82817a48c7cSmrg offset = (area->box.y1 * pitch) + (top * dstPitch); 82917a48c7cSmrg dst_start = ((unsigned char *)pApm->FbBase) + 83017a48c7cSmrg (pPriv->data = offset + left); 83117a48c7cSmrg switch(id) { 83217a48c7cSmrg case 0x32315659: 83317a48c7cSmrg top &= ~1; 83417a48c7cSmrg tmp = ((top >> 1) * srcPitch2) + (left >> 2); 83517a48c7cSmrg offset2 += tmp; 83617a48c7cSmrg offset3 += tmp; 83717a48c7cSmrg nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top; 83817a48c7cSmrg xf86XVCopyYUV12ToPacked(buf + (top * srcPitch) + (left >> 1), 83917a48c7cSmrg buf + offset2, buf + offset3, dst_start, 84017a48c7cSmrg srcPitch, srcPitch2, dstPitch, 84117a48c7cSmrg nlines, npixels); 84217a48c7cSmrg break; 84317a48c7cSmrg default: 84417a48c7cSmrg if (id == 0x32335652) 84517a48c7cSmrg npixels <<= 1; 84617a48c7cSmrg else if (id == 0x59595959) 84717a48c7cSmrg npixels >>= 1; 84817a48c7cSmrg buf += (top * srcPitch) + left; 84917a48c7cSmrg nlines = ((y2 + 0xffff) >> 16) - top; 85017a48c7cSmrg if (offscreen) 85117a48c7cSmrg xf86XVCopyPacked(buf, dst_start, srcPitch, dstPitch, 85217a48c7cSmrg nlines, npixels); 85317a48c7cSmrg break; 85417a48c7cSmrg } 85517a48c7cSmrg } 85617a48c7cSmrg else 85717a48c7cSmrg pPriv->data = buf - (unsigned char *)pApm->FbBase; 85817a48c7cSmrg pPriv->on = 1; 85917a48c7cSmrg A(WaitForFifo)(pApm, 3); 86017a48c7cSmrg WRXW(pPriv->reg + 0x02, dstPitch >> 2); 86117a48c7cSmrg WRXW(pPriv->reg + 0x04, scalex); 86217a48c7cSmrg WRXW(pPriv->reg + 0x08, scaley); 86317a48c7cSmrg pPriv->scalex = scalex; 86417a48c7cSmrg pPriv->scaley = scaley; 86517a48c7cSmrg if (scalex && scaley) 86617a48c7cSmrg scale = 0x0E00; 86717a48c7cSmrg else if (scalex) 86817a48c7cSmrg scale = 0x0600; 86917a48c7cSmrg else if (scaley) 87017a48c7cSmrg scale = 0x0A00; 87117a48c7cSmrg else 87217a48c7cSmrg scale = 0; 87317a48c7cSmrg switch(id) { 87417a48c7cSmrg case 0x59595959: 87517a48c7cSmrg pPriv->val = 0x017B | scale; 87617a48c7cSmrg break; 87717a48c7cSmrg case 0x32335652: 87817a48c7cSmrg pPriv->val = 0x002F | (scale & 0xF7FF);/*Smoothing filter doesn't work*/ 87917a48c7cSmrg break; 88017a48c7cSmrg case 0x36315652: 88117a48c7cSmrg pPriv->val = 0x002B | (scale & 0xF7FF); 88217a48c7cSmrg break; 88317a48c7cSmrg case 0x35315652: 88417a48c7cSmrg pPriv->val = 0x0029 | (scale & 0xF7FF); 88517a48c7cSmrg break; 88617a48c7cSmrg case 0x59555956: 88717a48c7cSmrg pPriv->val = 0x013B | scale; 88817a48c7cSmrg break; 88917a48c7cSmrg case 0x55595659: 89017a48c7cSmrg pPriv->val = 0x014B | scale; 89117a48c7cSmrg break; 89217a48c7cSmrg case 0x32315659: 89317a48c7cSmrg case 0x59565955: 89417a48c7cSmrg default: 89517a48c7cSmrg pPriv->val = 0x016B | scale; 89617a48c7cSmrg break; 89717a48c7cSmrg } 89817a48c7cSmrg 89917a48c7cSmrg (void) A(ReputImage)(pScrn, drw_x, drw_y, clipBoxes, data, pDraw); 90017a48c7cSmrg 90117a48c7cSmrg A(WaitForFifo)(pApm, 1); 90217a48c7cSmrg WRXW(pPriv->reg, pPriv->val); 90317a48c7cSmrg 90417a48c7cSmrg return Success; 90517a48c7cSmrg} 90617a48c7cSmrg 90717a48c7cSmrg#ifndef IOP_ACCESS 90817a48c7cSmrgstatic int 90917a48c7cSmrgApmQueryImageAttributes(ScrnInfoPtr pScrn, int id, 91017a48c7cSmrg unsigned short *w, unsigned short *h, 91117a48c7cSmrg int *pitches, int *offsets) 91217a48c7cSmrg{ 91317a48c7cSmrg int size, tmp; 91417a48c7cSmrg 91517a48c7cSmrg if(*w > 1024) *w = 1024; 91617a48c7cSmrg if(*h > 1024) *h = 1024; 91717a48c7cSmrg 91817a48c7cSmrg *w = (*w + 1) & ~1; 91917a48c7cSmrg if(offsets) offsets[0] = 0; 92017a48c7cSmrg 92117a48c7cSmrg switch(id) { 92217a48c7cSmrg case 0x32315659: 92317a48c7cSmrg *h = (*h + 1) & ~1; 92417a48c7cSmrg size = (*w + 3) & ~3; 92517a48c7cSmrg if(pitches) pitches[0] = size; 92617a48c7cSmrg size *= *h; 92717a48c7cSmrg if(offsets) offsets[1] = size; 92817a48c7cSmrg tmp = ((*w >> 1) + 3) & ~3; 92917a48c7cSmrg if(pitches) pitches[1] = pitches[2] = tmp; 93017a48c7cSmrg tmp *= (*h >> 1); 93117a48c7cSmrg size += tmp; 93217a48c7cSmrg if(offsets) offsets[2] = size; 93317a48c7cSmrg size += tmp; 93417a48c7cSmrg break; 93517a48c7cSmrg case 0x59565955: 93617a48c7cSmrg case 0x55595659: 93717a48c7cSmrg case 0x59555956: 93817a48c7cSmrg case 0x32595559: 93917a48c7cSmrg size = *w << 1; 94017a48c7cSmrg goto common; 94117a48c7cSmrg case 0x59595959: 94217a48c7cSmrg default: 94317a48c7cSmrg size = *w; 94417a48c7cSmrgcommon: 94517a48c7cSmrg if (pitches) 94617a48c7cSmrg pitches[0] = size; 94717a48c7cSmrg size *= *h; 94817a48c7cSmrg break; 94917a48c7cSmrg } 95017a48c7cSmrg 95117a48c7cSmrg return size; 95217a48c7cSmrg} 95317a48c7cSmrg#endif 95417a48c7cSmrg#endif 955