Evgeny Boltik <BSTSoft AT narod DOT ru>:

Generic StretchBlt implementation for all bitrates with partial ROP and clipping support, see bug #4075.
Some changes from me applied to the patch:
- ROP variables renamed, applied consistent indentation, abort operation if pattern ROP and dprint once, split src and dst dprints
- Access source surface only if source is actually used, fixes mem access crashes
- Offer external drivers a NULL surface ptr if source is not used, since they (VMWare for example) access it although they shouldn't (another crash)
- Fixes bug #2609, support for pattern ROPs will be added after some restructuring
- Clipping still has some issues (bugs 3325, 3477, 4089) which seem to be related to IntEng- and EngStretchBlt

svn path=/trunk/; revision=39227
This commit is contained in:
Gregor Schneider 2009-01-31 13:05:11 +00:00
parent a51869e510
commit 2bb3d73470
6 changed files with 223 additions and 30 deletions

View file

@ -39,37 +39,37 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] =
/* BMF_1BPP */
{
DIB_1BPP_PutPixel, DIB_1BPP_GetPixel, DIB_1BPP_HLine, DIB_1BPP_VLine,
DIB_1BPP_BitBlt, DIB_1BPP_BitBltSrcCopy, DIB_1BPP_StretchBlt,
DIB_1BPP_BitBlt, DIB_1BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_1BPP_AlphaBlend
},
/* BMF_4BPP */
{
DIB_4BPP_PutPixel, DIB_4BPP_GetPixel, DIB_4BPP_HLine, DIB_4BPP_VLine,
DIB_4BPP_BitBlt, DIB_4BPP_BitBltSrcCopy, DIB_4BPP_StretchBlt,
DIB_4BPP_BitBlt, DIB_4BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_4BPP_AlphaBlend
},
/* BMF_8BPP */
{
DIB_8BPP_PutPixel, DIB_8BPP_GetPixel, DIB_8BPP_HLine, DIB_8BPP_VLine,
DIB_8BPP_BitBlt, DIB_8BPP_BitBltSrcCopy, DIB_8BPP_StretchBlt,
DIB_8BPP_BitBlt, DIB_8BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_8BPP_AlphaBlend
},
/* BMF_16BPP */
{
DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine,
DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_16BPP_StretchBlt,
DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend
},
/* BMF_24BPP */
{
DIB_24BPP_PutPixel, DIB_24BPP_GetPixel, DIB_24BPP_HLine, DIB_24BPP_VLine,
DIB_24BPP_BitBlt, DIB_24BPP_BitBltSrcCopy, DIB_24BPP_StretchBlt,
DIB_24BPP_BitBlt, DIB_24BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
DIB_24BPP_TransparentBlt, DIB_24BPP_ColorFill, DIB_24BPP_AlphaBlend
},
/* BMF_32BPP */
{
DIB_32BPP_PutPixel, DIB_32BPP_GetPixel, DIB_32BPP_HLine, DIB_32BPP_VLine,
DIB_32BPP_BitBlt, DIB_32BPP_BitBltSrcCopy, DIB_32BPP_StretchBlt,
DIB_32BPP_BitBlt, DIB_32BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt,
DIB_32BPP_TransparentBlt, DIB_32BPP_ColorFill, DIB_32BPP_AlphaBlend
},
/* BMF_4RLE */

View file

@ -78,7 +78,6 @@ VOID DIB_1BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_1BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_1BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_1BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_1BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -89,7 +88,6 @@ VOID DIB_4BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_4BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_4BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_4BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_4BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -100,7 +98,6 @@ VOID DIB_8BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_8BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_8BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_8BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -111,7 +108,6 @@ VOID DIB_16BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_16BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_16BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -122,7 +118,6 @@ VOID DIB_24BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_24BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_24BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_24BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_24BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_24BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
@ -133,11 +128,12 @@ VOID DIB_32BPP_HLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
VOID DIB_32BPP_VLine(SURFOBJ*,LONG,LONG,LONG,ULONG);
BOOLEAN DIB_32BPP_BitBlt(PBLTINFO);
BOOLEAN DIB_32BPP_BitBltSrcCopy(PBLTINFO);
BOOLEAN DIB_32BPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
BOOLEAN DIB_32BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,POINTL*,XLATEOBJ*,ULONG);
BOOLEAN DIB_32BPP_ColorFill(SURFOBJ*, RECTL*, ULONG);
BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*);
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,POINTL,CLIPOBJ*,XLATEOBJ*,ULONG);
extern unsigned char notmask[2];
extern unsigned char altnotmask[2];
#define MASK1BPP(x) (1<<(7-((x)&7)))

View file

@ -0,0 +1,181 @@
/*
* ReactOS W32 Subsystem
* Copyright (C) 2009 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <w32k.h>
#define NDEBUG
#include <debug.h>
BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG ROP)
{
LONG SrcSizeY;
LONG SrcSizeX;
LONG DesSizeY;
LONG DesSizeX;
LONG sx = 0;
LONG sy = 0;
LONG DesX;
LONG DesY;
LONG SrcZoomXHight;
LONG SrcZoomXLow;
LONG SrcZoomYHight;
LONG SrcZoomYLow;
LONG sy_dec = 0;
LONG sy_max;
LONG sx_dec = 0;
LONG sx_max;
ULONG color;
ULONG Dest, Source = 0, Pattern = 0;
ULONG xxBPPMask;
PFN_DIB_GetPixel fnSource_GetPixel = NULL;
PFN_DIB_GetPixel fnDest_GetPixel = NULL;
PFN_DIB_PutPixel fnDest_PutPixel = NULL;
RECT_ENUM RectEnum;
BOOL EnumMore;
unsigned i;
RECTL OutputRect;
BOOL UsesSource = ROP4_USES_SOURCE(ROP);
BOOL UsesPattern = ROP4_USES_PATTERN(ROP);
fnDest_GetPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_GetPixel;
fnDest_PutPixel = DibFunctionsForBitmapFormat[DestSurf->iBitmapFormat].DIB_PutPixel;
DPRINT("Dest BPP: %u, dstRect: (%d,%d)-(%d,%d)\n",
BitsPerFormat(DestSurf->iBitmapFormat), DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
if (UsesSource)
{
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);
}
/* Calc the Zoom height of Source */
SrcSizeY = SourceRect->bottom - SourceRect->top;
/* Calc the Zoom Width of Source */
SrcSizeX = SourceRect->right - SourceRect->left;
/* Calc the Zoom height of Destinations */
DesSizeY = DestRect->bottom - DestRect->top;
/* Calc the Zoom width of Destinations */
DesSizeX = DestRect->right - DestRect->left;
/* Calc the zoom factor of source height */
SrcZoomYHight = SrcSizeY / DesSizeY;
SrcZoomYLow = SrcSizeY - (SrcZoomYHight * DesSizeY);
/* Calc the zoom factor of source width */
SrcZoomXHight = SrcSizeX / DesSizeX;
SrcZoomXLow = SrcSizeX - (SrcZoomXHight * DesSizeX);
sx_max = DesSizeX;
sy_max = DesSizeY;
/* FIXME : MaskOrigin, BrushOrigin? */
switch(DestSurf->iBitmapFormat)
{
case BMF_1BPP: xxBPPMask = 0x1; break;
case BMF_4BPP: xxBPPMask = 0xF; break;
case BMF_8BPP: xxBPPMask = 0xFF; break;
case BMF_16BPP: xxBPPMask = 0xFFFF; break;
case BMF_24BPP: xxBPPMask = 0xFFFFFF; break;
default:
xxBPPMask = 0xFFFFFFFF;
}
if (UsesPattern)
{
DPRINT1("StretchBlt does not support pattern ROPs yet\n");
return TRUE;
}
CLIPOBJ_cEnumStart(ClipRegion, FALSE, CT_RECTANGLES, CD_ANY, 0);
do
{
EnumMore = CLIPOBJ_bEnum(ClipRegion,(ULONG) sizeof(RectEnum), (PVOID) &RectEnum);
for (i = 0; i < RectEnum.c; i++)
{
OutputRect.left = RectEnum.arcl[i].left;
OutputRect.right = RectEnum.arcl[i].right;
OutputRect.top = RectEnum.arcl[i].top;
OutputRect.bottom = RectEnum.arcl[i].bottom;
sy = SourceRect->top;
sy_dec = 0;
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sx = SourceRect->left;
sx_dec = 0;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
if (UsesSource)
{
Source = XLATEOBJ_iXlate(ColorTranslation, fnSource_GetPixel(SourceSurf, sx, sy));
}
if (UsesPattern)
{
/* TBD as soon as BRUSHOBJ is available */
}
Dest = fnDest_GetPixel(DestSurf, DesX, DesY);
color = DIB_DoRop(ROP, Dest, Source, Pattern) & xxBPPMask;
fnDest_PutPixel(DestSurf, DesX, DesY, color);
sx += SrcZoomXHight;
sx_dec += SrcZoomXLow;
if (sx_dec >= sx_max)
{
sx++;
sx_dec -= sx_max;
}
}
sy += SrcZoomYHight;
sy_dec += SrcZoomYLow;
if (sy_dec >= sy_max)
{
sy++;
sy_dec -= sy_max;
}
}
}
}
while (EnumMore);
return TRUE;
}
/* EOF */

View file

@ -836,15 +836,19 @@ EngStretchBlt(
PSTRETCHRECTFUNC BltRectFunc;
BOOLEAN Ret;
POINTL AdjustedBrushOrigin;
BOOL UsesSource = ROP4_USES_SOURCE(Mode);
InputRect.left = prclSrc->left;
InputRect.right = prclSrc->right;
InputRect.top = prclSrc->top;
InputRect.bottom = prclSrc->bottom;
if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &psoInput))
if (UsesSource)
{
return FALSE;
if (! IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &psoInput))
{
return FALSE;
}
}
InputPoint.x = InputRect.left + Translate.x;
@ -856,13 +860,19 @@ EngStretchBlt(
nothing to do */
if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top)
{
IntEngLeave(&EnterLeaveSource);
if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return TRUE;
}
if (! IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &psoOutput))
{
IntEngLeave(&EnterLeaveSource);
if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return FALSE;
}
@ -886,8 +896,10 @@ EngStretchBlt(
//BltRectFunc = BltMask;
DPRINT("EngStretchBlt isn't capable of handling mask yet.\n");
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return FALSE;
}
else
@ -901,7 +913,10 @@ EngStretchBlt(
&AdjustedBrushOrigin, Mode);
IntEngLeave(&EnterLeaveDest);
IntEngLeave(&EnterLeaveSource);
if (UsesSource)
{
IntEngLeave(&EnterLeaveSource);
}
return Ret;
}
@ -917,13 +932,14 @@ IntEngStretchBlt(SURFOBJ *psoDest,
POINTL *pMaskOrigin,
BRUSHOBJ *Brush,
POINTL *BrushOrigin,
ULONG Mode)
ROP4 ROP)
{
BOOLEAN ret;
COLORADJUSTMENT ca;
POINT MaskOrigin;
SURFACE *psurfDest;
SURFACE *psurfSource = NULL;
BOOL UsesSource = ROP4_USES_SOURCE(ROP);
ASSERT(psoDest);
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
@ -941,7 +957,7 @@ IntEngStretchBlt(SURFOBJ *psoDest,
MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top,
DestRect->right, DestRect->bottom);
if (NULL != psoSource)
if (UsesSource)
{
psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
ASSERT(SourceRect);
@ -958,22 +974,21 @@ IntEngStretchBlt(SURFOBJ *psoDest,
/* Call the driver's DrvStretchBlt if available */
if (psurfDest->flHooks & HOOK_STRETCHBLT)
{
/* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm )
SURFOBJ *psoMask // optional, if it exists, then rop4=0xCCAA, otherwise rop4=0xCCCC */
/* Drv->StretchBlt (look at http://www.osr.com/ddk/graphics/ddifncs_3ew7.htm ) */
// FIXME: MaskOrigin is always NULL !
ret = GDIDEVFUNCS(psoDest).StretchBlt(
psoDest, psoSource, MaskSurf, ClipRegion, ColorTranslation,
&ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
psoDest, (UsesSource) ? psoSource : NULL, MaskSurf, ClipRegion, ColorTranslation,
&ca, BrushOrigin, DestRect, SourceRect, NULL, ROP);
}
if (! ret)
{
// FIXME: see previous fixme
ret = EngStretchBlt(psoDest, psoSource, MaskSurf, ClipRegion, ColorTranslation,
&ca, BrushOrigin, DestRect, SourceRect, NULL, Mode);
&ca, BrushOrigin, DestRect, SourceRect, NULL, ROP);
}
if (NULL != psoSource)
if (UsesSource)
{
MouseSafetyOnDrawEnd(psoSource);
if (psoSource != psoDest)

View file

@ -750,8 +750,8 @@ NtGdiStretchBlt(
BOOL Status = FALSE;
XLATEOBJ *XlateObj = NULL;
PGDIBRUSHOBJ BrushObj = NULL;
BOOL UsesSource = ((ROP & 0xCC0000) >> 2) != (ROP & 0x330000);
BOOL UsesPattern = ((ROP & 0xF00000) >> 4) != (ROP & 0x0F0000);
BOOL UsesSource = ROP3_USES_SOURCE(ROP);
BOOL UsesPattern = ROP3_USES_PATTERN(ROP);
if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
{
@ -915,7 +915,7 @@ NtGdiStretchBlt(
Status = IntEngStretchBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj,
NULL, DCDest->CombinedClip, XlateObj,
&DestRect, &SourceRect, NULL, NULL, NULL,
COLORONCOLOR);
ROP3_TO_ROP4(ROP));
failed:
if (XlateObj)

View file

@ -28,6 +28,7 @@
<file>dib16bpp.c</file>
<file>dib24bpp.c</file>
<file>dib32bpp.c</file>
<file>dibXXbpp.c</file>
<file>dib.c</file>
<if property="ARCH" value="i386">