Line drawing improvements to Xgl
authorDavid Reveman <c99drn@cs.umu.se>
Wed, 27 Apr 2005 09:29:33 +0000 (09:29 +0000)
committerDavid Reveman <c99drn@cs.umu.se>
Wed, 27 Apr 2005 09:29:33 +0000 (09:29 +0000)
hw/xgl/glx/xglx.c
hw/xgl/xgl.h
hw/xgl/xglfill.c
hw/xgl/xglgc.c
hw/xgl/xglparse.c
hw/xgl/xglscreen.c

index 4bdf59b..15dfa8b 100644 (file)
@@ -84,7 +84,8 @@ xglScreenInfoRec xglScreenInfo = {
     DEFAULT_GEOMETRY_DATA_TYPE,
     DEFAULT_GEOMETRY_USAGE,
     FALSE,
-    XGL_DEFAULT_PBO_MASK
+    XGL_DEFAULT_PBO_MASK,
+    FALSE
 };
 
 static Bool
index 82680e3..b1094be 100644 (file)
@@ -67,6 +67,7 @@ typedef struct _xglScreenInfo {
     int                     geometryUsage;
     Bool            yInverted;
     int                     pboMask;
+    Bool            lines;
 } xglScreenInfoRec, *xglScreenInfoPtr;
 
 typedef struct _xglPixelFormat {
@@ -223,6 +224,7 @@ typedef struct _xglScreen {
     int                                  geometryDataType;
     Bool                         yInverted;
     int                                  pboMask;
+    Bool                         lines;
     xglGeometryRec               scratchGeometry;
     
 #ifdef RENDER
@@ -1002,7 +1004,7 @@ xglFill (DrawablePtr      pDrawable,
         BoxPtr         pBox,
         int            nBox);
 
-Bool
+void
 xglFillSpan (DrawablePtr pDrawable,
             GCPtr       pGC,
             int         n,
index 577caac..4bce656 100644 (file)
@@ -69,6 +69,79 @@ xglFill (DrawablePtr pDrawable,
     return FALSE;
 }
 
+static void
+xglFillBox (DrawablePtr pDrawable, 
+           GCPtr       pGC,
+           int         x,
+           int         y,
+           int         width,
+           int         height,
+           BoxPtr      pBox,
+           int         nBox)
+{
+    BoxRec box;
+    
+    if (!nBox)
+       return;   
+    
+    if (!xglFill (pDrawable, pGC, NULL, x, y, width, height, pBox, nBox))
+    {
+       RegionRec       region;
+       RegionPtr       pDamageRegion;
+       glitz_surface_t *surface;
+       int             xOff, yOff;
+
+       XGL_DRAWABLE_PIXMAP (pDrawable);
+       XGL_PIXMAP_PRIV (pPixmap);
+
+       if (!xglMapPixmapBits (pPixmap))
+           FatalError (XGL_SW_FAILURE_STRING);
+
+       switch (pGC->fillStyle) {
+       case FillSolid:
+           break;
+       case FillStippled:
+       case FillOpaqueStippled:
+           if (!xglSyncBits (&pGC->stipple->drawable, NullBox))
+               FatalError (XGL_SW_FAILURE_STRING);
+           break;
+       case FillTiled:
+           if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox))
+               FatalError (XGL_SW_FAILURE_STRING);
+           break;
+       }
+
+       pDamageRegion = DamageRegion (pPixmapPriv->pDamage);
+       
+       XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
+       
+       pPixmapPriv->damageBox = miEmptyBox;
+       
+       while (nBox--)
+       {
+           fbFill (pDrawable, pGC,
+                   pBox->x1, pBox->y1,
+                   pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+
+           if (pPixmapPriv->format)
+           {
+               box.x1 = pBox->x1 + xOff;
+               box.y1 = pBox->y1 + yOff;
+               box.x2 = pBox->x2 + xOff;
+               box.y2 = pBox->y2 + yOff;
+               
+               REGION_INIT (pDrawable->pScreen, &region, &box, 1);
+               REGION_UNION (pDrawable->pScreen,
+                             pDamageRegion, pDamageRegion, &region);
+               REGION_UNINIT (pDrawable->pScreen, &region);
+           }
+           
+           pBox++;
+       }
+    } else
+       xglAddCurrentBitDamage (pDrawable);
+}
+
 #define N_STACK_BOX 1024
 
 static BoxPtr
@@ -94,12 +167,18 @@ xglMoreBoxes (BoxPtr stackBox,
        {                                                       \
            (size) *= 2;                                        \
            (heapBox) = xglMoreBoxes (stackBox, heapBox, size); \
-           if (!(heapBox))                                     \
-               return;                                         \
-           (pBox) = (heapBox) + (nBox);                        \
+           if (heapBox)                                        \
+           {                                                   \
+               (pBox) = (heapBox) + (nBox);                    \
+               *(pBox)++ = (box);                              \
+               (nBox)++;                                       \
+           }                                                   \
+       }                                                       \
+       else                                                    \
+       {                                                       \
+           *(pBox)++ = (box);                                  \
+           (nBox)++;                                           \
        }                                                       \
-       *(pBox)++ = (box);                                      \
-       (nBox)++;                                               \
     }
 
 void
@@ -111,12 +190,12 @@ xglFillRect (DrawablePtr pDrawable,
     RegionPtr pClip = pGC->pCompositeClip;
     BoxPtr    pClipBox;
     BoxPtr    pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
-    BoxRec    full, part;
+    BoxRec    part, full;
     BoxPtr    heapBox = NULL;
     BoxRec    stackBox[N_STACK_BOX];
     int       size = N_STACK_BOX;
     BoxPtr    pBox = stackBox;
-    int              n, nBox = 0;
+    int              nClip, nBox = 0;
 
     while (nrect--)
     {
@@ -124,53 +203,41 @@ xglFillRect (DrawablePtr pDrawable,
        full.y1 = prect->y + pDrawable->y;
        full.x2 = full.x1 + (int) prect->width;
        full.y2 = full.y1 + (int) prect->height;
-       
+
        prect++;
        
        if (full.x1 < pExtent->x1)
            full.x1 = pExtent->x1;
-
        if (full.y1 < pExtent->y1)
-           full.y1 = pExtent->y1;
-       
+           full.y1 = pExtent->y1;          
        if (full.x2 > pExtent->x2)
            full.x2 = pExtent->x2;
-       
        if (full.y2 > pExtent->y2)
            full.y2 = pExtent->y2;
        
        if (full.x1 >= full.x2 || full.y1 >= full.y2)
            continue;
        
-       n = REGION_NUM_RECTS (pClip);
-
-       if (n == 1)
+       nClip = REGION_NUM_RECTS (pClip);
+       if (nClip == 1)
        {
            ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
        }
        else
        {
            pClipBox = REGION_RECTS (pClip);
-
-           while (n--)
+           while (nClip--)
            {
-               part.x1 = pClipBox->x1;
+               part = *pClipBox++;
+
                if (part.x1 < full.x1)
                    part.x1 = full.x1;
-               
-               part.y1 = pClipBox->y1;
                if (part.y1 < full.y1)
                    part.y1 = full.y1;
-               
-               part.x2 = pClipBox->x2;
                if (part.x2 > full.x2)
                    part.x2 = full.x2;
-               
-               part.y2 = pClipBox->y2;
                if (part.y2 > full.y2)
                    part.y2 = full.y2;
-    
-               pClipBox++;
                
                if (part.x1 < part.x2 && part.y1 < part.y2)
                    ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
@@ -178,106 +245,88 @@ xglFillRect (DrawablePtr pDrawable,
        }
     }
 
-    if (!nBox)
-       return;
-    
-    pBox = (heapBox) ? heapBox : stackBox;
-
-    if (!xglFill (pDrawable, pGC, NULL,
-                 pExtent->x1, pExtent->y1,
-                 pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
-                 pBox, nBox))
-    {
-       RegionRec       region;
-       RegionPtr       pDamageRegion;
-       glitz_surface_t *surface;
-       int             xOff, yOff;
-
-       XGL_DRAWABLE_PIXMAP (pDrawable);
-       XGL_PIXMAP_PRIV (pPixmap);
-
-       if (!xglMapPixmapBits (pPixmap))
-           FatalError (XGL_SW_FAILURE_STRING);
-
-       switch (pGC->fillStyle) {
-       case FillSolid:
-           break;
-       case FillStippled:
-       case FillOpaqueStippled:
-           if (!xglSyncBits (&pGC->stipple->drawable, NullBox))
-               FatalError (XGL_SW_FAILURE_STRING);
-           break;
-       case FillTiled:
-           if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox))
-               FatalError (XGL_SW_FAILURE_STRING);
-           break;
-       }
-
-       pDamageRegion = DamageRegion (pPixmapPriv->pDamage);
-       
-       XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
-       
-       pPixmapPriv->damageBox = miEmptyBox;
-       
-       while (nBox--)
-       {
-           fbFill (pDrawable, pGC,
-                   pBox->x1, pBox->y1,
-                   pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
-
-           if (pPixmapPriv->format)
-           {
-               part.x1 = pBox->x1 + xOff;
-               part.y1 = pBox->y1 + yOff;
-               part.x2 = pBox->x2 + xOff;
-               part.y2 = pBox->y2 + yOff;
+    xglFillBox (pDrawable, pGC,
+               pExtent->x1, pExtent->y1,
+               pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+               (heapBox) ? heapBox : stackBox, nBox);
                
-               REGION_INIT (pDrawable->pScreen, &region, &part, 1);
-               REGION_UNION (pDrawable->pScreen,
-                             pDamageRegion, pDamageRegion, &region);
-               REGION_UNINIT (pDrawable->pScreen, &region);
-           }
-           
-           pBox++;
-       }
-    } else
-       xglAddCurrentBitDamage (pDrawable);
-
     if (heapBox)
        xfree (heapBox);
 }
 
-Bool
+void
 xglFillSpan (DrawablePtr pDrawable,
             GCPtr       pGC,
             int         n,
             DDXPointPtr ppt,
             int         *pwidth)
 {
-    BoxPtr        pExtent;
-    xglGeometryPtr pGeometry;
-
-    if (n < 1)
-       return TRUE;
+    RegionPtr pClip = pGC->pCompositeClip;
+    BoxPtr    pClipBox;
+    BoxPtr    pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
+    BoxRec    part, full;
+    BoxPtr    heapBox = NULL;
+    BoxRec    stackBox[N_STACK_BOX];
+    int       size = N_STACK_BOX;
+    BoxPtr    pBox = stackBox;
+    int              nClip, nBox = 0;
 
-    pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
+    while (n--)
+    {
+       full.x1 = ppt->x;
+       full.y1 = ppt->y;
+       full.x2 = full.x1 + *pwidth;
+       full.y2 = full.y1 + 1;
 
-    pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * n);
-    
-    GEOMETRY_ADD_SPAN (pGC->pScreen, pGeometry, ppt, pwidth, n);
+       pwidth++;
+       ppt++;
+       
+       if (full.x1 < pExtent->x1)
+           full.x1 = pExtent->x1;
+       if (full.y1 < pExtent->y1)
+           full.y1 = pExtent->y1;          
+       if (full.x2 > pExtent->x2)
+           full.x2 = pExtent->x2;
+       if (full.y2 > pExtent->y2)
+           full.y2 = pExtent->y2;
+       
+       if (full.x1 >= full.x2 || full.y1 >= full.y2)
+           continue;
+       
+       nClip = REGION_NUM_RECTS (pClip);
+       if (nClip == 1)
+       {
+           ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
+       }
+       else
+       {
+           pClipBox = REGION_RECTS (pClip);
+           while (nClip--)
+           {
+               part = *pClipBox++;
 
-    /* Spans are treated as lines so they need a 0.5 translate */
-    GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
-    GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
+               if (part.x1 < full.x1)
+                   part.x1 = full.x1;
+               if (part.y1 < full.y1)
+                   part.y1 = full.y1;
+               if (part.x2 > full.x2)
+                   part.x2 = full.x2;
+               if (part.y2 > full.y2)
+                   part.y2 = full.y2;
+               
+               if (part.x1 < part.x2 && part.y1 < part.y2)
+                   ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
+           }
+       }
+    }
 
-    if (xglFill (pDrawable, pGC, pGeometry,
-                pExtent->x1, pExtent->y1,
-                pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
-                REGION_RECTS (pGC->pCompositeClip),
-                REGION_NUM_RECTS (pGC->pCompositeClip)))
-       return TRUE;
-    
-    return FALSE;
+    xglFillBox (pDrawable, pGC,
+               pExtent->x1, pExtent->y1,
+               pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+               (heapBox) ? heapBox : stackBox, nBox);
+               
+    if (heapBox)
+       xfree (heapBox);
 }
 
 Bool
@@ -287,29 +336,32 @@ xglFillLine (DrawablePtr pDrawable,
             int         npt,
             DDXPointPtr ppt)
 {
-    BoxPtr        pExtent;
+    RegionPtr     pClip = pGC->pCompositeClip;
+    BoxPtr        pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
+    Bool          coincidentEndpoints = FALSE;
+    Bool          horizontalAndVertical = TRUE;
+    DDXPointPtr    pptTmp;
+    int                   nptTmp;
+    DDXPointRec    pt;
     xglGeometryPtr pGeometry;
-    Bool          coincident_endpoints;
 
+    XGL_SCREEN_PRIV (pGC->pScreen);
+       
     if (npt < 2)
        return TRUE;
     
-    pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
-
-    coincident_endpoints = FALSE;
+    pt = *ppt;
+       
+    nptTmp = npt - 1;
+    pptTmp = ppt + 1;
+       
     if (mode == CoordModePrevious)
     {
-       DDXPointPtr pptTmp;
-       int         nptTmp;
-       DDXPointRec pt;
-
-       pt = *ppt;
-       
-       nptTmp = npt - 1;
-       pptTmp = ppt + 1;
-
        while (nptTmp--)
        {
+           if (pptTmp->x && pptTmp->y)
+               horizontalAndVertical = FALSE;
+           
            pt.x += pptTmp->x;
            pt.y += pptTmp->y;
            
@@ -317,23 +369,167 @@ xglFillLine (DrawablePtr pDrawable,
        }
        
        if (pt.x == ppt->x && pt.y == ppt->y)
-           coincident_endpoints = TRUE;
+           coincidentEndpoints = TRUE;
     }
     else
     {
+       while (nptTmp--)
+       {
+           if (pptTmp->x != pt.x && pptTmp->y != pt.y)
+               horizontalAndVertical = FALSE;
+
+           pt = *pptTmp++;
+       }
+       
        if (ppt[npt - 1].x == ppt->x && ppt[npt - 1].y == ppt->y)
-           coincident_endpoints = TRUE;
+           coincidentEndpoints = TRUE;
     }
 
-    if (coincident_endpoints)
+    if (horizontalAndVertical)
+    {
+       BoxPtr pClipBox;
+       BoxRec part, full;
+       BoxPtr heapBox = NULL;
+       BoxRec stackBox[N_STACK_BOX];
+       int    size = N_STACK_BOX;
+       BoxPtr pBox = stackBox;
+       int    nClip, nBox = 0;
+       int    dx, dy;
+
+       pt = *ppt;
+
+       ppt++;
        npt--;
+    
+       while (npt--)
+       {
+           if (mode == CoordModePrevious)
+           {
+               dx = ppt->x;
+               dy = ppt->y;
+           }
+           else
+           {
+               dx = ppt->x - pt.x;
+               dy = ppt->y - pt.y;
+           }
+       
+           if (dx)
+           {
+               if (dx > 0)
+               {
+                   full.x1 = pt.x + pDrawable->x;
+                   
+                   if (npt || coincidentEndpoints)
+                       full.x2 = full.x1 + dx;
+                   else
+                       full.x2 = full.x1 + dx + 1;
+               }
+               else
+               {
+                   full.x2 = pt.x + pDrawable->x + 1;
+
+                   if (npt || coincidentEndpoints)
+                       full.x1 = full.x2 + dx;
+                   else
+                       full.x1 = full.x2 + dx - 1;
+               }
+               
+               full.y1 = pt.y + pDrawable->y;
+               full.y2 = full.y1 + 1;
+           }
+           else
+           {
+               if (dy > 0)
+               {
+                   full.y1 = pt.y + pDrawable->y;
+                       
+                   if (npt || coincidentEndpoints)
+                       full.y2 = full.y1 + dy;
+                   else
+                       full.y2 = full.y1 + dy + 1;
+               }
+               else
+               {
+                   full.y2 = pt.y + pDrawable->y + 1;
+
+                   if (npt || coincidentEndpoints)
+                       full.y1 = full.y2 + dy;
+                   else
+                       full.y1 = full.y2 + dy - 1;
+               }
+               
+               full.x1 = pt.x + pDrawable->x;
+               full.x2 = full.x1 + 1;
+           }
+           
+           pt.x += dx;
+           pt.y += dy;
+           
+           ppt++;
+           
+           if (full.x1 < pExtent->x1)
+               full.x1 = pExtent->x1;
+           if (full.y1 < pExtent->y1)
+               full.y1 = pExtent->y1;      
+           if (full.x2 > pExtent->x2)
+               full.x2 = pExtent->x2;
+           if (full.y2 > pExtent->y2)
+               full.y2 = pExtent->y2;
+       
+           if (full.x1 >= full.x2 || full.y1 >= full.y2)
+               continue;
+       
+           nClip = REGION_NUM_RECTS (pClip);
+           if (nClip == 1)
+           {
+               ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
+           }
+           else
+           {
+               pClipBox = REGION_RECTS (pClip);
+               while (nClip--)
+               {
+                   part = *pClipBox++;
+
+                   if (part.x1 < full.x1)
+                       part.x1 = full.x1;
+                   if (part.y1 < full.y1)
+                       part.y1 = full.y1;
+                   if (part.x2 > full.x2)
+                       part.x2 = full.x2;
+                   if (part.y2 > full.y2)
+                       part.y2 = full.y2;
+               
+                   if (part.x1 < part.x2 && part.y1 < part.y2)
+                       ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
+               }
+           }
+       }
+
+       xglFillBox (pDrawable, pGC,
+                   pExtent->x1, pExtent->y1,
+                   pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+                   (heapBox) ? heapBox : stackBox, nBox);
+               
+       if (heapBox)
+           xfree (heapBox);
+
+       return TRUE;
+    }
+
+    if (!pScreenPriv->lines)
+       return FALSE;
 
+    if (coincidentEndpoints)
+       npt--;
+    
     pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, npt);
     
     GEOMETRY_ADD_LINE (pGC->pScreen, pGeometry,
-                      coincident_endpoints, mode, npt, ppt);
+                      coincidentEndpoints, mode, npt, ppt);
 
-    if (coincident_endpoints)
+    if (coincidentEndpoints)
        GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_LOOP);
     else
        GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_STRIP);
@@ -358,20 +554,138 @@ xglFillLine (DrawablePtr pDrawable,
 Bool
 xglFillSegment (DrawablePtr pDrawable,
                GCPtr       pGC, 
-               int         nsegInit,
+               int         nSegInit,
                xSegment    *pSegInit)
 {
-    BoxPtr        pExtent;
+    RegionPtr     pClip = pGC->pCompositeClip;
+    BoxPtr        pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
+    Bool          horizontalAndVertical = TRUE;
     xglGeometryPtr pGeometry;
+    xSegment      *pSeg;
+    int                   nSeg;
 
-    if (nsegInit < 1)
+    XGL_SCREEN_PRIV (pGC->pScreen);
+
+    if (nSegInit < 1)
        return TRUE;
 
-    pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
+    pSeg = pSegInit;
+    nSeg = nSegInit;
+    while (nSeg--)
+    {
+       if (pSeg->x1 != pSeg->x2 && pSeg->y1 != pSeg->y2)
+           horizontalAndVertical = FALSE;
+
+       pSeg++;
+    }
+
+    if (horizontalAndVertical)
+    {
+       BoxPtr pClipBox;
+       BoxRec part, full;
+       BoxPtr heapBox = NULL;
+       BoxRec stackBox[N_STACK_BOX];
+       int    size = N_STACK_BOX;
+       BoxPtr pBox = stackBox;
+       int    nClip, nBox = 0;
+
+       while (nSegInit--)
+       {
+           if (pSegInit->x1 != pSegInit->x2)
+           {
+               if (pSegInit->x1 < pSegInit->x2)
+               {
+                   full.x1 = pSegInit->x1;
+                   full.x2 = pSegInit->x2;
+               }
+               else
+               {
+                   full.x1 = pSegInit->x2;
+                   full.x2 = pSegInit->x1;
+               }
+
+               full.x1 += pDrawable->x;
+               full.x2 += pDrawable->x + 1;
+               full.y1  = pSegInit->y1 + pDrawable->y;
+               full.y2  = full.y1 + 1;
+           }
+           else
+           {
+               if (pSegInit->y1 < pSegInit->y2)
+               {
+                   full.y1 = pSegInit->y1;
+                   full.y2 = pSegInit->y2;
+               }
+               else
+               {
+                   full.y1 = pSegInit->y2;
+                   full.y2 = pSegInit->y1;
+               }
+
+               full.y1 += pDrawable->y;
+               full.y2 += pDrawable->y + 1;
+               full.x1  = pSegInit->x1 + pDrawable->x;
+               full.x2  = full.x1 + 1;
+           }
 
-    pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * nsegInit);
+           pSegInit++;
+           
+           if (full.x1 < pExtent->x1)
+               full.x1 = pExtent->x1;
+           if (full.y1 < pExtent->y1)
+               full.y1 = pExtent->y1;      
+           if (full.x2 > pExtent->x2)
+               full.x2 = pExtent->x2;
+           if (full.y2 > pExtent->y2)
+               full.y2 = pExtent->y2;
+       
+           if (full.x1 >= full.x2 || full.y1 >= full.y2)
+               continue;
+       
+           nClip = REGION_NUM_RECTS (pClip);
+           if (nClip == 1)
+           {
+               ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
+           }
+           else
+           {
+               pClipBox = REGION_RECTS (pClip);
+               while (nClip--)
+               {
+                   part = *pClipBox++;
+
+                   if (part.x1 < full.x1)
+                       part.x1 = full.x1;
+                   if (part.y1 < full.y1)
+                       part.y1 = full.y1;
+                   if (part.x2 > full.x2)
+                       part.x2 = full.x2;
+                   if (part.y2 > full.y2)
+                       part.y2 = full.y2;
+               
+                   if (part.x1 < part.x2 && part.y1 < part.y2)
+                       ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
+               }
+           }
+       }
+
+       xglFillBox (pDrawable, pGC,
+                   pExtent->x1, pExtent->y1,
+                   pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+                   (heapBox) ? heapBox : stackBox, nBox);
+               
+       if (heapBox)
+           xfree (heapBox);
+
+       return TRUE;
+    }
+
+    if (!pScreenPriv->lines)
+       return FALSE;
+    
+    pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * nSegInit);
        
-    GEOMETRY_ADD_SEGMENT (pGC->pScreen, pGeometry, nsegInit, pSegInit);
+    GEOMETRY_ADD_SEGMENT (pGC->pScreen, pGeometry, nSegInit, pSegInit);
 
     /* Line segments need 0.5 translate */
     GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
index 6107559..5a85ead 100644 (file)
@@ -100,18 +100,17 @@ xglFillSpans (DrawablePtr pDrawable,
 {
     XGL_GC_PRIV (pGC);
 
-    if (!pGCPriv->flags)
+    if (pGCPriv->flags || pGC->fillStyle == FillStippled)
     {
-       if (xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth))
-       {
-           xglAddCurrentBitDamage (pDrawable);
-           return;
-       }
+       XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
+       (*pGC->ops->FillSpans) (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+       XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
+    }
+    else
+    {
+       /* xglFillSpan handles fall-back */
+       xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth);
     }
-
-    XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
-    (*pGC->ops->FillSpans) (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
-    XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
 }
 
 void
index 1cf6bac..663d798 100644 (file)
@@ -108,6 +108,8 @@ xglUseMsg (void)
     ErrorF ("-yinverted             Y is upside-down\n");
     ErrorF ("-pbomask [1|4|8|16|32] "
            "set bpp's to use with pixel buffer objects\n");
+    ErrorF ("-lines                 "
+           "accelerate lines that are not vertical or horizontal\n");
 }
 
 int
@@ -167,6 +169,11 @@ xglProcessArgument (xglScreenInfoPtr pScreenInfo,
        
        return 2;
     }
+    else if (!strcmp (argv[i], "-lines"))
+    {
+       pScreenInfo->lines = TRUE;
+       return 1;
+    }
     
     return 0;
 }
index 87da17c..711f060 100644 (file)
@@ -170,6 +170,7 @@ xglScreenInit (ScreenPtr        pScreen,
     pScreenPriv->geometryUsage    = pScreenInfo->geometryUsage;
     pScreenPriv->yInverted       = pScreenInfo->yInverted;
     pScreenPriv->pboMask         = pScreenInfo->pboMask;
+    pScreenPriv->lines           = pScreenInfo->lines;
 
     GEOMETRY_INIT (pScreen, &pScreenPriv->scratchGeometry,
                   GLITZ_GEOMETRY_TYPE_VERTEX,