mirror of
https://github.com/reactos/reactos.git
synced 2024-11-29 14:33:32 +08:00
Use GDI Batch for PatBlt
This should increase speed a bit. Makes a good argument to use PolyPatBlt for more than one call. PolyPatBlt is not fully tested yet.
This commit is contained in:
parent
1114b89952
commit
b6262a25fd
@ -388,8 +388,8 @@ GdiAllocBatchCommand(
|
||||
}
|
||||
|
||||
/* Get the size of the entry */
|
||||
if (Cmd == GdiBCPatBlt) cjSize = 0;
|
||||
else if (Cmd == GdiBCPolyPatBlt) cjSize = 0;
|
||||
if (Cmd == GdiBCPatBlt) cjSize = sizeof(GDIBSPATBLT);
|
||||
else if (Cmd == GdiBCPolyPatBlt) cjSize = sizeof(GDIBSPPATBLT);
|
||||
else if (Cmd == GdiBCTextOut) cjSize = 0;
|
||||
else if (Cmd == GdiBCExtTextOut) cjSize = 0;
|
||||
else if (Cmd == GdiBCSetBrushOrg) cjSize = sizeof(GDIBSSETBRHORG);
|
||||
|
@ -456,9 +456,35 @@ PatBlt(
|
||||
_In_ INT nHeight,
|
||||
_In_ DWORD dwRop)
|
||||
{
|
||||
PDC_ATTR pdcattr;
|
||||
|
||||
HANDLE_METADC(BOOL, PatBlt, FALSE, hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
|
||||
|
||||
/* FIXME some part need be done in user mode */
|
||||
/* Get the DC attribute */
|
||||
pdcattr = GdiGetDcAttr(hdc);
|
||||
if (pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION))
|
||||
{
|
||||
PGDIBSPATBLT pgO;
|
||||
|
||||
pgO = GdiAllocBatchCommand(hdc, GdiBCPatBlt);
|
||||
if (pgO)
|
||||
{
|
||||
pgO->nXLeft = nXLeft;
|
||||
pgO->nYLeft = nYLeft;
|
||||
pgO->nWidth = nWidth;
|
||||
pgO->nHeight = nHeight;
|
||||
pgO->dwRop = dwRop;
|
||||
/* Snapshot attributes */
|
||||
pgO->hbrush = pdcattr->hbrush;
|
||||
pgO->crForegroundClr = pdcattr->crForegroundClr;
|
||||
pgO->crBackgroundClr = pdcattr->crBackgroundClr;
|
||||
pgO->crBrushClr = pdcattr->crBrushClr;
|
||||
pgO->ulForegroundClr = pdcattr->ulForegroundClr;
|
||||
pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
|
||||
pgO->ulBrushClr = pdcattr->ulBrushClr;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return NtGdiPatBlt( hdc, nXLeft, nYLeft, nWidth, nHeight, dwRop);
|
||||
}
|
||||
|
||||
@ -474,6 +500,7 @@ PolyPatBlt(
|
||||
UINT i;
|
||||
BOOL bResult;
|
||||
HBRUSH hbrOld;
|
||||
PDC_ATTR pdcattr;
|
||||
|
||||
/* Handle meta DCs */
|
||||
if ((GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) ||
|
||||
@ -511,7 +538,37 @@ PolyPatBlt(
|
||||
return bResult;
|
||||
}
|
||||
|
||||
/* FIXME some part need be done in user mode */
|
||||
/* Get the DC attribute */
|
||||
pdcattr = GdiGetDcAttr(hdc);
|
||||
if (nCount && pdcattr && !(pdcattr->ulDirty_ & DC_DIBSECTION))
|
||||
{
|
||||
PGDIBSPPATBLT pgO;
|
||||
PTEB pTeb = NtCurrentTeb();
|
||||
|
||||
pgO = GdiAllocBatchCommand(hdc, GdiBCPolyPatBlt);
|
||||
if (pgO)
|
||||
{
|
||||
USHORT cjSize = sizeof(GDIBSPPATBLT) + (nCount-1) * sizeof(PATRECT);
|
||||
|
||||
if ((pTeb->GdiTebBatch.Offset + cjSize) <= GDIBATCHBUFSIZE)
|
||||
{
|
||||
pgO->Count = nCount;
|
||||
pgO->Mode = dwMode;
|
||||
pgO->rop4 = dwRop;
|
||||
/* Snapshot attributes */
|
||||
pgO->crForegroundClr = pdcattr->crForegroundClr;
|
||||
pgO->crBackgroundClr = pdcattr->crBackgroundClr;
|
||||
pgO->crBrushClr = pdcattr->crBrushClr;
|
||||
pgO->ulForegroundClr = pdcattr->ulForegroundClr;
|
||||
pgO->ulBackgroundClr = pdcattr->ulBackgroundClr;
|
||||
pgO->ulBrushClr = pdcattr->ulBrushClr;
|
||||
RtlCopyMemory(pgO->pRect, pPoly, nCount * sizeof(PATRECT));
|
||||
// Recompute offset, remember one is already accounted for in the structure.
|
||||
pTeb->GdiTebBatch.Offset += (nCount-1) * sizeof(PATRECT);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NtGdiPolyPatBlt(hdc, dwRop, pPoly, nCount, dwMode);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
BOOL FASTCALL IntPatBlt( PDC,INT,INT,INT,INT,DWORD,PEBRUSHOBJ);
|
||||
|
||||
//
|
||||
// Gdi Batch Flush support functions.
|
||||
@ -89,16 +90,171 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
|
||||
switch(Cmd)
|
||||
{
|
||||
case GdiBCPatBlt:
|
||||
{
|
||||
PGDIBSPATBLT pgDPB;
|
||||
DWORD dwRop, flags;
|
||||
HBRUSH hOrgBrush;
|
||||
COLORREF crColor, crBkColor, crBrushClr;
|
||||
ULONG ulForegroundClr, ulBackgroundClr, ulBrushClr;
|
||||
if (!dc) break;
|
||||
pgDPB = (PGDIBSPATBLT) pHdr;
|
||||
/* Convert the ROP3 to a ROP4 */
|
||||
dwRop = pgDPB->dwRop;
|
||||
dwRop = MAKEROP4(dwRop & 0xFF0000, dwRop);
|
||||
/* Check if the rop uses a source */
|
||||
if (WIN32_ROP4_USES_SOURCE(dwRop))
|
||||
{
|
||||
/* This is not possible */
|
||||
break;
|
||||
}
|
||||
/* Check if the DC has no surface (empty mem or info DC) */
|
||||
if (dc->dclevel.pSurface == NULL)
|
||||
{
|
||||
/* Nothing to do */
|
||||
break;
|
||||
}
|
||||
// Save current attributes and flags
|
||||
crColor = dc->pdcattr->crForegroundClr;
|
||||
crBkColor = dc->pdcattr->ulBackgroundClr;
|
||||
crBrushClr = dc->pdcattr->crBrushClr;
|
||||
ulForegroundClr = dc->pdcattr->ulForegroundClr;
|
||||
ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
|
||||
ulBrushClr = dc->pdcattr->ulBrushClr;
|
||||
hOrgBrush = dc->pdcattr->hbrush;
|
||||
flags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND | DIRTY_TEXT | DIRTY_FILL | DC_BRUSH_DIRTY);
|
||||
// Set the attribute snapshot
|
||||
dc->pdcattr->hbrush = pgDPB->hbrush;
|
||||
dc->pdcattr->crForegroundClr = pgDPB->crForegroundClr;
|
||||
dc->pdcattr->crBackgroundClr = pgDPB->crBackgroundClr;
|
||||
dc->pdcattr->crBrushClr = pgDPB->crBrushClr;
|
||||
dc->pdcattr->ulForegroundClr = pgDPB->ulForegroundClr;
|
||||
dc->pdcattr->ulBackgroundClr = pgDPB->ulBackgroundClr;
|
||||
dc->pdcattr->ulBrushClr = pgDPB->ulBrushClr;
|
||||
// Process dirty attributes if any
|
||||
if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
|
||||
DC_vUpdateFillBrush(dc);
|
||||
if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
|
||||
DC_vUpdateTextBrush(dc);
|
||||
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
|
||||
DC_vUpdateBackgroundBrush(dc);
|
||||
/* Call the internal function */
|
||||
IntPatBlt(dc, pgDPB->nXLeft, pgDPB->nYLeft, pgDPB->nWidth, pgDPB->nHeight, dwRop, &dc->eboFill);
|
||||
// Restore attributes and flags
|
||||
dc->pdcattr->hbrush = hOrgBrush;
|
||||
dc->pdcattr->crForegroundClr = crColor;
|
||||
dc->pdcattr->crBackgroundClr = crBkColor;
|
||||
dc->pdcattr->crBrushClr = crBrushClr;
|
||||
dc->pdcattr->ulForegroundClr = ulForegroundClr;
|
||||
dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
|
||||
dc->pdcattr->ulBrushClr = ulBrushClr;
|
||||
dc->pdcattr->ulDirty_ |= flags;
|
||||
break;
|
||||
}
|
||||
|
||||
case GdiBCPolyPatBlt:
|
||||
break;
|
||||
{
|
||||
PGDIBSPPATBLT pgDPB;
|
||||
EBRUSHOBJ eboFill;
|
||||
PBRUSH pbrush;
|
||||
PPATRECT pRects;
|
||||
INT cRects, i;
|
||||
DWORD dwRop, flags;
|
||||
COLORREF crColor, crBkColor, crBrushClr;
|
||||
ULONG ulForegroundClr, ulBackgroundClr, ulBrushClr;
|
||||
if (!dc) break;
|
||||
pgDPB = (PGDIBSPPATBLT) pHdr;
|
||||
/* Convert the ROP3 to a ROP4 */
|
||||
dwRop = pgDPB->rop4;
|
||||
dwRop = MAKEROP4(dwRop & 0xFF0000, dwRop);
|
||||
/* Check if the rop uses a source */
|
||||
if (WIN32_ROP4_USES_SOURCE(dwRop))
|
||||
{
|
||||
/* This is not possible */
|
||||
break;
|
||||
}
|
||||
/* Check if the DC has no surface (empty mem or info DC) */
|
||||
if (dc->dclevel.pSurface == NULL)
|
||||
{
|
||||
/* Nothing to do */
|
||||
break;
|
||||
}
|
||||
// Save current attributes and flags
|
||||
crColor = dc->pdcattr->crForegroundClr;
|
||||
crBkColor = dc->pdcattr->ulBackgroundClr;
|
||||
crBrushClr = dc->pdcattr->crBrushClr;
|
||||
ulForegroundClr = dc->pdcattr->ulForegroundClr;
|
||||
ulBackgroundClr = dc->pdcattr->ulBackgroundClr;
|
||||
ulBrushClr = dc->pdcattr->ulBrushClr;
|
||||
flags = dc->pdcattr->ulDirty_ & (DIRTY_BACKGROUND | DIRTY_TEXT | DIRTY_FILL | DC_BRUSH_DIRTY);
|
||||
// Set the attribute snapshot
|
||||
dc->pdcattr->crForegroundClr = pgDPB->crForegroundClr;
|
||||
dc->pdcattr->crBackgroundClr = pgDPB->crBackgroundClr;
|
||||
dc->pdcattr->crBrushClr = pgDPB->crBrushClr;
|
||||
dc->pdcattr->ulForegroundClr = pgDPB->ulForegroundClr;
|
||||
dc->pdcattr->ulBackgroundClr = pgDPB->ulBackgroundClr;
|
||||
dc->pdcattr->ulBrushClr = pgDPB->ulBrushClr;
|
||||
// Process dirty attributes if any
|
||||
if (dc->pdcattr->ulDirty_ & DIRTY_TEXT)
|
||||
DC_vUpdateTextBrush(dc);
|
||||
if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
|
||||
DC_vUpdateBackgroundBrush(dc);
|
||||
|
||||
DPRINT1("GdiBCPolyPatBlt Testing\n");
|
||||
pRects = pgDPB->pRect;
|
||||
cRects = pgDPB->Count;
|
||||
|
||||
for (i = 0; i < cRects; i++)
|
||||
{
|
||||
pbrush = BRUSH_ShareLockBrush(pRects->hBrush);
|
||||
|
||||
/* Check if we could lock the brush */
|
||||
if (pbrush != NULL)
|
||||
{
|
||||
/* Initialize a brush object */
|
||||
EBRUSHOBJ_vInitFromDC(&eboFill, pbrush, dc);
|
||||
|
||||
IntPatBlt(
|
||||
dc,
|
||||
pRects->r.left,
|
||||
pRects->r.top,
|
||||
pRects->r.right,
|
||||
pRects->r.bottom,
|
||||
dwRop,
|
||||
&eboFill);
|
||||
|
||||
/* Cleanup the brush object and unlock the brush */
|
||||
EBRUSHOBJ_vCleanup(&eboFill);
|
||||
BRUSH_ShareUnlockBrush(pbrush);
|
||||
}
|
||||
pRects++;
|
||||
}
|
||||
|
||||
// Restore attributes and flags
|
||||
dc->pdcattr->crForegroundClr = crColor;
|
||||
dc->pdcattr->crBackgroundClr = crBkColor;
|
||||
dc->pdcattr->crBrushClr = crBrushClr;
|
||||
dc->pdcattr->ulForegroundClr = ulForegroundClr;
|
||||
dc->pdcattr->ulBackgroundClr = ulBackgroundClr;
|
||||
dc->pdcattr->ulBrushClr = ulBrushClr;
|
||||
dc->pdcattr->ulDirty_ |= flags;
|
||||
break;
|
||||
}
|
||||
case GdiBCTextOut:
|
||||
break;
|
||||
|
||||
case GdiBCExtTextOut:
|
||||
{
|
||||
//GreExtTextOutW( hDC,
|
||||
// XStart,
|
||||
// YStart,
|
||||
// fuOptions,
|
||||
// &SafeRect,
|
||||
// SafeString,
|
||||
// Count,
|
||||
// SafeDx,
|
||||
// dwCodePage );
|
||||
break;
|
||||
}
|
||||
|
||||
case GdiBCSetBrushOrg:
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user