- Create default hatch brush bitmaps on win32k init
- After creating a PDEV fill the fields in the ahsurf array that are not filled by the driver with these bitmaps
- don't create a new bitmap when a hatch brush is created, instead only store the style and use the related bitmap from the PDEV when realizing the brush.
- Fix the palette of DIB brushes, when realizing the brush
- Don't leak the bitmaps for DIB brushes in BRUSH_Cleanup

svn path=/trunk/; revision=56523
This commit is contained in:
Timo Kreuzer 2012-05-06 08:17:48 +00:00
parent f030e937a4
commit f5acffdf62
5 changed files with 123 additions and 39 deletions

View file

@ -12,8 +12,42 @@
#define NDEBUG
#include <debug.h>
static const ULONG gaulHatchBrushes[HS_DDI_MAX][8] =
{
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
{0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
{0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
{0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
{0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
};
HSURF gahsurfHatch[HS_DDI_MAX];
/** Internal functions ********************************************************/
INIT_FUNCTION
NTSTATUS
NTAPI
InitBrushImpl(VOID)
{
ULONG i;
SIZEL sizl = {8, 8};
/* Loop all hatch styles */
for (i = 0; i < HS_DDI_MAX; i++)
{
/* Create a default hatch bitmap */
gahsurfHatch[i] = (HSURF)EngCreateBitmap(sizl,
0,
BMF_1BPP,
0,
(PVOID)gaulHatchBrushes[i]);
}
return STATUS_SUCCESS;
}
VOID
NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
@ -38,7 +72,8 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc)
pebo->ppalSurf = pebo->psurfTrg->ppal;
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject);
//pebo->ppalDC = pdc->dclevel.ppal;
pebo->ppalDC = pdc->dclevel.ppal;
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalDC->BaseObject);
if (pbrush->flAttrs & BR_IS_NULL)
{
@ -111,7 +146,10 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
pebo->BrushObject.pvRbrush = NULL;
}
/* Dereference the palettes */
PALETTE_ShareUnlockPalette(pebo->ppalSurf);
PALETTE_ShareUnlockPalette(pebo->ppalDC);
if (pebo->ppalDIB) PALETTE_ShareUnlockPalette(pebo->ppalDIB);
}
VOID
@ -186,6 +224,41 @@ EngRealizeBrush(
return TRUE;
}
static
PPALETTE
FixupDIBBrushPalette(
_In_ PPALETTE ppalDIB,
_In_ PPALETTE ppalDC)
{
PPALETTE ppalNew;
ULONG i, iPalIndex, crColor;
/* Allocate a new palette */
ppalNew = PALETTE_AllocPalette(PAL_INDEXED,
ppalDIB->NumColors,
NULL,
0,
0,
0);
/* Loop all colors */
for (i = 0; i < ppalDIB->NumColors; i++)
{
/* Get the RGB color, which is the index into the DC palette */
iPalIndex = PALETTE_ulGetRGBColorFromIndex(ppalDIB, i);
/* Roll over when index is too big */
iPalIndex %= ppalDC->NumColors;
/* Set the indexed DC color as the new color */
crColor = PALETTE_ulGetRGBColorFromIndex(ppalDC, iPalIndex);
PALETTE_vSetRGBColorForIndex(ppalNew, i, crColor);
}
/* Return the new palette */
return ppalNew;
}
BOOL
NTAPI
EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
@ -193,23 +266,40 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
BOOL bResult;
PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
PSURFACE psurfPattern, psurfMask;
PPDEVOBJ ppdev = NULL;
PPDEVOBJ ppdev;
EXLATEOBJ exlo;
PPALETTE ppalPattern;
PBRUSH pbr = pebo->pbrush;
HBITMAP hbmPattern;
ULONG iHatch;
/* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
ASSERT(pebo->psurfTrg);
ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
if (!ppdev) ppdev = gppdevPrimary;
// FIXME: all SURFACEs need a PDEV
if (ppdev && bCallDriver)
if (bCallDriver)
pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
if (!pfnRealzizeBrush)
pfnRealzizeBrush = EngRealizeBrush;
psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern);
/* Check if this is a hatch brush */
if (pbr->flAttrs & BR_IS_HATCH)
{
/* Get the hatch brush pattern from the PDEV */
hbmPattern = (HBITMAP)ppdev->ahsurf[pbr->ulStyle];
iHatch = pbr->ulStyle;
}
else
{
/* Use the brushes pattern */
hbmPattern = pbr->hbmPattern;
iHatch = -1;
}
psurfPattern = SURFACE_ShareLockSurface(hbmPattern);
ASSERT(psurfPattern);
ASSERT(psurfPattern->ppal);
@ -217,11 +307,11 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
psurfMask = NULL;
/* DIB brushes with DIB_PAL_COLORS usage need a new palette */
if (pebo->pbrush->flAttrs & BR_IS_DIBPALCOLORS)
if (pbr->flAttrs & BR_IS_DIBPALCOLORS)
{
ASSERT(FALSE);
ppalPattern = 0; //CreateDIBPalette(psurfPattern->ppal, pebo->ppalDC);
// pebo->ppalDIB = ppalPattern;
ppalPattern = FixupDIBBrushPalette(psurfPattern->ppal, pebo->ppalDC);
pebo->ppalDIB = ppalPattern;
}
else
{
@ -243,7 +333,7 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
&psurfPattern->SurfObj,
psurfMask ? &psurfMask->SurfObj : NULL,
&exlo.xlo,
-1); // FIXME: what about hatch brushes?
iHatch);
/* Cleanup the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo);

View file

@ -136,6 +136,7 @@ PDEVOBJ_bEnablePDEV(
PWSTR pwszLogAddress)
{
PFN_DrvEnablePDEV pfnEnablePDEV;
ULONG i;
DPRINT("PDEVOBJ_bEnablePDEV()\n");
@ -165,6 +166,13 @@ PDEVOBJ_bEnablePDEV(
/* Setup Palette */
ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault);
/* Setup hatch brushes */
for (i = 0; i < HS_DDI_MAX; i++)
{
if (ppdev->ahsurf[i] == NULL)
ppdev->ahsurf[i] = gahsurfHatch[i];
}
DPRINT("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
return TRUE;

View file

@ -25,16 +25,6 @@ typedef struct _GDI_OBJ_ATTR_ENTRY
RGN_ATTR Attr[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY;
static const ULONG HatchBrushes[NB_HATCH_STYLES][8] =
{
{0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */
{0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */
{0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F}, /* HS_FDIAGONAL */
{0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE}, /* HS_BDIAGONAL */
{0xF7, 0xF7, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0xF7}, /* HS_CROSS */
{0x7E, 0xBD, 0xDB, 0xE7, 0xE7, 0xDB, 0xBD, 0x7E} /* HS_DIAGCROSS */
};
BOOL
FASTCALL
IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
@ -129,9 +119,8 @@ NTAPI
BRUSH_Cleanup(PVOID ObjectBody)
{
PBRUSH pbrush = (PBRUSH)ObjectBody;
if (pbrush->flAttrs & (BR_IS_HATCH | BR_IS_BITMAP))
if (pbrush->hbmPattern)
{
ASSERT(pbrush->hbmPattern);
GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(pbrush->hbmPattern);
}
@ -273,34 +262,23 @@ IntGdiCreateHatchBrush(
{
HBRUSH hBrush;
PBRUSH pbrush;
HBITMAP hPattern;
if (Style < 0 || Style >= NB_HATCH_STYLES)
{
return 0;
}
hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
if (hPattern == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
pbrush = BRUSH_AllocBrushWithHandle();
if (pbrush == NULL)
{
GreDeleteObject(hPattern);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
hBrush = pbrush->BaseObject.hHmgr;
pbrush->flAttrs |= BR_IS_HATCH;
pbrush->hbmPattern = hPattern;
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
pbrush->ulStyle = Style;
GDIOBJ_vUnlockObject(&pbrush->BaseObject);

View file

@ -96,8 +96,15 @@ typedef struct _EBRUSHOBJ
INT FASTCALL BRUSH_GetObject (PBRUSH GdiObject, INT Count, LPLOGBRUSH Buffer);
BOOL NTAPI BRUSH_Cleanup(PVOID ObjectBody);
extern HSURF gahsurfHatch[HS_DDI_MAX];
struct _DC;
INIT_FUNCTION
NTSTATUS
NTAPI
InitBrushImpl(VOID);
VOID
NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, struct _DC *);

View file

@ -75,7 +75,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
sizeof(PROCESSINFO),
USERTAG_PROCESSINFO);
if (ppiCurrent == NULL)
if (ppiCurrent == NULL)
{
ERR_CH(UserProcess, "Failed to allocate ppi for PID:%d\n", Process->UniqueProcessId);
RETURN( STATUS_NO_MEMORY);
@ -127,7 +127,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
ppiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
EngCreateEvent((PEVENT *)&ppiCurrent->InputIdleEvent);
KeInitializeEvent(ppiCurrent->InputIdleEvent, NotificationEvent, FALSE);
/* map the gdi handle table to user land */
Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(Process);
@ -163,7 +163,7 @@ Win32kProcessCallback(struct _EPROCESS *Process,
TRACE_CH(UserProcess, "Destroying ppi 0x%x\n", ppiCurrent);
ppiCurrent->W32PF_flags |= W32PF_TERMINATED;
if (ppiScrnSaver == ppiCurrent)
if (ppiScrnSaver == ppiCurrent)
ppiScrnSaver = NULL;
if (ppiCurrent->InputIdleEvent)
@ -244,7 +244,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
}
RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));
PsSetThreadWin32Thread(Thread, ptiCurrent);
pTeb->Win32ThreadInfo = ptiCurrent;
ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
@ -275,14 +275,14 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
if (ptiCurrent->KeyboardLayout)
UserReferenceObject(ptiCurrent->KeyboardLayout);
ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
/* Initialize the CLIENTINFO */
pci = (PCLIENTINFO)pTeb->Win32ClientInfo;
RtlZeroMemory(pci, sizeof(CLIENTINFO));
pci->ppi = ptiCurrent->ppi;
pci->fsHooks = ptiCurrent->fsHooks;
pci->dwTIFlags = ptiCurrent->TIF_flags;
if (ptiCurrent->KeyboardLayout)
if (ptiCurrent->KeyboardLayout)
pci->hKL = ptiCurrent->KeyboardLayout->hkl;
/* Assign a default window station and desktop to the process */
@ -614,6 +614,7 @@ DriverEntry(
CreateStockObjects();
CreateSysColorObjects();
NT_ROF(InitBrushImpl());
NT_ROF(InitPDEVImpl());
NT_ROF(InitLDEVImpl());
NT_ROF(InitDeviceImpl());