(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
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;
}