From 363e65143d02534a6021d6c67c2e3d8e9257dc5e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 28 May 2008 22:25:08 +0000 Subject: [PATCH] (Nt)GdiFlushUserBatch: - optmize by moving the locking of the dc to NtGdiFlushUserBatch instead of doing it for every object - fix wrong pointer calculation (GdiFlushUserBatch returns the size of the objects in bytes not in ULONG) - simplify a check - add a comment: on XP NtGdiFlushUserBatch doesn't return NTSTATUS, but a pointer to inside the Teb, maybe random/VOID svn path=/trunk/; revision=33750 --- .../win32/win32k/objects/gdibatch.c | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/reactos/subsystems/win32/win32k/objects/gdibatch.c b/reactos/subsystems/win32/win32k/objects/gdibatch.c index 575f688d432..9bcac6b714e 100644 --- a/reactos/subsystems/win32/win32k/objects/gdibatch.c +++ b/reactos/subsystems/win32/win32k/objects/gdibatch.c @@ -61,18 +61,13 @@ SynchonizeDriver(FLONG Flags) // ULONG FASTCALL -GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr) +GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr) { - PDC dc = NULL; PDC_ATTR Dc_Attr = NULL; - if (hDC && !IsObjectDead(hDC)) + if (dc) { - dc = DC_LockDc(hDC); - if (dc) - { - Dc_Attr = dc->pDc_Attr; - if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; - } + Dc_Attr = dc->pDc_Attr; + if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr; } // The thread is approaching the end of sunset. switch(pHdr->Cmd) @@ -113,7 +108,7 @@ GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr) default: break; } - if (dc) DC_UnlockDc(dc); + return pHdr->Size; // Return the full size of the structure. } @@ -146,25 +141,39 @@ NtGdiFlushUserBatch(VOID) if( (GdiBatchCount > 0) && (GdiBatchCount <= (GDIBATCHBUFSIZE/4))) { HDC hDC = (HDC) pTeb->GdiTebBatch.HDC; -// -// If hDC is zero and the buffer fills up with delete objects we need to run -// anyway. So, hard code to the system batch limit. -// - if ((hDC) || ((!hDC) && (GdiBatchCount >= GDI_BATCH_LIMIT))) + + /* If hDC is zero and the buffer fills up with delete objects we need + to run anyway. So, hard code to the system batch limit. */ + if ((hDC) || (GdiBatchCount >= GDI_BATCH_LIMIT)) { - PULONG pHdr = &pTeb->GdiTebBatch.Buffer[0]; + PCHAR pHdr = (PCHAR)&pTeb->GdiTebBatch.Buffer[0]; + PDC pDC = NULL; + + if (hDC && !IsObjectDead(hDC)) + { + pDC = DC_LockDc(hDC); + } + // No need to init anything, just go! for (; GdiBatchCount > 0; GdiBatchCount--) { // Process Gdi Batch! - pHdr += GdiFlushUserBatch( hDC, (PGDIBATCHHDR) pHdr ); + pHdr += GdiFlushUserBatch(pDC, (PGDIBATCHHDR) pHdr); } + + if (pDC) + { + DC_UnlockDc(pDC); + } + // Exit and clear out for the next round. pTeb->GdiTebBatch.Offset = 0; pTeb->GdiBatchCount = 0; pTeb->GdiTebBatch.HDC = 0; } } + + // FIXME: on xp the function returns &pTeb->RealClientId, maybe VOID? return STATUS_SUCCESS; }