mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 01:40:36 +00:00
added ability to cache gdi objects so they don't have to be allocated and deallocated all the time. it is disabled by default but could perhaps speed up the gui a bit.
svn path=/trunk/; revision=8459
This commit is contained in:
parent
d7b74d7460
commit
f54363658f
1 changed files with 136 additions and 9 deletions
|
@ -19,7 +19,7 @@
|
||||||
/*
|
/*
|
||||||
* GDIOBJ.C - GDI object manipulation routines
|
* GDIOBJ.C - GDI object manipulation routines
|
||||||
*
|
*
|
||||||
* $Id: gdiobj.c,v 1.60 2004/02/19 21:12:10 weiden Exp $
|
* $Id: gdiobj.c,v 1.61 2004/02/28 21:16:55 weiden Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -43,6 +43,10 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* enable/disable GDI object caching */
|
||||||
|
#define GDI_CACHE_OBJECTS 0
|
||||||
|
|
||||||
/*! Size of the GDI handle table
|
/*! Size of the GDI handle table
|
||||||
* http://www.windevnet.com/documents/s=7290/wdj9902b/9902b.htm
|
* http://www.windevnet.com/documents/s=7290/wdj9902b/9902b.htm
|
||||||
* gdi handle table can hold 0x4000 handles
|
* gdi handle table can hold 0x4000 handles
|
||||||
|
@ -85,9 +89,66 @@ typedef struct _GDI_HANDLE_TABLE
|
||||||
{
|
{
|
||||||
WORD wTableSize;
|
WORD wTableSize;
|
||||||
WORD AllocationHint;
|
WORD AllocationHint;
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
ULONG ObjHdrSize;
|
||||||
|
PGDIOBJHDR *CachedObjects;
|
||||||
|
#endif
|
||||||
PGDIOBJHDR Handles[1];
|
PGDIOBJHDR Handles[1];
|
||||||
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
|
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
|
||||||
|
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
|
||||||
|
#define N_OBJ_TYPES 16
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ULONG Type;
|
||||||
|
ULONG Size;
|
||||||
|
} GDI_OBJ_SIZE;
|
||||||
|
|
||||||
|
typedef struct _GDI_DONTCARE
|
||||||
|
{
|
||||||
|
PVOID Data;
|
||||||
|
} GDI_DONTCARE, *PGDI_DONTCARE;
|
||||||
|
|
||||||
|
const
|
||||||
|
GDI_OBJ_SIZE ObjSizes[N_OBJ_TYPES] =
|
||||||
|
{
|
||||||
|
{GDI_OBJECT_TYPE_DC, sizeof(DC)},
|
||||||
|
{GDI_OBJECT_TYPE_DCE, sizeof(DCE)},
|
||||||
|
{GDI_OBJECT_TYPE_PALETTE, sizeof(PALGDI)},
|
||||||
|
{GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_BRUSH, sizeof(BRUSHOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_PEN, sizeof(PENOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_REGION, sizeof(ROSRGNDATA)},
|
||||||
|
{GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ)},
|
||||||
|
/*
|
||||||
|
{GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW)},
|
||||||
|
{GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE)},
|
||||||
|
*/
|
||||||
|
{GDI_OBJECT_TYPE_DONTCARE, sizeof(GDI_DONTCARE)},
|
||||||
|
{GDI_OBJECT_TYPE_EXTPEN, 0},
|
||||||
|
{GDI_OBJECT_TYPE_METADC, 0},
|
||||||
|
{GDI_OBJECT_TYPE_METAFILE, 0},
|
||||||
|
{GDI_OBJECT_TYPE_ENHMETAFILE, 0},
|
||||||
|
{GDI_OBJECT_TYPE_ENHMETADC, 0},
|
||||||
|
{GDI_OBJECT_TYPE_MEMDC, 0},
|
||||||
|
{GDI_OBJECT_TYPE_EMF, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
ULONG FASTCALL
|
||||||
|
GDI_MaxGdiObjHeaderSize(VOID)
|
||||||
|
{
|
||||||
|
ULONG i, Size;
|
||||||
|
for(i = 0, Size = 0; i < N_OBJ_TYPES; i++)
|
||||||
|
{
|
||||||
|
Size = max(Size, ObjSizes[i].Size);
|
||||||
|
}
|
||||||
|
return Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* GDI stock objects */
|
/* GDI stock objects */
|
||||||
|
|
||||||
static LOGBRUSH WhiteBrush =
|
static LOGBRUSH WhiteBrush =
|
||||||
|
@ -166,17 +227,24 @@ static PGDI_HANDLE_TABLE FASTCALL
|
||||||
GDIOBJ_iAllocHandleTable (WORD Size)
|
GDIOBJ_iAllocHandleTable (WORD Size)
|
||||||
{
|
{
|
||||||
PGDI_HANDLE_TABLE handleTable;
|
PGDI_HANDLE_TABLE handleTable;
|
||||||
|
ULONG MemSize;
|
||||||
|
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * (Size << 1);
|
||||||
|
#else
|
||||||
|
MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * Size;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* prevent APC delivery for the *FastMutexUnsafe calls */
|
/* prevent APC delivery for the *FastMutexUnsafe calls */
|
||||||
const KIRQL PrevIrql = KfRaiseIrql(APC_LEVEL);
|
const KIRQL PrevIrql = KfRaiseIrql(APC_LEVEL);
|
||||||
ExAcquireFastMutexUnsafe (&HandleTableMutex);
|
ExAcquireFastMutexUnsafe (&HandleTableMutex);
|
||||||
handleTable = ExAllocatePoolWithTag(PagedPool,
|
handleTable = ExAllocatePoolWithTag(PagedPool, MemSize, TAG_GDIHNDTBLE);
|
||||||
sizeof(GDI_HANDLE_TABLE) +
|
|
||||||
sizeof(PGDIOBJ) * Size, TAG_GDIHNDTBLE);
|
|
||||||
ASSERT( handleTable );
|
ASSERT( handleTable );
|
||||||
memset (handleTable,
|
memset (handleTable, 0, MemSize);
|
||||||
0,
|
#if GDI_CACHE_OBJECTS
|
||||||
sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * Size);
|
handleTable->CachedObjects = &handleTable->Handles[Size];
|
||||||
|
handleTable->ObjHdrSize = sizeof(GDIOBJHDR) + GDI_MaxGdiObjHeaderSize();
|
||||||
|
#endif
|
||||||
handleTable->wTableSize = Size;
|
handleTable->wTableSize = Size;
|
||||||
handleTable->AllocationHint = 1;
|
handleTable->AllocationHint = 1;
|
||||||
ExReleaseFastMutexUnsafe (&HandleTableMutex);
|
ExReleaseFastMutexUnsafe (&HandleTableMutex);
|
||||||
|
@ -252,23 +320,63 @@ GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc)
|
||||||
PW32PROCESS W32Process;
|
PW32PROCESS W32Process;
|
||||||
PGDIOBJHDR newObject;
|
PGDIOBJHDR newObject;
|
||||||
WORD Index;
|
WORD Index;
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
PGDIOBJHDR *CachedObject;
|
||||||
|
#endif
|
||||||
|
|
||||||
ExAcquireFastMutex(&HandleTableMutex);
|
ExAcquireFastMutex(&HandleTableMutex);
|
||||||
Index = GDIOBJ_iGetNextOpenHandleIndex ();
|
Index = GDIOBJ_iGetNextOpenHandleIndex ();
|
||||||
if (0 == Index)
|
if (0 == Index)
|
||||||
{
|
{
|
||||||
|
ExReleaseFastMutex(&HandleTableMutex);
|
||||||
DPRINT1("Out of GDI handles\n");
|
DPRINT1("Out of GDI handles\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
CachedObject = (PGDIOBJHDR*)(HandleTable->CachedObjects + Index);
|
||||||
|
if(!(newObject = *CachedObject))
|
||||||
|
{
|
||||||
|
/* allocate new gdi object */
|
||||||
|
newObject = ExAllocatePoolWithTag(PagedPool, HandleTable->ObjHdrSize, TAG_GDIOBJ);
|
||||||
|
if(!newObject)
|
||||||
|
{
|
||||||
|
ExReleaseFastMutex(&HandleTableMutex);
|
||||||
|
DPRINT1("GDIOBJ_AllocObj: failed\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
RtlZeroMemory(newObject, HandleTable->ObjHdrSize);
|
||||||
|
*CachedObject = newObject;
|
||||||
|
}
|
||||||
|
/* Zero the memory when destroying the object */
|
||||||
|
if(ObjectType == GDI_OBJECT_TYPE_DONTCARE)
|
||||||
|
{
|
||||||
|
PVOID *Data;
|
||||||
|
PGDI_DONTCARE dc;
|
||||||
|
|
||||||
|
Data = ExAllocatePoolWithTag(PagedPool, sizeof(PVOID) + Size, TAG_GDIOBJ);
|
||||||
|
if(!Data)
|
||||||
|
{
|
||||||
|
ExReleaseFastMutex(&HandleTableMutex);
|
||||||
|
DPRINT1("GDIOBJ_AllocObj failed: %d bytes for GDI_OBJECT_TYPE_DONTCARE\n", Size + sizeof(PVOID));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dc = (PGDI_DONTCARE)((PCHAR)newObject + sizeof(GDIOBJHDR));
|
||||||
|
RtlZeroMemory((PVOID)(Data + 1), Size);
|
||||||
|
((PGDI_DONTCARE)((PCHAR)newObject + sizeof(GDIOBJHDR)))->Data = Data;
|
||||||
|
*Data = newObject;
|
||||||
|
}
|
||||||
|
#else
|
||||||
DPRINT("GDIOBJ_AllocObj: handle: %d, size: %d, type: 0x%08x\n", Index, Size, ObjectType);
|
DPRINT("GDIOBJ_AllocObj: handle: %d, size: %d, type: 0x%08x\n", Index, Size, ObjectType);
|
||||||
newObject = ExAllocatePoolWithTag(PagedPool, Size + sizeof (GDIOBJHDR), TAG_GDIOBJ);
|
newObject = ExAllocatePoolWithTag(PagedPool, Size + sizeof (GDIOBJHDR), TAG_GDIOBJ);
|
||||||
if (newObject == NULL)
|
if (newObject == NULL)
|
||||||
{
|
{
|
||||||
|
ExReleaseFastMutex(&HandleTableMutex);
|
||||||
DPRINT1("GDIOBJ_AllocObj: failed\n");
|
DPRINT1("GDIOBJ_AllocObj: failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
RtlZeroMemory (newObject, Size + sizeof(GDIOBJHDR));
|
RtlZeroMemory (newObject, Size + sizeof(GDIOBJHDR));
|
||||||
|
#endif
|
||||||
|
|
||||||
newObject->wTableIndex = Index;
|
newObject->wTableIndex = Index;
|
||||||
|
|
||||||
|
@ -280,7 +388,7 @@ GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc)
|
||||||
newObject->lockline = 0;
|
newObject->lockline = 0;
|
||||||
ExInitializeFastMutex(&newObject->Lock);
|
ExInitializeFastMutex(&newObject->Lock);
|
||||||
HandleTable->Handles[Index] = newObject;
|
HandleTable->Handles[Index] = newObject;
|
||||||
ExReleaseFastMutexUnsafe (&HandleTableMutex);
|
ExReleaseFastMutex(&HandleTableMutex);
|
||||||
|
|
||||||
W32Process = PsGetCurrentProcess()->Win32Process;
|
W32Process = PsGetCurrentProcess()->Win32Process;
|
||||||
if(W32Process)
|
if(W32Process)
|
||||||
|
@ -347,8 +455,19 @@ GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ObjectType, DWORD Flag)
|
||||||
Obj = (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
|
Obj = (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
|
||||||
bRet = (*(objectHeader->CleanupProc))(Obj);
|
bRet = (*(objectHeader->CleanupProc))(Obj);
|
||||||
}
|
}
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
if(GDI_MAGIC_TO_TYPE(objectHeader->Magic) == GDI_OBJECT_TYPE_DONTCARE)
|
||||||
|
{
|
||||||
|
PGDI_DONTCARE dc = (PGDI_DONTCARE)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
|
||||||
|
if(dc->Data)
|
||||||
|
{
|
||||||
|
ExFreePool(dc->Data);
|
||||||
|
}
|
||||||
|
RtlZeroMemory(objectHeader, HandleTable->ObjHdrSize);
|
||||||
|
}
|
||||||
|
#else
|
||||||
ExFreePool(objectHeader);
|
ExFreePool(objectHeader);
|
||||||
|
#endif
|
||||||
HandleTable->Handles[GDI_HANDLE_GET_INDEX(hObj)] = NULL;
|
HandleTable->Handles[GDI_HANDLE_GET_INDEX(hObj)] = NULL;
|
||||||
|
|
||||||
W32Process = PsGetCurrentProcess()->Win32Process;
|
W32Process = PsGetCurrentProcess()->Win32Process;
|
||||||
|
@ -648,7 +767,15 @@ GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType)
|
||||||
ObjHdr->lockline = line;
|
ObjHdr->lockline = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if GDI_CACHE_OBJECTS
|
||||||
|
if(GDI_MAGIC_TO_TYPE(ObjHdr->Magic) != GDI_OBJECT_TYPE_DONTCARE)
|
||||||
|
{
|
||||||
|
return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR));
|
||||||
|
}
|
||||||
|
return (PGDIOBJ)((PVOID)(((PGDI_DONTCARE)((PCHAR)ObjHdr + sizeof(GDIOBJHDR)))->Data) + 1);
|
||||||
|
#else
|
||||||
return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR));
|
return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif//GDIOBJ_LockObj
|
#endif//GDIOBJ_LockObj
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue