Accelerate PATCOPY blits.

svn path=/trunk/; revision=3528
This commit is contained in:
David Welch 2002-09-21 18:05:25 +00:00
parent 93dd94f0db
commit 02d56c87f1
3 changed files with 246 additions and 173 deletions

View file

@ -6,98 +6,53 @@
#include "brush.h"
#include "bitblt.h"
// FIXME:
// RGBtoULONG (eng/xlate.c) will be faster than RtlCopyMemory?
typedef BOOL (*PFN_VGABlt)(SURFOBJ*, SURFOBJ*, XLATEOBJ*, RECTL*, POINTL*);
// Note: All of our BitBlt ops expect to be working with 4BPP data
typedef BOOL (*PFN_VGABlt)(SURFOBJ *, SURFOBJ *, SURFOBJ *, XLATEOBJ *,
RECTL *, POINTL *, POINTL *,
BRUSHOBJ *, POINTL *, ROP4);
BOOL DIBtoVGA(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
BOOL
DIBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
LONG i, j, dx, dy, alterx, altery, idxColor, RGBulong = 0, c8;
BYTE *GDIpos, *initial, *tMask, *lMask;
if(Source != NULL) {
GDIpos = Source->pvBits /* +
SourcePoint->y * Source->lDelta + (SourcePoint->x >> 1) */ ;
}
GDIpos = Source->pvBits;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
alterx = abs(SourcePoint->x - DestRect->left);
altery = abs(SourcePoint->y - DestRect->top);
// FIXME: ColorTranslation will never be null. We must always map the colors (see PCGPE's bmp.txt)
if(ColorTranslation == NULL)
{
if(Mask != NULL)
if (ColorTranslation == NULL)
{
DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits,
Source->lDelta);
}
else
{
if(rop4 == 0xAACC) { // no source, just paint the brush according to the mask
tMask = Mask->pvBits;
for (j=0; j<dy; j++)
{
lMask = tMask;
c8 = 0;
for (i=0; i<dx; i++)
{
if((*lMask & maskbit[c8]) != 0)
vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
c8++;
if(c8 == 8) { lMask++; c8=0; }
}
tMask += Mask->lDelta;
}
}
} else if (rop4 == PATCOPY)
{
for (j=0;j<dy;j++)
{
for (i=0;i<dx;i++)
{
vgaPutPixel(DestRect->left+i, DestRect->top+j,
Brush->iSolidColor);
}
}
}
else
DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, Source->lDelta);
} else {
// Perform color translation
for(j=SourcePoint->y; j<SourcePoint->y+dy; j++)
{
initial = GDIpos;
for(i=SourcePoint->x; i<SourcePoint->x+dx; i++)
{
idxColor = XLATEOBJ_iXlate(ColorTranslation, *GDIpos);
vgaPutPixel(i+alterx, j+altery, idxColor);
GDIpos+=1;
}
GDIpos = initial + Source->lDelta;
/* Perform color translation */
for (j = SourcePoint->y; j < SourcePoint->y+dy; j++)
{
initial = GDIpos;
for (i=SourcePoint->x; i<SourcePoint->x+dx; i++)
{
idxColor = XLATEOBJ_iXlate(ColorTranslation, *GDIpos);
vgaPutPixel(i+alterx, j+altery, idxColor);
GDIpos+=1;
}
GDIpos = initial + Source->lDelta;
}
}
}
}
BOOL VGAtoDIB(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
BOOL
VGAtoDIB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
LONG i, j, dx, dy, RGBulong;
BYTE *GDIpos, *initial, idxColor;
// Used by the temporary DFB
PDEVSURF TargetSurf;
DEVSURF DestDevSurf;
@ -135,26 +90,23 @@ BOOL VGAtoDIB(
}
}
BOOL DFBtoVGA(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
BOOL
DFBtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
// Do DFBs need color translation??
}
BOOL VGAtoDFB(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
BOOL
VGAtoDFB(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
// Do DFBs need color translation??
}
BOOL VGAtoVGA(
SURFOBJ *Dest, SURFOBJ *Source, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint, POINTL *MaskPoint,
BRUSHOBJ *Brush, POINTL *BrushPoint, ROP4 rop4)
BOOL
VGAtoVGA(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
// FIXME: Use fast blts instead of get and putpixels
@ -210,6 +162,184 @@ BOOL VGAtoVGA(
return TRUE;
}
BOOL STDCALL
VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect,
BRUSHOBJ* Brush, POINTL* BrushPoint, ROP4 Rop4)
{
UCHAR SolidColor;
ULONG Left;
ULONG Right;
ULONG Length;
PUCHAR Video;
UCHAR Mask;
ULONG i, j;
/* Punt brush blts to non-device surfaces. */
if (Dest->iType != STYPE_DEVICE)
{
return(FALSE);
}
/* Punt pattern fills. */
if (Rop4 == PATCOPY && Brush->iSolidColor == 0xFFFFFFFF)
{
return(FALSE);
}
if (Rop4 == PATCOPY)
{
SolidColor = Brush->iSolidColor;
}
else if (Rop4 == WHITENESS)
{
SolidColor = 1;
}
else
{
SolidColor = 0;
}
/* Fill any pixels on the left which don't fall into a full row of eight. */
if ((DestRect->left % 8) != 0)
{
/* Disable writes to pixels outside of the destination rectangle. */
Mask = (1 << (8 - (DestRect->left % 8))) - 1;
if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
{
Mask &= ~((1 << (8 - (DestRect->right % 8))) - 1);
}
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask);
/* Write the same color to each pixel. */
Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->left >> 3);
for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
{
(VOID)READ_REGISTER_UCHAR(Video);
WRITE_REGISTER_UCHAR(Video, SolidColor);
}
}
/* Enable writes to all pixels. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
/* Have we finished. */
if ((DestRect->right - DestRect->left) < (8 - (DestRect->left % 8)))
{
return(TRUE);
}
/* Fill any whole rows of eight pixels. */
Left = (DestRect->left + 7) & ~0x7;
Length = (DestRect->right >> 3) - (Left >> 3);
for (i = DestRect->top; i < DestRect->bottom; i++)
{
Video = (PUCHAR)vidmem + i * 80 + (Left >> 3);
for (j = 0; j < Length; j++, Video++)
{
WRITE_REGISTER_UCHAR(Video, SolidColor);
}
}
/* Fill any pixels on the right which don't fall into a complete row. */
if ((DestRect->right % 8) != 0)
{
/* Disable writes to pixels outside the destination rectangle. */
Mask = ~((1 << (8 - (DestRect->right % 8))) - 1);
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, Mask);
Video = (PUCHAR)vidmem + DestRect->top * 80 + (DestRect->right >> 3);
for (i = DestRect->top; i < DestRect->bottom; i++, Video+=80)
{
/* Read the existing colours for this pixel into the latches. */
(VOID)READ_REGISTER_UCHAR(Video);
/* Write the new colour for the pixels selected in the mask. */
WRITE_REGISTER_UCHAR(Video, SolidColor);
}
/* Restore the default write masks. */
WRITE_PORT_UCHAR((PUCHAR)GRA_I, 0x8);
WRITE_PORT_UCHAR((PUCHAR)GRA_D, 0xFF);
}
return(TRUE);
}
BOOL STDCALL
VGADDI_BltSrc(SURFOBJ *Dest, SURFOBJ *Source, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *SourcePoint)
{
RECT_ENUM RectEnum;
BOOL EnumMore;
PFN_VGABlt BltOperation;
ULONG SourceType;
SourceType = Source->iType;
if (SourceType == STYPE_BITMAP && Dest->iType == STYPE_DEVICE)
{
BltOperation = DIBtoVGA;
}
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP)
{
BltOperation = VGAtoDIB;
}
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE)
{
BltOperation = VGAtoVGA;
}
else if (SourceType == STYPE_DEVBITMAP && Dest->iType == STYPE_DEVICE)
{
BltOperation = DFBtoVGA;
}
else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVBITMAP)
{
BltOperation = VGAtoDFB;
}
else
{
/* Punt blts not involving a device or a device-bitmap. */
return(FALSE);
}
BltOperation(Dest, Source, ColorTranslation, DestRect, SourcePoint);
return(TRUE);
}
BOOL STDCALL
VGADDI_BltMask(SURFOBJ *Dest, SURFOBJ *Mask, XLATEOBJ *ColorTranslation,
RECTL *DestRect, POINTL *MaskPoint, BRUSHOBJ* Brush,
POINTL* BrushPoint)
{
LONG i, j, dx, dy, idxColor, RGBulong = 0, c8;
BYTE *initial, *tMask, *lMask;
dx = DestRect->right - DestRect->left;
dy = DestRect->bottom - DestRect->top;
if (ColorTranslation == NULL)
{
if (Mask != NULL)
{
tMask = Mask->pvBits;
for (j=0; j<dy; j++)
{
lMask = tMask;
c8 = 0;
for (i=0; i<dx; i++)
{
if((*lMask & maskbit[c8]) != 0)
{
vgaPutPixel(DestRect->left + i, DestRect->top + j, Brush->iSolidColor);
}
c8++;
if(c8 == 8) { lMask++; c8=0; }
}
tMask += Mask->lDelta;
}
}
}
}
BOOL STDCALL
DrvBitBlt(SURFOBJ *Dest,
@ -224,88 +354,29 @@ DrvBitBlt(SURFOBJ *Dest,
POINTL *BrushPoint,
ROP4 rop4)
{
RECT_ENUM RectEnum;
BOOL EnumMore;
PFN_VGABlt BltOperation;
ULONG SourceType;
/* Punt bitblts with complex clipping to the GDI. */
if (Clip != NULL)
{
return(FALSE);
}
switch (rop4)
{
case BLACKNESS:
case PATCOPY:
case WHITENESS:
return(VGADDI_BltBrush(Dest, ColorTranslation, DestRect, Brush,
BrushPoint, rop4));
if(Source == NULL)
{
SourceType = STYPE_BITMAP;
} else
SourceType = Source->iType;
case SRCCOPY:
return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect,
SourcePoint));
DPRINT("VGADDIBitBlt: Dest->pvScan0: %08x\n", Dest->pvScan0);
case 0xAACC:
return(VGADDI_BltMask(Dest, Mask, ColorTranslation, DestRect,
MaskPoint, Brush, BrushPoint));
// Determine the bltbit operation
if((SourceType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE))
{
DPRINT("DIB2VGA\n");
BltOperation = DIBtoVGA;
} else
if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_BITMAP))
{
DPRINT("VGA2DIB\n");
BltOperation = VGAtoDIB;
} else
if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVICE))
{
DPRINT("VGA2VGA\n");
BltOperation = VGAtoVGA;
} else
if((SourceType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVICE))
{
DPRINT("DFB2VGA\n");
BltOperation = DFBtoVGA;
} else
if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVBITMAP))
{
DPRINT("VGA2DFB\n");
BltOperation = VGAtoDFB;
} else
{
DPRINT("VGA:bitblt.c: Can't handle requested BitBlt operation (source:%u dest:%u)\n", SourceType, Dest->iType);
// Cannot handle given surfaces for VGA BitBlt
return FALSE;
}
// Perform the necessary operatings according to the clipping
if(Clip == NULL)
{
BltOperation(Dest, Source, Mask, ColorTranslation, DestRect,
SourcePoint, MaskPoint, Brush, BrushPoint, rop4);
} else
{
switch(Clip->iMode) {
case TC_RECTANGLES:
if (Clip->iDComplexity == DC_RECT)
{
// FIXME: Intersect clip rectangle
BltOperation(Dest, Source, Mask, ColorTranslation,
DestRect, SourcePoint, MaskPoint, Brush, BrushPoint, rop4);
} else {
// Enumerate all the rectangles and draw them
/* CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, CD_ANY,
ENUM_RECT_LIMIT);
do {
EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID) &RectEnum);
// FIXME: Calc new source point (diff between new & old destrects?)
VGADDIFillSolid(Dest, Srouce, Mask,
&RectEnum.arcl[0], NewSourcePoint);
} while (EnumMore); */
}
}
}
return TRUE;
default:
return(FALSE);
}
}

View file

@ -3,9 +3,11 @@
#include "../../drivers/input/include/mouse.h"
#include "objects.h"
BOOLEAN SafetySwitch = FALSE, SafetySwitch2 = FALSE, MouseEnabled = FALSE;
LONG mouse_x, mouse_y;
UINT mouse_width = 0, mouse_height = 0;
static BOOLEAN SafetySwitch = FALSE;
static BOOLEAN SafetySwitch2 = FALSE;
static BOOLEAN MouseEnabled = FALSE;
static LONG mouse_x, mouse_y;
static UINT mouse_width = 0, mouse_height = 0;
INT MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2)
{
@ -148,7 +150,7 @@ VOID EnableMouse(HDC hDisplayDC)
MouseRect.left = 0;
MouseRect.bottom = 16;
MouseRect.right = 16;
EngBitBlt(MouseSurf, SurfObj, NULL, NULL, NULL, &MouseRect, &ZeroPoint, NULL, NULL, NULL, 0);
EngBitBlt(MouseSurf, SurfObj, NULL, NULL, NULL, &MouseRect, &ZeroPoint, NULL, NULL, NULL, SRCCOPY);
SurfGDI->SetPointerShape(SurfObj, MouseSurf, NULL, NULL, 0, 0, 50, 50, &MouseRect, 0);
mouse_x = 320;

View file

@ -86,7 +86,7 @@ BOOL STDCALL W32kBitBlt(HDC hDCDest,
// Perform the bitblt operation
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, XlateObj, &DestRect, &SourcePoint, NULL, NULL, NULL, ROP);
if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);