(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
This commit is contained in:
Timo Kreuzer 2008-05-28 22:25:08 +00:00
parent 5a47d0b0ad
commit 363e65143d

View file

@ -61,18 +61,13 @@ SynchonizeDriver(FLONG Flags)
// //
ULONG ULONG
FASTCALL FASTCALL
GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr) GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
{ {
PDC dc = NULL;
PDC_ATTR Dc_Attr = NULL; PDC_ATTR Dc_Attr = NULL;
if (hDC && !IsObjectDead(hDC)) if (dc)
{ {
dc = DC_LockDc(hDC); Dc_Attr = dc->pDc_Attr;
if (dc) 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. // The thread is approaching the end of sunset.
switch(pHdr->Cmd) switch(pHdr->Cmd)
@ -113,7 +108,7 @@ GdiFlushUserBatch(HDC hDC, PGDIBATCHHDR pHdr)
default: default:
break; break;
} }
if (dc) DC_UnlockDc(dc);
return pHdr->Size; // Return the full size of the structure. return pHdr->Size; // Return the full size of the structure.
} }
@ -146,25 +141,39 @@ NtGdiFlushUserBatch(VOID)
if( (GdiBatchCount > 0) && (GdiBatchCount <= (GDIBATCHBUFSIZE/4))) if( (GdiBatchCount > 0) && (GdiBatchCount <= (GDIBATCHBUFSIZE/4)))
{ {
HDC hDC = (HDC) pTeb->GdiTebBatch.HDC; HDC hDC = (HDC) pTeb->GdiTebBatch.HDC;
//
// If hDC is zero and the buffer fills up with delete objects we need to run /* If hDC is zero and the buffer fills up with delete objects we need
// anyway. So, hard code to the system batch limit. to run anyway. So, hard code to the system batch limit. */
// if ((hDC) || (GdiBatchCount >= GDI_BATCH_LIMIT))
if ((hDC) || ((!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! // No need to init anything, just go!
for (; GdiBatchCount > 0; GdiBatchCount--) for (; GdiBatchCount > 0; GdiBatchCount--)
{ {
// Process Gdi Batch! // 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. // Exit and clear out for the next round.
pTeb->GdiTebBatch.Offset = 0; pTeb->GdiTebBatch.Offset = 0;
pTeb->GdiBatchCount = 0; pTeb->GdiBatchCount = 0;
pTeb->GdiTebBatch.HDC = 0; pTeb->GdiTebBatch.HDC = 0;
} }
} }
// FIXME: on xp the function returns &pTeb->RealClientId, maybe VOID?
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }