Accelerate PATCOPY blits.
authorDavid Welch <welch@cwcom.net>
Sat, 21 Sep 2002 18:05:25 +0000 (18:05 +0000)
committerDavid Welch <welch@cwcom.net>
Sat, 21 Sep 2002 18:05:25 +0000 (18:05 +0000)
svn path=/trunk/; revision=3528

reactos/drivers/dd/vga/display/objects/bitblt.c
reactos/subsys/win32k/eng/mouse.c
reactos/subsys/win32k/objects/bitmaps.c

index 279e6a7..963b66b 100644 (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(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++)
+  if (ColorTranslation == NULL)
+    {      
+      DIB_BltToVGA(DestRect->left, DestRect->top, dx, dy, Source->pvBits, 
+                  Source->lDelta);
+    } 
+  else
     {
-      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,102 +162,221 @@ BOOL VGAtoVGA(
   return TRUE;
 }
 
-
 BOOL STDCALL
-DrvBitBlt(SURFOBJ *Dest,
-         SURFOBJ *Source,
-         SURFOBJ *Mask,
-         CLIPOBJ *Clip,
-         XLATEOBJ *ColorTranslation,
-         RECTL *DestRect,
-         POINTL *SourcePoint,
-         POINTL *MaskPoint,
-         BRUSHOBJ *Brush,
-         POINTL *BrushPoint,
-         ROP4 rop4)
+VGADDI_BltBrush(SURFOBJ* Dest, XLATEOBJ* ColorTranslation, RECTL* DestRect,
+               BRUSHOBJ* Brush, POINTL* BrushPoint, ROP4 Rop4)
 {
-   RECT_ENUM RectEnum;
-   BOOL EnumMore;
-   PFN_VGABlt  BltOperation;
-   ULONG SourceType;
+  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);
+    }
 
-   if(Source == NULL)
-   {
-     SourceType = STYPE_BITMAP;
-   } else
-     SourceType = Source->iType;
+  /* 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;
+    }
 
-DPRINT("VGADDIBitBlt: Dest->pvScan0: %08x\n", Dest->pvScan0);
+  /* 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);
+       }
+    }
 
-   // Determine the bltbit operation
+  /* 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);
+       }
+    }
 
-   if((SourceType == STYPE_BITMAP) && (Dest->iType == STYPE_DEVICE))
-   {
-DPRINT("DIB2VGA\n");
+  /* 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))
-   {
-DPRINT("VGA2DIB\n");
+    } 
+  else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_BITMAP)
+    {
       BltOperation = VGAtoDIB;
-   } else
-   if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVICE))
-   {
-DPRINT("VGA2VGA\n");
+    } 
+  else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVICE)
+    {
       BltOperation = VGAtoVGA;
-   } else
-   if((SourceType == STYPE_DEVBITMAP) && (Dest->iType == STYPE_DEVICE))
-   {
-DPRINT("DFB2VGA\n");
+    } 
+  else if (SourceType == STYPE_DEVBITMAP && Dest->iType == STYPE_DEVICE)
+    {
       BltOperation = DFBtoVGA;
-   } else
-   if((SourceType == STYPE_DEVICE) && (Dest->iType == STYPE_DEVBITMAP))
-   {
-DPRINT("VGA2DFB\n");
+    } 
+  else if (SourceType == STYPE_DEVICE && Dest->iType == STYPE_DEVBITMAP)
+    {
       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;
+    } 
+  else
+    {
+      /* Punt blts not involving a device or a device-bitmap. */
+      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);
+  BltOperation(Dest, Source, ColorTranslation, DestRect, SourcePoint);
+  return(TRUE);
+}
 
-            } while (EnumMore); */
-         }
-      }
-   }
+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;
+           }
+       }
+    }
+}
 
-   return TRUE;
+BOOL STDCALL
+DrvBitBlt(SURFOBJ *Dest,
+         SURFOBJ *Source,
+         SURFOBJ *Mask,
+         CLIPOBJ *Clip,
+         XLATEOBJ *ColorTranslation,
+         RECTL *DestRect,
+         POINTL *SourcePoint,
+         POINTL *MaskPoint,
+         BRUSHOBJ *Brush,
+         POINTL *BrushPoint,
+         ROP4 rop4)
+{
+  /* 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));
+
+    case SRCCOPY:
+      return(VGADDI_BltSrc(Dest, Source, ColorTranslation, DestRect, 
+                          SourcePoint));
+
+    case 0xAACC:
+      return(VGADDI_BltMask(Dest, Mask, ColorTranslation, DestRect,
+                           MaskPoint, Brush, BrushPoint));
+
+    default:
+      return(FALSE);
+    }
 }
index 03b0c48..983f1fe 100644 (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;
index 4198d11..c80db98 100644 (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);