mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1475 lines
41 KiB
1475 lines
41 KiB
/*
|
|
* Copyright (c) 1995 FirePower Systems, Inc.
|
|
* DO NOT DISTRIBUTE without permission
|
|
*
|
|
* $RCSfile: debug.c $
|
|
* $Revision: 1.1 $
|
|
* $Date: 1996/03/08 01:19:00 $
|
|
* $Locker: $
|
|
*/
|
|
/******************************Module*Header*******************************\
|
|
* Module Name: debug.c
|
|
*
|
|
* debug helpers routine
|
|
*
|
|
* Copyright (c) 1992-1995 Microsoft Corporation
|
|
*
|
|
* Copyright (c) 1994 FirePower Systems, Inc.
|
|
* Modified for FirePower display model by Neil Ogura (9-7-1994)
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "driver.h"
|
|
|
|
#if DBG || INVESTIGATE
|
|
|
|
#include <stdio.h>
|
|
|
|
#endif
|
|
|
|
#if DBG
|
|
|
|
#define DUMP_PARAM_LEVEL 0
|
|
ULONG DebugLevel = 0;
|
|
|
|
#endif
|
|
|
|
#if INVESTIGATE
|
|
|
|
#include <stdarg.h>
|
|
|
|
#define MEMMAXBANDWIDTH FALSE
|
|
#define MEMCPYPERFORM FALSE
|
|
#define MEMCPYVERIFY FALSE
|
|
|
|
#define SMP_TRACE FALSE
|
|
|
|
static char *bittable[256] = {
|
|
"........",".......*","......*.","......**",".....*..",".....*.*",".....**.",".....***",
|
|
"....*...","....*..*","....*.*.","....*.**","....**..","....**.*","....***.","....****",
|
|
"...*....","...*...*","...*..*.","...*..**","...*.*..","...*.*.*","...*.**.","...*.***",
|
|
"...**...","...**..*","...**.*.","...**.**","...***..","...***.*","...****.","...*****",
|
|
"..*.....","..*....*","..*...*.","..*...**","..*..*..","..*..*.*","..*..**.","..*..***",
|
|
"..*.*...","..*.*..*","..*.*.*.","..*.*.**","..*.**..","..*.**.*","..*.***.","..*.****",
|
|
"..**....","..**...*","..**..*.","..**..**","..**.*..","..**.*.*","..**.**.","..**.***",
|
|
"..***...","..***..*","..***.*.","..***.**","..****..","..****.*","..*****.","..******",
|
|
".*......",".*.....*",".*....*.",".*....**",".*...*..",".*...*.*",".*...**.",".*...***",
|
|
".*..*...",".*..*..*",".*..*.*.",".*..*.**",".*..**..",".*..**.*",".*..***.",".*..****",
|
|
".*.*....",".*.*...*",".*.*..*.",".*.*..**",".*.*.*..",".*.*.*.*",".*.*.**.",".*.*.***",
|
|
".*.**...",".*.**..*",".*.**.*.",".*.**.**",".*.***..",".*.***.*",".*.****.",".*.*****",
|
|
".**.....",".**....*",".**...*.",".**...**",".**..*..",".**..*.*",".**..**.",".**..***",
|
|
".**.*...",".**.*..*",".**.*.*.",".**.*.**",".**.**..",".**.**.*",".**.***.",".**.****",
|
|
".***....",".***...*",".***..*.",".***..**",".***.*..",".***.*.*",".***.**.",".***.***",
|
|
".****...",".****..*",".****.*.",".****.**",".*****..",".*****.*",".******.",".*******",
|
|
"*.......","*......*","*.....*.","*.....**","*....*..","*....*.*","*....**.","*....***",
|
|
"*...*...","*...*..*","*...*.*.","*...*.**","*...**..","*...**.*","*...***.","*...****",
|
|
"*..*....","*..*...*","*..*..*.","*..*..**","*..*.*..","*..*.*.*","*..*.**.","*..*.***",
|
|
"*..**...","*..**..*","*..**.*.","*..**.**","*..***..","*..***.*","*..****.","*..*****",
|
|
"*.*.....","*.*....*","*.*...*.","*.*...**","*.*..*..","*.*..*.*","*.*..**.","*.*..***",
|
|
"*.*.*...","*.*.*..*","*.*.*.*.","*.*.*.**","*.*.**..","*.*.**.*","*.*.***.","*.*.****",
|
|
"*.**....","*.**...*","*.**..*.","*.**..**","*.**.*..","*.**.*.*","*.**.**.","*.**.***",
|
|
"*.***...","*.***..*","*.***.*.","*.***.**","*.****..","*.****.*","*.*****.","*.******",
|
|
"**......","**.....*","**....*.","**....**","**...*..","**...*.*","**...**.","**...***",
|
|
"**..*...","**..*..*","**..*.*.","**..*.**","**..**..","**..**.*","**..***.","**..****",
|
|
"**.*....","**.*...*","**.*..*.","**.*..**","**.*.*..","**.*.*.*","**.*.**.","**.*.***",
|
|
"**.**...","**.**..*","**.**.*.","**.**.**","**.***..","**.***.*","**.****.","**.*****",
|
|
"***.....","***....*","***...*.","***...**","***..*..","***..*.*","***..**.","***..***",
|
|
"***.*...","***.*..*","***.*.*.","***.*.**","***.**..","***.**.*","***.***.","***.****",
|
|
"****....","****...*","****..*.","****..**","****.*..","****.*.*","****.**.","****.***",
|
|
"*****...","*****..*","*****.*.","*****.**","******..","******.*","*******.","********"
|
|
};
|
|
|
|
static CHAR dbgbuf[1024];
|
|
|
|
#define MAX_CRITICAL 6 // Number of maximum critical sections where CPU switch shouldn't happen
|
|
#define MAX_STEP 100
|
|
#define RECORDINTERVAL 30000000 // Measure and out statistics every INTERVAL * 0.01 ms
|
|
#define INITIALINTERVAL 12000000 // Initial addtion to the interval
|
|
#define MAX_HOOKED_OPS 20 // Number of hooked operations by DrbBitBlt
|
|
|
|
static ULONG FileId = 0;
|
|
static FILE *stream = NULL;
|
|
static ULONG startsec[MAX_TRAP], activated = 0, timercount=0, clockoverhead = 0;
|
|
static ULONG numcalled[MAX_TRAP];
|
|
static ULONG totalelapse[MAX_TRAP];
|
|
static ULONG distribution[MAX_TRAP][MAX_STEP];
|
|
static ULONG enterCPU[MAX_TRAP];
|
|
static ULONG CPUSwitch[MAX_TRAP][4];
|
|
static ULONG SwitchDuringCritical[MAX_CRITICAL];
|
|
static ULONG TotalCritical[MAX_CRITICAL];
|
|
static UCHAR EnterCriticalCPU[MAX_CRITICAL];
|
|
static CHAR *TrapName[MAX_TRAP] = {
|
|
"BITBLT","COPYBITS","STRETCHBLT","PLGBLT", "FILLPATH","STROKENFIL","TEXTOUT","PAINT","STROKEPATH","REALIZE_BRUSH",
|
|
"DRV_BITBLT","DRV_COPYBITS","DRV_STRETCHBLT","DRV_PLGBLT", "DRV_FILLPATH","DRV_STROKENFIL","DRV_TEXTOUT","DRV_PAINT","DRV_STROKEPATH","DRV_REALIZE_BRUSH",
|
|
"DITHER","SETPOINTERSHAPE","SETPALETTE","SAVESCREEN","DESTROYFONT"
|
|
};
|
|
static CHAR *TextPerfCtgry[4] = {"Opaque no clipping", "Opaque with clipping",
|
|
"Transparent no clipping", "Transparent with clipping" };
|
|
static CHAR *CriticalNames[MAX_CRITICAL] = {
|
|
"RectFill", "RectOp", "RectCopy", "OpTgt", "PatFill", "EntireText" };
|
|
static CHAR *PaintCatNames[MAX_PAINT_CATEGORY] = {
|
|
"SolidFill", "PatFill", "SolidOp", "PatOp", "NotSupported" };
|
|
static CHAR *PaintOpNames[MAX_PAINT_OPS] = {
|
|
"ff", "00", "05", "0a", "0f", "50", "55", "5a", "5f", "a0",
|
|
"a5", "aa", "af", "f0", "f5", "fa", "Pat-5a", "Pat-f0", "Pat-0f", "Pat-a5" };
|
|
static ULONG HookedBitBltOp[MAX_HOOKED_OPS] = {0x00000000, 0x0000ffff, 0x1111f0f0, 0xfffff0f0, 0x11110f0f, 0x00005555,
|
|
0x11115a5a, 0x1111a5a5, 0xffff5a5a, 0xffffa5a5, 0xffff0a0a, 0xffffa0a0, 0x1111b8b8,
|
|
0x00006666, 0x00008888, 0x0000eeee, 0x0000bbbb, 0x00004444, 0x00001111, 0x00003333 };
|
|
|
|
LONG TimesToMeasure = 1;
|
|
ULONG Interval = INITIALINTERVAL;
|
|
ULONG spentindrv;
|
|
BOOL InitTable;
|
|
|
|
ULONG FontTblMax, GlyphTblMax, CacheTblMax;
|
|
ULONG CopyBitsHist[MAX_CATEGORY];
|
|
ULONG BitBltHist[MAX_CATEGORY];
|
|
ULONG TextOutHist[MAX_TEXT_CATEGORY];
|
|
ULONG fontSize[MAX_FONT_SIZE];
|
|
ULONG GlyphCountTable[MAX_GLYPH_COUNT];
|
|
ULONG FontAccl[MAX_CATEGORY];
|
|
ULONG TextRect[MAX_TEXT_RECT];
|
|
ULONG TextClip[MAX_CLIP_CONDITION];
|
|
ULONG TextWidthHist[6][MAX_WIDTH_STEP];
|
|
ULONG TextHeightHist[6][MAX_HEIGHT_STEP];
|
|
ULONG FontWidth[MAX_FONT_SIZE];
|
|
ULONG FontHeight[MAX_FONT_SIZE];
|
|
ULONG StrObjCountTable[MAX_STROBJ_COUNT];
|
|
ULONG FontIDTable[MAX_FONT_ENTRY][2];
|
|
ULONG GlyphHndlTable[MAX_GLYPH_HNDL_ENTRY][2];
|
|
ULONG CacheTable[MAX_CACHE_ENTRY][3];
|
|
ULONG CopyBitWidthHist[4][MAX_WIDTH_STEP];
|
|
ULONG CopyBitHeightHist[4][MAX_HEIGHT_STEP];
|
|
ULONG BitBltWidthHist[6][MAX_WIDTH_STEP];
|
|
ULONG BitBltHeightHist[6][MAX_HEIGHT_STEP];
|
|
ULONG BitBltRop[37][MAX_ROP_ENTRY];
|
|
ULONG BitBltBrush[2][MAX_BRUSH_ENTRY];
|
|
ULONG TextPerfByCtgry[4][2];
|
|
ULONG TextSubEntryCalled[MAX_TEXT_SUB_ENTRY];
|
|
ULONG TextSubEntryDCBZCalled[MAX_TEXT_SUB_ENTRY];
|
|
ULONG TextSubEntryTransCalled[MAX_TEXT_SUB_ENTRY];
|
|
ULONG PaintOp[MAX_PAINT_OPS];
|
|
ULONG PaintCategories[MAX_PAINT_CATEGORY];
|
|
ULONG PaintClips[MAX_PAINT_CATEGORY-1][MAX_PAINT_CLIP_ENTRY];
|
|
ULONG PaintHeight[MAX_PAINT_CATEGORY-1][MAX_PAINT_HEIGHT_ENTRY];
|
|
ULONG PaintWidth[MAX_PAINT_CATEGORY-1][MAX_PAINT_WIDTH_ENTRY];
|
|
ULONG PaintBounds[MAX_PAINT_CATEGORY-1][MAX_PAINT_BOUNDS_ENTRY];
|
|
|
|
VOID DisplayPDEV();
|
|
|
|
VOID PerformCheck(
|
|
ULONG start,
|
|
ULONG end,
|
|
ULONG step,
|
|
ULONG height);
|
|
|
|
VOID VramAccess();
|
|
|
|
ULONG GetTime();
|
|
|
|
LONG
|
|
SaveScreenMem(
|
|
ULONG FileCategory,
|
|
ULONG FileNumber
|
|
);
|
|
|
|
LONG
|
|
RestoreScreenMem(
|
|
ULONG FileCategory,
|
|
ULONG FileNumber
|
|
);
|
|
|
|
VOID
|
|
InitializeTable()
|
|
{
|
|
ULONG ui, uj;
|
|
|
|
// Initialize table
|
|
for(ui=0; ui<MAX_TRAP; ++ui) {
|
|
startsec[ui] = numcalled[ui] = totalelapse[ui] = 0;
|
|
for(uj=0; uj<MAX_STEP; ++uj) {
|
|
distribution[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<4; ++uj) {
|
|
CPUSwitch[ui][uj] = 0;
|
|
}
|
|
}
|
|
for(ui=0; ui<MAX_CRITICAL; ++ui) {
|
|
SwitchDuringCritical[ui] = TotalCritical[ui] = 0;
|
|
}
|
|
FontTblMax = GlyphTblMax = CacheTblMax = 0;
|
|
for(ui=0; ui<MAX_CATEGORY; ++ui) {
|
|
CopyBitsHist[ui] = FontAccl[ui] = BitBltHist[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_TEXT_CATEGORY; ++ui) {
|
|
TextOutHist[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_TEXT_RECT; ++ui) {
|
|
TextRect[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_CLIP_CONDITION; ++ui) {
|
|
TextClip[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_FONT_SIZE; ++ui) {
|
|
fontSize[ui] = FontWidth[ui] = FontHeight[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_GLYPH_COUNT; ++ui) {
|
|
GlyphCountTable[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_STROBJ_COUNT; ++ui) {
|
|
StrObjCountTable[ui] = 0;
|
|
}
|
|
for(ui=0; ui<4; ++ui) {
|
|
for(uj=0; uj<2; ++uj)
|
|
TextPerfByCtgry[ui][uj] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_TEXT_SUB_ENTRY; ++ui) {
|
|
TextSubEntryCalled[ui] = 0;
|
|
TextSubEntryDCBZCalled[ui] = 0;
|
|
TextSubEntryTransCalled[ui] = 0;
|
|
}
|
|
for(ui=0; ui<4; ++ui) {
|
|
for(uj=0; uj<MAX_WIDTH_STEP; ++uj) {
|
|
CopyBitWidthHist[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<MAX_HEIGHT_STEP; ++uj) {
|
|
CopyBitHeightHist[ui][uj] = 0;
|
|
}
|
|
}
|
|
for(ui=0; ui<6; ++ui) {
|
|
for(uj=0; uj<MAX_WIDTH_STEP; ++uj) {
|
|
BitBltWidthHist[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<MAX_HEIGHT_STEP; ++uj) {
|
|
BitBltHeightHist[ui][uj] = 0;
|
|
}
|
|
}
|
|
for(ui=0; ui<6; ++ui) {
|
|
for(uj=0; uj<MAX_WIDTH_STEP; ++uj) {
|
|
TextWidthHist[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<MAX_HEIGHT_STEP; ++uj) {
|
|
TextHeightHist[ui][uj] = 0;
|
|
}
|
|
}
|
|
for(ui=0; ui<37; ++ui) {
|
|
for(uj=0; uj<MAX_ROP_ENTRY; ++uj)
|
|
BitBltRop[ui][uj] = 0;
|
|
}
|
|
for(ui=0; ui<2; ++ui) {
|
|
for(uj=0; uj<MAX_BRUSH_ENTRY; ++uj)
|
|
BitBltBrush[ui][uj] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY; ++ui) {
|
|
PaintCategories[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_OPS; ++ui) {
|
|
PaintOp[ui] = 0;
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY-1; ++ui) {
|
|
for(uj=0; uj<MAX_PAINT_CLIP_ENTRY; ++uj) {
|
|
PaintClips[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<MAX_PAINT_HEIGHT_ENTRY; ++uj) {
|
|
PaintHeight[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<MAX_PAINT_WIDTH_ENTRY; ++uj) {
|
|
PaintWidth[ui][uj] = 0;
|
|
}
|
|
for(uj=0; uj<MAX_PAINT_BOUNDS_ENTRY; ++uj) {
|
|
PaintBounds[ui][uj] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID
|
|
RecordPerformance()
|
|
{
|
|
ULONG ui, uj, time;
|
|
|
|
// oneshot = 1;
|
|
|
|
if(FileId == 0) { // The first call
|
|
clockoverhead = 0;
|
|
for(ui=0; ui<10; ++ui) {
|
|
time = GetTime();
|
|
clockoverhead += (GetTime() - time);
|
|
}
|
|
clockoverhead /= 10;
|
|
InitializeTable();
|
|
InitTable = FALSE;
|
|
Interval = RECORDINTERVAL;
|
|
FileId = 1;
|
|
// DisplayPDEV();
|
|
DISPDBG((0,"Statistic table initialized overhead = %d.%02d\n", clockoverhead/100, clockoverhead%100));
|
|
#if DBG
|
|
// EngDebugBreak();
|
|
#endif
|
|
} else {
|
|
|
|
// Change continue to break for the function you need performance data.
|
|
// It will prints function name, # of calls and elapse time.
|
|
// As a default, BitBlt and Paint information will be displayed.
|
|
|
|
for(ui=0; ui<MAX_TRAP; ++ui) {
|
|
switch(ui) {
|
|
case TRAP_BITBLT: break;
|
|
case TRAP_COPYBITS: continue;
|
|
case TRAP_STRETCHBLT: continue;
|
|
case TRAP_PLGBLT: continue;
|
|
case TRAP_FILLPATH: continue;
|
|
case TRAP_STROKENFIL: continue;
|
|
case TRAP_TEXTOUT: continue;
|
|
case TRAP_PAINT: break;
|
|
case TRAP_STROKEPATH: continue;
|
|
case TRAP_REALIZE_BRUSH: continue;
|
|
|
|
case DRV_TRAP_BITBLT: break;
|
|
case DRV_TRAP_COPYBITS: continue;
|
|
case DRV_TRAP_STRETCHBLT: continue;
|
|
case DRV_TRAP_PLGBLT: continue;
|
|
case DRV_TRAP_FILLPATH: continue;
|
|
case DRV_TRAP_STROKENFIL: continue;
|
|
case DRV_TRAP_TEXTOUT: continue;
|
|
case DRV_TRAP_PAINT: break;
|
|
case DRV_TRAP_STROKEPATH: continue;
|
|
case DRV_REALIZE_BRUSH: continue;
|
|
|
|
case TRAP_DITHER: continue;
|
|
case TRAP_SETPOINTER: continue;
|
|
case TRAP_SETPALETTE: continue;
|
|
case TRAP_SVSCRNBIT: continue;
|
|
case TRAP_DESTRYFONT: continue;
|
|
}
|
|
DISPDBG((1, "%s %u %u.%02u\n", TrapName[ui], numcalled[ui], totalelapse[ui]/100, totalelapse[ui]%100));
|
|
}
|
|
|
|
if(MAX_CATEGORY >= 10)
|
|
DISPDBG((1, "BitBlt category: %u %u %u %u %u %u %u %u %u %u\n",
|
|
BitBltHist[0], BitBltHist[1], BitBltHist[2], BitBltHist[3], BitBltHist[4],
|
|
BitBltHist[5], BitBltHist[6], BitBltHist[7], BitBltHist[8], BitBltHist[9]));
|
|
|
|
DISPDBG((1, "BitBlt ROP table count ave-width\n"));
|
|
for(ui=0; ui<MAX_ROP_ENTRY; ++ui) {
|
|
if(BitBltRop[1][ui] == 0)
|
|
break;
|
|
for(uj=0; uj < MAX_HOOKED_OPS; ++uj) {
|
|
if(BitBltRop[0][ui] == HookedBitBltOp[uj])
|
|
break;
|
|
}
|
|
if(uj < MAX_HOOKED_OPS)
|
|
uj = 1;
|
|
else
|
|
uj = 0;
|
|
DISPDBG((1, " %6u.%02u %04x-%s %c %8u %4u\n",
|
|
BitBltRop[2][ui]/100, BitBltRop[2][ui]%100, BitBltRop[0][ui] & 0xffff,
|
|
(BitBltRop[0][ui] & 0xffff0000)?(((BitBltRop[0][ui] & 0xffff0000) == 0xffff0000)?"PatBrush":"SolBrush"):"NoBrush ", uj?'*':' ',
|
|
BitBltRop[1][ui], BitBltRop[3][ui]/BitBltRop[1][ui]));
|
|
}
|
|
|
|
// InitTable = TRUE;
|
|
|
|
/****** sprintf and file I/O is not available from NT 4.0, so it's commented out,
|
|
in case we need special performance data, we can use DebugPrint for the data.
|
|
For now, only limited performance data is printed.
|
|
|
|
CHAR fname[30];
|
|
ULONG length;
|
|
|
|
sprintf(fname, "C:\\TMP\\DSP%05d.txt", FileId++);
|
|
|
|
if((stream = fopen(fname, "w")) != NULL) {
|
|
length = sprintf(dbgbuf, "PSIDISP-%d #OfCalls Total", FileId-1);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=1; ui<MAX_STEP; ++ui) {
|
|
length = sprintf(dbgbuf, " ~%d.%d", ui/10, ui%10);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, " %d.%d~\n", (MAX_STEP-1)/10, (MAX_STEP-1)%10);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_TRAP; ++ui) {
|
|
length = sprintf(dbgbuf, "%s %u %u.%02u", TrapName[ui], numcalled[ui], totalelapse[ui]/100, totalelapse[ui]%100);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
|
|
for(uj=0; uj<MAX_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, " %u", distribution[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
#if SMP_TRACE
|
|
length = sprintf(dbgbuf, "[0->0]: %d, [0->1]: %d, [1->0]: %d, [1->1]: %d\n",
|
|
CPUSwitch[ui][0], CPUSwitch[ui][1], CPUSwitch[ui][2], CPUSwitch[ui][3]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
#endif
|
|
}
|
|
#if SMP_TRACE
|
|
length = sprintf(dbgbuf, "\nCPU Switch dring critical section\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_CRITICAL; ++ui) {
|
|
if(TotalCritical[ui]) {
|
|
length = sprintf(dbgbuf, "[%s] %u out of %u (%d.%03d%%)\n", CriticalNames[ui], SwitchDuringCritical[ui], TotalCritical[ui],
|
|
SwitchDuringCritical[ui]*100/TotalCritical[ui],
|
|
(SwitchDuringCritical[ui]*100000/TotalCritical[ui])%100);
|
|
} else {
|
|
length = sprintf(dbgbuf, "[%s] %u out of %u (0.0%%)\n", CriticalNames[ui], SwitchDuringCritical[ui], TotalCritical[ui]);
|
|
}
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
#endif
|
|
length = sprintf(dbgbuf, "\nBitBlt Category\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_CATEGORY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", BitBltHist[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nCopyBit Category\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_CATEGORY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", CopyBitsHist[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nTextOut Category\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_TEXT_CATEGORY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", TextOutHist[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nFontAccl Category\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_CATEGORY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", FontAccl[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nText subroutines called\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_TEXT_SUB_ENTRY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", TextSubEntryCalled[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nText subroutines called with DCBZ\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_TEXT_SUB_ENTRY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", TextSubEntryDCBZCalled[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nTransparent text subroutines called\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_TEXT_SUB_ENTRY; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", TextSubEntryTransCalled[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nText Rectangles\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_TEXT_RECT; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", TextRect[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nText rectangles size distribution Top, Bottom, Left, Right, Extra, Text");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<6; ++ui) {
|
|
length = sprintf(dbgbuf, "\nText Rectangles Width Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_WIDTH_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", TextWidthHist[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\n Text Rectangles Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_HEIGHT_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", TextHeightHist[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
length = sprintf(dbgbuf, "\nText Clipping Conditions\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_CLIP_CONDITION; ++ui) {
|
|
length = sprintf(dbgbuf, "%6u", TextClip[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nFont Size Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_FONT_SIZE; ++ui) {
|
|
length = sprintf(dbgbuf, "%u ", fontSize[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nFont Width Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_FONT_SIZE; ++ui) {
|
|
length = sprintf(dbgbuf, "%u ", FontWidth[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nFont Height Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_FONT_SIZE; ++ui) {
|
|
length = sprintf(dbgbuf, "%u ", FontHeight[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nCopyBit size distribution D->D, D->V, V->D, V->V");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<4; ++ui) {
|
|
length = sprintf(dbgbuf, "\nWidth Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_WIDTH_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", CopyBitWidthHist[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nHeight Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_HEIGHT_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", CopyBitHeightHist[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
length = sprintf(dbgbuf, "\nBitBlt size distribution N->D, N->V, D->D, D->V, V->D, V->V");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<6; ++ui) {
|
|
length = sprintf(dbgbuf, "\nWidth Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_WIDTH_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", BitBltWidthHist[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nHeight Distribution\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_HEIGHT_STEP; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", BitBltHeightHist[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
length = sprintf(dbgbuf, "\nGlyph Count Table\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_GLYPH_COUNT; ++ui) {
|
|
length = sprintf(dbgbuf, "%u ", GlyphCountTable[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nSTROBJ Count Table\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_STROBJ_COUNT; ++ui) {
|
|
length = sprintf(dbgbuf, "%u ", StrObjCountTable[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
|
|
length = sprintf(dbgbuf, "\nFontId Table (%u)\n", FontTblMax);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<FontTblMax; ++ui) {
|
|
length = sprintf(dbgbuf, "0x%08x - %d\n", FontIDTable[ui][0], FontIDTable[ui][1]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nGlyph Table (%u)\n", GlyphTblMax);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<GlyphTblMax; ++ui) {
|
|
length = sprintf(dbgbuf, "0x%08x - %d\n",
|
|
GlyphHndlTable[ui][0], GlyphHndlTable[ui][1]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\nFontId Table (%u)\n", CacheTblMax);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<CacheTblMax; ++ui) {
|
|
length = sprintf(dbgbuf, "0x%08x - 0x%08x - %d\n",
|
|
CacheTable[ui][0], CacheTable[ui][1], CacheTable[ui][2]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
|
|
length = sprintf(dbgbuf, "\nBitBlt ROP table\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(ui=0; ui<MAX_ROP_ENTRY; ++ui) {
|
|
if(BitBltRop[1][ui] == 0)
|
|
break;
|
|
for(uj=0; uj < MAX_HOOKED_OPS; ++uj) {
|
|
if(BitBltRop[0][ui] == HookedBitBltOp[uj])
|
|
break;
|
|
}
|
|
if(uj < MAX_HOOKED_OPS)
|
|
uj = 1;
|
|
else
|
|
uj = 0;
|
|
length = sprintf(dbgbuf, "%6u.%02u %04x-%s %c called:%u avg_width:%u src_VRAM:%u\n",
|
|
BitBltRop[2][ui]/100, BitBltRop[2][ui]%100, BitBltRop[0][ui] & 0xffff,
|
|
(BitBltRop[0][ui] & 0xffff0000)?(((BitBltRop[0][ui] & 0xffff0000) == 0xffff0000)?"PatBrush":"SolBrush"):"NoBrush", uj?'*':' ',
|
|
BitBltRop[1][ui], BitBltRop[3][ui]/BitBltRop[1][ui], BitBltRop[4][ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<32; ++uj) {
|
|
length = sprintf(dbgbuf, " %u", BitBltRop[uj+5][ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
length = sprintf(dbgbuf, "\n");
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
for(ui=0; ui<MAX_BRUSH_ENTRY; ++ui) {
|
|
if(BitBltBrush[1][ui] == 0)
|
|
break;
|
|
length = sprintf(dbgbuf, "BitBlt Sold Brush %04x:%u\n",
|
|
BitBltBrush[0][ui], BitBltBrush[1][ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
for(ui=0; ui<4; ++ui) {
|
|
length = sprintf(dbgbuf, "TextOut %s %u times, %d.%02d msec\n",
|
|
TextPerfCtgry[ui], TextPerfByCtgry[ui][0],
|
|
TextPerfByCtgry[ui][1]/100, TextPerfByCtgry[ui][1]%100);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_OPS; ++ui) {
|
|
length = sprintf(dbgbuf, "Paint OP %s : %d\n",
|
|
PaintOpNames[ui], PaintOp[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY; ++ui) {
|
|
length = sprintf(dbgbuf, "Paint category %s : %d\n",
|
|
PaintCatNames[ui], PaintCategories[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY-1; ++ui) {
|
|
length = sprintf(dbgbuf, "\nPaint CLIP distribution for %s\n", PaintCatNames[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_PAINT_CLIP_ENTRY; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", PaintClips[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY-1; ++ui) {
|
|
length = sprintf(dbgbuf, "\nPaint Height distribution for %s\n", PaintCatNames[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_PAINT_HEIGHT_ENTRY; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", PaintHeight[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY-1; ++ui) {
|
|
length = sprintf(dbgbuf, "\nPaint Width distribution for %s\n", PaintCatNames[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_PAINT_WIDTH_ENTRY; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", PaintWidth[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
for(ui=0; ui<MAX_PAINT_CATEGORY-1; ++ui) {
|
|
length = sprintf(dbgbuf, "\nPaint Bounds distribution for %s\n", PaintCatNames[ui]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
for(uj=0; uj<MAX_PAINT_BOUNDS_ENTRY; ++uj) {
|
|
length = sprintf(dbgbuf, "%u ", PaintBounds[ui][uj]);
|
|
fwrite(dbgbuf, 1, length, stream);
|
|
}
|
|
}
|
|
fclose(stream);
|
|
DISPDBG((0,"### Performance file %s created ###\n", fname));
|
|
} else {
|
|
DISPDBG((0,"### Performance file creation error ###\n"));
|
|
}
|
|
***************************************************************************/
|
|
if(InitTable) {
|
|
InitializeTable();
|
|
InitTable = FALSE;
|
|
DISPDBG((0,"Statistic table initialized\n"));
|
|
}
|
|
}
|
|
|
|
#if MEMCPYVERIFY
|
|
{
|
|
char buf1[1024], buf2[1024], buf3[512], buf4[512];
|
|
int i, j, k, l, rc1, rc2;
|
|
|
|
for(i=0; i<32; ++i) {
|
|
for(j=0; j<32; ++j) {
|
|
for(k=0; k<256; ++k) {
|
|
for(l=0; l<512; ++l) {
|
|
buf1[l] = buf3[l] = 0;
|
|
buf2[l] = buf4[l] = l;
|
|
}
|
|
memcpy(buf1+128+i, buf2+128+j, k);
|
|
memcpy2(buf3+128+i, buf4+128+j, k, TFLUSHBIT | TTOUCHBIT | SFLUSHBIT);
|
|
if(memcmp(buf1, buf3, 512) || memcmp(buf2, buf4, 512)) {
|
|
DISPDBG((0, "memcpy2 error 1 i=%d j=%d k=%d\n", i, j, k));
|
|
#if DBG
|
|
EngDebugBreak();
|
|
#endif
|
|
for(l=0; l<512; ++l) {
|
|
buf1[l] = buf3[l] = 0;
|
|
buf2[l] = buf4[l] = l;
|
|
}
|
|
memcpy2(buf3+128+i, buf4+128+j, k, TFLUSHBIT | TTOUCHBIT | SFLUSHBIT);
|
|
}
|
|
for(l=0; l<512; ++l) {
|
|
buf1[l] = buf3[l] = 0xff;
|
|
buf2[l] = buf4[l] = l;
|
|
}
|
|
memcpy2(buf1+128+i, buf2+128+j, k, TFLUSHBIT | TTOUCHBIT | SFLUSHBIT);
|
|
memcpy(buf3+128+i, buf4+128+j, k);
|
|
if(memcmp(buf1, buf3, 512) || memcmp(buf2, buf4, 512)) {
|
|
DISPDBG((0, "memcpy2 error 2 i=%d j=%d k=%d\n", i, j, k));
|
|
#if DBG
|
|
EngDebugBreak();
|
|
#endif
|
|
for(l=0; l<512; ++l) {
|
|
buf1[l] = buf3[l] = 0xff;
|
|
buf2[l] = buf4[l] = l;
|
|
}
|
|
memcpy2(buf1+128+i, buf2+128+j, k, TFLUSHBIT | TTOUCHBIT | SFLUSHBIT);
|
|
}
|
|
}
|
|
}
|
|
DISPDBG((0, "memcpy2 Test A PASSED i=%d\n", i));
|
|
}
|
|
|
|
for(i=0; i<32; ++i) {
|
|
for(j=-128; j<=128; ++j) {
|
|
for(k=0; k<256; ++k) {
|
|
for(l=0; l<1024; ++l) {
|
|
buf1[l] = buf2[l] = l;
|
|
}
|
|
memcpy(buf1+512+i, buf1+512+i+j, k);
|
|
memcpy2(buf2+512+i, buf2+512+i+j, k, TFLUSHBIT | TTOUCHBIT | SFLUSHBIT);
|
|
if(memcmp(buf1, buf2, 1024)) {
|
|
DISPDBG((0, "## memcpy2 error 3 i=%d j=%d k=%d\n", i, j, k));
|
|
#if DBG
|
|
EngDebugBreak();
|
|
#endif
|
|
for(l=0; l<1024; ++l) {
|
|
buf2[l] = l;
|
|
}
|
|
memcpy2(buf2+512+i, buf2+512+i+j, k, TFLUSHBIT | TTOUCHBIT | SFLUSHBIT);
|
|
|
|
}
|
|
}
|
|
}
|
|
DISPDBG((0, "memcpy2 Test B PASSED i=%d\n", i));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if MEMMAXBANDWIDTH || MEMCPYPERFORM
|
|
if(TimesToMeasure >= 0) {
|
|
#if DBG
|
|
// EngDebugBreak();
|
|
#endif
|
|
if(TimesToMeasure) {
|
|
SaveScreenMem(0, 9999);
|
|
#if MEMMAXBANDWIDTH
|
|
VramAccess();
|
|
#endif
|
|
#if MEMCPYPERFORM
|
|
PerformCheck(1, 64, 1, 300);
|
|
PerformCheck(250, 350, 7, 400);
|
|
PerformCheck(650, 750, 31, 600);
|
|
#endif
|
|
RestoreScreenMem(0, 9999);
|
|
}
|
|
TimesToMeasure -= 1;
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
VOID
|
|
ReportNesting(
|
|
IN ULONG FunctionID
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
DISPDBG((0,"### Nesting function call: %s is called while executing", TrapName[FunctionID]));
|
|
for(i=0; i<MAX_TRAP; ++i) {
|
|
if(startsec[i] != 0) {
|
|
DISPDBG((0," %s", TrapName[i]));
|
|
}
|
|
}
|
|
DISPDBG((0," ###\n"));
|
|
}
|
|
|
|
VOID
|
|
EnterCritical(
|
|
IN ULONG SectionID
|
|
)
|
|
{
|
|
UCHAR tscReg;
|
|
|
|
if(myPDEV->TscStatusReg && SectionID < MAX_CRITICAL) {
|
|
tscReg = *(myPDEV->TscStatusReg + 7);
|
|
EnterCriticalCPU[SectionID] = tscReg & 0x40;
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
ExitCritical(
|
|
IN ULONG SectionID
|
|
)
|
|
{
|
|
UCHAR tscReg;
|
|
|
|
if(myPDEV->TscStatusReg && SectionID < MAX_CRITICAL) {
|
|
tscReg = *(myPDEV->TscStatusReg + 7);
|
|
if((tscReg & 0x40) != EnterCriticalCPU[SectionID]) {
|
|
SwitchDuringCritical[SectionID] += 1;
|
|
}
|
|
TotalCritical[SectionID] += 1;
|
|
}
|
|
}
|
|
|
|
VOID
|
|
ClockStart(
|
|
IN ULONG FunctionID
|
|
)
|
|
{
|
|
ULONG i;
|
|
UCHAR tscReg;
|
|
|
|
if(myPDEV->TscStatusReg) {
|
|
tscReg = *(myPDEV->TscStatusReg + 7);
|
|
if(tscReg & 0x40)
|
|
enterCPU[FunctionID] = 1;
|
|
else
|
|
enterCPU[FunctionID] = 0;
|
|
}
|
|
|
|
if(timercount) { // There are some other functions nesting
|
|
if(FunctionID == TRAP_PAINT || FunctionID == DRV_TRAP_PAINT || FunctionID == TRAP_BITBLT || FunctionID == TRAP_DITHER || FunctionID == DRV_TRAP_BITBLT || FunctionID == DRV_REALIZE_BRUSH) {
|
|
for(i=0; i<MAX_TRAP; ++i) {
|
|
if(i == TRAP_PAINT || i == TRAP_STROKENFIL || i == TRAP_BITBLT || i == DRV_TRAP_BITBLT || i == DRV_TRAP_PAINT) // We are aware of this situation
|
|
continue;
|
|
if(startsec[i])
|
|
break;
|
|
}
|
|
if(i != MAX_TRAP)
|
|
ReportNesting(FunctionID);
|
|
} else {
|
|
ReportNesting(FunctionID);
|
|
}
|
|
}
|
|
|
|
timercount += 1;
|
|
|
|
numcalled[FunctionID] += 1;
|
|
|
|
startsec[FunctionID] = GetTime();
|
|
}
|
|
|
|
VOID
|
|
ClockEnd(
|
|
IN ULONG FunctionID
|
|
)
|
|
{
|
|
ULONG time, time2, index;
|
|
UCHAR tscReg;
|
|
|
|
time = GetTime();
|
|
|
|
time2 = time;
|
|
|
|
time -= (startsec[FunctionID] + clockoverhead);
|
|
spentindrv = time;
|
|
totalelapse[FunctionID] += time;
|
|
|
|
index = time/10; // Histgram unit is 0.1 msec (measured time is 0.01 msec)
|
|
if(index >= MAX_STEP)
|
|
index = MAX_STEP-1;
|
|
distribution[FunctionID][index] += 1;
|
|
|
|
timercount -= 1;
|
|
startsec[FunctionID] = 0;
|
|
|
|
if(timercount < 0) {
|
|
DISPDBG((0,"### Timer Count Becomes Negative ###\n", TrapName[FunctionID]));
|
|
}
|
|
|
|
if(activated == 0)
|
|
activated = time2;
|
|
else {
|
|
if(time2 > activated + Interval && timercount == 0) { // statistics out every INTERVAL seconds
|
|
activated = 0; // reset acivated counter
|
|
RecordPerformance();
|
|
}
|
|
}
|
|
|
|
if(myPDEV->TscStatusReg) {
|
|
tscReg = *(myPDEV->TscStatusReg + 7);
|
|
if(tscReg & 0x40) {
|
|
if(enterCPU[FunctionID]) {
|
|
CPUSwitch[FunctionID][3] += 1;
|
|
} else {
|
|
CPUSwitch[FunctionID][2] += 1;
|
|
}
|
|
} else {
|
|
if(enterCPU[FunctionID]) {
|
|
CPUSwitch[FunctionID][1] += 1;
|
|
} else {
|
|
CPUSwitch[FunctionID][0] += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
VOID
|
|
CountUp(
|
|
IN ULONG FunctionID
|
|
)
|
|
{
|
|
numcalled[FunctionID] += 1;
|
|
}
|
|
|
|
VOID
|
|
CountBreak()
|
|
{
|
|
if(breakcnt) { // break point counting mode?
|
|
if(--breakcnt == 0) {
|
|
EngDebugBreak();
|
|
}
|
|
} else {
|
|
if(dbgflg)
|
|
EngDebugBreak();
|
|
}
|
|
}
|
|
|
|
#endif // INVESTIGATE
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Routine Description:
|
|
*
|
|
* This function is variable-argument, level-sensitive debug print
|
|
* routine.
|
|
* If the specified debug level for the print statement is lower or equal
|
|
* to the current debug level, the message will be printed.
|
|
*
|
|
* Arguments:
|
|
*
|
|
* DebugPrintLevel - Specifies at which debugging level the string should
|
|
* be printed
|
|
*
|
|
* DebugMessage - Variable argument ascii c string
|
|
*
|
|
* Return Value:
|
|
*
|
|
* None.
|
|
*
|
|
***************************************************************************/
|
|
|
|
VOID
|
|
DebugPrint(
|
|
ULONG DebugPrintLevel,
|
|
PCHAR DebugMessage,
|
|
...
|
|
)
|
|
|
|
{
|
|
|
|
#if DBG
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, DebugMessage);
|
|
|
|
#endif
|
|
|
|
#if DBG
|
|
|
|
if (DebugPrintLevel <= DebugLevel) {
|
|
|
|
EngDebugPrint(STANDARD_DEBUG_PREFIX, DebugMessage, ap);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#if DBG
|
|
|
|
va_end(ap);
|
|
|
|
#endif
|
|
|
|
} // DebugPrint()
|
|
|
|
#if INVESTIGATE
|
|
|
|
LONG
|
|
DumpSurfObj(
|
|
char *title,
|
|
SURFOBJ *pso
|
|
)
|
|
{
|
|
|
|
#define STYPE_MAX 9
|
|
#define ITYPE_MAX 4
|
|
|
|
char *StypeString[STYPE_MAX] = {"DEVICE", "1BPP", "4BPP", "8BPP", "16BPP",
|
|
"24BPP", "32BPP", "4RLE", "8RLE" };
|
|
char *ItypeString[ITYPE_MAX] = {"BITMAP", "DEVICE", "JOURNAL", "DEVBITMAP"};
|
|
|
|
if(pso == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return (0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpHex(" device handle", (ULONG) pso->dhsurf);
|
|
DumpHex(" logical handle for the surface", (ULONG) pso->hsurf);
|
|
DumpHex(" pdev handle", (ULONG) pso->dhpdev);
|
|
DumpHex(" logical handle for the pdev", (ULONG) pso->hdev);
|
|
DumpSizel(" bitmap size", &(pso->sizlBitmap));
|
|
DumpCombo(" buffer size", pso->cjBits);
|
|
DumpHex(" bitmap address", (ULONG) pso->pvBits);
|
|
DumpHex(" first scan line address", (ULONG) pso->pvScan0);
|
|
DumpDecimal(" bytes per line", pso->lDelta);
|
|
DumpCombo(" status", pso->iUniq);
|
|
DumpTable(" bitmap format", pso->iBitmapFormat, StypeString, STYPE_MAX);
|
|
DumpTable(" surface type", pso->iType, ItypeString, ITYPE_MAX);
|
|
return(DumpDecimal(" bitmap style (direction)", pso->fjBitmap));
|
|
}
|
|
|
|
LONG
|
|
DumpClipObj(
|
|
char *title,
|
|
CLIPOBJ *pco
|
|
)
|
|
{
|
|
|
|
#define DCOMP_MAX 4
|
|
#define FCOMP_MAX 4
|
|
|
|
char *DcompString[DCOMP_MAX] = {"TRIVIAL", "RECT", "#INVALID#", "COMPLEX"};
|
|
char *FcompString[FCOMP_MAX] = {"#INVALID#", "RECT", "RECT4", "COMPLEX"};
|
|
|
|
if(pco == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpCombo(" clip region ID", pco->iUniq);
|
|
DumpRectl(" bounding rectangle", &(pco->rclBounds));
|
|
DumpTable(" complexity", pco->iDComplexity, DcompString, DCOMP_MAX);
|
|
DumpTable(" whole region complexity", pco->iFComplexity, FcompString, FCOMP_MAX);
|
|
DumpCombo(" mode", pco->iMode);
|
|
return(DumpCombo(" options", pco->fjOptions));
|
|
}
|
|
|
|
LONG
|
|
DumpXlateObj(
|
|
char *title,
|
|
XLATEOBJ *pxlo
|
|
)
|
|
{
|
|
|
|
#define XLATFL_MAX 3
|
|
#define XLATST_MAX 4
|
|
|
|
FLTABLE xlatfltbl[XLATFL_MAX] = { {XO_TRIVIAL, "TRIVIAL"},
|
|
{XO_TABLE, "TABLE"},
|
|
{XO_TO_MONO, "TO_MONO"}
|
|
};
|
|
|
|
KEYTABLE xlatsttbl[XLATST_MAX] = { {PAL_INDEXED, "PAL_INDEXED"},
|
|
{PAL_BITFIELDS, "PAL_BITFIELDS"},
|
|
{PAL_RGB, "PAL_RGB"},
|
|
{PAL_BGR, "PAL_BGR"}
|
|
};
|
|
|
|
ULONG i;
|
|
|
|
if(pxlo == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpCombo(" xlate object ID", pxlo->iUniq);
|
|
DumpFlong(" hints for translation", pxlo->flXlate, xlatfltbl, XLATFL_MAX);
|
|
DumpKeyTable(" source palette type", pxlo->iSrcType, xlatsttbl, XLATST_MAX);
|
|
DumpKeyTable(" target palette type", pxlo->iDstType, xlatsttbl, XLATST_MAX);
|
|
DumpDecimal(" number of translation entries", pxlo->cEntries);
|
|
for(i=0; i<pxlo->cEntries; ++i) {
|
|
DumpCombo(" translation", pxlo->pulXlate[i]);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpRectl(
|
|
char *title,
|
|
RECTL *prect
|
|
)
|
|
{
|
|
if(prect == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d) - (%d, %d)\n",
|
|
title, prect->left, prect->top, prect->right, prect->bottom));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpPointl(
|
|
char *title,
|
|
POINTL *pptl
|
|
)
|
|
{
|
|
if(pptl == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d)\n", title, pptl->x, pptl->y));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpBrushObj(
|
|
char *title,
|
|
BRUSHOBJ *pbo
|
|
)
|
|
{
|
|
if(pbo == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpDecimal(" solid brush color index", pbo->iSolidColor);
|
|
return(DumpHex(" realization of the brush", (ULONG) pbo->pvRbrush));
|
|
}
|
|
|
|
LONG
|
|
DumpColorAdjustment(
|
|
char *title,
|
|
COLORADJUSTMENT *pca
|
|
)
|
|
{
|
|
|
|
#define CAFLG_MAX 2
|
|
|
|
static FLTABLE cafltbl[CAFLG_MAX] = {{CA_NEGATIVE, "NEGATIVE"}, {CA_LOG_FILTER, "LOG_FILTER"}};
|
|
|
|
#define CAILL_MAX 9
|
|
|
|
static char *cailltbl[CAILL_MAX] = {"DEFAULT", "A", "B", "C", "D50", "D55", "D65", "D75", "F2"};
|
|
|
|
if(pca == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpDecimal(" size of the structure", pca->caSize);
|
|
DumpFlong(" color flags", pca->caFlags, cafltbl, CAFLG_MAX);
|
|
DumpTable(" illuminant", pca->caIlluminantIndex, cailltbl, CAILL_MAX);
|
|
DumpDecimal(" RedGamma", pca->caRedGamma);
|
|
DumpDecimal(" GreenGamma", pca->caGreenGamma);
|
|
DumpDecimal(" BlueGamma", pca->caBlueGamma);
|
|
DumpDecimal(" ReferenceBlack", pca->caReferenceBlack);
|
|
DumpDecimal(" ReferenceWhite", pca->caReferenceWhite);
|
|
DumpDecimal(" Contrast", pca->caContrast);
|
|
DumpDecimal(" Brightness", pca->caBrightness);
|
|
DumpDecimal(" Colorfulness", pca->caColorfulness);
|
|
return(DumpDecimal(" RedGreenTint", pca->caRedGreenTint));
|
|
}
|
|
|
|
LONG
|
|
DumpPointFix(
|
|
char *title,
|
|
POINTFIX *pptfx
|
|
)
|
|
{
|
|
if(pptfx == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d)\n", title, pptfx->x, pptfx->y));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpSizel(
|
|
char *title,
|
|
SIZEL *sizep
|
|
)
|
|
{
|
|
if(sizep == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: (%d, %d)\n", title, sizep->cx, sizep->cy));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpStrObj(
|
|
char *title,
|
|
STROBJ *pstro
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
#define STRFL_MAX 7
|
|
|
|
static FLTABLE strfltbl[STRFL_MAX] = {
|
|
{SO_FLAG_DEFAULT_PLACEMENT, "DEFAULT"},
|
|
{SO_HORIZONTAL, "HORIZONTAL"},
|
|
{SO_VERTICAL, "VERTICAL"},
|
|
{SO_REVERSED, "REVERSED"},
|
|
{SO_ZERO_BEARINGS, "ZERO_BEARINGS"},
|
|
{SO_CHAR_INC_EQUAL_BM_BASE, "BM_BASE"},
|
|
{SO_MAXEXT_EQUAL_BM_SIDE, "BM_SIZE"}};
|
|
|
|
if(pstro == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpDecimal(" number of glyphs", pstro->cGlyphs);
|
|
DumpFlong(" accelerator flag", pstro->flAccel, strfltbl, STRFL_MAX);
|
|
DumpDecimal(" fixed pitch width", pstro->ulCharInc);
|
|
DumpRectl(" bounding box", &(pstro->rclBkGround));
|
|
if(pstro->pgp) { // Has glyph
|
|
DumpString(" glyphs\n");
|
|
for(i=0; i<pstro->cGlyphs; ++i) {
|
|
DumpGlyphpos("glyphpos", &(pstro->pgp[i]));
|
|
}
|
|
} else {
|
|
DumpString(" no glyphs\n");
|
|
}
|
|
if(pstro->pwszOrg)
|
|
DISPDBG((DUMP_PARAM_LEVEL, " unicode string: %S\n", pstro->pwszOrg));
|
|
else
|
|
DISPDBG((DUMP_PARAM_LEVEL, " unicode string: NULL\n"));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpGlyphpos(
|
|
char *title,
|
|
GLYPHPOS *pgp
|
|
)
|
|
{
|
|
if(pgp == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, " %s: NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, " -- %s dump --\n", title));
|
|
DumpCombo(" handle for the glyph", pgp->hg);
|
|
if(pgp->pgdf != NULL) {
|
|
DumpPointl(" character origin", &(pgp->pgdf->pgb->ptlOrigin));
|
|
DumpSizel(" glyph size", &(pgp->pgdf->pgb->sizlBitmap));
|
|
/******* printing gryph pattern is not practical using DISPDBG ******
|
|
{
|
|
LONG i, j;
|
|
BYTE *bp;
|
|
|
|
bp = pgp->pgdf->pgb->aj;
|
|
for(i=0; i<pgp->pgdf->pgb->sizlBitmap.cy; ++i) {
|
|
for(j=0; j<(pgp->pgdf->pgb->sizlBitmap.cx + 7)/8; ++j) {
|
|
DumpString(bittable[*bp++]);
|
|
}
|
|
DumpString("\n");
|
|
}
|
|
}
|
|
********************************************************************/
|
|
}
|
|
return(DumpPointl(" position on device space", &(pgp->ptl)));
|
|
}
|
|
|
|
LONG
|
|
DumpFontObj(
|
|
char *title,
|
|
FONTOBJ *pfo
|
|
)
|
|
{
|
|
|
|
#define FNTFL_MAX 6
|
|
|
|
FLTABLE fntfltbl[FNTFL_MAX] = {
|
|
{FO_TYPE_RASTER, "RASTER"},
|
|
{FO_TYPE_DEVICE, "DEVICE"},
|
|
{FO_TYPE_TRUETYPE, "TRUETYPE"},
|
|
{FO_SIM_BOLD, "BOLD"},
|
|
{FO_SIM_ITALIC, "ITALIC"},
|
|
{FO_EM_HEIGHT, "EM_HEIGHT"}};
|
|
|
|
if(pfo == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpCombo(" font ID", pfo->iUniq);
|
|
DumpDecimal(" index to the device font", pfo->iFace);
|
|
DumpDecimal(" maximum width", pfo->cxMax);
|
|
DumpFlong(" font type", pfo->flFontType, fntfltbl, FNTFL_MAX);
|
|
DumpCombo(" ID for true type font", pfo->iTTUniq);
|
|
DumpCombo(" ID for device font", pfo->iFile);
|
|
DumpSizel(" resolution", &(pfo->sizLogResPpi));
|
|
DumpDecimal(" size in point", pfo->ulStyleSize);
|
|
DumpHex(" consumer", (ULONG) pfo->pvConsumer);
|
|
return(DumpHex(" producer", (ULONG) pfo->pvProducer));
|
|
}
|
|
|
|
LONG
|
|
DumpMix(
|
|
char *title,
|
|
MIX mix
|
|
)
|
|
{
|
|
|
|
#define OP_MAX 17
|
|
|
|
static char *optbl[OP_MAX] = { "NULL", "BLACK (0)", "NOTMERGEPEN (DPon)", "MASKNOTPEN (DPna)",
|
|
"NOTCOPYPEN (PN)", "MASKPENNOT (PDna)", "NOT (Dn)", "XORPEN (DPx)", "NOTMASKPEN (DPan)",
|
|
"MASKPEN (DPa)", "NOTXORPEN (DPxn)", "NOP (D)", "MERGENOTPEN (DPno)", "COPYPEN (P)",
|
|
"MERGEPENNOT (PDno)", "MERGEPEN (DPo)", "WHITE (1)" };
|
|
|
|
DumpTable(title, (mix & 0xff00) >> 8, optbl, OP_MAX);
|
|
return(DumpTable(title, (mix & 0xff), optbl, OP_MAX));
|
|
}
|
|
|
|
LONG
|
|
DumpPathObj(
|
|
char *title,
|
|
PATHOBJ *ppo
|
|
)
|
|
{
|
|
|
|
#define PATHFL_MAX 2
|
|
|
|
FLTABLE pathfltbl[PATHFL_MAX] = {{PO_BEZIERS, "BEZIERS"} , {PO_ELLIPSE, "ELLIPSE"}};
|
|
|
|
if(ppo == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
DumpFlong(" hint flags", ppo->fl, pathfltbl, PATHFL_MAX);
|
|
return(DumpDecimal(" number of curves", ppo->cCurves));
|
|
}
|
|
|
|
LONG
|
|
DumpXformObj(
|
|
char *title,
|
|
XFORMOBJ *pxo
|
|
)
|
|
{
|
|
if(pxo == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s] -- NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, "[%s]\n", title));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpLineAttrs(
|
|
char *title,
|
|
LINEATTRS *plineattrs
|
|
)
|
|
{
|
|
|
|
#define LINEFL_MAX 3
|
|
|
|
FLTABLE linefltbl[LINEFL_MAX] = {{LA_GEOMETRIC, "Geometric"}, {LA_ALTERNATE, "Alternate"},
|
|
{LA_STARTGAP, "StartGap"}};
|
|
|
|
#define LINEJOIN_MAX 3
|
|
|
|
char *linejointbl[LINEJOIN_MAX] = {"Round", "Bevel", "Mitter"};
|
|
|
|
#define LINEEND_MAX 3
|
|
|
|
char *linenedtbl[LINEEND_MAX] = {"Round", "Square", "Butt"};
|
|
|
|
if(plineattrs == NULL) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, " %s: NULL\n", title));
|
|
return(0);
|
|
}
|
|
DISPDBG((DUMP_PARAM_LEVEL, " -- %s dump --\n", title));
|
|
DumpFlong(" option flag", plineattrs->fl, linefltbl, LINEFL_MAX);
|
|
DumpTable(" join style", plineattrs->iJoin, linejointbl, LINEJOIN_MAX);
|
|
DumpTable(" end style", plineattrs->iEndCap, linenedtbl, LINEEND_MAX);
|
|
return(DumpDecimal(" number of style array", plineattrs->cstyle));
|
|
}
|
|
|
|
LONG
|
|
DumpDecimal(
|
|
char *title,
|
|
ULONG value
|
|
)
|
|
{
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: %d\n", title, value));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpHex(
|
|
char *title,
|
|
ULONG value
|
|
)
|
|
{
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: 0x%08x)\n", title, value));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpCombo(
|
|
char *title,
|
|
ULONG value
|
|
)
|
|
{
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: %d (0x%x)\n", title, value, value));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpFlong(
|
|
char *title,
|
|
FLONG value,
|
|
FLTABLE *fltblp,
|
|
ULONG numentry
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s\n", title));
|
|
for(i=0; i<numentry; ++i) {
|
|
if(value & fltblp[i].mask)
|
|
DISPDBG((DUMP_PARAM_LEVEL, " %s\n", fltblp[i].string));
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpKeyTable(
|
|
char *title,
|
|
FLONG value,
|
|
KEYTABLE *keytblp,
|
|
ULONG numentry
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s\n", title));
|
|
for(i=0; i<numentry; ++i) {
|
|
if(value == keytblp[i].key) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, " %s\n", keytblp[i].string));
|
|
break;
|
|
}
|
|
}
|
|
if(i == numentry) {
|
|
DISPDBG((DUMP_PARAM_LEVEL, "Key not found (%d 0x%x)\n", value, value));
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpTable(
|
|
char *title,
|
|
FLONG value,
|
|
char **tablep,
|
|
ULONG numentry
|
|
)
|
|
{
|
|
DISPDBG((DUMP_PARAM_LEVEL, "%s: %s\n", title, (value < numentry)?tablep[value]:"Table index over"));
|
|
return(0);
|
|
}
|
|
|
|
LONG
|
|
DumpString(
|
|
char *string
|
|
)
|
|
{
|
|
DISPDBG((DUMP_PARAM_LEVEL, string));
|
|
return(0);
|
|
}
|
|
|
|
#endif // INVESTIGATE
|