- Rework NtGdiStretchBlt into GreStretchBltMask function, which provides stretch blitting with mask support.

- Add NtGdiStretchBlt as a simple forwarder to the internal GreStretchBltMask helper.
- Based on a patch by Evgeniy Boltik.
- Some optimisation issues could still be solved as Timo suggested.
See issue #4294 for more details.

svn path=/trunk/; revision=40334
This commit is contained in:
Aleksey Bragin 2009-04-02 19:00:09 +00:00
parent c993561d5d
commit 0666bda0bc
6 changed files with 104 additions and 24 deletions

View file

@ -224,7 +224,7 @@ BOOLEAN Dummy_BitBlt(PBLTINFO BltInfo)
}
BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
SURFOBJ *PatternSurface,
SURFOBJ *PatternSurface, SURFOBJ *MaskSurf,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, BRUSHOBJ* Brush,
POINTL* BrushOrign,

View file

@ -41,7 +41,7 @@ typedef ULONG (*PFN_DIB_GetPixel)(SURFOBJ*,LONG,LONG);
typedef VOID (*PFN_DIB_HLine)(SURFOBJ*,LONG,LONG,LONG,ULONG);
typedef VOID (*PFN_DIB_VLine)(SURFOBJ*,LONG,LONG,LONG,ULONG);
typedef BOOLEAN (*PFN_DIB_BitBlt)(PBLTINFO);
typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
typedef BOOLEAN (*PFN_DIB_StretchBlt)(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
typedef BOOLEAN (*PFN_DIB_TransparentBlt)(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
typedef BOOLEAN (*PFN_DIB_ColorFill)(SURFOBJ*, RECTL*, ULONG);
typedef BOOLEAN (*PFN_DIB_AlphaBlend)(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -67,7 +67,7 @@ ULONG Dummy_GetPixel(SURFOBJ*,LONG,LONG);
VOID Dummy_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID Dummy_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN Dummy_BitBlt(PBLTINFO);
BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
BOOLEAN Dummy_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
BOOLEAN Dummy_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN Dummy_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN Dummy_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -132,7 +132,7 @@ BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULON
BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,XLATEOBJ*,ROP4);
extern unsigned char notmask[2];
extern unsigned char altnotmask[2];

View file

@ -22,7 +22,7 @@
#define NDEBUG
#include <debug.h>
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFOBJ *MaskSurf,
SURFOBJ *PatternSurface,
RECTL *DestRect, RECTL *SourceRect,
POINTL *MaskOrigin, BRUSHOBJ *Brush,
@ -48,6 +48,7 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
PFN_DIB_GetPixel fnDest_GetPixel = NULL;
PFN_DIB_PutPixel fnDest_PutPixel = NULL;
PFN_DIB_GetPixel fnPattern_GetPixel = NULL;
PFN_DIB_GetPixel fnMask_GetPixel = NULL;
ULONG PatternX = 0, PatternY = 0;
@ -67,6 +68,11 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom);
}
if (MaskSurf)
{
fnMask_GetPixel = DibFunctionsForBitmapFormat[MaskSurf->iBitmapFormat].DIB_GetPixel;
}
DstHeight = DestRect->bottom - DestRect->top;
DstWidth = DestRect->right - DestRect->left;
SrcHeight = SourceRect->bottom - SourceRect->top;
@ -120,7 +126,19 @@ BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
for (DesX = DestRect->left; DesX < DestRect->right; DesX++)
{
CanDraw = TRUE;
if (UsesSource)
if (fnMask_GetPixel)
{
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
if (sx < 0 || sy < 0 ||
MaskSurf->sizlBitmap.cx < sx || MaskSurf->sizlBitmap.cy < sy ||
fnMask_GetPixel(MaskSurf, sx, sy) != 0)
{
CanDraw = FALSE;
}
}
if (UsesSource && CanDraw)
{
sx = SourceRect->left+(DesX - DestRect->left) * SrcWidth / DstWidth;
if (sx >= 0 && sy >= 0 &&

View file

@ -808,7 +808,7 @@ CallDibStretchBlt(SURFOBJ* psoDest,
}
return DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_StretchBlt(
psoDest, psoSource, PatternSurface,
psoDest, psoSource, Mask, PatternSurface,
OutputRect, InputRect, MaskOrigin, pbo, &RealBrushOrigin,
ColorTranslation, XlatePatternToDest, Rop4);
@ -1021,21 +1021,7 @@ EngStretchBltROP(
AdjustedBrushOrigin = Translate;
}
if (Mask != NULL)
{
//BltRectFunc = BltMask;
DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
IntEngLeave(&EnterLeaveDest);
if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return FALSE;
}
else
{
BltRectFunc = CallDibStretchBlt;
}
BltRectFunc = CallDibStretchBlt;
DstHeight = OutputRect.bottom - OutputRect.top;
DstWidth = OutputRect.right - OutputRect.left;

View file

@ -253,5 +253,20 @@ IntGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors);
UINT APIENTRY
IntSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors);
BOOL APIENTRY
GreStretchBltMask(IN HDC hdcDst,
IN INT xDst,
IN INT yDst,
IN INT cxDst,
IN INT cyDst,
IN HDC hdcSrc,
IN INT xSrc,
IN INT ySrc,
IN INT cxSrc,
IN INT cySrc,
IN DWORD dwRop,
IN DWORD dwBackColor,
IN HDC hdcMask);
#endif /* _WIN32K_INTGDI_H */

View file

@ -720,7 +720,7 @@ NtGdiPlgBlt(
}
BOOL APIENTRY
NtGdiStretchBlt(
GreStretchBltMask(
HDC hDCDest,
INT XOriginDest,
INT YOriginDest,
@ -732,12 +732,15 @@ NtGdiStretchBlt(
INT WidthSrc,
INT HeightSrc,
DWORD ROP,
IN DWORD dwBackColor)
IN DWORD dwBackColor,
HDC hDCMask)
{
PDC DCDest;
PDC DCSrc = NULL;
PDC DCMask = NULL;
PDC_ATTR pdcattr;
SURFACE *BitmapDest, *BitmapSrc = NULL;
SURFACE *BitmapMask = NULL;
RECTL DestRect;
RECTL SourceRect;
BOOL Status = FALSE;
@ -853,6 +856,23 @@ NtGdiStretchBlt(
BrushOrigin.x += DCDest->ptlDCOrig.x;
BrushOrigin.y += DCDest->ptlDCOrig.y;
/* Make mask surface for source surface */
if (BitmapSrc && hDCMask)
{
DCMask = DC_LockDc(hDCMask);
if (DCMask)
{
BitmapMask = SURFACE_LockSurface(DCMask->rosdc.hBitmap);
if (BitmapMask &&
(BitmapMask->SurfObj.sizlBitmap.cx != WidthSrc ||
BitmapMask->SurfObj.sizlBitmap.cy != HeightSrc))
{
DPRINT1("Mask and bitmap sizes don't match!\n");
goto failed;
}
}
}
/* Perform the bitblt operation */
Status = IntEngStretchBlt(&BitmapDest->SurfObj,
&BitmapSrc->SurfObj,
@ -879,15 +899,56 @@ failed:
{
SURFACE_UnlockSurface(BitmapDest);
}
if (BitmapMask)
{
SURFACE_UnlockSurface(BitmapMask);
}
if (UsesSource && hDCSrc != hDCDest)
{
DC_UnlockDc(DCSrc);
}
if (DCMask)
{
DC_UnlockDc(DCMask);
}
DC_UnlockDc(DCDest);
return Status;
}
BOOL APIENTRY
NtGdiStretchBlt(
HDC hDCDest,
INT XOriginDest,
INT YOriginDest,
INT WidthDest,
INT HeightDest,
HDC hDCSrc,
INT XOriginSrc,
INT YOriginSrc,
INT WidthSrc,
INT HeightSrc,
DWORD ROP,
IN DWORD dwBackColor)
{
return GreStretchBltMask(
hDCDest,
XOriginDest,
YOriginDest,
WidthDest,
HeightDest,
hDCSrc,
XOriginSrc,
YOriginSrc,
WidthSrc,
HeightSrc,
ROP,
dwBackColor,
NULL);
}
BOOL FASTCALL
IntPatBlt(
PDC dc,