smi_xaa.c revision 09885543
109885543Smrg/* 209885543SmrgCopyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 309885543SmrgCopyright (C) 2000 Silicon Motion, Inc. All Rights Reserved. 409885543Smrg 509885543SmrgPermission is hereby granted, free of charge, to any person obtaining a copy of 609885543Smrgthis software and associated documentation files (the "Software"), to deal in 709885543Smrgthe Software without restriction, including without limitation the rights to 809885543Smrguse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 909885543Smrgof the Software, and to permit persons to whom the Software is furnished to do 1009885543Smrgso, subject to the following conditions: 1109885543Smrg 1209885543SmrgThe above copyright notice and this permission notice shall be included in all 1309885543Smrgcopies or substantial portions of the Software. 1409885543Smrg 1509885543SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1609885543SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT- 1709885543SmrgNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1809885543SmrgXFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1909885543SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2009885543SmrgWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2109885543Smrg 2209885543SmrgExcept as contained in this notice, the names of the XFree86 Project and 2309885543SmrgSilicon Motion shall not be used in advertising or otherwise to promote the 2409885543Smrgsale, use or other dealings in this Software without prior written 2509885543Smrgauthorization from the XFree86 Project and silicon Motion. 2609885543Smrg*/ 2709885543Smrg 2809885543Smrg#ifdef HAVE_CONFIG_H 2909885543Smrg#include "config.h" 3009885543Smrg#endif 3109885543Smrg 3209885543Smrg#include "smi.h" 3309885543Smrg 3409885543Smrg#include "miline.h" 3509885543Smrg#include "xaalocal.h" 3609885543Smrg#include "xaarop.h" 3709885543Smrg#include "servermd.h" 3809885543Smrg 3909885543Smrgstatic void SMI_SetupForScreenToScreenCopy(ScrnInfoPtr, int, int, int, 4009885543Smrg unsigned int, int); 4109885543Smrgstatic void SMI_SubsequentScreenToScreenCopy(ScrnInfoPtr, int, int, int, int, 4209885543Smrg int, int); 4309885543Smrgstatic void SMI_SetupForSolidFill(ScrnInfoPtr, int, int, unsigned); 4409885543Smrgstatic void SMI_SubsequentSolidFillRect(ScrnInfoPtr, int, int, int, int); 4509885543Smrgstatic void SMI_SubsequentSolidHorVertLine(ScrnInfoPtr, int, int, int, int); 4609885543Smrgstatic void SMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int, 4709885543Smrg unsigned int); 4809885543Smrgstatic void SMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr, int, int, int, 4909885543Smrg int, int); 5009885543Smrgstatic void SMI_SetupForMono8x8PatternFill(ScrnInfoPtr, int, int, int, int, int, 5109885543Smrg unsigned int); 5209885543Smrgstatic void SMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr, int, int, int, 5309885543Smrg int, int, int); 5409885543Smrgstatic void SMI_SetupForColor8x8PatternFill(ScrnInfoPtr, int, int, int, 5509885543Smrg unsigned int, int); 5609885543Smrgstatic void SMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr, int, int, int, 5709885543Smrg int, int, int); 5809885543Smrg#if SMI_USE_IMAGE_WRITES 5909885543Smrgstatic void SMI_SetupForImageWrite(ScrnInfoPtr, int, unsigned int, int, int, 6009885543Smrg int); 6109885543Smrgstatic void SMI_SubsequentImageWriteRect(ScrnInfoPtr, int, int, int, int, int); 6209885543Smrg#endif 6309885543Smrg/* #671 */ 6409885543Smrgstatic void SMI_ValidatePolylines(GCPtr, unsigned long, DrawablePtr); 6509885543Smrgstatic void SMI_Polylines(DrawablePtr, GCPtr, int, int, DDXPointPtr); 6609885543Smrg 6709885543Smrg 6809885543SmrgBool 6909885543SmrgSMI_XAAInit(ScreenPtr pScreen) 7009885543Smrg{ 7109885543Smrg XAAInfoRecPtr infoPtr; 7209885543Smrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 7309885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 7409885543Smrg /*BoxRec AvailFBArea;*/ 7509885543Smrg Bool ret; 7609885543Smrg /*int numLines, maxLines;*/ 7709885543Smrg 7809885543Smrg ENTER_PROC("SMI_XAAInit"); 7909885543Smrg 8009885543Smrg pSmi->XAAInfoRec = infoPtr = XAACreateInfoRec(); 8109885543Smrg if (infoPtr == NULL) { 8209885543Smrg LEAVE_PROC("SMI_AccelInit"); 8309885543Smrg return FALSE; 8409885543Smrg } 8509885543Smrg 8609885543Smrg infoPtr->Flags = PIXMAP_CACHE 8709885543Smrg | LINEAR_FRAMEBUFFER 8809885543Smrg | OFFSCREEN_PIXMAPS; 8909885543Smrg 9009885543Smrg infoPtr->Sync = SMI_AccelSync; 9109885543Smrg 9209885543Smrg /* Screen to screen copies */ 9309885543Smrg infoPtr->ScreenToScreenCopyFlags = NO_PLANEMASK 9409885543Smrg | ONLY_TWO_BITBLT_DIRECTIONS; 9509885543Smrg infoPtr->SetupForScreenToScreenCopy = SMI_SetupForScreenToScreenCopy; 9609885543Smrg infoPtr->SubsequentScreenToScreenCopy = SMI_SubsequentScreenToScreenCopy; 9709885543Smrg if (pScrn->bitsPerPixel == 24) { 9809885543Smrg infoPtr->ScreenToScreenCopyFlags |= NO_TRANSPARENCY; 9909885543Smrg } 10009885543Smrg if ((pSmi->Chipset == SMI_LYNX3D) && (pScrn->bitsPerPixel == 8)) { 10109885543Smrg infoPtr->ScreenToScreenCopyFlags |= GXCOPY_ONLY; 10209885543Smrg } 10309885543Smrg 10409885543Smrg /* Solid Fills */ 10509885543Smrg infoPtr->SolidFillFlags = NO_PLANEMASK; 10609885543Smrg infoPtr->SetupForSolidFill = SMI_SetupForSolidFill; 10709885543Smrg infoPtr->SubsequentSolidFillRect = SMI_SubsequentSolidFillRect; 10809885543Smrg 10909885543Smrg /* Solid Lines */ 11009885543Smrg infoPtr->SolidLineFlags = NO_PLANEMASK; 11109885543Smrg infoPtr->SetupForSolidLine = SMI_SetupForSolidFill; 11209885543Smrg infoPtr->SubsequentSolidHorVertLine = SMI_SubsequentSolidHorVertLine; 11309885543Smrg 11409885543Smrg /* Color Expansion Fills */ 11509885543Smrg infoPtr->CPUToScreenColorExpandFillFlags = ROP_NEEDS_SOURCE 11609885543Smrg | NO_PLANEMASK 11709885543Smrg | BIT_ORDER_IN_BYTE_MSBFIRST 11809885543Smrg | LEFT_EDGE_CLIPPING 11909885543Smrg | CPU_TRANSFER_PAD_DWORD 12009885543Smrg | SCANLINE_PAD_DWORD; 12109885543Smrg infoPtr->ColorExpandBase = pSmi->DataPortBase; 12209885543Smrg infoPtr->ColorExpandRange = pSmi->DataPortSize; 12309885543Smrg infoPtr->SetupForCPUToScreenColorExpandFill = 12409885543Smrg SMI_SetupForCPUToScreenColorExpandFill; 12509885543Smrg infoPtr->SubsequentCPUToScreenColorExpandFill = 12609885543Smrg SMI_SubsequentCPUToScreenColorExpandFill; 12709885543Smrg 12809885543Smrg /* 8x8 Mono Pattern Fills */ 12909885543Smrg infoPtr->Mono8x8PatternFillFlags = NO_PLANEMASK 13009885543Smrg | HARDWARE_PATTERN_PROGRAMMED_BITS 13109885543Smrg | HARDWARE_PATTERN_SCREEN_ORIGIN 13209885543Smrg | BIT_ORDER_IN_BYTE_MSBFIRST; 13309885543Smrg infoPtr->SetupForMono8x8PatternFill = SMI_SetupForMono8x8PatternFill; 13409885543Smrg infoPtr->SubsequentMono8x8PatternFillRect = 13509885543Smrg SMI_SubsequentMono8x8PatternFillRect; 13609885543Smrg 13709885543Smrg /* 8x8 Color Pattern Fills */ 13809885543Smrg if (!SMI_LYNX3D_SERIES(pSmi->Chipset) || (pScrn->bitsPerPixel != 24)) { 13909885543Smrg infoPtr->Color8x8PatternFillFlags = NO_PLANEMASK 14009885543Smrg | HARDWARE_PATTERN_SCREEN_ORIGIN; 14109885543Smrg infoPtr->SetupForColor8x8PatternFill = 14209885543Smrg SMI_SetupForColor8x8PatternFill; 14309885543Smrg infoPtr->SubsequentColor8x8PatternFillRect = 14409885543Smrg SMI_SubsequentColor8x8PatternFillRect; 14509885543Smrg } 14609885543Smrg 14709885543Smrg#if SMI_USE_IMAGE_WRITES 14809885543Smrg /* Image Writes */ 14909885543Smrg infoPtr->ImageWriteFlags = ROP_NEEDS_SOURCE 15009885543Smrg | NO_PLANEMASK 15109885543Smrg | CPU_TRANSFER_PAD_DWORD 15209885543Smrg | SCANLINE_PAD_DWORD; 15309885543Smrg infoPtr->ImageWriteBase = pSmi->DataPortBase; 15409885543Smrg infoPtr->ImageWriteRange = pSmi->DataPortSize; 15509885543Smrg infoPtr->SetupForImageWrite = SMI_SetupForImageWrite; 15609885543Smrg infoPtr->SubsequentImageWriteRect = SMI_SubsequentImageWriteRect; 15709885543Smrg#endif 15809885543Smrg 15909885543Smrg /* Clipping */ 16009885543Smrg infoPtr->ClippingFlags = HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY 16109885543Smrg | HARDWARE_CLIP_MONO_8x8_FILL 16209885543Smrg | HARDWARE_CLIP_COLOR_8x8_FILL 16309885543Smrg | HARDWARE_CLIP_SOLID_FILL 16409885543Smrg | HARDWARE_CLIP_SOLID_LINE 16509885543Smrg | HARDWARE_CLIP_DASHED_LINE; 16609885543Smrg infoPtr->SetClippingRectangle = SMI_SetClippingRectangle; 16709885543Smrg infoPtr->DisableClipping = SMI_DisableClipping; 16809885543Smrg 16909885543Smrg /* Pixmap Cache */ 17009885543Smrg if (pScrn->bitsPerPixel == 24) { 17109885543Smrg infoPtr->CachePixelGranularity = 16; 17209885543Smrg } else { 17309885543Smrg infoPtr->CachePixelGranularity = 128 / pScrn->bitsPerPixel; 17409885543Smrg } 17509885543Smrg 17609885543Smrg /* Offscreen Pixmaps */ 17709885543Smrg infoPtr->maxOffPixWidth = 4096; 17809885543Smrg infoPtr->maxOffPixHeight = 4096; 17909885543Smrg if (pScrn->bitsPerPixel == 24) { 18009885543Smrg infoPtr->maxOffPixWidth = 4096 / 3; 18109885543Smrg 18209885543Smrg if (pSmi->Chipset == SMI_LYNX) { 18309885543Smrg infoPtr->maxOffPixHeight = 4096 / 3; 18409885543Smrg } 18509885543Smrg } 18609885543Smrg 18709885543Smrg SMI_EngineReset(pScrn); 18809885543Smrg 18909885543Smrg 19009885543Smrg /* CZ 18.06.2001: moved to smi_driver.c before the NoAccel question 19109885543Smrg to have offscreen framebuffer in NoAccel mode */ 19209885543Smrg#if 0 19309885543Smrg maxLines = pSmi->FBReserved / (pSmi->width * pSmi->Bpp); 19409885543Smrg if (pSmi->rotate) { 19509885543Smrg numLines = maxLines; 19609885543Smrg } else { 19709885543Smrg#if SMI_USE_VIDEO 19809885543Smrg numLines = ((pSmi->FBReserved - pSmi->width * pSmi->Bpp * pSmi->height) 19909885543Smrg * 25 / 100 + pSmi->width * pSmi->Bpp - 1) 20009885543Smrg / (pSmi->width * pSmi->Bpp); 20109885543Smrg numLines += pSmi->height; 20209885543Smrg#else 20309885543Smrg numLines = maxLines; 20409885543Smrg#endif 20509885543Smrg } 20609885543Smrg 20709885543Smrg AvailFBArea.x1 = 0; 20809885543Smrg AvailFBArea.y1 = 0; 20909885543Smrg AvailFBArea.x2 = pSmi->width; 21009885543Smrg AvailFBArea.y2 = numLines; 21109885543Smrg xf86DrvMsg(pScrn->scrnIndex, X_INFO, "FrameBuffer Box: %d,%d - %d,%d\n", 21209885543Smrg AvailFBArea.x1, AvailFBArea.y1, AvailFBArea.x2, AvailFBArea.y2); 21309885543Smrg xf86InitFBManager(pScreen, &AvailFBArea); 21409885543Smrg#endif 21509885543Smrg 21609885543Smrg ret = XAAInit(pScreen, infoPtr); 21709885543Smrg if (ret && pSmi->shadowFB) /* #671 */ { 21809885543Smrg pSmi->ValidatePolylines = infoPtr->ValidatePolylines; 21909885543Smrg infoPtr->ValidatePolylines = SMI_ValidatePolylines; 22009885543Smrg } 22109885543Smrg 22209885543Smrg LEAVE_PROC("SMI_XAAInit"); 22309885543Smrg return ret; 22409885543Smrg} 22509885543Smrg 22609885543Smrg/******************************************************************************/ 22709885543Smrg/* Screen to Screen Copies */ 22809885543Smrg/******************************************************************************/ 22909885543Smrg 23009885543Smrgstatic void 23109885543SmrgSMI_SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir, int rop, 23209885543Smrg unsigned int planemask, int trans) 23309885543Smrg{ 23409885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 23509885543Smrg 23609885543Smrg ENTER_PROC("SMI_SetupForScreenToScreenCopy"); 23709885543Smrg DEBUG((VERBLEV, "xdir=%d ydir=%d rop=%02X trans=%08X\n", xdir, ydir, 23809885543Smrg rop, trans)); 23909885543Smrg 24009885543Smrg pSmi->AccelCmd = XAAGetCopyROP(rop) 24109885543Smrg | SMI_BITBLT 24209885543Smrg | SMI_START_ENGINE; 24309885543Smrg 24409885543Smrg if ((xdir == -1) || (ydir == -1)) { 24509885543Smrg pSmi->AccelCmd |= SMI_RIGHT_TO_LEFT; 24609885543Smrg } 24709885543Smrg 24809885543Smrg if (trans != -1) { 24909885543Smrg pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL; 25009885543Smrg WaitQueue(1); 25109885543Smrg WRITE_DPR(pSmi, 0x20, trans); 25209885543Smrg } 25309885543Smrg 25409885543Smrg if (pSmi->ClipTurnedOn) { 25509885543Smrg WaitQueue(1); 25609885543Smrg WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft); 25709885543Smrg pSmi->ClipTurnedOn = FALSE; 25809885543Smrg } 25909885543Smrg 26009885543Smrg LEAVE_PROC("SMI_SetupForScreenToScreenCopy"); 26109885543Smrg} 26209885543Smrg 26309885543Smrgstatic void 26409885543SmrgSMI_SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int x1, int y1, int x2, 26509885543Smrg int y2, int w, int h) 26609885543Smrg{ 26709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 26809885543Smrg 26909885543Smrg ENTER_PROC("SMI_SubsequentScreenToScreenCopy"); 27009885543Smrg DEBUG((VERBLEV, "x1=%d y1=%d x2=%d y2=%d w=%d h=%d\n", x1, y1, x2, y2, w, h)); 27109885543Smrg 27209885543Smrg if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 27309885543Smrg x1 += w - 1; 27409885543Smrg y1 += h - 1; 27509885543Smrg x2 += w - 1; 27609885543Smrg y2 += h - 1; 27709885543Smrg } 27809885543Smrg 27909885543Smrg if (pScrn->bitsPerPixel == 24) { 28009885543Smrg x1 *= 3; 28109885543Smrg x2 *= 3; 28209885543Smrg w *= 3; 28309885543Smrg 28409885543Smrg if (pSmi->Chipset == SMI_LYNX) { 28509885543Smrg y1 *= 3; 28609885543Smrg y2 *= 3; 28709885543Smrg } 28809885543Smrg 28909885543Smrg if (pSmi->AccelCmd & SMI_RIGHT_TO_LEFT) { 29009885543Smrg x1 += 2; 29109885543Smrg x2 += 2; 29209885543Smrg } 29309885543Smrg } 29409885543Smrg 29509885543Smrg WaitQueue(4); 29609885543Smrg WRITE_DPR(pSmi, 0x00, (x1 << 16) + (y1 & 0xFFFF)); 29709885543Smrg WRITE_DPR(pSmi, 0x04, (x2 << 16) + (y2 & 0xFFFF)); 29809885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) + (h & 0xFFFF)); 29909885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 30009885543Smrg 30109885543Smrg LEAVE_PROC("SMI_SubsequentScreenToScreenCopy"); 30209885543Smrg} 30309885543Smrg 30409885543Smrg/******************************************************************************/ 30509885543Smrg/* Solid Fills */ 30609885543Smrg/******************************************************************************/ 30709885543Smrg 30809885543Smrgstatic void 30909885543SmrgSMI_SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, 31009885543Smrg unsigned int planemask) 31109885543Smrg{ 31209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 31309885543Smrg 31409885543Smrg ENTER_PROC("SMI_SetupForSolidFill"); 31509885543Smrg DEBUG((VERBLEV, "color=%08X rop=%02X\n", color, rop)); 31609885543Smrg 31709885543Smrg pSmi->AccelCmd = XAAGetPatternROP(rop) 31809885543Smrg | SMI_BITBLT 31909885543Smrg | SMI_START_ENGINE; 32009885543Smrg 32109885543Smrg if (pSmi->ClipTurnedOn) { 32209885543Smrg WaitQueue(4); 32309885543Smrg WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft); 32409885543Smrg pSmi->ClipTurnedOn = FALSE; 32509885543Smrg } else { 32609885543Smrg WaitQueue(3); 32709885543Smrg } 32809885543Smrg WRITE_DPR(pSmi, 0x14, color); 32909885543Smrg WRITE_DPR(pSmi, 0x34, 0xFFFFFFFF); 33009885543Smrg WRITE_DPR(pSmi, 0x38, 0xFFFFFFFF); 33109885543Smrg 33209885543Smrg LEAVE_PROC("SMI_SetupForSolidFill"); 33309885543Smrg} 33409885543Smrg 33509885543Smrgvoid 33609885543SmrgSMI_SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) 33709885543Smrg{ 33809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 33909885543Smrg 34009885543Smrg ENTER_PROC("SMI_SubsequentSolidFillRect"); 34109885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h)); 34209885543Smrg 34309885543Smrg if (pScrn->bitsPerPixel == 24) { 34409885543Smrg x *= 3; 34509885543Smrg w *= 3; 34609885543Smrg 34709885543Smrg if (pSmi->Chipset == SMI_LYNX) { 34809885543Smrg y *= 3; 34909885543Smrg } 35009885543Smrg } 35109885543Smrg 35209885543Smrg WaitQueue(3); 35309885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 35409885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 35509885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 35609885543Smrg 35709885543Smrg LEAVE_PROC("SMI_SubsequentSolidFillRect"); 35809885543Smrg} 35909885543Smrg 36009885543Smrg/******************************************************************************/ 36109885543Smrg/* Solid Lines */ 36209885543Smrg/******************************************************************************/ 36309885543Smrg 36409885543Smrgstatic void 36509885543SmrgSMI_SubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, 36609885543Smrg int dir) 36709885543Smrg{ 36809885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 36909885543Smrg int w, h; 37009885543Smrg 37109885543Smrg ENTER_PROC("SMI_SubsequentSolidHorVertLine"); 37209885543Smrg DEBUG((VERBLEV, "x=%d y=%d len=%d dir=%d\n", x, y, len, dir)); 37309885543Smrg 37409885543Smrg if (dir == DEGREES_0) { 37509885543Smrg w = len; 37609885543Smrg h = 1; 37709885543Smrg } else { 37809885543Smrg w = 1; 37909885543Smrg h = len; 38009885543Smrg } 38109885543Smrg 38209885543Smrg if (pScrn->bitsPerPixel == 24) { 38309885543Smrg x *= 3; 38409885543Smrg w *= 3; 38509885543Smrg 38609885543Smrg if (pSmi->Chipset == SMI_LYNX) { 38709885543Smrg y *= 3; 38809885543Smrg } 38909885543Smrg } 39009885543Smrg 39109885543Smrg WaitQueue(3); 39209885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 39309885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 39409885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 39509885543Smrg 39609885543Smrg LEAVE_PROC("SMI_SubsequentSolidHorVertLine"); 39709885543Smrg} 39809885543Smrg 39909885543Smrg/******************************************************************************/ 40009885543Smrg/* Color Expansion Fills */ 40109885543Smrg/******************************************************************************/ 40209885543Smrg 40309885543Smrgstatic void 40409885543SmrgSMI_SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg, int bg, 40509885543Smrg int rop, unsigned int planemask) 40609885543Smrg{ 40709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 40809885543Smrg 40909885543Smrg ENTER_PROC("SMI_SetupForCPUToScreenColorExpandFill"); 41009885543Smrg DEBUG((VERBLEV, "fg=%08X bg=%08X rop=%02X\n", fg, bg, rop)); 41109885543Smrg 41209885543Smrg pSmi->AccelCmd = XAAGetCopyROP(rop) 41309885543Smrg | SMI_HOSTBLT_WRITE 41409885543Smrg | SMI_SRC_MONOCHROME 41509885543Smrg | SMI_START_ENGINE; 41609885543Smrg 41709885543Smrg if (bg == -1) { 41809885543Smrg pSmi->AccelCmd |= SMI_TRANSPARENT_SRC; 41909885543Smrg 42009885543Smrg WaitQueue(3); 42109885543Smrg WRITE_DPR(pSmi, 0x14, fg); 42209885543Smrg WRITE_DPR(pSmi, 0x18, ~fg); 42309885543Smrg WRITE_DPR(pSmi, 0x20, fg); 42409885543Smrg } else { 42509885543Smrg WaitQueue(2); 42609885543Smrg WRITE_DPR(pSmi, 0x14, fg); 42709885543Smrg WRITE_DPR(pSmi, 0x18, bg); 42809885543Smrg } 42909885543Smrg 43009885543Smrg LEAVE_PROC("SMI_SetupForCPUToScreenColorExpandFill"); 43109885543Smrg} 43209885543Smrg 43309885543Smrgvoid 43409885543SmrgSMI_SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int x, int y, int w, 43509885543Smrg int h, int skipleft) 43609885543Smrg{ 43709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 43809885543Smrg 43909885543Smrg ENTER_PROC("SMI_SubsequentCPUToScreenColorExpandFill"); 44009885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft)); 44109885543Smrg 44209885543Smrg if (pScrn->bitsPerPixel == 24) { 44309885543Smrg x *= 3; 44409885543Smrg w *= 3; 44509885543Smrg skipleft *= 3; 44609885543Smrg 44709885543Smrg if (pSmi->Chipset == SMI_LYNX) { 44809885543Smrg y *= 3; 44909885543Smrg } 45009885543Smrg } 45109885543Smrg 45209885543Smrg if (skipleft) { 45309885543Smrg WaitQueue(5); 45409885543Smrg WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) 45509885543Smrg | (x + skipleft) | 0x2000); 45609885543Smrg pSmi->ClipTurnedOn = TRUE; 45709885543Smrg } else { 45809885543Smrg if (pSmi->ClipTurnedOn) { 45909885543Smrg WaitQueue(5); 46009885543Smrg WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft); 46109885543Smrg pSmi->ClipTurnedOn = FALSE; 46209885543Smrg } else { 46309885543Smrg WaitQueue(4); 46409885543Smrg } 46509885543Smrg } 46609885543Smrg WRITE_DPR(pSmi, 0x00, 0); 46709885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 46809885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 46909885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 47009885543Smrg 47109885543Smrg LEAVE_PROC("SMI_SubsequentCPUToScreenColorExpandFill"); 47209885543Smrg} 47309885543Smrg 47409885543Smrg/******************************************************************************/ 47509885543Smrg/* 8x8 Mono Pattern Fills */ 47609885543Smrg/******************************************************************************/ 47709885543Smrg 47809885543Smrgstatic void 47909885543SmrgSMI_SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int fg, 48009885543Smrg int bg, int rop, unsigned int planemask) 48109885543Smrg{ 48209885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 48309885543Smrg 48409885543Smrg ENTER_PROC("SMI_SetupForMono8x8PatternFill"); 48509885543Smrg DEBUG((VERBLEV, "patx=%08X paty=%08X fg=%08X bg=%08X rop=%02X\n", patx, 48609885543Smrg paty, fg, bg, rop)); 48709885543Smrg 48809885543Smrg pSmi->AccelCmd = XAAGetPatternROP(rop) 48909885543Smrg | SMI_BITBLT 49009885543Smrg | SMI_START_ENGINE; 49109885543Smrg 49209885543Smrg if (pSmi->ClipTurnedOn) { 49309885543Smrg WaitQueue(1); 49409885543Smrg WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft); 49509885543Smrg pSmi->ClipTurnedOn = FALSE; 49609885543Smrg } 49709885543Smrg 49809885543Smrg if (bg == -1) { 49909885543Smrg WaitQueue(5); 50009885543Smrg WRITE_DPR(pSmi, 0x14, fg); 50109885543Smrg WRITE_DPR(pSmi, 0x18, ~fg); 50209885543Smrg WRITE_DPR(pSmi, 0x20, fg); 50309885543Smrg WRITE_DPR(pSmi, 0x34, patx); 50409885543Smrg WRITE_DPR(pSmi, 0x38, paty); 50509885543Smrg } else { 50609885543Smrg WaitQueue(4); 50709885543Smrg WRITE_DPR(pSmi, 0x14, fg); 50809885543Smrg WRITE_DPR(pSmi, 0x18, bg); 50909885543Smrg WRITE_DPR(pSmi, 0x34, patx); 51009885543Smrg WRITE_DPR(pSmi, 0x38, paty); 51109885543Smrg } 51209885543Smrg 51309885543Smrg LEAVE_PROC("SMI_SetupForMono8x8PatternFill"); 51409885543Smrg} 51509885543Smrg 51609885543Smrgstatic void 51709885543SmrgSMI_SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 51809885543Smrg int x, int y, int w, int h) 51909885543Smrg{ 52009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 52109885543Smrg 52209885543Smrg ENTER_PROC("SMI_SubsequentMono8x8PatternFillRect"); 52309885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h)); 52409885543Smrg 52509885543Smrg if (pScrn->bitsPerPixel == 24) { 52609885543Smrg x *= 3; 52709885543Smrg w *= 3; 52809885543Smrg if (pSmi->Chipset == SMI_LYNX) { 52909885543Smrg y *= 3; 53009885543Smrg } 53109885543Smrg } 53209885543Smrg 53309885543Smrg WaitQueue(3); 53409885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 53509885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 53609885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 53709885543Smrg 53809885543Smrg LEAVE_PROC("SMI_SubsequentMono8x8PatternFillRect"); 53909885543Smrg} 54009885543Smrg 54109885543Smrg/******************************************************************************/ 54209885543Smrg/* 8x8 Color Pattern Fills */ 54309885543Smrg/******************************************************************************/ 54409885543Smrg 54509885543Smrgstatic void 54609885543SmrgSMI_SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty, int rop, 54709885543Smrg unsigned int planemask, int trans_color) 54809885543Smrg{ 54909885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 55009885543Smrg 55109885543Smrg ENTER_PROC("SMI_SetupForColor8x8PatternFill"); 55209885543Smrg DEBUG((VERBLEV, "patx=%d paty=%d rop=%02X trans_color=%08X\n", patx, paty, 55309885543Smrg rop, trans_color)); 55409885543Smrg 55509885543Smrg pSmi->AccelCmd = XAAGetPatternROP(rop) 55609885543Smrg | SMI_BITBLT 55709885543Smrg | SMI_COLOR_PATTERN 55809885543Smrg | SMI_START_ENGINE; 55909885543Smrg 56009885543Smrg if (pScrn->bitsPerPixel <= 16) { 56109885543Smrg /* PDR#950 */ 56209885543Smrg CARD8* pattern = pSmi->FBBase + (patx + paty * pSmi->Stride) * pSmi->Bpp; 56309885543Smrg 56409885543Smrg WaitIdleEmpty(); 56509885543Smrg WRITE_DPR(pSmi, 0x0C, SMI_BITBLT | SMI_COLOR_PATTERN); 56609885543Smrg memcpy(pSmi->DataPortBase, pattern, 8 * pSmi->Bpp * 8); 56709885543Smrg } else { 56809885543Smrg if (pScrn->bitsPerPixel == 24) { 56909885543Smrg patx *= 3; 57009885543Smrg 57109885543Smrg if (pSmi->Chipset == SMI_LYNX) { 57209885543Smrg paty *= 3; 57309885543Smrg } 57409885543Smrg } 57509885543Smrg 57609885543Smrg WaitQueue(1); 57709885543Smrg WRITE_DPR(pSmi, 0x00, (patx << 16) | (paty & 0xFFFF)); 57809885543Smrg } 57909885543Smrg 58009885543Smrg if (trans_color == -1) { 58109885543Smrg pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL; 58209885543Smrg 58309885543Smrg WaitQueue(1); 58409885543Smrg WRITE_DPR(pSmi, 0x20, trans_color); 58509885543Smrg } 58609885543Smrg 58709885543Smrg if (pSmi->ClipTurnedOn) { 58809885543Smrg WaitQueue(1); 58909885543Smrg WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft); 59009885543Smrg pSmi->ClipTurnedOn = FALSE; 59109885543Smrg } 59209885543Smrg 59309885543Smrg LEAVE_PROC("SMI_SetupForColor8x8PatternFill"); 59409885543Smrg} 59509885543Smrg 59609885543Smrgstatic void 59709885543SmrgSMI_SubsequentColor8x8PatternFillRect(ScrnInfoPtr pScrn, int patx, int paty, 59809885543Smrg int x, int y, int w, int h) 59909885543Smrg{ 60009885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 60109885543Smrg 60209885543Smrg ENTER_PROC("SMI_SubsequentColor8x8PatternFillRect"); 60309885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", x, y, w, h)); 60409885543Smrg 60509885543Smrg if (pScrn->bitsPerPixel == 24) { 60609885543Smrg x *= 3; 60709885543Smrg w *= 3; 60809885543Smrg 60909885543Smrg if (pSmi->Chipset == SMI_LYNX) { 61009885543Smrg y *= 3; 61109885543Smrg } 61209885543Smrg } 61309885543Smrg 61409885543Smrg WaitQueue(3); 61509885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y & 0xFFFF)); 61609885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); /* PDR#950 */ 61709885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 61809885543Smrg 61909885543Smrg LEAVE_PROC("SMI_SubsequentColor8x8PatternFillRect"); 62009885543Smrg} 62109885543Smrg 62209885543Smrg#if SMI_USE_IMAGE_WRITES 62309885543Smrg/******************************************************************************/ 62409885543Smrg/* Image Writes */ 62509885543Smrg/******************************************************************************/ 62609885543Smrg 62709885543Smrgstatic void 62809885543SmrgSMI_SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask, 62909885543Smrg int trans_color, int bpp, int depth) 63009885543Smrg{ 63109885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 63209885543Smrg 63309885543Smrg ENTER_PROC("SMI_SetupForImageWrite"); 63409885543Smrg DEBUG((VERBLEV, "rop=%02X trans_color=%08X bpp=%d depth=%d\n", rop, 63509885543Smrg trans_color, bpp, depth)); 63609885543Smrg 63709885543Smrg pSmi->AccelCmd = XAAGetCopyROP(rop) 63809885543Smrg | SMI_HOSTBLT_WRITE 63909885543Smrg | SMI_START_ENGINE; 64009885543Smrg 64109885543Smrg if (trans_color != -1) { 64209885543Smrg pSmi->AccelCmd |= SMI_TRANSPARENT_SRC | SMI_TRANSPARENT_PXL; 64309885543Smrg 64409885543Smrg WaitQueue(1); 64509885543Smrg WRITE_DPR(pSmi, 0x20, trans_color); 64609885543Smrg } 64709885543Smrg 64809885543Smrg LEAVE_PROC("SMI_SetupForImageWrite"); 64909885543Smrg} 65009885543Smrg 65109885543Smrgstatic void 65209885543SmrgSMI_SubsequentImageWriteRect(ScrnInfoPtr pScrn, int x, int y, int w, int h, 65309885543Smrg int skipleft) 65409885543Smrg{ 65509885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 65609885543Smrg 65709885543Smrg ENTER_PROC("SMI_SubsequentImageWriteRect"); 65809885543Smrg DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d skipleft=%d\n", x, y, w, h, skipleft)); 65909885543Smrg 66009885543Smrg if (pScrn->bitsPerPixel == 24) { 66109885543Smrg x *= 3; 66209885543Smrg w *= 3; 66309885543Smrg skipleft *= 3; 66409885543Smrg 66509885543Smrg if (pSmi->Chipset == SMI_LYNX) { 66609885543Smrg y *= 3; 66709885543Smrg } 66809885543Smrg } 66909885543Smrg 67009885543Smrg if (skipleft) { 67109885543Smrg WaitQueue(5); 67209885543Smrg WRITE_DPR(pSmi, 0x2C, (pSmi->ScissorsLeft & 0xFFFF0000) | 67309885543Smrg (x + skipleft) | 0x2000); 67409885543Smrg pSmi->ClipTurnedOn = TRUE; 67509885543Smrg } else { 67609885543Smrg if (pSmi->ClipTurnedOn) { 67709885543Smrg WaitQueue(5); 67809885543Smrg WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft); 67909885543Smrg pSmi->ClipTurnedOn = FALSE; 68009885543Smrg } else { 68109885543Smrg WaitQueue(4); 68209885543Smrg } 68309885543Smrg } 68409885543Smrg WRITE_DPR(pSmi, 0x00, 0); 68509885543Smrg WRITE_DPR(pSmi, 0x04, (x << 16) | (y * 0xFFFF)); 68609885543Smrg WRITE_DPR(pSmi, 0x08, (w << 16) | (h & 0xFFFF)); 68709885543Smrg WRITE_DPR(pSmi, 0x0C, pSmi->AccelCmd); 68809885543Smrg 68909885543Smrg LEAVE_PROC("SMI_SubsequentImageWriteRect"); 69009885543Smrg} 69109885543Smrg#endif 69209885543Smrg 69309885543Smrg/******************************************************************************/ 69409885543Smrg/* Polylines #671 */ 69509885543Smrg/******************************************************************************/ 69609885543Smrg 69709885543Smrg/* 69809885543Smrg 69909885543SmrgIn order to speed up the "logout" screen in rotated modes, we need to intercept 70009885543Smrgthe Polylines function. Normally, the polylines are drawn and the shadowFB is 70109885543Smrgthen sending a request of the bounding rectangle of those poylines. This should 70209885543Smrgbe okay, if it weren't for the fact that the Gnome logout screen is drawing 70309885543Smrgpolylines in rectangles and this asks for a rotation of the entire rectangle. 70409885543SmrgThis is very slow. 70509885543Smrg 70609885543SmrgTo circumvent this slowness, we intercept the ValidatePolylines function and 70709885543Smrgoverride the default "Fallback" Polylines with our own Polylines function. Our 70809885543SmrgPolylines function first draws the polylines through the original Fallback 70909885543Smrgfunction and then rotates the lines, line by line. We then set a flag and 71009885543Smrgreturn control to the shadowFB which will try to rotate the bounding rectangle. 71109885543SmrgHowever, the flag has been set and the RefreshArea function does nothing but 71209885543Smrgclear the flag so the next Refresh that comes in shoiuld be handled correctly. 71309885543Smrg 71409885543SmrgAll this code improves the speed quite a bit. 71509885543Smrg 71609885543Smrg*/ 71709885543Smrg 71809885543Smrg#define IS_VISIBLE(pWin) \ 71909885543Smrg( \ 72009885543Smrg pScrn->vtSema \ 72109885543Smrg && (((WindowPtr) pWin)->visibility != VisibilityFullyObscured) \ 72209885543Smrg) 72309885543Smrg 72409885543Smrg#define TRIM_BOX(box, pGC) \ 72509885543Smrg{ \ 72609885543Smrg BoxPtr extents = &pGC->pCompositeClip->extents; \ 72709885543Smrg if (box.x1 < extents->x1) box.x1 = extents->x1; \ 72809885543Smrg if (box.y1 < extents->y1) box.y1 = extents->y1; \ 72909885543Smrg if (box.x2 > extents->x2) box.x2 = extents->x2; \ 73009885543Smrg if (box.y2 > extents->y2) box.y2 = extents->y2; \ 73109885543Smrg} 73209885543Smrg 73309885543Smrg#define TRANSLATE_BOX(box, pDraw) \ 73409885543Smrg{ \ 73509885543Smrg box.x1 += pDraw->x; \ 73609885543Smrg box.y1 += pDraw->y; \ 73709885543Smrg box.x2 += pDraw->x; \ 73809885543Smrg box.y2 += pDraw->y; \ 73909885543Smrg} 74009885543Smrg 74109885543Smrg#define BOX_NOT_EMPTY(box) \ 74209885543Smrg ((box.x2 > box.x1) && (box.y2 > box.y1)) 74309885543Smrg 74409885543Smrgstatic void 74509885543SmrgSMI_ValidatePolylines(GCPtr pGC, unsigned long changes, DrawablePtr pDraw) 74609885543Smrg{ 74709885543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 74809885543Smrg SMIPtr pSmi = SMIPTR(infoRec->pScrn); 74909885543Smrg 75009885543Smrg ENTER_PROC("SMI_ValidatePolylines"); 75109885543Smrg 75209885543Smrg pSmi->ValidatePolylines(pGC, changes, pDraw); 75309885543Smrg if (pGC->ops->Polylines == XAAGetFallbackOps()->Polylines) { 75409885543Smrg /* Override the Polylines function with our own Polylines function. */ 75509885543Smrg pGC->ops->Polylines = SMI_Polylines; 75609885543Smrg } 75709885543Smrg 75809885543Smrg LEAVE_PROC("SMI_ValidatePolylines"); 75909885543Smrg} 76009885543Smrg 76109885543Smrgstatic void 76209885543SmrgSMI_Polylines(DrawablePtr pDraw, GCPtr pGC, int mode, int npt, 76309885543Smrg DDXPointPtr pptInit) 76409885543Smrg{ 76509885543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 76609885543Smrg ScrnInfoPtr pScrn = infoRec->pScrn; 76709885543Smrg SMIPtr pSmi = SMIPTR(pScrn); 76809885543Smrg 76909885543Smrg ENTER_PROC("SMI_Polylines"); 77009885543Smrg 77109885543Smrg /* Call the original Polylines function. */ 77209885543Smrg pGC->ops->Polylines = XAAGetFallbackOps()->Polylines; 77309885543Smrg (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit); 77409885543Smrg pGC->ops->Polylines = SMI_Polylines; 77509885543Smrg 77609885543Smrg if (IS_VISIBLE(pDraw) && npt) { 77709885543Smrg /* Allocate a temporary buffer for all segments of the polyline. */ 77809885543Smrg BoxPtr pBox = xnfcalloc(sizeof(BoxRec), npt); 77909885543Smrg int extra = pGC->lineWidth >> 1, box; 78009885543Smrg 78109885543Smrg if (npt > 1) { 78209885543Smrg /* Adjust the extra space required per polyline segment. */ 78309885543Smrg if (pGC->joinStyle == JoinMiter) { 78409885543Smrg extra = 6 * pGC->lineWidth; 78509885543Smrg } else if (pGC->capStyle == CapProjecting) { 78609885543Smrg extra = pGC->lineWidth; 78709885543Smrg } 78809885543Smrg } 78909885543Smrg 79009885543Smrg for (box = 0; --npt;) { 79109885543Smrg /* Setup the bounding box for one polyline segment. */ 79209885543Smrg pBox[box].x1 = pptInit->x; 79309885543Smrg pBox[box].y1 = pptInit->y; 79409885543Smrg pptInit++; 79509885543Smrg pBox[box].x2 = pptInit->x; 79609885543Smrg pBox[box].y2 = pptInit->y; 79709885543Smrg if (mode == CoordModePrevious) { 79809885543Smrg pBox[box].x2 += pBox[box].x1; 79909885543Smrg pBox[box].y2 += pBox[box].y1; 80009885543Smrg } 80109885543Smrg 80209885543Smrg /* Sort coordinates. */ 80309885543Smrg if (pBox[box].x1 > pBox[box].x2) { 80409885543Smrg int tmp = pBox[box].x1; 80509885543Smrg pBox[box].x1 = pBox[box].x2; 80609885543Smrg pBox[box].x2 = tmp; 80709885543Smrg } 80809885543Smrg if (pBox[box].y1 > pBox[box].y2) { 80909885543Smrg int tmp = pBox[box].y1; 81009885543Smrg pBox[box].y1 = pBox[box].y2; 81109885543Smrg pBox[box].y2 = tmp; 81209885543Smrg } 81309885543Smrg 81409885543Smrg /* Add extra space required for each polyline segment. */ 81509885543Smrg pBox[box].x1 -= extra; 81609885543Smrg pBox[box].y1 -= extra; 81709885543Smrg pBox[box].x2 += extra + 1; 81809885543Smrg pBox[box].y2 += extra + 1; 81909885543Smrg 82009885543Smrg /* See if we need to draw this polyline segment. */ 82109885543Smrg TRANSLATE_BOX(pBox[box], pDraw); 82209885543Smrg TRIM_BOX(pBox[box], pGC); 82309885543Smrg if (BOX_NOT_EMPTY(pBox[box])) { 82409885543Smrg box++; 82509885543Smrg } 82609885543Smrg } 82709885543Smrg 82809885543Smrg if (box) { 82909885543Smrg /* Refresh all polyline segments now. */ 83009885543Smrg if (pSmi->Chipset == SMI_COUGAR3DR) { 83109885543Smrg SMI_RefreshArea730(pScrn, box, pBox); 83209885543Smrg } else { 83309885543Smrg SMI_RefreshArea(pScrn, box, pBox); 83409885543Smrg } 83509885543Smrg } 83609885543Smrg 83709885543Smrg /* Free the temporary buffer. */ 83809885543Smrg xfree(pBox); 83909885543Smrg } 84009885543Smrg 84109885543Smrg pSmi->polyLines = TRUE; 84209885543Smrg LEAVE_PROC("SMI_Polylines"); 84309885543Smrg} 84409885543Smrg 845