From fe5c1a52ce91b721c46bd7cc3d99f3fb10ab766f Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 15 Jul 2009 21:06:40 +0000 Subject: [PATCH] [WIN32K] Keep a shared lock on palettes selected into DCs. This allows us to get rid of a large number of lock and unlock operations and checks. svn path=/trunk/; revision=41988 --- reactos/subsystems/win32/win32k/include/dc.h | 17 ++++++++++++++++- .../subsystems/win32/win32k/include/palette.h | 6 ++++++ .../subsystems/win32/win32k/objects/dclife.c | 9 +++++++-- .../subsystems/win32/win32k/objects/dcobjs.c | 5 +++-- .../subsystems/win32/win32k/objects/dcstate.c | 8 ++++---- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 1bda87a2cae..023fad7f7d0 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -1,9 +1,12 @@ #ifndef __WIN32K_DC_H #define __WIN32K_DC_H +typedef struct _DC *PDC; + #include "brush.h" #include "bitmaps.h" #include "pdevobj.h" +#include "palette.h" /* Constants ******************************************************************/ @@ -125,7 +128,7 @@ typedef struct _DC /* Reactos specific members */ ROS_DC_INFO rosdc; -} DC, *PDC; +} DC; /* Internal functions *********************************************************/ @@ -217,6 +220,18 @@ DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine) pdc->dclevel.pbrLine = pbrLine; } +VOID +FORCEINLINE +DC_vSelectPalette(PDC pdc, PPALETTE ppal) +{ + PPALETTE ppalOld = pdc->dclevel.ppal; + if (ppalOld) + PALETTE_ShareUnlockPalette(ppalOld); + if (ppal) + GDIOBJ_IncrementShareCount((POBJ)ppal); + pdc->dclevel.ppal = ppal; +} + BOOL FASTCALL IntPrepareDriverIfNeeded(); extern PDEVOBJ PrimarySurface; diff --git a/reactos/subsystems/win32/win32k/include/palette.h b/reactos/subsystems/win32/win32k/include/palette.h index 71822d1bf7b..0509c468dbe 100644 --- a/reactos/subsystems/win32/win32k/include/palette.h +++ b/reactos/subsystems/win32/win32k/include/palette.h @@ -67,6 +67,12 @@ HPALETTE FASTCALL PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, #define PALETTE_FreePaletteByHandle(hPalette) GDIOBJ_FreeObjByHandle((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE) #define PALETTE_LockPalette(hPalette) ((PPALETTE)GDIOBJ_LockObj((HGDIOBJ)hPalette, GDI_OBJECT_TYPE_PALETTE)) #define PALETTE_UnlockPalette(pPalette) GDIOBJ_UnlockObjByPtr((POBJ)pPalette) + +#define PALETTE_ShareLockPalette(hpal) \ + ((PPALETTE)GDIOBJ_ShareLockObj((HGDIOBJ)hpal, GDI_OBJECT_TYPE_PALETTE)) +#define PALETTE_ShareUnlockPalette(ppal) \ + GDIOBJ_ShareUnlockObjByPtr(&ppal->BaseObject) + BOOL INTERNAL_CALL PALETTE_Cleanup(PVOID ObjectBody); HPALETTE FASTCALL PALETTE_Init (VOID); diff --git a/reactos/subsystems/win32/win32k/objects/dclife.c b/reactos/subsystems/win32/win32k/objects/dclife.c index 6f95467b78b..73a1b14c270 100644 --- a/reactos/subsystems/win32/win32k/objects/dclife.c +++ b/reactos/subsystems/win32/win32k/objects/dclife.c @@ -120,7 +120,11 @@ DC_AllocDC(PUNICODE_STRING Driver) TextIntRealizeFont(pdcattr->hlfntNew,NULL); NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE); - NewDC->dclevel.laPath.eMiterLimit = 10.0; + NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal); + /* This should never fail */ + ASSERT(NewDC->dclevel.ppal); + + NewDC->dclevel.laPath.eMiterLimit = 10.0; // FIXME: use FLOATL or FLOATOBJ! NewDC->dclevel.lSaveDepth = 1; @@ -153,10 +157,11 @@ DC_Cleanup(PVOID ObjectBody) if (pDC->rosdc.DriverName.Buffer) ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC); - /* Clean up selected objects */ + /* Deselect dc objects */ DC_vSelectSurface(pDC, NULL); DC_vSelectFillBrush(pDC, NULL); DC_vSelectLineBrush(pDC, NULL); + DC_vSelectPalette(pDC, NULL); /* Dereference default brushes */ BRUSH_ShareUnlockBrush(pDC->eboText.pbrush); diff --git a/reactos/subsystems/win32/win32k/objects/dcobjs.c b/reactos/subsystems/win32/win32k/objects/dcobjs.c index db9059e08bc..6897b3f7d6e 100644 --- a/reactos/subsystems/win32/win32k/objects/dcobjs.c +++ b/reactos/subsystems/win32/win32k/objects/dcobjs.c @@ -200,7 +200,7 @@ GdiSelectPalette( } /* Check if this is a valid palette handle */ - ppal = PALETTE_LockPalette(hpal); + ppal = PALETTE_ShareLockPalette(hpal); if (!ppal) { DC_UnlockDc(pdc); @@ -215,13 +215,14 @@ GdiSelectPalette( /* Get old palette, set new one */ oldPal = pdc->dclevel.hpal; pdc->dclevel.hpal = hpal; + DC_vSelectPalette(pdc, ppal); /* Mark the brushes invalid */ pdc->pdcattr->ulDirty_ |= DIRTY_FILL | DIRTY_LINE | DIRTY_BACKGROUND | DIRTY_TEXT; } - PALETTE_UnlockPalette(ppal); + PALETTE_ShareUnlockPalette(ppal); DC_UnlockDc(pdc); return oldPal; diff --git a/reactos/subsystems/win32/win32k/objects/dcstate.c b/reactos/subsystems/win32/win32k/objects/dcstate.c index 32dc51e05f9..05656aff5c5 100644 --- a/reactos/subsystems/win32/win32k/objects/dcstate.c +++ b/reactos/subsystems/win32/win32k/objects/dcstate.c @@ -36,15 +36,15 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst) pdcDst->dclevel.efM11PtoD = pdcSrc->dclevel.efM11PtoD; pdcDst->dclevel.efM22PtoD = pdcSrc->dclevel.efM22PtoD; pdcDst->dclevel.sizl = pdcSrc->dclevel.sizl; + pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal; /* Handle references here correctly */ DC_vSelectSurface(pdcDst, pdcSrc->dclevel.pSurface); DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill); DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine); + DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal); // FIXME: handle refs - pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal; - pdcDst->dclevel.ppal = pdcSrc->dclevel.ppal; pdcDst->dclevel.plfnt = pdcSrc->dclevel.plfnt; /* ROS hacks */ @@ -122,7 +122,7 @@ NtGdiRestoreDC( /* Check if we have a valid instance */ if (iSaveLevel <= 0 || iSaveLevel >= pdc->dclevel.lSaveDepth) { - DPRINT("Illegal save level, requested: %ld, current: %ld\n", + DPRINT("Illegal save level, requested: %ld, current: %ld\n", iSaveLevel, pdc->dclevel.lSaveDepth); DC_UnlockDc(pdc); SetLastWin32Error(ERROR_INVALID_PARAMETER); @@ -220,7 +220,7 @@ NtGdiSaveDC( } hdcSave = pdcSave->BaseObject.hHmgr; - /* Make it a kernel handle + /* Make it a kernel handle (FIXME: windows handles this different, see wiki)*/ GDIOBJ_SetOwnership(hdcSave, NULL);