- 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 #define NDEBUG
#include <debug.h> #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 ********************************************************/ /** 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 VOID
NTAPI NTAPI
EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) 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; pebo->ppalSurf = pebo->psurfTrg->ppal;
GDIOBJ_vReferenceObjectByPointer(&pebo->ppalSurf->BaseObject); 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) if (pbrush->flAttrs & BR_IS_NULL)
{ {
@ -111,7 +146,10 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo)
pebo->BrushObject.pvRbrush = NULL; pebo->BrushObject.pvRbrush = NULL;
} }
/* Dereference the palettes */
PALETTE_ShareUnlockPalette(pebo->ppalSurf); PALETTE_ShareUnlockPalette(pebo->ppalSurf);
PALETTE_ShareUnlockPalette(pebo->ppalDC);
if (pebo->ppalDIB) PALETTE_ShareUnlockPalette(pebo->ppalDIB);
} }
VOID VOID
@ -186,6 +224,41 @@ EngRealizeBrush(
return TRUE; 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 BOOL
NTAPI NTAPI
EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver) EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
@ -193,23 +266,40 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
BOOL bResult; BOOL bResult;
PFN_DrvRealizeBrush pfnRealzizeBrush = NULL; PFN_DrvRealizeBrush pfnRealzizeBrush = NULL;
PSURFACE psurfPattern, psurfMask; PSURFACE psurfPattern, psurfMask;
PPDEVOBJ ppdev = NULL; PPDEVOBJ ppdev;
EXLATEOBJ exlo; EXLATEOBJ exlo;
PPALETTE ppalPattern; PPALETTE ppalPattern;
PBRUSH pbr = pebo->pbrush;
HBITMAP hbmPattern;
ULONG iHatch;
/* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */ /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */
ASSERT(pebo->psurfTrg); ASSERT(pebo->psurfTrg);
ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev; ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev;
if (!ppdev) ppdev = gppdevPrimary;
// FIXME: all SURFACEs need a PDEV if (bCallDriver)
if (ppdev && bCallDriver)
pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush; pfnRealzizeBrush = ppdev->DriverFunctions.RealizeBrush;
if (!pfnRealzizeBrush) if (!pfnRealzizeBrush)
pfnRealzizeBrush = EngRealizeBrush; 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);
ASSERT(psurfPattern->ppal); ASSERT(psurfPattern->ppal);
@ -217,11 +307,11 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
psurfMask = NULL; psurfMask = NULL;
/* DIB brushes with DIB_PAL_COLORS usage need a new palette */ /* 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); ASSERT(FALSE);
ppalPattern = 0; //CreateDIBPalette(psurfPattern->ppal, pebo->ppalDC); ppalPattern = FixupDIBBrushPalette(psurfPattern->ppal, pebo->ppalDC);
// pebo->ppalDIB = ppalPattern; pebo->ppalDIB = ppalPattern;
} }
else else
{ {
@ -243,7 +333,7 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver)
&psurfPattern->SurfObj, &psurfPattern->SurfObj,
psurfMask ? &psurfMask->SurfObj : NULL, psurfMask ? &psurfMask->SurfObj : NULL,
&exlo.xlo, &exlo.xlo,
-1); // FIXME: what about hatch brushes? iHatch);
/* Cleanup the XLATEOBJ */ /* Cleanup the XLATEOBJ */
EXLATEOBJ_vCleanup(&exlo); EXLATEOBJ_vCleanup(&exlo);

View file

@ -136,6 +136,7 @@ PDEVOBJ_bEnablePDEV(
PWSTR pwszLogAddress) PWSTR pwszLogAddress)
{ {
PFN_DrvEnablePDEV pfnEnablePDEV; PFN_DrvEnablePDEV pfnEnablePDEV;
ULONG i;
DPRINT("PDEVOBJ_bEnablePDEV()\n"); DPRINT("PDEVOBJ_bEnablePDEV()\n");
@ -165,6 +166,13 @@ PDEVOBJ_bEnablePDEV(
/* Setup Palette */ /* Setup Palette */
ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); 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); DPRINT("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev);
return TRUE; return TRUE;

View file

@ -25,16 +25,6 @@ typedef struct _GDI_OBJ_ATTR_ENTRY
RGN_ATTR Attr[GDIOBJATTRFREE]; RGN_ATTR Attr[GDIOBJATTRFREE];
} GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY; } 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 BOOL
FASTCALL FASTCALL
IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner) IntGdiSetBrushOwner(PBRUSH pbr, ULONG ulOwner)
@ -129,9 +119,8 @@ NTAPI
BRUSH_Cleanup(PVOID ObjectBody) BRUSH_Cleanup(PVOID ObjectBody)
{ {
PBRUSH pbrush = (PBRUSH)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); GreSetObjectOwner(pbrush->hbmPattern, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(pbrush->hbmPattern); GreDeleteObject(pbrush->hbmPattern);
} }
@ -273,34 +262,23 @@ IntGdiCreateHatchBrush(
{ {
HBRUSH hBrush; HBRUSH hBrush;
PBRUSH pbrush; PBRUSH pbrush;
HBITMAP hPattern;
if (Style < 0 || Style >= NB_HATCH_STYLES) if (Style < 0 || Style >= NB_HATCH_STYLES)
{ {
return 0; return 0;
} }
hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
if (hPattern == NULL)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
pbrush = BRUSH_AllocBrushWithHandle(); pbrush = BRUSH_AllocBrushWithHandle();
if (pbrush == NULL) if (pbrush == NULL)
{ {
GreDeleteObject(hPattern);
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL; return NULL;
} }
hBrush = pbrush->BaseObject.hHmgr; hBrush = pbrush->BaseObject.hHmgr;
pbrush->flAttrs |= BR_IS_HATCH; pbrush->flAttrs |= BR_IS_HATCH;
pbrush->hbmPattern = hPattern;
pbrush->BrushAttr.lbColor = Color & 0xFFFFFF; pbrush->BrushAttr.lbColor = Color & 0xFFFFFF;
pbrush->ulStyle = Style;
GreSetObjectOwner(hPattern, GDI_OBJ_HMGR_PUBLIC);
GDIOBJ_vUnlockObject(&pbrush->BaseObject); GDIOBJ_vUnlockObject(&pbrush->BaseObject);

View file

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

View file

@ -614,6 +614,7 @@ DriverEntry(
CreateStockObjects(); CreateStockObjects();
CreateSysColorObjects(); CreateSysColorObjects();
NT_ROF(InitBrushImpl());
NT_ROF(InitPDEVImpl()); NT_ROF(InitPDEVImpl());
NT_ROF(InitLDEVImpl()); NT_ROF(InitLDEVImpl());
NT_ROF(InitDeviceImpl()); NT_ROF(InitDeviceImpl());