From 02d56c87f1bc3e7855dbc2e06949aa77dbfbfebb Mon Sep 17 00:00:00 2001 From: David Welch Date: Sat, 21 Sep 2002 18:05:25 +0000 Subject: [PATCH] Accelerate PATCOPY blits. svn path=/trunk/; revision=3528 --- .../drivers/dd/vga/display/objects/bitblt.c | 407 ++++++++++-------- reactos/subsys/win32k/eng/mouse.c | 10 +- reactos/subsys/win32k/objects/bitmaps.c | 2 +- 3 files changed, 246 insertions(+), 173 deletions(-) diff --git a/reactos/drivers/dd/vga/display/objects/bitblt.c b/reactos/drivers/dd/vga/display/objects/bitblt.c index 279e6a78363..963b66b0189 100644 --- a/reactos/drivers/dd/vga/display/objects/bitblt.c +++ b/reactos/drivers/dd/vga/display/objects/bitblt.c @@ -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; jleft + i, DestRect->top + j, Brush->iSolidColor); - c8++; - if(c8 == 8) { lMask++; c8=0; } - } - tMask += Mask->lDelta; - } - } - } else if (rop4 == PATCOPY) - { - for (j=0;jleft+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; jy+dy; j++) - { - initial = GDIpos; - - for(i=SourcePoint->x; ix+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; ix+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; jleft + 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); + } } diff --git a/reactos/subsys/win32k/eng/mouse.c b/reactos/subsys/win32k/eng/mouse.c index 03b0c482959..983f1fee055 100644 --- a/reactos/subsys/win32k/eng/mouse.c +++ b/reactos/subsys/win32k/eng/mouse.c @@ -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; diff --git a/reactos/subsys/win32k/objects/bitmaps.c b/reactos/subsys/win32k/objects/bitmaps.c index 4198d11828f..c80db98bf7a 100644 --- a/reactos/subsys/win32k/objects/bitmaps.c +++ b/reactos/subsys/win32k/objects/bitmaps.c @@ -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);