- 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:
Timo Kreuzer 2010-06-06 03:12:56 +00:00
parent 160142322e
commit 0c60cdb311
5 changed files with 105 additions and 41 deletions

View file

@ -232,6 +232,11 @@ EngAllocSectionMem(
return NULL; return NULL;
} }
if (fl & FL_ZERO_MEMORY)
{
RtlZeroMemory(pSection->pvMappedBase, cjSize);
}
/* Set section pointer and return base address */ /* Set section pointer and return base address */
*ppvSection = pSection; *ppvSection = pSection;
return pSection->pvMappedBase; return pSection->pvMappedBase;

View file

@ -79,6 +79,7 @@ EngAllocUserMem(SIZE_T cj, ULONG Tag)
} }
/* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */ /* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */
//hSecure = EngSecureMem(NewMem, cj);
return NewMem; return NewMem;
} }
@ -166,6 +167,7 @@ HackUnsecureVirtualMemory(
HANDLE APIENTRY HANDLE APIENTRY
EngSecureMem(PVOID Address, ULONG Length) EngSecureMem(PVOID Address, ULONG Length)
{ {
return (HANDLE)-1; // HACK!!!
return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE); return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE);
} }
@ -175,6 +177,7 @@ EngSecureMem(PVOID Address, ULONG Length)
VOID APIENTRY VOID APIENTRY
EngUnsecureMem(HANDLE Mem) EngUnsecureMem(HANDLE Mem)
{ {
if (Mem == (HANDLE)-1) return; // HACK!!!
MmUnsecureVirtualMemory((PVOID) Mem); MmUnsecureVirtualMemory((PVOID) Mem);
} }

View file

@ -90,46 +90,63 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
} }
} }
BOOL INTERNAL_CALL BOOL
INTERNAL_CALL
SURFACE_Cleanup(PVOID ObjectBody) SURFACE_Cleanup(PVOID ObjectBody)
{ {
PSURFACE psurf = (PSURFACE)ObjectBody; PSURFACE psurf = (PSURFACE)ObjectBody;
PVOID pvBits = psurf->SurfObj.pvBits; PVOID pvBits = psurf->SurfObj.pvBits;
NTSTATUS Status;
/* If this is an API bitmap, free the bits */ /* Check if the surface has bits */
if (pvBits != NULL && if (pvBits)
(psurf->flags & API_BITMAP))
{ {
/* Check if we have a DIB section */ /* Only bitmaps can have bits */
if (psurf->hSecure) ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
{
// FIXME: IMPLEMENT ME!
// MmUnsecureVirtualMemory(psurf->hSecure);
if (psurf->hDIBSection)
{
/* DIB was created from a section */
NTSTATUS Status;
pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset); /* Check if it is a DIB section */
Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits); if (psurf->hDIBSection)
if (!NT_SUCCESS(Status)) {
{ /* Unsecure the memory */
DPRINT1("Could not unmap section view!\n"); EngUnsecureMem(psurf->hSecure);
// Should we BugCheck here?
} /* Calculate the real start of the section */
} pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset);
else
/* Unmap the section */
Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits);
if (!NT_SUCCESS(Status))
{ {
/* DIB was allocated */ DPRINT1("Could not unmap section view!\n");
EngFreeUserMem(pvBits); // 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 else
{ {
// FIXME: use TAG /* There should be nothing to free */
ExFreePool(psurf->SurfObj.pvBits); ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
} }
} }
/* Free palette */ /* Free palette */
@ -168,6 +185,8 @@ EngCreateDeviceBitmap(IN DHSURF dhsurf,
} }
pso->dhsurf = dhsurf; pso->dhsurf = dhsurf;
pso->iType = STYPE_DEVBITMAP;
EngUnlockSurface(pso); EngUnlockSurface(pso);
return NewBitmap; return NewBitmap;
@ -206,13 +225,13 @@ VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LO
case RLE_EOL: case RLE_EOL:
x = 0; x = 0;
y--; y--;
break; break;
case RLE_END: case RLE_END:
return; return;
case RLE_DELTA: case RLE_DELTA:
x += (*bits++)/2; x += (*bits++)/2;
y -= (*bits++)/2; y -= (*bits++)/2;
break; break;
default: default:
length /= 2; length /= 2;
while (length--) while (length--)
@ -306,7 +325,7 @@ IntCreateBitmap(IN SIZEL Size,
PSURFACE psurf; PSURFACE psurf;
PVOID UncompressedBits; PVOID UncompressedBits;
ULONG UncompressedFormat; ULONG UncompressedFormat;
if (Format == 0) if (Format == 0)
return 0; return 0;
@ -326,6 +345,7 @@ IntCreateBitmap(IN SIZEL Size,
UncompressedFormat = BMF_4BPP; UncompressedFormat = BMF_4BPP;
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta); Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
Flags |= BMF_RLE_HACK;
} }
else if (Format == BMF_8RLE) else if (Format == BMF_8RLE)
{ {
@ -334,6 +354,7 @@ IntCreateBitmap(IN SIZEL Size,
UncompressedFormat = BMF_8BPP; UncompressedFormat = BMF_8BPP;
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta); Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
Flags |= BMF_RLE_HACK;
} }
else else
{ {
@ -346,6 +367,7 @@ IntCreateBitmap(IN SIZEL Size,
if (UncompressedBits != NULL) if (UncompressedBits != NULL)
{ {
pso->pvBits = UncompressedBits; pso->pvBits = UncompressedBits;
Flags |= BMF_DONT_FREE;
} }
else else
{ {
@ -361,9 +383,15 @@ IntCreateBitmap(IN SIZEL Size,
} }
else else
{ {
pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? PVOID pvSection;
0 : FL_ZERO_MEMORY, Flags |= BMF_KMSECTION;
pso->cjBits, TAG_DIB); 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) if (pso->pvBits == NULL)
{ {
@ -392,7 +420,7 @@ IntCreateBitmap(IN SIZEL Size,
pso->sizlBitmap = Size; pso->sizlBitmap = Size;
pso->iBitmapFormat = UncompressedFormat; pso->iBitmapFormat = UncompressedFormat;
pso->iType = STYPE_BITMAP; 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; pso->iUniq = 0;
psurf->flags = 0; psurf->flags = 0;
@ -430,11 +458,11 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
SIZEL LocalSize; SIZEL LocalSize;
BOOLEAN AllocatedLocally = FALSE; BOOLEAN AllocatedLocally = FALSE;
/* /*
* First, check the format so we can get the aligned scanline width. * 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 * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
* since they are compressed surfaces! * since they are compressed surfaces!
*/ */
switch (BitmapInfo->Format) switch (BitmapInfo->Format)
{ {
case BMF_1BPP: case BMF_1BPP:
@ -499,10 +527,15 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
} }
else else
{ {
/* Get kernel bits (zeroed out if requested) */ PVOID pvSection;
Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY, BitmapInfo->Flags |= BMF_KMSECTION;
Size, Bits = EngAllocSectionMem(&pvSection,
TAG_DIB); (BitmapInfo->Flags & BMF_NOZEROINIT) ?
0 : FL_ZERO_MEMORY,
Size, TAG_DIB);
/* Free the section already, keep the mapping */
EngFreeSectionMem(pvSection, NULL);
} }
AllocatedLocally = TRUE; AllocatedLocally = TRUE;
/* Bail out if that failed */ /* Bail out if that failed */
@ -513,6 +546,9 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
{ {
/* Should not have asked for user memory */ /* Should not have asked for user memory */
ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0); ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
/* Must not free anything */
BitmapInfo->Flags |= BMF_DONT_FREE;
} }
/* Allocate the actual surface object structure */ /* Allocate the actual surface object structure */
@ -534,7 +570,7 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
/* Save format and flags */ /* Save format and flags */
pso->iBitmapFormat = BitmapInfo->Format; 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 */ /* Save size and type */
LocalSize.cy = BitmapInfo->Height; LocalSize.cy = BitmapInfo->Height;
@ -692,6 +728,7 @@ EngCreateDeviceSurface(IN DHSURF dhsurf,
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)); pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
pso->iType = STYPE_DEVICE; pso->iType = STYPE_DEVICE;
pso->iUniq = 0; pso->iUniq = 0;
pso->pvBits = NULL;
psurf->flags = 0; psurf->flags = 0;

View file

@ -21,3 +21,18 @@ IntEngWindowChanged(
VOID FASTCALL IntGdiAcquireSemaphore ( HSEMAPHORE hsem ); VOID FASTCALL IntGdiAcquireSemaphore ( HSEMAPHORE hsem );
VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem ); VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem );
ULONGLONG APIENTRY EngGetTickCount(VOID); 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);

View file

@ -86,6 +86,10 @@ typedef struct _SURFACE
#define PDEV_SURFACE 0x80000000 #define PDEV_SURFACE 0x80000000
#define BMF_DONT_FREE 0x100
#define BMF_RLE_HACK 0x200
/* Internal interface */ /* Internal interface */
#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE)) #define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE))