mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[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 svn path=/branches/reactos-yarotows/; revision=47606
This commit is contained in:
parent
160142322e
commit
0c60cdb311
5 changed files with 105 additions and 41 deletions
|
@ -232,6 +232,11 @@ EngAllocSectionMem(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (fl & FL_ZERO_MEMORY)
|
||||
{
|
||||
RtlZeroMemory(pSection->pvMappedBase, cjSize);
|
||||
}
|
||||
|
||||
/* Set section pointer and return base address */
|
||||
*ppvSection = pSection;
|
||||
return pSection->pvMappedBase;
|
||||
|
|
|
@ -79,6 +79,7 @@ EngAllocUserMem(SIZE_T cj, ULONG Tag)
|
|||
}
|
||||
|
||||
/* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */
|
||||
//hSecure = EngSecureMem(NewMem, cj);
|
||||
|
||||
return NewMem;
|
||||
}
|
||||
|
@ -166,6 +167,7 @@ HackUnsecureVirtualMemory(
|
|||
HANDLE APIENTRY
|
||||
EngSecureMem(PVOID Address, ULONG Length)
|
||||
{
|
||||
return (HANDLE)-1; // HACK!!!
|
||||
return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
|
@ -175,6 +177,7 @@ EngSecureMem(PVOID Address, ULONG Length)
|
|||
VOID APIENTRY
|
||||
EngUnsecureMem(HANDLE Mem)
|
||||
{
|
||||
if (Mem == (HANDLE)-1) return; // HACK!!!
|
||||
MmUnsecureVirtualMemory((PVOID) Mem);
|
||||
}
|
||||
|
||||
|
|
|
@ -90,46 +90,63 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
|
|||
}
|
||||
}
|
||||
|
||||
BOOL INTERNAL_CALL
|
||||
BOOL
|
||||
INTERNAL_CALL
|
||||
SURFACE_Cleanup(PVOID ObjectBody)
|
||||
{
|
||||
PSURFACE psurf = (PSURFACE)ObjectBody;
|
||||
PVOID pvBits = psurf->SurfObj.pvBits;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* If this is an API bitmap, free the bits */
|
||||
if (pvBits != NULL &&
|
||||
(psurf->flags & API_BITMAP))
|
||||
/* Check if the surface has bits */
|
||||
if (pvBits)
|
||||
{
|
||||
/* 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;
|
||||
/* Only bitmaps can have bits */
|
||||
ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
|
||||
|
||||
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
|
||||
/* 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))
|
||||
{
|
||||
/* DIB was allocated */
|
||||
EngFreeUserMem(pvBits);
|
||||
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 @@ EngCreateDeviceBitmap(IN DHSURF dhsurf,
|
|||
}
|
||||
|
||||
pso->dhsurf = dhsurf;
|
||||
pso->iType = STYPE_DEVBITMAP;
|
||||
|
||||
EngUnlockSurface(pso);
|
||||
|
||||
return NewBitmap;
|
||||
|
@ -206,13 +225,13 @@ VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LO
|
|||
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 @@ IntCreateBitmap(IN SIZEL Size,
|
|||
PSURFACE psurf;
|
||||
PVOID UncompressedBits;
|
||||
ULONG UncompressedFormat;
|
||||
|
||||
|
||||
if (Format == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -326,6 +345,7 @@ IntCreateBitmap(IN SIZEL Size,
|
|||
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 @@ IntCreateBitmap(IN SIZEL Size,
|
|||
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 @@ IntCreateBitmap(IN SIZEL Size,
|
|||
if (UncompressedBits != NULL)
|
||||
{
|
||||
pso->pvBits = UncompressedBits;
|
||||
Flags |= BMF_DONT_FREE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -361,9 +383,15 @@ IntCreateBitmap(IN SIZEL Size,
|
|||
}
|
||||
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 @@ IntCreateBitmap(IN SIZEL Size,
|
|||
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 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
|||
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 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
|||
}
|
||||
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 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
|||
{
|
||||
/* 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 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
|||
|
||||
/* 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 @@ EngCreateDeviceSurface(IN DHSURF dhsurf,
|
|||
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
|
||||
pso->iType = STYPE_DEVICE;
|
||||
pso->iUniq = 0;
|
||||
pso->pvBits = NULL;
|
||||
|
||||
psurf->flags = 0;
|
||||
|
||||
|
|
|
@ -21,3 +21,18 @@ IntEngWindowChanged(
|
|||
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);
|
||||
|
||||
|
|
|
@ -86,6 +86,10 @@ typedef struct _SURFACE
|
|||
#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))
|
||||
|
|
Loading…
Reference in a new issue