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