summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <c99drn@cs.umu.se>2005-04-27 09:29:33 +0000
committerDavid Reveman <c99drn@cs.umu.se>2005-04-27 09:29:33 +0000
commit28a2d841cee596c0242b1649587d6b180529c0ef (patch)
tree524b3b59a03bf6a997c7728723ab1d7ab75c875d
parentabcc8c352e5fe6dd3b7ce5c6a25f435f877264c3 (diff)
Line drawing improvements to Xgl
-rw-r--r--hw/xgl/glx/xglx.c3
-rw-r--r--hw/xgl/xgl.h4
-rw-r--r--hw/xgl/xglfill.c586
-rw-r--r--hw/xgl/xglgc.c19
-rw-r--r--hw/xgl/xglparse.c7
-rw-r--r--hw/xgl/xglscreen.c1
6 files changed, 472 insertions, 148 deletions
diff --git a/hw/xgl/glx/xglx.c b/hw/xgl/glx/xglx.c
index 4bdf59b2b..15dfa8b3d 100644
--- a/hw/xgl/glx/xglx.c
+++ b/hw/xgl/glx/xglx.c
@@ -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
diff --git a/hw/xgl/xgl.h b/hw/xgl/xgl.h
index 82680e368..b1094beff 100644
--- a/hw/xgl/xgl.h
+++ b/hw/xgl/xgl.h
@@ -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,
diff --git a/hw/xgl/xglfill.c b/hw/xgl/xglfill.c
index 577caac11..4bce65690 100644
--- a/hw/xgl/xglfill.c
+++ b/hw/xgl/xglfill.c
@@ -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);
diff --git a/hw/xgl/xglgc.c b/hw/xgl/xglgc.c
index 610755932..5a85ead69 100644
--- a/hw/xgl/xglgc.c
+++ b/hw/xgl/xglgc.c
@@ -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
diff --git a/hw/xgl/xglparse.c b/hw/xgl/xglparse.c
index 1cf6bac89..663d79872 100644
--- a/hw/xgl/xglparse.c
+++ b/hw/xgl/xglparse.c
@@ -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;
}
diff --git a/hw/xgl/xglscreen.c b/hw/xgl/xglscreen.c
index 87da17c78..711f060cd 100644
--- a/hw/xgl/xglscreen.c
+++ b/hw/xgl/xglscreen.c
@@ -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,