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/di…
==============================================================================
--- 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/di…
==============================================================================
--- 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/di…
==============================================================================
--- 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/en…
==============================================================================
--- 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/in…
==============================================================================
--- 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/ob…
==============================================================================
--- 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(