/******************************Module*Header*******************************\ * Module Name: enable.c * * This module contains the functions that enable and disable the * driver, the pdev, and the surface. * * Copyright (c) 1992 Microsoft Corporation * * Copyright (c) 1994 FirePower Systems, Inc. * Modified for FirePower display model by Neil Ogura (9-7-1994) * \**************************************************************************/ /* * Copyright (c) 1995 FirePower Systems, Inc. * DO NOT DISTRIBUTE without permission * * $RCSfile: enable.c $ * $Revision: 1.3 $ * $Date: 1996/05/13 23:17:20 $ * $Locker: $ */ #include "driver.h" PPDEV myPDEV = NULL; // Used for surface identification in HOOKED functions ULONG ScreenBase = 0; // To make sure that surface is on VRAM #define NUMCOLOR 256 #if BUG_5737_WORKAROUND VOID DisplayModeChanged(); #endif // // Define the function table here. // DrvDitherColor & DrvSetPalette are used only in 8 bpp // #if INVESTIGATE #define MAXBANDWIDTH TRUE #define BANDWIDTH TRUE #include #include ULONG oneshot = 0; ULONG traseentry = 0; ULONG breakentry = 0; ULONG traseexit = 0; ULONG breakexit = 0; ULONG dumpparam = 0; #define DRV_HOOKED (FL_DRV_COPYBIT | FL_DRV_BITBLT | FL_DRV_TEXTOUT | FL_DRV_STRTBIT | FL_DRV_PAINT) ULONG paramcheck = DRV_HOOKED; ULONG compare = 0; ULONG donebydrv = 0; ULONG usedrvfunc = DRV_HOOKED ; ULONG useengfunc = FL_DRV_HOOKED & (~DRV_HOOKED); ULONG dbgflg = 0xffffffff; ULONG breakcnt = 0; ULONG flushtest = 0; ULONG comparecount = 0; #define BEFORE_SCREEN 0 #define AFTER_DRV 1 #define AFTER_ENG 2 #define FPSTR_MAX 3 static char *fpstrtbl[FPSTR_MAX] = {"#INVALID#", "ALTERNATE", "WINDING"}; #define ROP_MAX 16 static KEYTABLE bitbltoptbl[ROP_MAX] = {{0x00000000, "BLACKNESS"}, {0x0000FFFF, "WHITENESS"}, {0x0000F0F0, "PATCOPY"}, {0x00000F0F, "NOTPATCOPY"}, {0x0000CCCC, "SOURCE"}, {0x00005555, "DSTINVERT"}, {0x00005a5a, "PATINVERT"}, {0x0000b8b8, "B8OP"}, {0x00006666, "SRCINVERT"}, {0x00008888, "SRCAND"}, {0x0000eeee, "SRCPAINT"}, {0x0000bbbb, "MERGEPAINT"}, {0x00004444, "SRCERASE"}, {0x00001111, "NOTSRCERASE"}, {0x00000a0a, "INVPATANDDEST"}, {0x0000a0a0, "PATANDEST"}}; static ULONG FileNumberBase = 0; #define BUFBLOCK 8 #define PAGEBLOCK 5 #define BUFPAGE (BUFBLOCK*PAGEBLOCK) #define BLOCKSIZE (1024*PAGEBLOCK) #define BUFSIZE (BLOCKSIZE*BUFBLOCK) static CHAR linebuf[BUFSIZE]; static CHAR linebuf2[BUFSIZE]; static CHAR *category[3] = {"BEF", "DRV", "ENG"}; ULONG ScreenMemory = 0; PBYTE ScreenBuf1 = 0; PBYTE ScreenBuf2 = 0; extern const BYTE gaMix[]; #define PAINT_RECT_LIMIT 10 typedef struct _PAINTENUMRECTLIST { ULONG c; RECTL arcl[PAINT_RECT_LIMIT]; } PAINTENUMRECTLIST; static PAINTENUMRECTLIST PaintClipEnum; LONG SaveScreenMem( ULONG FileCategory, ULONG FileNumber ); LONG SaveGlyphPos( STROBJ *pstro ); LONG RestoreGlyphPos( STROBJ *pstro ); LONG RestoreScreenMem( ULONG FileCategory, ULONG FileNumber ); LONG CompareScreenMem( ULONG FileCategory, ULONG FileNumber ); LONG CheckHeader( FILE *stream ); extern ULONG FontTblMax, GlyphTblMax, CacheTblMax; extern ULONG CopyBitsHist[MAX_CATEGORY]; extern ULONG BitBltHist[MAX_CATEGORY]; extern ULONG TextOutHist[MAX_TEXT_CATEGORY]; extern ULONG fontSize[MAX_FONT_SIZE]; extern ULONG GlyphCountTable[MAX_GLYPH_COUNT]; extern ULONG FontAccl[MAX_CATEGORY]; extern ULONG TextRect[MAX_TEXT_RECT]; extern ULONG TextClip[MAX_CLIP_CONDITION]; extern ULONG TextWidthHist[6][MAX_WIDTH_STEP]; extern ULONG TextHeightHist[6][MAX_HEIGHT_STEP]; extern ULONG FontWidth[MAX_FONT_SIZE]; extern ULONG FontHeight[MAX_FONT_SIZE]; extern ULONG StrObjCountTable[MAX_STROBJ_COUNT]; extern ULONG FontIDTable[MAX_FONT_ENTRY][2]; extern ULONG GlyphHndlTable[MAX_GLYPH_HNDL_ENTRY][2]; extern ULONG CacheTable[MAX_CACHE_ENTRY][3]; extern ULONG CopyBitWidthHist[4][MAX_WIDTH_STEP]; extern ULONG CopyBitHeightHist[4][MAX_HEIGHT_STEP]; extern ULONG BitBltWidthHist[6][MAX_WIDTH_STEP]; extern ULONG BitBltHeightHist[6][MAX_HEIGHT_STEP]; extern ULONG BitBltRop[37][MAX_ROP_ENTRY]; extern ULONG BitBltBrush[2][MAX_BRUSH_ENTRY]; extern ULONG TextPerfByCtgry[4][2]; extern ULONG PaintOp[MAX_PAINT_OPS]; extern ULONG PaintCategories[MAX_PAINT_CATEGORY]; extern ULONG PaintBounds[MAX_PAINT_CATEGORY-1][MAX_PAINT_BOUNDS_ENTRY]; extern ULONG PaintClips[MAX_PAINT_CATEGORY-1][MAX_PAINT_CLIP_ENTRY]; extern ULONG PaintHeight[MAX_PAINT_CATEGORY-1][MAX_PAINT_HEIGHT_ENTRY]; extern ULONG PaintWidth[MAX_PAINT_CATEGORY-1][MAX_PAINT_WIDTH_ENTRY]; extern BOOL InitTable; #define SO_MASK \ (SO_FLAG_DEFAULT_PLACEMENT | SO_ZERO_BEARINGS | \ SO_CHAR_INC_EQUAL_BM_BASE | SO_MAXEXT_EQUAL_BM_SIDE) #define SO_LTOR (SO_MASK | SO_HORIZONTAL) #define SO_RTOL (SO_LTOR | SO_REVERSED) #define SO_TTOB (SO_MASK | SO_VERTICAL) #define SO_BTOT (SO_TTOB | SO_REVERSED) BOOL PDEVDisplay = TRUE; VOID DisplayPDEV() { ULONG i; if(! PDEVDisplay) return; PDEVDisplay = FALSE; DebugPrint(1,"hDriver = 0x%08x\n", myPDEV->hDriver); DebugPrint(1,"hdevEng = 0x%08x\n", myPDEV->hdevEng); DebugPrint(1,"hsurfEng = 0x%08x\n", myPDEV->hsurfEng); DebugPrint(1,"hpalDefault = 0x%08x\n", myPDEV->hpalDefault); DebugPrint(1,"pjScreen = 0x%08x\n", myPDEV->pjScreen); DebugPrint(1,"pjCachedScreen = 0x%08x\n", myPDEV->pjCachedScreen); DebugPrint(1,"VRAMcacheflg = 0x%08x\n", myPDEV->VRAMcacheflg); DebugPrint(1,"Screen = %d X %d\n", myPDEV->cxScreen, myPDEV->cyScreen); DebugPrint(1,"ulMode = %d\n", myPDEV->ulMode); DebugPrint(1,"lDeltaScreen = %d\n", myPDEV->lDeltaScreen); DebugPrint(1,"RGB Mask = (0x%08x, 0x%08x, 0x%08x)\n", myPDEV->flRed, myPDEV->flGreen, myPDEV->flBlue); DebugPrint(1,"ulBitCount = %d\n", myPDEV->ulBitCount); DebugPrint(1,"PointerCapabilities = 0x%08x, (%d X %d), 0x%08x - 0x%08x\n", myPDEV->PointerCapabilities.Flags, myPDEV->PointerCapabilities.MaxWidth, myPDEV->PointerCapabilities.MaxHeight, myPDEV->PointerCapabilities.HWPtrBitmapStart, myPDEV->PointerCapabilities.HWPtrBitmapEnd); if(myPDEV->pPointerAttributes) { DebugPrint(1,"PointerAttributes = 0x%08x, Size = (%d X %d), Byte = %d, Enable = 0x%08x, Pos = (%d, %d)\n", myPDEV->pPointerAttributes->Flags, myPDEV->pPointerAttributes->Width, myPDEV->pPointerAttributes->Height, myPDEV->pPointerAttributes->WidthInBytes, myPDEV->pPointerAttributes->Enable, myPDEV->pPointerAttributes->Column, myPDEV->pPointerAttributes->Row); } DebugPrint(1,"cjPointerAttributes = %d\n", myPDEV->cjPointerAttributes); DebugPrint(1,"fHwCursorActive = %d\n", myPDEV->fHwCursorActive); DebugPrint(1,"MemorySize = 0x%x (%d)\n", myPDEV->MemorySize, myPDEV->MemorySize); DebugPrint(1,"FrameBufferWidth = %d\n", myPDEV->FrameBufferWidth); DebugPrint(1,"ModelID = %d\n", myPDEV->ModelID); DebugPrint(1,"ColorModeShift = %d\n", myPDEV->ColorModeShift); if(myPDEV->pPal) { for(i=0; ipPal[i].peRed, myPDEV->pPal[i].peGreen, myPDEV->pPal[i].peBlue); if(i%4 != 3) DebugPrint(1, " "); else DebugPrint(1, "\n"); } } } ULONG GetTime() { DWORD returnedDataLength; ULONG work; static BOOL TimerError = FALSE; work = 0; if(! TimerError) { if (EngDeviceIoControl(myPDEV->hDriver, IOCTL_GET_TIMER_COUNTER, NULL, 0, &work, sizeof(ULONG), &returnedDataLength)) { DISPDBG((0,"#### Getting Elapse Time Error ####\n")); TimerError = TRUE; } } return(work); } ULONG makemask( ULONG maxcount) { ULONG i; for(i=2; i<=512; i*=2) { if(i > maxcount) break; } return(i/2-1); } VOID PerformCheck( ULONG st, ULONG ed, ULONG sp, ULONG height) { ULONG i, j, k, bpp, totallen, len, overhead; UCHAR *cps, *cpt; ULONG start, srced, sdelta=0, tdelta=0, smask=0, tmask=0, cache, record[2][5]; ULONG flags[4] = { NOCACHECTRL, TTOUCHBIT, TFLUSHBIT, TFLUSHBIT | TTOUCHBIT}; UCHAR *title[14] = { "D->V", "V->V", "D->CV", "D->CV(T)", "D->CV(Ft)", "D->CV(TFt)", "CV->CV", "CV->CV(T)", "CV->CV(Ft)", "CV->CV(TFt)", "CV->CV(Fs)", "CV->CV(TFs)", "CV->CV(FtFs)", "CV->CV(TFtFs)" }; st <<= myPDEV->ColorModeShift; ed <<= myPDEV->ColorModeShift; sp <<= myPDEV->ColorModeShift; bpp = 1 << myPDEV->ColorModeShift; switch(bpp) { case 1: srced = (ed/256 + 1)*256; break; case 2: srced = (ed/1024 + 1)*1024; break; case 4: srced = (ed/2560 + 1)*2560; break; } start = GetTime(); for(len=st; len\n", totallen/1024, overhead/100, overhead%100)); DISPDBG((0, "MemKind mc-0 mc-1 mc-2 mc-3 mc-ttl mc2-0 mc2-1 mc2-2 mc2-3 mc2-ttl\n")); for(k=0; k<14; ++k) { DISPDBG((0, "%s", title[k])); record[0][4] = record[1][4] = 0; // Clear total switch(k) { case 0: // DRAM to VRAM cpt = myPDEV->pjScreen; cps = linebuf; tdelta = myPDEV->lDeltaScreen; sdelta = srced; tmask = 0xff; smask = makemask(BUFSIZE/srced); cache = NOCACHECTRL; break; case 1: // VRAM to VRAM tdelta = sdelta = myPDEV->lDeltaScreen; tmask = smask = 0xff; cpt = myPDEV->pjScreen + (myPDEV->cyScreen)*(tdelta)/2; cps = myPDEV->pjScreen; cache = NOCACHECTRL; break; default: // 2~5: DRAM to Cached VRAM, 6~13: Cached VRAM to Cached VRAM if((LONG) myPDEV->ModelID == -1) { // PSI S3 VRAM cpt = linebuf2; tdelta = ed; tmask = makemask(BUFSIZE/ed); } else { // PSI DCC & VRAM cpt = myPDEV->pjCachedScreen; tdelta = myPDEV->lDeltaScreen; tmask = 0xff; } if(k < 6) { // Source is DRAM cps = linebuf; sdelta = srced; smask = makemask(BUFSIZE/srced); cache = flags[k-2]; } else { // Source is Cached VRAM if((LONG) myPDEV->ModelID == -1) { // PSI S3 VRAM sdelta = srced; smask = makemask(BUFSIZE/srced); cps = linebuf; } else { // PSI DCC & VRAM sdelta = myPDEV->lDeltaScreen; smask = 0xff; cpt = myPDEV->pjCachedScreen + (myPDEV->cyScreen)*(tdelta)/2; cps = myPDEV->pjCachedScreen; } if(k < 10) cache = flags[k-6]; else cache = flags[k-10] | SFLUSHBIT; } break; } // DISPDBG((0, "smask=%x tmask=%x sdelta=%d tdelta=%d smax=%d tmax=%d cps=%x cpt=%x cache=%08x\n", // smask, tmask, sdelta, tdelta, sdelta*(smask+1), tdelta*(tmask+1), cps, cpt, cache)); cache &= myPDEV->VRAMcacheflg; for(j=0; j<4; ++j) { start = GetTime(); for(len=st; lencxScreen; sizl.cy = myPDEV->cyScreen; dx = myPDEV->lDeltaScreen; bpp = 1 << myPDEV->ColorModeShift; dy = sizl.cx * bpp; if(dy >= BLOCKSIZE) dy = BLOCKSIZE-bpp; #if MAXBANDWIDTH base = myPDEV->pjCachedScreen; cache = (TFLUSHBIT | TTOUCHBIT | SFLUSHBIT) & myPDEV->VRAMcacheflg; k = sizl.cy * (myPDEV->lDeltaScreen); length = k*20*10/1024*100/1024; // length = 1/100 MB if(myPDEV->MemorySize >= (ULONG) k*2) memcpy2(base+k, base, k, cache); start = GetTime(); overhead0 = GetTime() - start; start = GetTime(); for(l=0; l<10; ++l) { for(i=0; i<20; ++i) { memcpy2(base, base+dy*35, k, cache); } } end = GetTime() - start - overhead0; DISPDBG((0,"%d.%02d MB copy %d.%02d milli sec - %d.%02d MB/sec (measurement overhead %d.%02d)\n", length/100, length%100, end/100, end%100, (length*100000/end)/100, (length*100000/end)%100, overhead0/100, overhead0%100)); #else // MAXBANDWIDTH switch(myPDEV->ColorModeShift) { case 0: for(i=0; i<256; ++i) linebuf[i] = (CHAR) i; length = 256; break; case 1: spt = (PUSHORT) linebuf; j = 5; k = 32; if(myPDEV->VRAM1MBWorkAround && myPDEV->FrameBufferWidth == VRAM_32BIT) { j = 4; k = 16; } for(i=0; i length) { memcpy(linebuf+j, linebuf, length); j += length; m -= length; } memcpy(linebuf+j, linebuf, i); for(i=1; i>\n", myPDEV->MemorySize/1024)); #if BANDWIDTH DISPDBG((0,"Access memcpy memcpy2 memcpy-na memcpy2-na memset0 memsetff meset2-0 memset2-ff\n")); maxtstno = 7; #else // BANDWIDTH DISPDBG((0,"Access Byte HW Word memcpy memcpyNA memcpy2 memcpy2NA memset memset2 VLine SameWord Flush\n")); maxtstno = 11; #endif // ELSE BANDWIDTH for(m=0; m<5; ++m) { base = myPDEV->pjCachedScreen; if((LONG) myPDEV->ModelID == -1) { // PSI S3 VRAM cache = NOCACHECTRL; if(m==1) break; } switch(m) { case 0: // Non cached VRAM cache = NOCACHECTRL; base = myPDEV->pjScreen; DISPDBG((0,"NonCache")); break; case 1: // Cached VRAM no control cache = NOCACHECTRL; DISPDBG((0,"NoCTRL")); break; case 2: // Cached VRAM src & target touch cache = TTOUCHBIT; DISPDBG((0,"Touch")); break; case 3: // Cached VRAM target flush cache = TFLUSHBIT; DISPDBG((0,"TgtFlush")); break; case 4: // Cached VRAM src & target touch and target flush cache = TFLUSHBIT | TTOUCHBIT; DISPDBG((0,"Touch&TgtFlush")); break; } cache &= myPDEV->VRAMcacheflg; for(l=-2; l<=maxtstno; ++l) { memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT & myPDEV->VRAMcacheflg); start = GetTime(); switch(l) { case -2: // overhead measurement 0 break; case -1: // overhead measurement 1 for(i=0; ilDeltaScreen); memcpy(base+k, base, k); for(i=0; i<18; ++i) { memcpy(base, base+dy*35, k); } memcpy(base, base+k, k); break; case 1: k = sizl.cy * (myPDEV->lDeltaScreen); memcpy2(base+k, base, k, cache); for(i=0; i<18; ++i) { memcpy2(base, base+dy*35, k, cache); } memcpy2(base, base+k, k, cache); break; case 2: k = sizl.cy * (myPDEV->lDeltaScreen); memcpy(base+k, base, k); for(i=0; i<18; ++i) { memcpy(base, base+dy*35-1, k); } memcpy(base, base+k, k); break; case 3: k = sizl.cy * (myPDEV->lDeltaScreen); memcpy2(base+k, base, k, cache); for(i=0; i<18; ++i) { memcpy2(base, base+dy*35-1, k, cache); } memcpy2(base, base+k, k, cache); break; case 4: // memset if(m==0) { memset(base, 0x01, myPDEV->MemorySize); memset(base, 0x01, myPDEV->MemorySize); memset(base, 0x01, myPDEV->MemorySize); memset(base, 0x01, myPDEV->MemorySize); memset(base, 0x01, myPDEV->MemorySize); } else { memset(base, 0x00, myPDEV->MemorySize); memset(base, 0x00, myPDEV->MemorySize); memset(base, 0x00, myPDEV->MemorySize); memset(base, 0x00, myPDEV->MemorySize); memset(base, 0x00, myPDEV->MemorySize); } break; case 5: // memset2 memset(base, 0xff, myPDEV->MemorySize); memset(base, 0xff, myPDEV->MemorySize); memset(base, 0xff, myPDEV->MemorySize); memset(base, 0xff, myPDEV->MemorySize); memset(base, 0xff, myPDEV->MemorySize); break; case 6: // memset memset2(base, 0x00, myPDEV->MemorySize, cache); memset2(base, 0x00, myPDEV->MemorySize, cache); memset2(base, 0x00, myPDEV->MemorySize, cache); memset2(base, 0x00, myPDEV->MemorySize, cache); memset2(base, 0x00, myPDEV->MemorySize, cache); break; case 7: // memset2 memset2(base, 0xff, myPDEV->MemorySize, cache); memset2(base, 0xff, myPDEV->MemorySize, cache); memset2(base, 0xff, myPDEV->MemorySize, cache); memset2(base, 0xff, myPDEV->MemorySize, cache); memset2(base, 0xff, myPDEV->MemorySize, cache); break; #else // BANDWIDTH case 0: // byte fill for(i=0; iMemorySize); memset(base, 0x88, myPDEV->MemorySize); break; case 8: // memset2 memset2(base, 0xff, myPDEV->MemorySize, cache); memset2(base, 0x88, myPDEV->MemorySize, cache); break; case 9: // vertical line switch(bpp) { case 1: for(k=0; k<8; ++k) { for(j=k*4; jpjScreen, 0xff, dy); memset(myPDEV->pjScreen+(sizl.cy-1)*dx, 0xff, dy); cpt = myPDEV->pjScreen; switch(bpp) { case 1: for(i=0; iVRAM1MBWorkAround && myPDEV->FrameBufferWidth == VRAM_32BIT) j = 0x0fff; for(i=0; ipjCachedScreen, myPDEV->MemorySize); break; #endif // ELSE BANDWIDTH } end = GetTime(); end -= start; switch(l) { case -2: if(m==0) { overhead0 = end; } break; case -1: if(m==0) { overhead1 = end; } break; case 10: record[l] = (end - overhead0)/10; Sleep(3000); break; default: record[l] = end - overhead0; } } for(i=0; i<=maxtstno; ++i) { DISPDBG((0," %d.%02d", record[i]/100, record[i]%100)); } DISPDBG((0,"\n")); // Cache flush test if(flushtest) { cpt = base; cps = myPDEV->pjScreen; j = dx/2; for(i=100; i<=500; i+=100) { memset2(cpt+i*dx, 0xff, j, cache); } for(i=100; i<=500; i+=100) { memset(cps+i*dx, 0x01, j); } memset2((myPDEV->pjScreen), 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memcpy2(cpt+i*dx, linebuf, j, cache); } for(i=100; i<=500; i+=100) { memset(cps+i*dx, 0x01, j); } memset2((myPDEV->pjScreen) + 10*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memset2(cpt+i*dx, 0xff, j, cache); } for(i=100; i<=500; i+=100) { memcpy2(cpt+(i+50)*dx+j, cpt+i*dx, j, cache); } for(i=100; i<=550; i+=50) { memset(cps+i*dx, 0x01, j*2); } memset2((myPDEV->pjScreen) + 20*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memset2(cpt+i*dx, 0xff, j, cache); } for(i=100; i<=500; i+=100) { memcpy2(cpt+(i+50)*dx+j, cpt+i*dx, j, cache | SFLUSHBIT); } for(i=100; i<=550; i+=50) { memset(cps+i*dx, 0x01, j*2); } memset2((myPDEV->pjScreen) + 30*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memset2(cpt+i*dx, 0xff, j, cache); } flush(myPDEV->pjCachedScreen, myPDEV->MemorySize); for(i=100; i<=500; i+=100) { memset(cps+i*dx, 0x01, j); } memset2((myPDEV->pjScreen) + 40*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memcpy2(cpt+i*dx, linebuf, j, cache); } flush(myPDEV->pjCachedScreen, myPDEV->MemorySize); for(i=100; i<=500; i+=100) { memset(cps+i*dx, 0x01, j); } memset2((myPDEV->pjScreen) + 50*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memset2(cpt+i*dx, 0xff, j, cache); } for(i=100; i<=500; i+=100) { memcpy2(cpt+(i+50)*dx+j, cpt+i*dx, j, cache); } flush(myPDEV->pjCachedScreen, myPDEV->MemorySize); for(i=100; i<=550; i+=50) { memset(cps+i*dx, 0x01, j*2); } memset2((myPDEV->pjScreen) + 60*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); for(i=100; i<=500; i+=100) { memset2(cpt+i*dx, 0xff, j, cache); } for(i=100; i<=500; i+=100) { memcpy2(cpt+(i+50)*dx+j, cpt+i*dx, j, cache | SFLUSHBIT); } flush(myPDEV->pjCachedScreen, myPDEV->MemorySize); for(i=100; i<=550; i+=50) { memset(cps+i*dx, 0x01, j*2); } memset2((myPDEV->pjScreen) + 70*dx, 0xff, (sizl.cx << myPDEV->ColorModeShift), NOCACHECTRL); Sleep(3000); memset2(myPDEV->pjCachedScreen, 0, myPDEV->MemorySize, TFLUSHBIT); } } #endif // ELSE MAXBANDWIDTH } #endif // INVESTIGATE // // The driver function table with all function index/address pairs // #if INVESTIGATE #define HOOKS_BMF8BPP_TOP (HOOK_BITBLT | HOOK_COPYBITS | HOOK_STRETCHBLT | \ HOOK_TEXTOUT | HOOK_PAINT | HOOK_STROKEPATH | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH) #define HOOKS_BMF8BPP_PRO (HOOK_BITBLT | HOOK_COPYBITS | HOOK_STRETCHBLT | \ HOOK_TEXTOUT | HOOK_PAINT | HOOK_STROKEPATH | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH) #define HOOKS_BMF16BPP (HOOK_BITBLT | HOOK_COPYBITS | HOOK_STRETCHBLT | \ HOOK_TEXTOUT | HOOK_PAINT | HOOK_STROKEPATH | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH) #define HOOKS_BMF32BPP (HOOK_BITBLT | HOOK_COPYBITS | HOOK_STRETCHBLT | \ HOOK_TEXTOUT | HOOK_PAINT | HOOK_STROKEPATH | HOOK_FILLPATH | HOOK_STROKEANDFILLPATH) #else // INVESTIGATE #define HOOKS_BMF8BPP_TOP (HOOK_COPYBITS | HOOK_BITBLT | HOOK_TEXTOUT | HOOK_PAINT) #define HOOKS_BMF8BPP_PRO (HOOK_COPYBITS | HOOK_BITBLT | HOOK_TEXTOUT) #define HOOKS_BMF16BPP (HOOK_COPYBITS | HOOK_BITBLT | HOOK_TEXTOUT | HOOK_STRETCHBLT | HOOK_PAINT) #define HOOKS_BMF32BPP (HOOK_COPYBITS | HOOK_BITBLT | HOOK_TEXTOUT | HOOK_STRETCHBLT | HOOK_PAINT) #endif #if INVESTIGATE BOOL WDrvBitBlt( SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclTrg, POINTL *pptlSrc, POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, ROP4 rop4) { BOOL rc; BOOL rcdrv; BOOL docomparison; BOOL srcinvolved; LONG stat; ULONG ropidx, brop4; static BOOL ropovfmsg = FALSE; static BOOL brushovfmsg = FALSE; docomparison = (compare & dbgflg & FL_DRV_BITBLT) && breakcnt == 0 && ScreenBuf2; if(paramcheck & FL_DRV_BITBLT) { ULONG category, ui; ULONG histidx = 0; if(((rop4 & 0xc0) != ((rop4 & 0x30) << 2)) || ((rop4 & 0xc) != ((rop4 & 0x3) << 2))) srcinvolved = TRUE; else srcinvolved = FALSE; if(srcinvolved) { if(psoSrc->pvScan0 == (PVOID)ScreenBase) histidx = 4; else histidx = 2; } else histidx = 0; if(psoTrg->pvScan0 == (PVOID)ScreenBase) histidx += 1; ui = (prclTrg->right - prclTrg->left)/10; if(ui >= MAX_WIDTH_STEP) ui = MAX_WIDTH_STEP-1; BitBltWidthHist[histidx][ui] += 1; ui = (prclTrg->bottom - prclTrg->top)/10; if(ui >= MAX_HEIGHT_STEP) ui = MAX_HEIGHT_STEP-1; BitBltHeightHist[histidx][ui] += 1; /** BitBlt categories ** 0: Not Hooked other reasons 1: Not Hooked because of unsupported operation 2: Not Hooked because Solid Brush is not supported 3: Not Hooked because Pattern Brush is not supported 4: Hooked other operations 5: Hooked SRC + DEST 6: Hooked PAT + DEST 7: Hooked SOLID + DEST 8: Hooked PTN fill 9: Hooked SOLID fill ************************/ category = 0; // default category if(((rop4 & 0x0f) != ((rop4 & 0xf0)>>4)) || ((rop4 & 0x0f00) != ((rop4 & 0xf000)>>4))) { // Pattern involved? if(pbo->iSolidColor == 0xFFFFFFFF) brop4 = rop4 | 0xffff0000; else { brop4 = rop4 | 0x11110000; for(ui=0; uiiSolidColor) { BitBltBrush[1][ui] += 1; break; } } if(ui == MAX_BRUSH_ENTRY) { if(! brushovfmsg) { DISPDBG((0,"### Solid Brush Table Overflow ###\n")); brushovfmsg = TRUE; } } else { if(BitBltBrush[1][ui] == 0) { BitBltBrush[0][ui] = pbo->iSolidColor; BitBltBrush[1][ui] = 1; } } } } else brop4 = rop4; for(ropidx=0; ropidxright - prclTrg->left); if(srcinvolved && psoSrc->pvScan0 == (PVOID)ScreenBase) BitBltRop[4][ropidx] += 1; ui = (prclTrg->right - prclTrg->left); if(ui > 31) ui = 31; BitBltRop[ui+5][ropidx] += 1; } if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) { if (psoTrg->pvScan0 != (PVOID)ScreenBase) { goto DrvExitBitBlt; } switch(rop4) { case 0x00000000: // (BLACKNESS) case 0x0000FFFF: // (WHITENESS) category = 9; break; case 0x0000F0F0: // (PATCOPY) if (pbo->iSolidColor != 0xFFFFFFFF) { category = 9; } else category = 8; break; case 0x00000F0F: // (NOTPATCOPY) if (pbo->iSolidColor != 0xFFFFFFFF) { category = 9; } else category = 3; break; case 0x00005555: // (Not Dest) category = 7; break; case 0x00005a5a: // (PAT XOR DEST) case 0x0000a5a5: // (INV PAT XOR DEST) if (pbo->iSolidColor != 0xFFFFFFFF) { category = 7; } else category = 6; break; case 0x0000a0a0: // (PAT XOR DEST) case 0x00000a0a: // (INV PAT XOR DEST) if (pbo->iSolidColor != 0xFFFFFFFF) { category = 2; } else category = 6; break; case 0x0000b8b8: if (pbo->iSolidColor != 0xFFFFFFFF) { category = 4; } else category = 3; break; case 0x00006666: case 0x00008888: case 0x0000eeee: case 0x0000bbbb: case 0x00004444: case 0x00001111: case 0x00003333: category = 5; break; default: category = 1; break; } } else { category=0; } DrvExitBitBlt: BitBltHist[category] += 1; } if((dumpparam & dbgflg & FL_DRV_BITBLT) && breakcnt == 0) { DumpDecimal("[BitBlt parameter]", stat); DumpSurfObj("Target surface object", psoTrg); DumpSurfObj("Source surface object", psoSrc); DumpSurfObj("Mask surface object", psoMask); DumpClipObj("Clip object", pco); DumpXlateObj("Xlate object", pxlo); DumpRectl("Target rectangle", prclTrg); DumpPointl("Source position", pptlSrc); DumpPointl("Mask position", pptlMask); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrush); DumpKeyTable("Raster operation", rop4, bitbltoptbl, ROP_MAX); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if((usedrvfunc & FL_DRV_BITBLT) || docomparison) { rc = rcdrv = DrvBitBlt( psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4); if((paramcheck & FL_DRV_BITBLT) && ropidx != MAX_ROP_ENTRY) BitBltRop[2][ropidx] += spentindrv; } if(docomparison && (donebydrv & FL_DRV_BITBLT)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_BITBLT) || (docomparison && (donebydrv & FL_DRV_BITBLT))) { if(traseentry & dbgflg & FL_DRV_BITBLT) DISPDBG((0,"+++ Entering EngBitBlt +++\n")); if(breakentry & FL_DRV_BITBLT) CountBreak(); CLOCKSTART((TRAP_BITBLT)); rc = EngBitBlt( psoTrg, psoSrc, psoMask, pco, pxlo, prclTrg, pptlSrc, pptlMask, pbo, pptlBrush, rop4); CLOCKEND((TRAP_BITBLT)); if((paramcheck & FL_DRV_BITBLT) && ropidx != MAX_ROP_ENTRY) BitBltRop[2][ropidx] += spentindrv; if(traseexit & dbgflg & FL_DRV_BITBLT) DISPDBG((0,"--- Exiting EngBitBlt ---\n")); if(breakexit & FL_DRV_BITBLT) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_BITBLT)) { if(rc != rcdrv) { DISPDBG((0, "BitBlt return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### BitBlt result unmatch", stat); DumpSurfObj("Target surface object", psoTrg); DumpSurfObj("Source surface object", psoSrc); DumpSurfObj("Mask surface object", psoMask); DumpClipObj("Clip object", pco); DumpXlateObj("Xlate object", pxlo); DumpRectl("Target rectangle", prclTrg); DumpPointl("Source position", pptlSrc); DumpPointl("Mask position", pptlMask); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrush); DumpKeyTable("Raster operation", rop4, bitbltoptbl, ROP_MAX); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } BOOL WDrvStretchBlt( SURFOBJ *psoDest, SURFOBJ *psoSrc, SURFOBJ *psoMask, CLIPOBJ *pco, XLATEOBJ *pxlo, COLORADJUSTMENT *pca, POINTL *pptlHTOrg, RECTL *prclDest, RECTL *prclSrc, POINTL *pptlMask, ULONG iMode) { BOOL rc; BOOL rcdrv; LONG stat; BOOL docomparison; docomparison = (compare & dbgflg & FL_DRV_STRTBIT) && breakcnt == 0 && ScreenBuf2; if((dumpparam & dbgflg & FL_DRV_STRTBIT) && breakcnt == 0) { DumpDecimal("[StretchBlt parameter]", stat); DumpSurfObj("Target surface object", psoDest); DumpSurfObj("Source surface object", psoSrc); DumpSurfObj("Mask surface object", psoMask); DumpClipObj("Clip object", pco); DumpXlateObj("Xlate object", pxlo); DumpColorAdjustment("Color adjustment", pca); DumpPointl("Halftone brush position", pptlHTOrg); DumpRectl("Target rectangle", prclDest); DumpRectl("Source rectangle", prclSrc); DumpPointl("Mask position", pptlMask); DumpCombo("iMode", iMode); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if(docomparison || (usedrvfunc & FL_DRV_STRTBIT)) { rcdrv = rc = DrvStretchBlt( psoDest, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDest, prclSrc, pptlMask, iMode); } if(docomparison && (donebydrv & FL_DRV_STRTBIT)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_STRTBIT) || (docomparison && (donebydrv & FL_DRV_STRTBIT))) { if(traseentry & dbgflg & FL_DRV_STRTBIT) DISPDBG((0,"+++ Entering EngStretchBlt +++\n")); if(breakentry & FL_DRV_STRTBIT) CountBreak(); CLOCKSTART((TRAP_STRETCHBLT)); rc = EngStretchBlt( psoDest, psoSrc, psoMask, pco, pxlo, pca, pptlHTOrg, prclDest, prclSrc, pptlMask, iMode); CLOCKEND((TRAP_STRETCHBLT)); if(traseexit & dbgflg & FL_DRV_STRTBIT) DISPDBG((0,"--- Exiting EngStretchBlt ---\n")); if(breakexit & FL_DRV_STRTBIT) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_STRTBIT)) { if(rc != rcdrv) { DISPDBG((0, "StretchBlt return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### StretchBlt result unmatch", stat); DumpSurfObj("Target surface object", psoDest); DumpSurfObj("Source surface object", psoSrc); DumpSurfObj("Mask surface object", psoMask); DumpClipObj("Clip object", pco); DumpXlateObj("Xlate object", pxlo); DumpColorAdjustment("Color adjustment", pca); DumpPointl("Halftone brush position", pptlHTOrg); DumpRectl("Target rectangle", prclDest); DumpRectl("Source rectangle", prclSrc); DumpPointl("Mask position", pptlMask); DumpCombo("iMode", iMode); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } VOID SetTextRect( ULONG width, ULONG height, ULONG index ) { ULONG ui; ui = width/10; if(ui >= MAX_WIDTH_STEP) ui = MAX_WIDTH_STEP-1; TextWidthHist[index][ui] += 1; ui = height; if(ui >= MAX_HEIGHT_STEP) ui = MAX_HEIGHT_STEP-1; TextHeightHist[index][ui] += 1; } BOOL WDrvTextOut( SURFOBJ *pso, STROBJ *pstro, FONTOBJ *pfo, CLIPOBJ *pco, RECTL *prclExtra, RECTL *prclOpaque, BRUSHOBJ *pboFore, BRUSHOBJ *pboOpaque, POINTL *pptlOrg, MIX mix) { BOOL rc; BOOL rcdrv; LONG stat; RECTL *prectl; BOOL docomparison; LONG textperfidx; docomparison = (compare & dbgflg & FL_DRV_TEXTOUT) && breakcnt == 0 && ScreenBuf2; if(paramcheck & FL_DRV_TEXTOUT) { ULONG ui, category, fontMax, StrCount, CharCount; ULONG FontId, GlyphHandle; ULONG GlyphCount; PGLYPHPOS GlyphEnd; ULONG GlyphHeight; PGLYPHPOS GlyphList; PGLYPHPOS GlyphStart; ULONG GlyphWidth; BOOL More; RECTL OpaqueRectl, *extraRect; GLYPHBITS *pgb; textperfidx = -1; if (pso->pvScan0 != (PVOID) ScreenBase) { category = 0; goto DevExitTextOut; } fontMax = pfo->cxMax; if(fontMax >= MAX_FONT_SIZE) fontMax = MAX_FONT_SIZE-1; fontSize[fontMax] += 1; if((pfo->flFontType & DEVICE_FONTTYPE) || (pso->lDelta & 0x03)) { category = 1; goto DevExitTextOut; } if((pstro->flAccel & (SO_HORIZONTAL | SO_VERTICAL | SO_REVERSED)) != SO_HORIZONTAL) { category = 2; goto DevExitTextOut; } if((pboFore->iSolidColor == 0xFFFFFFFFL) || ((prclOpaque != (PRECTL) NULL) && (pboOpaque->iSolidColor == 0xFFFFFFFFL))) { category = 3; goto DevExitTextOut; } if(pco != NULL && pco->iDComplexity != DC_TRIVIAL && pco->iDComplexity != DC_RECT) { category = 4; goto DevExitTextOut; } if(pfo->cxMax > 32) { category = 5; goto DevExitTextOut; } FontAccl[0] += 1; if ((pstro->flAccel & SO_HORIZONTAL) != 0) { FontAccl[1] += 1; } if ((pstro->flAccel & SO_VERTICAL) != 0) { FontAccl[2] += 1; } if ((pstro->flAccel & SO_REVERSED) != 0) { FontAccl[3] += 1; } if ((pstro->flAccel & SO_ZERO_BEARINGS) != 0) { FontAccl[4] += 1; } if ((pstro->flAccel & SO_CHAR_INC_EQUAL_BM_BASE) != 0) { FontAccl[5] += 1; } if ((pstro->flAccel & SO_MAXEXT_EQUAL_BM_SIDE) != 0) { FontAccl[6] += 1; } if ((pstro->flAccel & SO_FLAG_DEFAULT_PLACEMENT) != 0) { FontAccl[7] += 1; } FontId = pfo->iUniq; for(ui=0; uiflAccel == SO_LTOR) category = 6; else category = 8; } if(pco != NULL && pco->iDComplexity == DC_RECT) category += 1; textperfidx = category-6; TextPerfByCtgry[textperfidx][0] += 1; if (pstro->ulCharInc != 0) { // // The font is fixed pitch. Capture the glyph dimensions and // compute the starting display address. // if (pstro->pgp == NULL) { More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList); } else { GlyphCount = pstro->cGlyphs; GlyphList = pstro->pgp; More = FALSE; } pgb = GlyphList->pgdf->pgb; GlyphWidth = pgb->sizlBitmap.cx; GlyphHeight = pgb->sizlBitmap.cy; StrCount = CharCount = 0; do { CharCount += GlyphCount; GlyphEnd = &GlyphList[GlyphCount]; GlyphStart = GlyphList; if(GlyphCount >= MAX_GLYPH_COUNT) GlyphCount = MAX_GLYPH_COUNT-1; GlyphCountTable[GlyphCount] += 1; do { GlyphHandle = (ULONG) (GlyphStart->hg); for(ui=0; ui= MAX_STROBJ_COUNT) StrCount = MAX_STROBJ_COUNT-1; StrObjCountTable[StrCount] += 1; if(GlyphWidth >= MAX_FONT_SIZE) GlyphWidth = MAX_FONT_SIZE-1; if(GlyphHeight >= MAX_FONT_SIZE) GlyphHeight = MAX_FONT_SIZE-1; FontWidth[GlyphWidth] += CharCount; FontHeight[GlyphHeight] += CharCount; } else { // // The font is not fixed pitch. Compute the x and y values for // each glyph individually. // category += 4; StrCount = 0; do { More = STROBJ_bEnum(pstro, &GlyphCount, &GlyphList); GlyphEnd = &GlyphList[GlyphCount]; GlyphStart = GlyphList; if(GlyphCount >= MAX_GLYPH_COUNT) GlyphCount = MAX_GLYPH_COUNT-1; GlyphCountTable[GlyphCount] += 1; do { GlyphHandle = (ULONG) (GlyphStart->hg); for(ui=0; uipgdf->pgb; GlyphWidth = pgb->sizlBitmap.cx; GlyphHeight = pgb->sizlBitmap.cy; if(GlyphWidth >= MAX_FONT_SIZE) GlyphWidth = MAX_FONT_SIZE-1; if(GlyphHeight >= MAX_FONT_SIZE) GlyphHeight = MAX_FONT_SIZE-1; FontWidth[GlyphWidth] += 1; FontHeight[GlyphHeight] += 1; GlyphStart += 1; } while(GlyphStart != GlyphEnd); StrCount += 1; } while(More); if(StrCount >= MAX_STROBJ_COUNT) StrCount = MAX_STROBJ_COUNT-1; StrObjCountTable[StrCount] += 1; } if(prclOpaque != NULL) { TextRect[0] += 1; OpaqueRectl = *prclOpaque; if(OpaqueRectl.top < pstro->rclBkGround.top) { SetTextRect(OpaqueRectl.right-OpaqueRectl.left, pstro->rclBkGround.top-OpaqueRectl.top, 0); TextRect[1] += 1; OpaqueRectl.top = pstro->rclBkGround.top; } else if(OpaqueRectl.top == pstro->rclBkGround.top) { TextRect[2] += 1; } if(OpaqueRectl.bottom > pstro->rclBkGround.bottom) { SetTextRect(OpaqueRectl.right-OpaqueRectl.left, OpaqueRectl.bottom-pstro->rclBkGround.bottom, 1); TextRect[3] += 1; OpaqueRectl.bottom = pstro->rclBkGround.bottom; } else if(OpaqueRectl.bottom == pstro->rclBkGround.bottom) { TextRect[4] += 1; } if(OpaqueRectl.left < pstro->rclBkGround.left) { SetTextRect(pstro->rclBkGround.left-OpaqueRectl.left, OpaqueRectl.bottom-OpaqueRectl.top, 2); TextRect[5] += 1; } else if(OpaqueRectl.left == pstro->rclBkGround.left) { TextRect[6] += 1; } if(OpaqueRectl.right > pstro->rclBkGround.right) { SetTextRect(OpaqueRectl.right - pstro->rclBkGround.right, OpaqueRectl.bottom-OpaqueRectl.top, 3); TextRect[7] += 1; } else if(OpaqueRectl.right == pstro->rclBkGround.right) { TextRect[8] += 1; } } if(prclExtra != (PRECTL)NULL) { extraRect = prclExtra; while (extraRect->left != extraRect->right) { SetTextRect(extraRect->right - extraRect->left, extraRect->bottom - extraRect->top, 4); TextRect[9] += 1; prclExtra += 1; } } SetTextRect(pstro->rclBkGround.right - pstro->rclBkGround.left, pstro->rclBkGround.bottom - pstro->rclBkGround.top, 5); if(pco != NULL & pco->iDComplexity == DC_RECT) { TextClip[0] += 1; if(pco->rclBounds.top == pstro->rclBkGround.top) TextClip[1] += 1; if(pco->rclBounds.bottom == pstro->rclBkGround.bottom) TextClip[2] += 1; if(pco->rclBounds.left == pstro->rclBkGround.left) TextClip[3] += 1; if(pco->rclBounds.right == pstro->rclBkGround.right) TextClip[4] += 1; } DevExitTextOut: TextOutHist[category] += 1; } else { textperfidx = -1; } if((dumpparam & dbgflg & FL_DRV_TEXTOUT) && breakcnt == 0) { DumpDecimal("[TextOut parameter]", stat); DumpSurfObj("Source surface object", pso); DumpStrObj("String object", pstro); DumpFontObj("Font object", pfo); DumpClipObj("Clip object", pco); DumpString("[Extra rectangle array]\n"); prectl = prclExtra; while(prectl != NULL) { if(prectl->left || prectl->top || prectl->right || prectl->bottom) { DumpRectl(" ", prectl); prectl += 1; } else break; } DumpRectl("Opaque rectangle", prclOpaque); DumpBrushObj("Foreground brush object", pboFore); DumpBrushObj("Opaque brush object", pboOpaque); DumpPointl("Brush position", pptlOrg); DumpMix("Fore & back mix mode", mix); } if(docomparison) { SaveScreenMem(BEFORE_SCREEN, FileNumberBase); SaveGlyphPos(pstro); } if(docomparison || (usedrvfunc & FL_DRV_TEXTOUT)) { rcdrv = rc = DrvTextOut( pso, pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix); if(textperfidx >= 0) TextPerfByCtgry[textperfidx][1] += spentindrv; } if(docomparison && (donebydrv & FL_DRV_TEXTOUT)) { RestoreGlyphPos(pstro); SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); SaveGlyphPos(pstro); } if((useengfunc & FL_DRV_TEXTOUT) || (docomparison && (donebydrv & FL_DRV_TEXTOUT))) { if(traseentry & dbgflg & FL_DRV_TEXTOUT) DISPDBG((0,"+++ Entering EngTextOut +++\n")); if(breakentry & FL_DRV_TEXTOUT) CountBreak(); CLOCKSTART((TRAP_TEXTOUT)); rc = EngTextOut( pso, pstro, pfo, pco, prclExtra, prclOpaque, pboFore, pboOpaque, pptlOrg, mix); CLOCKEND((TRAP_TEXTOUT)); if(textperfidx >= 0) TextPerfByCtgry[textperfidx][1] += spentindrv; if(traseexit & dbgflg & FL_DRV_TEXTOUT) DISPDBG((0,"--- Exiting EngTextOut ---\n")); if(breakexit & FL_DRV_TEXTOUT) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_TEXTOUT)) { RestoreGlyphPos(pstro); if(rc != rcdrv) { DISPDBG((0, "TextOut return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### TextOut result unmatch", stat); DumpSurfObj("Source surface object", pso); DumpStrObj("String object", pstro); DumpFontObj("Font object", pfo); DumpClipObj("Clip object", pco); DumpString("[Extra rectangle array]\n"); prectl = prclExtra; while(prectl != NULL) { if(prectl->left || prectl->top || prectl->right || prectl->bottom) { DumpRectl(" ", prectl); prectl += 1; } else break; } DumpRectl("Opaque rectangle", prclOpaque); DumpBrushObj("Foreground brush object", pboFore); DumpBrushObj("Opaque brush object", pboOpaque); DumpPointl("Brush position", pptlOrg); DumpMix("Fore & back mix mode", mix); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } BOOL WDrvStrokePath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, LINEATTRS *plineattrs, MIX mix) { BOOL rc; BOOL rcdrv; LONG stat; BOOL docomparison; docomparison = (compare & dbgflg & FL_DRV_STRKPATH) && breakcnt == 0 && ScreenBuf2; if((dumpparam & dbgflg & FL_DRV_STRKPATH) && breakcnt == 0) { DumpDecimal("[StrokePath parameter]", stat); DumpSurfObj("Target surface object", pso); DumpPathObj("Path object", ppo); DumpClipObj("Clip object", pco); DumpXformObj("Xform object", pxo); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrushOrg); DumpLineAttrs("Line attributes structure", plineattrs); DumpMix("Brush & target mix mode", mix); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if(docomparison || (usedrvfunc & FL_DRV_STRKPATH)) { rcdrv = rc = DrvStrokePath( pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix); } if(docomparison && (donebydrv & FL_DRV_STRKPATH)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_STRKPATH) || (docomparison && (donebydrv & FL_DRV_STRKPATH))) { if(traseentry & dbgflg & FL_DRV_STRKPATH) DISPDBG((0,"+++ Entering EngStrokePath +++\n")); if(breakentry & FL_DRV_STRKPATH) CountBreak(); CLOCKSTART((TRAP_STROKEPATH)); rc = EngStrokePath( pso, ppo, pco, pxo, pbo, pptlBrushOrg, plineattrs, mix); CLOCKEND((TRAP_STROKEPATH)); if(traseexit & dbgflg & FL_DRV_STRKPATH) DISPDBG((0,"--- Exiting EngStrokePath ---\n")); if(breakexit & FL_DRV_STRKPATH) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_STRKPATH)) { if(rc != rcdrv) { DISPDBG((0, "StrokePath return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### StrokePath result unmatch", stat); DumpSurfObj("Target surface object", pso); DumpPathObj("Path object", ppo); DumpClipObj("Clip object", pco); DumpXformObj("Xform object", pxo); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrushOrg); DumpLineAttrs("Line attributes structure", plineattrs); DumpMix("Brush & target mix mode", mix); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } BOOL WDrvFillPath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, MIX mix, FLONG flOptions) { BOOL rc; BOOL rcdrv; LONG stat; BOOL docomparison; docomparison = (compare & dbgflg & FL_DRV_FILLPATH) && breakcnt == 0 && ScreenBuf2; if((dumpparam & dbgflg & FL_DRV_FILLPATH) && breakcnt == 0) { DumpDecimal("[FillPath parameter]", stat); DumpSurfObj("Target surface object", pso); DumpPathObj("Path object", ppo); DumpClipObj("Clip object", pco); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrushOrg); DumpMix("Pattern & target mix mode", mix); DumpTable("Fill option", flOptions, fpstrtbl, FPSTR_MAX); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if(docomparison || (usedrvfunc & FL_DRV_FILLPATH)) { rcdrv = rc = DrvFillPath( pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions); } if(docomparison && (donebydrv & FL_DRV_FILLPATH)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_FILLPATH) || (docomparison && (donebydrv & FL_DRV_FILLPATH))) { if(traseentry & dbgflg & FL_DRV_FILLPATH) DISPDBG((0,"+++ Entering EngFillPath +++\n")); if(breakentry & FL_DRV_FILLPATH) CountBreak(); CLOCKSTART((TRAP_FILLPATH)); rc = EngFillPath( pso, ppo, pco, pbo, pptlBrushOrg, mix, flOptions); CLOCKEND((TRAP_FILLPATH)); if(traseexit & dbgflg & FL_DRV_FILLPATH) DISPDBG((0,"--- Exiting EngFillPath ---\n")); if(breakexit & FL_DRV_FILLPATH) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_FILLPATH)) { if(rc != rcdrv) { DISPDBG((0, "FillPath return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### FillPath result unmatch", stat); DumpSurfObj("Target surface object", pso); DumpPathObj("Path object", ppo); DumpClipObj("Clip object", pco); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrushOrg); DumpMix("Pattern & target mix mode", mix); DumpTable("Fill option", flOptions, fpstrtbl, FPSTR_MAX); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } BOOL WDrvStrokeAndFillPath( SURFOBJ *pso, PATHOBJ *ppo, CLIPOBJ *pco, XFORMOBJ *pxo, BRUSHOBJ *pboStroke, LINEATTRS *plineattrs, BRUSHOBJ *pboFill, POINTL *pptlBrushOrg, MIX mixFill, FLONG flOptions) { BOOL rc; BOOL rcdrv; LONG stat; BOOL docomparison; docomparison = (compare & dbgflg & FL_DRV_STRKNFILL) && breakcnt == 0 && ScreenBuf2; if((dumpparam & dbgflg & FL_DRV_STRKNFILL) && breakcnt == 0) { DumpDecimal("[StrokeAndFillPath parameter]", stat); DumpSurfObj("Target surface object", pso); DumpPathObj("Path object", ppo); DumpClipObj("Clip object", pco); DumpXformObj("Xform object", pxo); DumpBrushObj("Brush object for stroke", pboStroke); DumpLineAttrs("Line attributes structure", plineattrs); DumpBrushObj("Brush object for fill", pboFill); DumpPointl("Brush position", pptlBrushOrg); DumpMix("Fore & back mix mode", mixFill); DumpTable("Fill option", flOptions, fpstrtbl, FPSTR_MAX); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if(docomparison || (usedrvfunc & FL_DRV_STRKNFILL)) { rcdrv = rc = DrvStrokeAndFillPath( pso, ppo, pco, pxo, pboStroke, plineattrs, pboFill, pptlBrushOrg, mixFill, flOptions); } if(docomparison && (donebydrv & FL_DRV_STRKNFILL)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_STRKNFILL) || (docomparison && (donebydrv & FL_DRV_STRKNFILL))) { if(traseentry & dbgflg & FL_DRV_STRKNFILL) DISPDBG((0,"+++ Entering EngStrokeAndFillPath +++\n")); if(breakentry & FL_DRV_STRKNFILL) CountBreak(); CLOCKSTART((TRAP_STROKENFIL)); rc = EngStrokeAndFillPath( pso, ppo, pco, pxo, pboStroke, plineattrs, pboFill, pptlBrushOrg, mixFill, flOptions); CLOCKEND((TRAP_STROKENFIL)); if(traseexit & dbgflg & FL_DRV_STRKNFILL) DISPDBG((0,"--- Exiting EngStrokeAndFillPath ---\n")); if(breakexit & FL_DRV_STRKNFILL) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_STRKNFILL)) { if(rc != rcdrv) { DISPDBG((0, "StrokeAndFillPath return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### StrokeAndFillPath result unmatch", stat); DumpSurfObj("Target surface object", pso); DumpPathObj("Path object", ppo); DumpClipObj("Clip object", pco); DumpXformObj("Xform object", pxo); DumpBrushObj("Brush object for stroke", pboStroke); DumpLineAttrs("Line attributes structure", plineattrs); DumpBrushObj("Brush object for fill", pboFill); DumpPointl("Brush position", pptlBrushOrg); DumpMix("Fore & back mix mode", mixFill); DumpTable("Fill option", flOptions, fpstrtbl, FPSTR_MAX); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } BOOL WDrvPaint( SURFOBJ *pso, CLIPOBJ *pco, BRUSHOBJ *pbo, POINTL *pptlBrushOrg, MIX mix) { BOOL rc; BOOL rcdrv; LONG stat; BOOL docomparison; docomparison = (compare & dbgflg & FL_DRV_PAINT) && breakcnt == 0 && ScreenBuf2; if(paramcheck & FL_DRV_PAINT) { ULONG category, index, op, clip, ui, ClipRegions; BOOL More; if((index = mix & 0xf) != (mix >> 8)) category = 4; else { switch(op = gaMix[index]) { case 0x00: case 0xff: category = 0; break; case 0xf0: if(pbo->iSolidColor == 0xffffffff) { category = 1; index = 17; } else category = 0; break; case 0x0f: if(pbo->iSolidColor == 0xffffffff) { category = 4; index = 18; } else category = 0; break; case 0x55: category = 2; break; case 0x5a: if(pbo->iSolidColor == 0xffffffff) { category = 3; index = 16; } else category = 2; break; case 0xa5: if(pbo->iSolidColor == 0xffffffff) { category = 3; index = 19; } else category = 2; break; default: category = 4; } PaintOp[index] += 1; } PaintCategories[category] += 1; if(category <= 3) { ui = (pco->rclBounds.right - pco->rclBounds.left)/10; if(ui >= MAX_PAINT_BOUNDS_ENTRY) ui = MAX_PAINT_BOUNDS_ENTRY-1; PaintBounds[category][ui] += 1; if(pco && pco->iDComplexity == DC_COMPLEX) { CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_ANY, PAINT_RECT_LIMIT); for(clip=1; clip < MAX_PAINT_CLIP_ENTRY-1; ++clip) { More = CLIPOBJ_bEnum(pco, sizeof(PaintClipEnum), (PVOID)&PaintClipEnum); for (ClipRegions=0; ClipRegions= 10) ui = ui/10 + 9; if(ui >= MAX_PAINT_HEIGHT_ENTRY) ui = MAX_PAINT_HEIGHT_ENTRY-1; PaintHeight[category][ui] += 1; ui = PaintClipEnum.arcl[ClipRegions].right - PaintClipEnum.arcl[ClipRegions].left; ui = ui/10; if(ui >= MAX_PAINT_WIDTH_ENTRY) ui = MAX_PAINT_WIDTH_ENTRY-1; PaintWidth[category][ui] += 1; } if(! More) break; } PaintClips[category][clip] += 1; } else { PaintClips[category][0] += 1; } } } if((dumpparam & dbgflg & FL_DRV_PAINT) && breakcnt == 0) { DumpDecimal("[Paint parameter]", stat); DumpSurfObj("Target surface object", pso); DumpClipObj("Clip object", pco); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrushOrg); DumpMix("Fore & back mix mode", mix); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if(docomparison || (usedrvfunc & FL_DRV_PAINT)) { rcdrv = rc = DrvPaint( pso, pco, pbo, pptlBrushOrg, mix); } if(docomparison && (donebydrv & FL_DRV_PAINT)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_PAINT) || (docomparison && (donebydrv & FL_DRV_PAINT))) { if(traseentry & dbgflg & FL_DRV_PAINT) DISPDBG((0,"+++ Entering EngPaint +++\n")); if(breakentry & FL_DRV_PAINT) CountBreak(); CLOCKSTART((TRAP_PAINT)); rc = EngPaint( pso, pco, pbo, pptlBrushOrg, mix); CLOCKEND((TRAP_PAINT)); if(traseexit & dbgflg & FL_DRV_PAINT) DISPDBG((0,"--- Exiting EngPaint ---\n")); if(breakexit & FL_DRV_PAINT) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_PAINT)) { if(rc != rcdrv) { DISPDBG((0, "Paint return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### Paint result unmatch", stat); DumpSurfObj("Target surface object", pso); DumpClipObj("Clip object", pco); DumpBrushObj("Brush object", pbo); DumpPointl("Brush position", pptlBrushOrg); DumpMix("Fore & back mix mode", mix); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } BOOL WDrvCopyBits( SURFOBJ *psoDest, SURFOBJ *psoSrc, CLIPOBJ *pco, XLATEOBJ *pxlo, RECTL *prclDest, POINTL *pptlSrc) { BOOL rc; BOOL rcdrv; LONG stat; BOOL docomparison; docomparison = (compare & dbgflg & FL_DRV_COPYBIT) && breakcnt == 0 && ScreenBuf2; if(paramcheck & FL_DRV_COPYBIT) { ULONG category, ui, uj; ULONG histidx = 0; if(psoSrc->pvScan0 == (PVOID)ScreenBase) histidx = 2; else histidx = 0; if(psoDest->pvScan0 == (PVOID)ScreenBase) histidx += 1; ui = (prclDest->right - prclDest->left)/10; if(ui >= MAX_WIDTH_STEP) ui = MAX_WIDTH_STEP-1; CopyBitWidthHist[histidx][ui] += 1; uj = (prclDest->bottom - prclDest->top)/10; if(uj >= MAX_HEIGHT_STEP) uj = MAX_HEIGHT_STEP-1; CopyBitHeightHist[histidx][uj] += 1; if ((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)) { if (psoDest->pvScan0 != (PVOID)ScreenBase) { category=1; goto DevExitCopyBits; } if (psoSrc->pvScan0 != (PVOID)ScreenBase) { category=2; } else { category=6; } if (pco != (CLIPOBJ *)NULL) { switch(pco->iDComplexity) { case DC_TRIVIAL: break; case DC_RECT: category += 1; break; case DC_COMPLEX: category += 2; break; default: category += 3; } } goto DevExitCopyBits; } else { category=0; } DevExitCopyBits: CopyBitsHist[category] += 1; } if((dumpparam & dbgflg & FL_DRV_COPYBIT) && breakcnt == 0) { DumpDecimal("[CopyBits parameter]", stat); DumpSurfObj("Target surface object", psoDest); DumpSurfObj("Source surface object", psoSrc); DumpClipObj("Clip object", pco); DumpXlateObj("Xlate object", pxlo); DumpRectl("Target rectangle", prclDest); DumpPointl("Source position", pptlSrc); } if(docomparison) SaveScreenMem(BEFORE_SCREEN, FileNumberBase); if(docomparison || (usedrvfunc & FL_DRV_COPYBIT)) { rcdrv = rc = DrvCopyBits( psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc); } if(docomparison && (donebydrv & FL_DRV_COPYBIT)) { SaveScreenMem(AFTER_DRV, FileNumberBase); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); } if((useengfunc & FL_DRV_COPYBIT) || (docomparison && (donebydrv & FL_DRV_COPYBIT))) { if(traseentry & dbgflg & FL_DRV_COPYBIT) DISPDBG((0,"+++ Entering EngCopyBits +++\n")); if(breakentry & FL_DRV_COPYBIT) CountBreak(); CLOCKSTART((TRAP_COPYBITS)); rc = EngCopyBits( psoDest, psoSrc, pco, pxlo, prclDest, pptlSrc); CLOCKEND((TRAP_COPYBITS)); if(traseexit & dbgflg & FL_DRV_COPYBIT) DISPDBG((0,"--- Exiting EngCopyBits ---\n")); if(breakexit & FL_DRV_COPYBIT) CountBreak(); } if(docomparison && (donebydrv & FL_DRV_COPYBIT)) { if(rc != rcdrv) { DISPDBG((0, "CopyBits return code unmatch\n")); } if((stat = CompareScreenMem(AFTER_DRV, FileNumberBase)) > 0) { // Result unmatch SaveScreenMem(BEFORE_SCREEN, FileNumberBase); // Save after ENG result in first screen buf RestoreScreenMem(AFTER_DRV, FileNumberBase); // Restore result of DRV to compare DumpDecimal("### CopyBits result unmatch", stat); DumpSurfObj("Target surface object", psoDest); DumpSurfObj("Source surface object", psoSrc); DumpClipObj("Clip object", pco); DumpXlateObj("Xlate object", pxlo); DumpRectl("Target rectangle", prclDest); DumpPointl("Source position", pptlSrc); RestoreScreenMem(BEFORE_SCREEN, FileNumberBase); // Restore result of ENG to continue FileNumberBase += 1; } } return(rc); } LONG SaveScreenMem( ULONG FileCategory, ULONG FileNumber ) { switch(FileCategory) { case 0: if(ScreenBuf1 != 0) { memcpy2(ScreenBuf1, myPDEV->pjScreen, ScreenMemory, 0); return (0); } break; case 1: if(ScreenBuf2 != 0) { memcpy2(ScreenBuf2, myPDEV->pjScreen, ScreenMemory, 0); return (0); } break; } return (-1); } LONG SaveGlyphPos( STROBJ *pstro ) { ULONG i; LONG count, *lp; GLYPHPOS *pgp; count = 0; if(pstro && pstro->pgp) { lp = (PLONG) linebuf; for(i=0; icGlyphs; ++i) { if((pgp = &(pstro->pgp[i])) == NULL) continue; if(count > BUFSIZE/sizeof(LONG) - 4) { DISPDBG((0,"### SaveGlyPos buffer overflow ###\n")); continue; } *lp++ = (ULONG) pgp->hg; *lp++ = (ULONG) pgp->pgdf; *lp++ = pgp->ptl.x; *lp++ = pgp->ptl.y; count += 4; } } return (count/4); } LONG RestoreGlyphPos( STROBJ *pstro ) { ULONG i; LONG count, *lp; GLYPHPOS *pgp; count = 0; if(pstro && pstro->pgp) { lp = (PLONG) linebuf; for(i=0; icGlyphs; ++i) { if((pgp = (&pstro->pgp[i])) == NULL) continue; if(count > BUFSIZE/sizeof(LONG) - 4) { continue; } (ULONG) pgp->hg = *lp++; (ULONG) pgp->pgdf = *lp++; pgp->ptl.x = *lp++; pgp->ptl.y = *lp++; count += 4; } } return (count/4); } LONG RestoreScreenMem( ULONG FileCategory, ULONG FileNumber ) { switch(FileCategory) { case 0: if(ScreenBuf1 != 0) { memcpy2(myPDEV->pjScreen, ScreenBuf1, ScreenMemory, 0); return (0); } break; case 1: if(ScreenBuf2 != 0) { memcpy2(myPDEV->pjScreen, ScreenBuf2, ScreenMemory, 0); return (0); } break; } return (-1); } LONG CompareScreenMem( ULONG FileCategory, ULONG FileNumber ) { LONG i, pos; ULONG imgwidth; PBYTE ScreenBuf; PUCHAR pb1, pb2; switch(FileCategory) { case 0: if(ScreenBuf1 != 0) { ScreenBuf = ScreenBuf1; } else { return(0); } break; case 1: if(ScreenBuf2 != 0) { ScreenBuf = ScreenBuf2; } else { return(0); } break; default: return(0); } imgwidth = (myPDEV->cxScreen) << (myPDEV->ColorModeShift); for(i=(myPDEV->cyScreen)-1; i>=0; --i) { pb1 = (myPDEV->pjScreen) + i * (myPDEV->lDeltaScreen); pb2 = ScreenBuf + i * (myPDEV->lDeltaScreen); if((pos = memcmp2(pb2, pb1, imgwidth)) >= 0) { break; } } if(i < 0) { DISPDBG((1,"... Screen compare %u O.K. ...\r", ++comparecount)); return (0); } else { DISPDBG((0,"### Screen Compare error line %d dot %d ###\n", i+1, (pos >> (myPDEV->ColorModeShift))+1)); return (i+1); } } DRVFN gadrvfn[] = { { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, { INDEX_DrvStrokePath, (PFN) WDrvStrokePath }, { INDEX_DrvFillPath, (PFN) WDrvFillPath }, { INDEX_DrvStrokeAndFillPath, (PFN) WDrvStrokeAndFillPath }, { INDEX_DrvPaint, (PFN) WDrvPaint }, { INDEX_DrvTextOut, (PFN) WDrvTextOut }, { INDEX_DrvBitBlt, (PFN) WDrvBitBlt }, { INDEX_DrvCopyBits, (PFN) WDrvCopyBits }, { INDEX_DrvStretchBlt, (PFN) WDrvStretchBlt }, // { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, { INDEX_DrvGetModes, (PFN) DrvGetModes }, { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush } // { INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits }, // { INDEX_DrvDestroyFont, (PFN) DrvDestroyFont } }; #else // INVESTIGATE DRVFN gadrvfn[] = { { INDEX_DrvEnablePDEV, (PFN) DrvEnablePDEV }, { INDEX_DrvCompletePDEV, (PFN) DrvCompletePDEV }, { INDEX_DrvDisablePDEV, (PFN) DrvDisablePDEV }, { INDEX_DrvEnableSurface, (PFN) DrvEnableSurface }, { INDEX_DrvDisableSurface, (PFN) DrvDisableSurface }, { INDEX_DrvAssertMode, (PFN) DrvAssertMode }, // { INDEX_DrvStrokePath, (PFN) DrvStrokePath }, // { INDEX_DrvFillPath, (PFN) DrvFillPath }, // { INDEX_DrvStrokeAndFillPath, (PFN) DrvStrokeAndFillPath }, { INDEX_DrvPaint, (PFN) DrvPaint }, { INDEX_DrvTextOut, (PFN) DrvTextOut }, { INDEX_DrvBitBlt, (PFN) DrvBitBlt }, { INDEX_DrvCopyBits, (PFN) DrvCopyBits }, { INDEX_DrvStretchBlt, (PFN) DrvStretchBlt }, // { INDEX_DrvSynchronize, (PFN) DrvSynchronize }, { INDEX_DrvDitherColor, (PFN) DrvDitherColor }, // { INDEX_DrvMovePointer, (PFN) DrvMovePointer }, { INDEX_DrvSetPointerShape, (PFN) DrvSetPointerShape }, { INDEX_DrvGetModes, (PFN) DrvGetModes }, { INDEX_DrvSetPalette, (PFN) DrvSetPalette }, { INDEX_DrvRealizeBrush, (PFN) DrvRealizeBrush } // { INDEX_DrvSaveScreenBits, (PFN) DrvSaveScreenBits }, // { INDEX_DrvDestroyFont, (PFN) DrvDestroyFont } }; #endif // INVESTIGATE /******************************Public*Routine******************************\ * DrvDisableDriver * * Tells the driver it is being disabled. Release any resources allocated in * DrvEnableDriver. * \**************************************************************************/ VOID DrvDisableDriver(VOID) { #if INVESTIGATE if(traseentry & FL_DRV_DISBLDRIVER) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvDisableDriver +++\n")); if(breakentry & FL_DRV_DISBLDRIVER) EngDebugBreak(); #endif #if INVESTIGATE if(traseexit & FL_DRV_DISBLDRIVER) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvDisableDriver ---\n")); if(breakexit & FL_DRV_DISBLDRIVER) EngDebugBreak(); #endif return; } /******************************Public*Routine******************************\ * DrvEnableDriver * * Enables the driver by retrieving the drivers function table and version. * \**************************************************************************/ BOOL DrvEnableDriver( ULONG iEngineVersion, ULONG cj, PDRVENABLEDATA pded) { // Engine Version is passed down so future drivers can support previous // engine versions. A next generation driver can support both the old // and new engine conventions if told what version of engine it is // working with. For the first version the driver does nothing with it. #if INVESTIGATE if(traseentry & FL_DRV_ENBLDRIVER) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvEnableDriver +++\n")); if(breakentry & FL_DRV_ENBLDRIVER) EngDebugBreak(); InitializeTable(); #endif // Fill in as much as we can. if (cj >= sizeof(DRVENABLEDATA)) pded->pdrvfn = gadrvfn; if (cj >= (sizeof(ULONG) * 2)) pded->c = sizeof(gadrvfn) / sizeof(DRVFN); // DDI version this driver was targeted for is passed back to engine. // Future graphic's engine may break calls down to old driver format. if (cj >= sizeof(ULONG)) pded->iDriverVersion = DDI_DRIVER_VERSION; #if INVESTIGATE if(traseexit & FL_DRV_ENBLDRIVER) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvEnableDriver ---\n")); if(breakexit & FL_DRV_ENBLDRIVER) EngDebugBreak(); #endif return(TRUE); } /******************************Public*Routine******************************\ * DrvEnablePDEV * * DDI function, Enables the Physical Device. * * Return Value: device handle to pdev. * \**************************************************************************/ DHPDEV DrvEnablePDEV( DEVMODEW *pDevmode, // Pointer to DEVMODE PWSTR pwszLogAddress, // Logical address ULONG cPatterns, // number of patterns HSURF *ahsurfPatterns, // return standard patterns ULONG cjGdiInfo, // Length of memory pointed to by pGdiInfo ULONG *pGdiInfo, // Pointer to GdiInfo structure ULONG cjDevInfo, // Length of following PDEVINFO structure DEVINFO *pDevInfo, // physical device information structure HDEV hdev, // HDEV, used for callbacks PWSTR pwszDeviceName, // DeviceName - not used HANDLE hDriver) // Handle to base driver { GDIINFO GdiInfo; DEVINFO DevInfo; PPDEV ppdev = (PPDEV) NULL; #if INVESTIGATE if(traseentry & FL_DRV_ENBLPDEV) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvEnablePDEV +++\n")); if(breakentry & FL_DRV_ENBLPDEV) EngDebugBreak(); #endif // Allocate a physical device structure. ppdev = (PPDEV) EngAllocMem(FL_ZERO_MEMORY, sizeof(PDEV), ALLOC_TAG); if (ppdev == (PPDEV) NULL) { DISPDBG((0,"### Exiting DrvEnablePDEV due to EngAllocMem failure ###\n")); return((DHPDEV) 0); } // Save the screen handle in the PDEV. ppdev->hDriver = hDriver; // Get the current screen mode information. Set up device caps and devinfo. if (!bInitPDEV(ppdev, pDevmode, &GdiInfo, &DevInfo)) { DISPDBG((0,"DISP DrvEnablePDEV failed bInitPDEV\n")); goto error_free; } // Initialize the cursor information. /******* No support for the pointer ********* if (!bInitPointer(ppdev, &DevInfo)) { // Not a fatal error... DISPDBG((0,"DISP DrvEnablePDEV failed bInitPointer\n")); } ********************************************/ ppdev->pPointerAttributes = (PVIDEO_POINTER_ATTRIBUTES) NULL; ppdev->cjPointerAttributes = 0; // initialized in screen.c ppdev->PointerCapabilities.Flags = 0; // Initialize palette information. if (!bInitPaletteInfo(ppdev, &DevInfo)) { DISPDBG((0,"DISP DrvEnableSurface failed bInitPalette\n")); goto error_free; } // Copy the devinfo into the engine buffer. memcpy(pDevInfo, &DevInfo, min(sizeof(DEVINFO), cjDevInfo)); // Set the pdevCaps with GdiInfo we have prepared to the list of caps for this // pdev. memcpy(pGdiInfo, &GdiInfo, min(cjGdiInfo, sizeof(GDIINFO))); DISPDBG((1, "PDEV CREATED %x\n", ppdev)); #if INVESTIGATE InitTable = TRUE; // Reset statistics table if(traseexit & FL_DRV_ENBLPDEV) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvEnablePDEV ---\n")); if(breakexit & FL_DRV_ENBLPDEV) EngDebugBreak(); #endif return((DHPDEV) ppdev); // Error case for failure. error_free: EngFreeMem(ppdev); DISPDBG((0,"### Exiting DrvEnablePDEV with error ###\n")); return((DHPDEV) 0); } /******************************Public*Routine******************************\ * DrvCompletePDEV * * Store the HPDEV, the engines handle for this PDEV, in the DHPDEV. * \**************************************************************************/ VOID DrvCompletePDEV( DHPDEV dhpdev, HDEV hdev) { #if INVESTIGATE if(traseentry & FL_DRV_CMPLTPDEV) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvCompletePDEV +++\n")); if(breakentry & FL_DRV_CMPLTPDEV) EngDebugBreak(); #endif ((PPDEV) dhpdev)->hdevEng = hdev; #if INVESTIGATE if(traseexit & FL_DRV_CMPLTPDEV) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvCompletePDEV ---\n")); if(breakexit & FL_DRV_CMPLTPDEV) EngDebugBreak(); #endif } /******************************Public*Routine******************************\ * DrvDisablePDEV * * Release the resources allocated in DrvEnablePDEV. If a surface has been * enabled DrvDisableSurface will have already been called. * \**************************************************************************/ VOID DrvDisablePDEV( DHPDEV dhpdev) { #if INVESTIGATE if(traseentry & FL_DRV_DISBLPDEV) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvDesablePDEV +++\n")); if(breakentry & FL_DRV_DISBLPDEV) EngDebugBreak(); #endif DISPDBG((1, "--- Disable PDEV %x, myPDEV = %x ---\n", dhpdev, myPDEV)); if(dhpdev == (DHPDEV)myPDEV) { DISPDBG((0, "### myPDEV %x is disabled\n", dhpdev)); myPDEV = NULL; } vDisablePalette((PPDEV) dhpdev); EngFreeMem(dhpdev); #if BUG_5737_WORKAROUND DisplayModeChanged(); #endif #if INVESTIGATE if(traseexit & FL_DRV_DISBLPDEV) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvDisablePDEV ---\n")); if(breakexit & FL_DRV_DISBLPDEV) EngDebugBreak(); #endif } /******************************Public*Routine******************************\ * DrvEnableSurface * * Enable the surface for the device. Hook the calls this driver supports. * * Return: Handle to the surface if successful, 0 for failure. * \**************************************************************************/ HSURF DrvEnableSurface( DHPDEV dhpdev) { PPDEV ppdev; HSURF hsurf; SIZEL sizl; FLONG flHooks; #if INVESTIGATE if(traseentry & FL_DRV_ENBLSURF) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvEnableSurface +++\n")); if(breakentry & FL_DRV_ENBLSURF) EngDebugBreak(); #endif // Create engine bitmap around frame buffer. ppdev = (PPDEV) dhpdev; if (!bInitSURF(ppdev, TRUE)) { DISPDBG((0,"### Exiting DrvEnableSurface due to bInitSURF failure ###\n")); return(FALSE); } sizl.cx = ppdev->cxScreen; sizl.cy = ppdev->cyScreen; switch (ppdev->ulBitCount) { case 8: if (!bInit256ColorPalette(ppdev)) { DISPDBG((0,"### Exiting DrvEnableSurface due to failure in initializing the 8bpp palette ###\n")); return(FALSE); } ppdev->iBitmapFormat = BMF_8BPP; if(ppdev->ModelID == POWER_PRO) flHooks = (FLONG) HOOKS_BMF8BPP_PRO; else flHooks = (FLONG) HOOKS_BMF8BPP_TOP; break; case 16: ppdev->iBitmapFormat = BMF_16BPP; flHooks = (FLONG) HOOKS_BMF16BPP; break; case 32: ppdev->iBitmapFormat = BMF_32BPP; flHooks = (FLONG) HOOKS_BMF32BPP; break; default: DISPDBG((0,"### Exiting DrvEnableSurface due to ulBitCount invalid ###\n")); return FALSE; } DISPDBG((1,"Creating Bitmap %d X %d Step %d, %x, %08x\n", sizl.cx, sizl.cy, ppdev->lDeltaScreen, ppdev->iBitmapFormat, ppdev->pjScreen)); #if FULLCACHE if(ppdev->VRAMcacheflg == 0) { // Couldn't find DBAT mapping cached VRAM flHooks = 0; } hsurf = (HSURF) EngCreateBitmap(sizl, ppdev->lDeltaScreen, ppdev->iBitmapFormat, (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0, (PVOID) (ppdev->pjCachedScreen)); #else // FULLCACHE hsurf = (HSURF) EngCreateBitmap(sizl, ppdev->lDeltaScreen, ppdev->iBitmapFormat, (ppdev->lDeltaScreen > 0) ? BMF_TOPDOWN : 0, (PVOID) (ppdev->pjScreen)); #endif if (hsurf == (HSURF) 0) { DISPDBG((0,"### Exiting DrvEnableSurface due to EngCreateBitmap failure ###\n")); return(FALSE); } if (!EngAssociateSurface(hsurf, ppdev->hdevEng, flHooks)) { DISPDBG((0,"### Exiting DrvEnableSurface due to EngAssociateSurface failure ###\n")); EngDeleteSurface(hsurf); return(FALSE); } ppdev->hsurfEng = hsurf; #if INVESTIGATE { VIDEO_PUBLIC_ACCESS_RANGES VideoAccessRange; DWORD ReturnedDataLength; ppdev->TscStatusReg = NULL; if(ppdev->ModelID != POWER_PRO) { if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES, NULL, // input buffer 0, &VideoAccessRange, // output buffer sizeof(VideoAccessRange), &ReturnedDataLength)) { DISPDBG((0,"### PSIDISP.DLL: VIDEO PUBLIC ACCESS RANGE ERROR ###\n")); } else { ppdev->TscStatusReg = (UCHAR*) VideoAccessRange.VirtualAddress; } } } #endif #if INVESTIGATE if(traseexit & FL_DRV_ENBLSURF) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvEnableSurface ---\n")); if(breakexit & FL_DRV_ENBLSURF) EngDebugBreak(); #endif return(hsurf); } /******************************Public*Routine******************************\ * DrvDisableSurface * * Free resources allocated by DrvEnableSurface. Release the surface. * \**************************************************************************/ VOID DrvDisableSurface( DHPDEV dhpdev) { #if INVESTIGATE if(traseentry & FL_DRV_DISBLSURF) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvDisableSurface +++\n")); if(breakentry & FL_DRV_DISBLSURF) EngDebugBreak(); #endif #if INVESTIGATE { VIDEO_MEMORY VideoMemory; DWORD ReturnedDataLength; VideoMemory.RequestedVirtualAddress = ((PPDEV) dhpdev)->TscStatusReg; if(((PPDEV) dhpdev)->ModelID != POWER_PRO && (((PPDEV) dhpdev)->TscStatusReg)) { if (EngDeviceIoControl(((PPDEV) dhpdev)->hDriver, IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES, &VideoMemory, sizeof(VideoMemory), NULL, 0, &ReturnedDataLength)) { DISPDBG((0,"### PSIDISP.DLL: VIDEO FREE PUBLIC ACCESS RANGE ERROR ###\n")); } ((PPDEV) dhpdev)->TscStatusReg = NULL; } } #endif EngDeleteSurface(((PPDEV) dhpdev)->hsurfEng); vDisableSURF((PPDEV) dhpdev); ((PPDEV) dhpdev)->hsurfEng = (HSURF) 0; #if INVESTIGATE if(traseexit & FL_DRV_DISBLSURF) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvDisableSurface ---\n")); if(breakexit & FL_DRV_DISBLSURF) EngDebugBreak(); #endif } /******************************Public*Routine******************************\ * DrvAssertMode * * This asks the device to reset itself to the mode of the pdev passed in. * \**************************************************************************/ BOOL DrvAssertMode( DHPDEV dhpdev, BOOL bEnable) { PPDEV ppdev = (PPDEV) dhpdev; ULONG ulReturn; BOOL retval; #if INVESTIGATE if(traseentry & FL_DRV_ASSERTMODE) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvAssertMode %s +++\n", bEnable?"TRUE":"FALSE")); if(breakentry & FL_DRV_ASSERTMODE) EngDebugBreak(); #endif if (bEnable) { // The screen must be reenabled, reinitialize the device to clean state. retval = bInitSURF(ppdev, FALSE); } else { // We must give up the display. // Call the kernel driver to reset the device to a known state. if (EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_RESET_DEVICE, NULL, 0, NULL, 0, &ulReturn)) { DISPDBG((0,"DISP DrvAssertMode failed IOCTL")); retval = FALSE; } else { retval = TRUE; } } #if INVESTIGATE if(traseexit & FL_DRV_ASSERTMODE) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvAssertMode ---\n")); if(breakexit & FL_DRV_ASSERTMODE) EngDebugBreak(); #endif return retval; } /******************************Public*Routine******************************\ * DrvGetModes * * Returns the list of available modes for the device. * \**************************************************************************/ ULONG DrvGetModes( HANDLE hDriver, ULONG cjSize, DEVMODEW *pdm) { DWORD cModes; DWORD cbOutputSize; PVIDEO_MODE_INFORMATION pVideoModeInformation, pVideoTemp; DWORD cOutputModes = cjSize / (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); DWORD cbModeSize; #if INVESTIGATE if(traseentry & FL_DRV_GETMODE) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvGetModes +++\n")); if(breakentry & FL_DRV_GETMODE) EngDebugBreak(); #endif cModes = getAvailableModes(hDriver, (PVIDEO_MODE_INFORMATION *) &pVideoModeInformation, &cbModeSize); if (cModes == 0) { DISPDBG((0, "### psidisp DrvGetModes failed to get mode information ###")); return 0; } if (pdm == NULL) { cbOutputSize = cModes * (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); } else { // // Now copy the information for the supported modes back into the output // buffer // cbOutputSize = 0; pVideoTemp = pVideoModeInformation; do { if (pVideoTemp->Length != 0) { if (cOutputModes == 0) { break; } // // Zero the entire structure to start off with. // memset(pdm, 0, sizeof(DEVMODEW)); // // Set the name of the device to the name of the DLL. // memcpy(pdm->dmDeviceName, DLL_NAME, sizeof(DLL_NAME)); pdm->dmSpecVersion = DM_SPECVERSION; pdm->dmDriverVersion = DM_SPECVERSION; pdm->dmSize = sizeof(DEVMODEW); pdm->dmDriverExtra = DRIVER_EXTRA_SIZE; pdm->dmBitsPerPel = pVideoTemp->NumberOfPlanes * pVideoTemp->BitsPerPlane; pdm->dmPelsWidth = pVideoTemp->VisScreenWidth; pdm->dmPelsHeight = pVideoTemp->VisScreenHeight; pdm->dmDisplayFrequency = pVideoTemp->Frequency; pdm->dmDisplayFlags = 0; pdm->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS ; // // Go to the next DEVMODE entry in the buffer. // cOutputModes--; pdm = (LPDEVMODEW) ( ((ULONG)pdm) + sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); cbOutputSize += (sizeof(DEVMODEW) + DRIVER_EXTRA_SIZE); } pVideoTemp = (PVIDEO_MODE_INFORMATION) (((PUCHAR)pVideoTemp) + cbModeSize); } while (--cModes); } EngFreeMem(pVideoModeInformation); #if INVESTIGATE if(traseexit & FL_DRV_GETMODE) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvGetModes ---\n")); if(breakexit & FL_DRV_GETMODE) EngDebugBreak(); #endif return cbOutputSize; } /******************************Public*Routine******************************\ * DrvSetPointerShape * * Tells the driver the shape of the driver. Since this driver doesn't * support pointer, this shouldn't be called (with NULL POINTER capability * flag, but it's called and if this entry doesn't exist, display driver * crashes, so we need this entry doing nothing. * \**************************************************************************/ ULONG DrvSetPointerShape ( SURFOBJ *pso, SURFOBJ *psoMask, SURFOBJ *psoColor, XLATEOBJ *pxlo, LONG xHot, LONG yHot, LONG x, LONG y, RECTL *prcl, FLONG fl ) { #if INVESTIGATE if(traseentry & dbgflg & FL_DRV_POINTERSHAPE) DISPDBG((0,"+++ PSIDISP.DLL: Entering DrvSetPointerShape +++\n")); if(breakentry & FL_DRV_POINTERSHAPE) CountBreak(); #endif CLOCKSTART((TRAP_SETPOINTER)); CLOCKEND((TRAP_SETPOINTER)); #if INVESTIGATE if(traseexit & dbgflg & FL_DRV_POINTERSHAPE) DISPDBG((0,"--- PSIDISP.DLL: Exiting DrvSetPointerShape ---\n")); if(breakexit & FL_DRV_POINTERSHAPE) CountBreak(); #endif return(SPS_DECLINE); }