Author: tkreuzer
Date: Sun Jun 6 05:12:56 2010
New Revision: 47606
URL:
http://svn.reactos.org/svn/reactos?rev=47606&view=rev
Log:
[WIN32K]
- Allocate bitmaps as kernel sections, instead of from paged pool, like it's done in
windows.
- Fix SURFACE_Cleanup. It was only freeing the memory for API_BITMAPs. If memory was
allocated by a driver it never got freed.
- Add BMF_RLE_HACK flag to free decompressed RLE bits
- Support FL_ZERO_MEMORY in EngAllocSectionMem
- Set SURFOBJ::iType when creating a surface
Modified:
branches/reactos-yarotows/subsystems/win32/win32k/eng/mapping.c
branches/reactos-yarotows/subsystems/win32/win32k/eng/mem.c
branches/reactos-yarotows/subsystems/win32/win32k/eng/surface.c
branches/reactos-yarotows/subsystems/win32/win32k/include/eng.h
branches/reactos-yarotows/subsystems/win32/win32k/include/surface.h
Modified: branches/reactos-yarotows/subsystems/win32/win32k/eng/mapping.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/eng/mapping.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/eng/mapping.c [iso-8859-1] Sun Jun
6 05:12:56 2010
@@ -232,6 +232,11 @@
return NULL;
}
+ if (fl & FL_ZERO_MEMORY)
+ {
+ RtlZeroMemory(pSection->pvMappedBase, cjSize);
+ }
+
/* Set section pointer and return base address */
*ppvSection = pSection;
return pSection->pvMappedBase;
Modified: branches/reactos-yarotows/subsystems/win32/win32k/eng/mem.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/eng/mem.c [iso-8859-1] (original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/eng/mem.c [iso-8859-1] Sun Jun 6
05:12:56 2010
@@ -79,6 +79,7 @@
}
/* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */
+ //hSecure = EngSecureMem(NewMem, cj);
return NewMem;
}
@@ -166,6 +167,7 @@
HANDLE APIENTRY
EngSecureMem(PVOID Address, ULONG Length)
{
+ return (HANDLE)-1; // HACK!!!
return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE);
}
@@ -175,6 +177,7 @@
VOID APIENTRY
EngUnsecureMem(HANDLE Mem)
{
+ if (Mem == (HANDLE)-1) return; // HACK!!!
MmUnsecureVirtualMemory((PVOID) Mem);
}
Modified: branches/reactos-yarotows/subsystems/win32/win32k/eng/surface.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/eng/surface.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/eng/surface.c [iso-8859-1] Sun Jun
6 05:12:56 2010
@@ -90,46 +90,63 @@
}
}
-BOOL INTERNAL_CALL
+BOOL
+INTERNAL_CALL
SURFACE_Cleanup(PVOID ObjectBody)
{
PSURFACE psurf = (PSURFACE)ObjectBody;
PVOID pvBits = psurf->SurfObj.pvBits;
-
- /* If this is an API bitmap, free the bits */
- if (pvBits != NULL &&
- (psurf->flags & API_BITMAP))
- {
- /* Check if we have a DIB section */
- if (psurf->hSecure)
- {
- // FIXME: IMPLEMENT ME!
- // MmUnsecureVirtualMemory(psurf->hSecure);
- if (psurf->hDIBSection)
- {
- /* DIB was created from a section */
- NTSTATUS Status;
-
- pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
- Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Could not unmap section view!\n");
- // Should we BugCheck here?
- }
- }
- else
- {
- /* DIB was allocated */
- EngFreeUserMem(pvBits);
- }
+ NTSTATUS Status;
+
+ /* Check if the surface has bits */
+ if (pvBits)
+ {
+ /* Only bitmaps can have bits */
+ ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
+
+ /* Check if it is a DIB section */
+ if (psurf->hDIBSection)
+ {
+ /* Unsecure the memory */
+ EngUnsecureMem(psurf->hSecure);
+
+ /* Calculate the real start of the section */
+ pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
+
+ /* Unmap the section */
+ Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not unmap section view!\n");
+ // Should we BugCheck here?
+ ASSERT(FALSE);
+ }
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_USERMEM)
+ {
+ /* Bitmap was allocated from usermode memory */
+ EngFreeUserMem(pvBits);
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION)
+ {
+ /* Bitmap was allocated from a kernel section */
+ if (!EngFreeSectionMem(NULL, pvBits))
+ {
+ DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits);
+ // Should we BugCheck here?
+ ASSERT(FALSE);
+ }
+ }
+ else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK)
+ {
+ /* HACK: Free RLE decompressed bits */
+ EngFreeMem(pvBits);
}
else
{
- // FIXME: use TAG
- ExFreePool(psurf->SurfObj.pvBits);
- }
-
+ /* There should be nothing to free */
+ ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
+ }
}
/* Free palette */
@@ -168,6 +185,8 @@
}
pso->dhsurf = dhsurf;
+ pso->iType = STYPE_DEVBITMAP;
+
EngUnlockSurface(pso);
return NewBitmap;
@@ -206,13 +225,13 @@
case RLE_EOL:
x = 0;
y--;
- break;
+ break;
case RLE_END:
return;
case RLE_DELTA:
x += (*bits++)/2;
y -= (*bits++)/2;
- break;
+ break;
default:
length /= 2;
while (length--)
@@ -306,7 +325,7 @@
PSURFACE psurf;
PVOID UncompressedBits;
ULONG UncompressedFormat;
-
+
if (Format == 0)
return 0;
@@ -326,6 +345,7 @@
UncompressedFormat = BMF_4BPP;
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
+ Flags |= BMF_RLE_HACK;
}
else if (Format == BMF_8RLE)
{
@@ -334,6 +354,7 @@
UncompressedFormat = BMF_8BPP;
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
+ Flags |= BMF_RLE_HACK;
}
else
{
@@ -346,6 +367,7 @@
if (UncompressedBits != NULL)
{
pso->pvBits = UncompressedBits;
+ Flags |= BMF_DONT_FREE;
}
else
{
@@ -361,9 +383,15 @@
}
else
{
- pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ?
- 0 : FL_ZERO_MEMORY,
- pso->cjBits, TAG_DIB);
+ PVOID pvSection;
+ Flags |= BMF_KMSECTION;
+ pso->pvBits = EngAllocSectionMem(&pvSection,
+ (Flags & BMF_NOZEROINIT) ?
+ 0 : FL_ZERO_MEMORY,
+ pso->cjBits, TAG_DIB);
+
+ /* Free the section already, keep the mapping */
+ EngFreeSectionMem(pvSection, NULL);
}
if (pso->pvBits == NULL)
{
@@ -392,7 +420,7 @@
pso->sizlBitmap = Size;
pso->iBitmapFormat = UncompressedFormat;
pso->iType = STYPE_BITMAP;
- pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT);
+ pso->fjBitmap = Flags &
(BMF_TOPDOWN|BMF_NOZEROINIT|BMF_KMSECTION|BMF_USERMEM|BMF_DONT_FREE);
pso->iUniq = 0;
psurf->flags = 0;
@@ -430,11 +458,11 @@
SIZEL LocalSize;
BOOLEAN AllocatedLocally = FALSE;
- /*
+/*
* First, check the format so we can get the aligned scanline width.
* RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
* since they are compressed surfaces!
- */
+ */
switch (BitmapInfo->Format)
{
case BMF_1BPP:
@@ -499,10 +527,15 @@
}
else
{
- /* Get kernel bits (zeroed out if requested) */
- Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 :
FL_ZERO_MEMORY,
- Size,
- TAG_DIB);
+ PVOID pvSection;
+ BitmapInfo->Flags |= BMF_KMSECTION;
+ Bits = EngAllocSectionMem(&pvSection,
+ (BitmapInfo->Flags & BMF_NOZEROINIT) ?
+ 0 : FL_ZERO_MEMORY,
+ Size, TAG_DIB);
+
+ /* Free the section already, keep the mapping */
+ EngFreeSectionMem(pvSection, NULL);
}
AllocatedLocally = TRUE;
/* Bail out if that failed */
@@ -513,6 +546,9 @@
{
/* Should not have asked for user memory */
ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
+
+ /* Must not free anything */
+ BitmapInfo->Flags |= BMF_DONT_FREE;
}
/* Allocate the actual surface object structure */
@@ -534,7 +570,7 @@
/* Save format and flags */
pso->iBitmapFormat = BitmapInfo->Format;
- pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM |
BMF_USERMEM);
+ pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM |
BMF_USERMEM | BMF_KMSECTION | BMF_DONT_FREE);
/* Save size and type */
LocalSize.cy = BitmapInfo->Height;
@@ -692,6 +728,7 @@
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
pso->iType = STYPE_DEVICE;
pso->iUniq = 0;
+ pso->pvBits = NULL;
psurf->flags = 0;
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/eng.h
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/include/eng.h [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/include/eng.h [iso-8859-1] Sun Jun
6 05:12:56 2010
@@ -21,3 +21,18 @@
VOID FASTCALL IntGdiAcquireSemaphore ( HSEMAPHORE hsem );
VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem );
ULONGLONG APIENTRY EngGetTickCount(VOID);
+
+BOOL
+APIENTRY
+EngFreeSectionMem(
+ IN PVOID pvSection OPTIONAL,
+ IN PVOID pvMappedBase OPTIONAL);
+
+PVOID
+APIENTRY
+EngAllocSectionMem(
+ OUT PVOID *ppvSection,
+ IN ULONG fl,
+ IN SIZE_T cjSize,
+ IN ULONG ulTag);
+
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/surface.h
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/include/surface.h [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/include/surface.h [iso-8859-1] Sun
Jun 6 05:12:56 2010
@@ -86,6 +86,10 @@
#define PDEV_SURFACE 0x80000000
+#define BMF_DONT_FREE 0x100
+#define BMF_RLE_HACK 0x200
+
+
/* Internal interface */
#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE))