Alan,
  this may be of use to you: It's the region optimisation I mentioned
before. It seems a little faster to me, which indicates that some
(most?) of the calls have mulitple clip regions. 

There's a little extra stuff for the rootless mode in win.h, but it
won't hurt to have that committed - if you're willing.

There is also some rootless stuff (the #if 1-else-end and #if
0-else-end's) in winsetsp and winfillsp, and that stuff should NOT go
into CVS, but I didn't want to corrupt the patch by hand removing. You
should be able to do it easily in your sandbox... (it's only 2-3 lines
to delete).

Index: win.h
===================================================================
RCS file: /cvsroot/xoncygwin/xc/programs/Xserver/hw/xwin/win.h,v
retrieving revision 1.1.1.1.2.2
diff -u -p -r1.1.1.1.2.2 win.h
--- win.h       5 Feb 2002 18:47:39 -0000       1.1.1.1.2.2
+++ win.h       10 Apr 2002 02:39:46 -0000
@@ -268,7 +268,8 @@ typedef Bool (*winHotKeyAltTabPtr)(Scree
 
 typedef struct
 {
-  DWORD                        dwDummy;
+  HWND                 hwnd;
+  HDC                  hdc;
 } winPrivWinRec, *winPrivWinPtr;
 
 typedef struct
@@ -414,6 +415,7 @@ extern miPointerScreenFuncRec       g_winPoint
 extern DWORD                   g_dwEvents;
 extern int                     g_fdMessageQueue;
 extern int                     g_iScreenPrivateIndex;
+extern int                     g_iWindowPrivateIndex;
 extern int                     g_iCmapPrivateIndex;
 extern int                     g_iGCPrivateIndex;
 extern int                     g_iPixmapPrivateIndex;
@@ -553,6 +555,8 @@ winBlockHandler (int nScreen,
 
 RegionPtr
 winPixmapToRegionNativeGDI (PixmapPtr pPix);
+HRGN
+makeNativeRgn (RegionPtr const pRegion);
 
 
 /*
Index: winclip.c
===================================================================
RCS file: /cvsroot/xoncygwin/xc/programs/Xserver/hw/xwin/winclip.c,v
retrieving revision 1.1.1.1.2.1
diff -u -p -r1.1.1.1.2.1 winclip.c
--- winclip.c   7 Feb 2002 21:34:19 -0000       1.1.1.1.2.1
+++ winclip.c   10 Apr 2002 02:39:46 -0000
@@ -248,3 +248,33 @@ winPixmapToRegionNativeGDI (PixmapPtr pP
 #endif
   return(pReg);
 }
+
+HRGN
+makeNativeRgn (RegionPtr const pRegion)
+{
+  BoxPtr pbox;
+  int nbox;
+  HRGN rv;
+  nbox = REGION_NUM_RECTS (pRegion);
+  pbox = REGION_RECTS (pRegion);
+  rv = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+  --nbox;
+  ++pbox;
+  while (nbox--)
+    {
+      int combinerv;
+      HRGN tempRgn;
+      tempRgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+      combinerv = CombineRgn (rv, rv, tempRgn, RGN_OR);
+      if (combinerv == ERROR)
+       {
+         ErrorF ("makeNativeRgn: Failed to create native region %u\n",
GetLastError());
+         DeleteObject (rv);
+         return NULL;
+       }
+      DeleteObject (tempRgn);
+      ++pbox;
+    }
+  return rv;
+}
+
Index: winsetsp.c
===================================================================
RCS file: /cvsroot/xoncygwin/xc/programs/Xserver/hw/xwin/winsetsp.c,v
retrieving revision 1.1.1.1.2.8
diff -u -p -r1.1.1.1.2.8 winsetsp.c
--- winsetsp.c  19 Feb 2002 20:31:25 -0000      1.1.1.1.2.8
+++ winsetsp.c  10 Apr 2002 02:39:46 -0000
@@ -27,6 +27,7 @@
  *
  * Authors:    Harold L Hunt II
  *             Alan Hourihane <[EMAIL PROTECTED]>
+ *             Robert Collins <[EMAIL PROTECTED]>
  */
 /* $XFree86: xc/programs/Xserver/hw/xwin/winsetsp.c,v 1.6 2001/10/22
15:21:12 alanh Exp $ */
 
@@ -48,8 +49,6 @@ winSetSpansNativeGDI (DrawablePtr     pDrawa
   HBITMAP              hbmpOrig = NULL;
   BITMAPINFO           bmi;
   HRGN                 hrgn;
-  int                  n;
-  BoxPtr               pbox;
 
   /* Branch on the drawable type */
   switch (pDrawable->type)
@@ -67,8 +66,6 @@ winSetSpansNativeGDI (DrawablePtr     pDrawa
 
       while (iSpans--)
         {
-         n = REGION_NUM_RECTS (pGC->pCompositeClip);
-         pbox = REGION_RECTS (pGC->pCompositeClip);
 
          ZeroMemory (&bmi, sizeof (BITMAPINFO));
          bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
@@ -85,14 +82,14 @@ winSetSpansNativeGDI (DrawablePtr   pDrawa
              bmi.bmiColors[1].rgbGreen = 255;
              bmi.bmiColors[1].rgbRed = 255;
            }
-
-         while (n--)
+         
+         hrgn = makeNativeRgn (pGC->pCompositeClip);
+         if (hrgn)
            {
-             hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
              SelectClipRgn (pGCPriv->hdcMem, hrgn);
              DeleteObject (hrgn);
              hrgn = NULL;
-
+             
              StretchDIBits (pGCPriv->hdcMem, 
                             pPoints->x, pPoints->y,
                             *piWidths, 1,
@@ -102,7 +99,6 @@ winSetSpansNativeGDI (DrawablePtr    pDrawa
                             (BITMAPINFO *) &bmi,
                             DIB_RGB_COLORS,
                             g_copyROP[pGC->alu]);
-             pbox++;
            }
 
          pSrcs += PixmapBytePad (*piWidths, pDrawable->depth);
@@ -118,10 +114,18 @@ winSetSpansNativeGDI (DrawablePtr pDrawa
       break;
 
     case DRAWABLE_WINDOW:
+      {
+       HDC hdc;
+       WindowPtr pWin = (WindowPtr) pDrawable;
+       winPrivWinRec *pPrivWin;
+       pPrivWin = (winPrivWinRec
*)(pWin->devPrivates[g_iWindowPrivateIndex].ptr);
+#if 0
+        hdc = pPrivWin->hdc;
+#else
+        hdc = pGCPriv->hdc;
+#endif
       while (iSpans--)
         {
-         n = REGION_NUM_RECTS (pGC->pCompositeClip);
-         pbox = REGION_RECTS (pGC->pCompositeClip);
 
          ZeroMemory (&bmi, sizeof (BITMAPINFO));
          bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
@@ -139,14 +143,14 @@ winSetSpansNativeGDI (DrawablePtr pDrawa
              bmi.bmiColors[1].rgbRed = 255;
            }
 
-         while (n--)
+         hrgn = makeNativeRgn (pGC->pCompositeClip);
+         if (hrgn)
            {
-             hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
-             SelectClipRgn (pGCPriv->hdc, hrgn);
+             SelectClipRgn (hdc, hrgn);
              DeleteObject (hrgn);
              hrgn = NULL;
-
-             StretchDIBits (pGCPriv->hdc, 
+             
+             StretchDIBits (hdc, 
                             pPoints->x, pPoints->y,
                             *piWidths, 1,
                             0, 0,
@@ -155,7 +159,6 @@ winSetSpansNativeGDI (DrawablePtr   pDrawa
                             (BITMAPINFO *) &bmi,
                             DIB_RGB_COLORS,
                             g_copyROP[pGC->alu]);
-             pbox++;
            }
 
          pSrcs += PixmapBytePad (*piWidths, pDrawable->depth);
@@ -164,7 +167,9 @@ winSetSpansNativeGDI (DrawablePtr   pDrawa
         }
 
       /* Reset the clip region */
-      SelectClipRgn (pGCPriv->hdc, NULL);
+      /* TODO: Restore a saved region */
+      SelectClipRgn (hdc, NULL);
+      }
       break;
 
     case UNDRAWABLE_WINDOW:
Index: winfillsp.c
===================================================================
RCS file: /cvsroot/xoncygwin/xc/programs/Xserver/hw/xwin/winfillsp.c,v
retrieving revision 1.1.1.1.2.13
diff -u -p -r1.1.1.1.2.13 winfillsp.c
--- winfillsp.c 19 Feb 2002 20:31:24 -0000      1.1.1.1.2.13
+++ winfillsp.c 10 Apr 2002 02:39:46 -0000
@@ -143,21 +143,19 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
        
              if (fullX1 >= fullX2)
                continue;
-       
-             nbox = REGION_NUM_RECTS (pClip);
-             pbox = REGION_RECTS (pClip);
-             while (nbox--)
+
+             hrgn = makeNativeRgn (pClip);
+             if (hrgn)
                {
-                 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
                  SelectClipRgn (pGCPriv->hdcMem, hrgn);
-                 DeleteObject (hrgn);
-                 hrgn = NULL;
+                 DeleteObject (hrgn);
+                 hrgn = NULL;
 
-                 MoveToEx (pGCPriv->hdcMem, fullX1, fullY1, NULL);
-                 LineTo (pGCPriv->hdcMem, fullX2, fullY1);
-                 pbox++;
+                 MoveToEx (pGCPriv->hdcMem, fullX1, fullY1, NULL);
+                 LineTo (pGCPriv->hdcMem, fullX2, fullY1);
                }
            }
+           
 
           SetROP2 (pGCPriv->hdcMem, R2_COPYPEN);
 
@@ -258,24 +256,20 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
              if (fullX1 >= fullX2)
                continue;
        
-             nbox = REGION_NUM_RECTS (pClip);
-             pbox = REGION_RECTS (pClip);
-             while (nbox--)
-               {
-                 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
+             hrgn = makeNativeRgn (pClip);
+             if (hrgn)
+               {
                  SelectClipRgn (pGCPriv->hdcMem, hrgn);
                  DeleteObject (hrgn);
                  hrgn = NULL;
-
+                 
                  for (iX = fullX1; iX < fullX2; iX +=
pStipple->drawable.width)
                    {
                      int width;
-
                      if ((iX + pStipple->drawable.width) > fullX2)
                        width = fullX2 - iX;
                      else
                        width = pStipple->drawable.width;
-
                      BitBlt (pGCPriv->hdcMem,
                              iX, fullY1,
                              width, 1,
@@ -284,8 +278,6 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
                              fullY1 % pStipple->drawable.height,
                              g_copyROP[pGC->alu]);
                    }
-
-                 pbox++;
                }
            }
 
@@ -333,25 +325,22 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
        
              if (fullX1 >= fullX2)
                continue;
-       
-             nbox = REGION_NUM_RECTS (pClip);
-             pbox = REGION_RECTS (pClip);
-             while (nbox--)
-               {
-                 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
+
+             hrgn = makeNativeRgn (pClip);
+             if (hrgn)
+               {
                  SelectClipRgn (pGCPriv->hdcMem, hrgn);
-                 DeleteObject (hrgn);
+                 DeleteObject (hrgn);
                  hrgn = NULL;
 
-                 for (iX = fullX1; iX < fullX2; iX +=
pTile->drawable.width)
-                   {
+                 for (iX = fullX1; iX < fullX2; iX +=
pTile->drawable.width)
+                   {
                      int width;
 
                      if ((iX + pTile->drawable.width) > fullX2)
                        width = fullX2 - iX;
                      else
                        width = pTile->drawable.width;
-
                      BitBlt (pGCPriv->hdcMem,
                              iX, fullY1,
                              width, 1,
@@ -360,7 +349,6 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
                              fullY1 % pTile->drawable.height,
                              g_copyROP[pGC->alu]);
                    }
-                 pbox++;
                }
            }
 
@@ -384,20 +372,36 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
       break;
       
     case DRAWABLE_WINDOW:
+      {
+       HDC hdc;
+       WindowPtr pWin = (WindowPtr) pDrawable;
+       winPrivWinRec *pPrivWin;
+       BoxPtr pBoundingBox;
+       pPrivWin = (winPrivWinRec
*)(pWin->devPrivates[g_iWindowPrivateIndex].ptr);
+       
+#if 0
+       hdc = pPrivWin->hdc;
+       /* Translating the GC is unreliable? */
+       pBoundingBox = REGION_EXTENTS ((pWin->winSize.pScreen),
&(pWin->winSize));
+/*     SetViewportOrgEx (hdc, pBoundingBox->x1, pBoundingBox->y1,
NULL);
+ */
+#else
+       hdc = pGCPriv->hdc;
+#endif
       /* Branch on fill style */
       switch (pGC->fillStyle)
        {
        case FillSolid:
 
-          ROP16 (pGCPriv->hdc, pGC->alu);
+          ROP16 (hdc, pGC->alu);
 
          if (pDrawable->depth == 1) 
            {
              if (pGC->fgPixel == 0)
-               hPenOrig = SelectObject (pGCPriv->hdc, 
+               hPenOrig = SelectObject (hdc, 
                                         GetStockObject (BLACK_PEN));
              else
-               hPenOrig = SelectObject (pGCPriv->hdc,
+               hPenOrig = SelectObject (hdc,
                                         GetStockObject (WHITE_PEN));
            } 
          else 
@@ -405,11 +409,12 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
              fg = pGC->fgPixel;
              TRANSLATE_COLOR (fg);
              hPen = CreatePen (PS_SOLID, 0, fg);
-             hPenOrig = SelectObject (pGCPriv->hdc, hPen);
+             hPenOrig = SelectObject (hdc, hPen);
            }
 
          while (iSpans--)
            {
+             HRGN clipRegion;
              fullX1 = pPoints->x;
              fullY1 = pPoints->y;
              fullX2 = fullX1 + (int) *piWidths;
@@ -426,26 +431,23 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
        
              if (fullX1 >= fullX2)
                continue;
-       
-             nbox = REGION_NUM_RECTS (pClip);
-             pbox = REGION_RECTS (pClip);
-             while (nbox--)
+
+             hrgn = makeNativeRgn (pClip);
+             if (hrgn)
                {
-                 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
-                 SelectClipRgn (pGCPriv->hdc, hrgn);
+                 SelectClipRgn (pGCPriv->hdcMem, hrgn);
                  DeleteObject (hrgn);
                  hrgn = NULL;
 
-                 MoveToEx (pGCPriv->hdc, fullX1, fullY1, NULL);
-                 LineTo (pGCPriv->hdc, fullX2, fullY1);
-                 pbox++;
+                 MoveToEx (hdc, fullX1, fullY1, NULL);
+                 LineTo (hdc, fullX2, fullY1);
                }
            }
 
-          SetROP2 (pGCPriv->hdc, R2_COPYPEN);
+          SetROP2 (hdc, R2_COPYPEN);
 
          /* Give back the Brush */
-         SelectObject (pGCPriv->hdc, hPenOrig);
+         SelectObject (hdc, hPenOrig);
 
          if (pDrawable->depth != 1)
            DeleteObject (hPen);
@@ -465,7 +467,7 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
                                    DIB_RGB_COLORS);
 
          /* Create a memory DC to hold the stipple */
-         hdcStipple = CreateCompatibleDC (pGCPriv->hdc);
+         hdcStipple = CreateCompatibleDC (hdc);
 
          /* Select the stipple bitmap into the stipple DC */
          hbmpOrigStipple = SelectObject (hdcStipple, hBitmap);
@@ -487,8 +489,8 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
           */
          if (pGC->bgPixel != -1 && pGC->fgPixel != -1) 
            {
-             SetTextColor (pGCPriv->hdc, fg);
-             SetBkColor (pGCPriv->hdc, bg);
+             SetTextColor (hdc, fg);
+             SetBkColor (hdc, bg);
              BitBlt (hdcStipple,
                      0, 0,
                      pStipple->drawable.width,
pStipple->drawable.height,
@@ -498,8 +500,8 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
            } 
          else if (pGC->bgPixel == -1) 
            {
-             SetTextColor (pGCPriv->hdc, fg);
-             SetBkMode (pGCPriv->hdc, TRANSPARENT);
+             SetTextColor (hdc, fg);
+             SetBkMode (hdc, TRANSPARENT);
              BitBlt (hdcStipple,
                      0, 0,
                      pStipple->drawable.width,
pStipple->drawable.height,
@@ -509,8 +511,8 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
            } 
          else if (pGC->fgPixel == -1) 
            {
-             SetTextColor (pGCPriv->hdc, bg);
-             SetBkMode (pGCPriv->hdc, TRANSPARENT);
+             SetTextColor (hdc, bg);
+             SetBkMode (hdc, TRANSPARENT);
 #if 0
              BitBlt (hdcStipple,
                      0, 0,
@@ -539,26 +541,23 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
        
              if (fullX1 >= fullX2)
                continue;
-       
-             nbox = REGION_NUM_RECTS (pClip);
-             pbox = REGION_RECTS (pClip);
-             while (nbox--)
-               {
-                 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
-                 SelectClipRgn (pGCPriv->hdc, hrgn);
+
+             hrgn = makeNativeRgn (pClip);
+             if (hrgn)
+               {
+                 /* TODO: should we intersect the clip region? */
+                 SelectClipRgn (pGCPriv->hdcMem, hrgn);
                  DeleteObject (hrgn);
                  hrgn = NULL;
 
                  for (iX = fullX1; iX < fullX2; iX +=
pStipple->drawable.width)
                    {
                      int width;
-
                      if ((iX + pStipple->drawable.width) > fullX2)
                        width = fullX2 - iX;
                      else
                        width = pStipple->drawable.width;
-
-                     BitBlt (pGCPriv->hdc,
+                     BitBlt (hdc,
                              iX, fullY1,
                              width, 1,
                              hdcStipple,
@@ -566,8 +565,6 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
                              fullY1 % pStipple->drawable.height,
                              g_copyROP[pGC->alu]);
                    }
-
-                 pbox++;
                }
            }
 
@@ -579,7 +576,7 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
          DeleteObject (hBitmap);
 
          /* Restore the background mode */
-         SetBkMode (pGCPriv->hdc, OPAQUE);       
+         SetBkMode (hdc, OPAQUE);        
          break;
 
        case FillTiled:
@@ -611,26 +608,22 @@ winFillSpansNativeGDI (DrawablePtr        pDraw
        
              if (fullX1 >= fullX2)
                continue;
-       
-             nbox = REGION_NUM_RECTS (pClip);
-             pbox = REGION_RECTS (pClip);
-             while (nbox--)
-               {
-                 hrgn = CreateRectRgn (pbox->x1, pbox->y1, pbox->x2,
pbox->y2);
-                 SelectClipRgn (pGCPriv->hdc, hrgn);
-                 DeleteObject (hrgn);
+
+             hrgn = makeNativeRgn (pClip);
+             if (hrgn)
+               {
+                 SelectClipRgn (pGCPriv->hdcMem, hrgn);
+                 DeleteObject (hrgn);
                  hrgn = NULL;
 
-                 for (iX = fullX1; iX < fullX2; iX +=
pTile->drawable.width)
-                   {
+                 for (iX = fullX1; iX < fullX2; iX +=
pTile->drawable.width)
+                   {
                      int width;
-
                      if ((iX + pTile->drawable.width) > fullX2)
                        width = fullX2 - iX;
                      else
                        width = pTile->drawable.width;
-
-                     BitBlt (pGCPriv->hdc,
+                     BitBlt (hdc,
                              iX, fullY1,
                              width, 1,
                              pGCPriv->hdcMem,
@@ -638,8 +631,6 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
                              fullY1 % pTile->drawable.height,
                              g_copyROP[pGC->alu]);
                    }
-
-                 pbox++;
                }
            }
 
@@ -653,7 +644,9 @@ winFillSpansNativeGDI (DrawablePtr  pDraw
        }
 
       /* Reset clip region */
-      SelectClipRgn (pGCPriv->hdc, NULL);
+      /* TODO: restore saved region as opposed to a NULL region */
+      SelectClipRgn (hdc, NULL);
+      }
       break;
 
     case UNDRAWABLE_WINDOW:

Reply via email to