Author: fireball Date: Thu Apr 2 23:00:09 2009 New Revision: 40334
URL: http://svn.reactos.org/svn/reactos?rev=40334&view=rev Log: - 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.
Modified: trunk/reactos/subsystems/win32/win32k/dib/dib.c trunk/reactos/subsystems/win32/win32k/dib/dib.h trunk/reactos/subsystems/win32/win32k/dib/dibXXbpp.c trunk/reactos/subsystems/win32/win32k/eng/bitblt.c trunk/reactos/subsystems/win32/win32k/include/intgdi.h trunk/reactos/subsystems/win32/win32k/objects/bitblt.c
Modified: trunk/reactos/subsystems/win32/win32k/dib/dib.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/dib... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/dib/dib.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/dib/dib.c [iso-8859-1] Thu Apr 2 23:00:09 2009 @@ -224,7 +224,7 @@ }
BOOLEAN Dummy_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, - SURFOBJ *PatternSurface, + SURFOBJ *PatternSurface, SURFOBJ *MaskSurf, RECTL* DestRect, RECTL *SourceRect, POINTL* MaskOrigin, BRUSHOBJ* Brush, POINTL* BrushOrign,
Modified: trunk/reactos/subsystems/win32/win32k/dib/dib.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/dib... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/dib/dib.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/dib/dib.h [iso-8859-1] Thu Apr 2 23:00:09 2009 @@ -41,7 +41,7 @@ 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 @@ 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_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];
Modified: trunk/reactos/subsystems/win32/win32k/dib/dibXXbpp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/dib... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/dib/dibXXbpp.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/dib/dibXXbpp.c [iso-8859-1] Thu Apr 2 23:00:09 2009 @@ -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 @@ 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;
@@ -65,6 +66,11 @@ fnSource_GetPixel = DibFunctionsForBitmapFormat[SourceSurf->iBitmapFormat].DIB_GetPixel; DPRINT("Source BPP: %u, srcRect: (%d,%d)-(%d,%d)\n", 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; @@ -120,7 +126,19 @@ 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 &&
Modified: trunk/reactos/subsystems/win32/win32k/eng/bitblt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/eng... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/eng/bitblt.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/eng/bitblt.c [iso-8859-1] Thu Apr 2 23:00:09 2009 @@ -808,7 +808,7 @@ }
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 @@ 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;
Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h [iso-8859-1] Thu Apr 2 23:00:09 2009 @@ -253,5 +253,20 @@ 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 */
Modified: trunk/reactos/subsystems/win32/win32k/objects/bitblt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] Thu Apr 2 23:00:09 2009 @@ -720,7 +720,7 @@ }
BOOL APIENTRY -NtGdiStretchBlt( +GreStretchBltMask( HDC hDCDest, INT XOriginDest, INT YOriginDest, @@ -732,12 +732,15 @@ 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 @@ 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,14 +899,55 @@ { 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(