miarc: Make the caller free the arc span data

drawArc does some fairly expensive computation, but it's only sensitive
to arc width/height. Thread the span data up through the call chain so
it's at least possible for the caller to cache things.

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Adam Jackson 2017-03-01 16:13:58 -05:00
parent 9426c5500b
commit 849c825855

View File

@ -215,10 +215,21 @@ typedef struct _miPolyArc {
miArcJoinPtr joins; miArcJoinPtr joins;
} miPolyArcRec, *miPolyArcPtr; } miPolyArcRec, *miPolyArcPtr;
typedef struct {
short lx, lw, rx, rw;
} miArcSpan;
typedef struct {
miArcSpan *spans;
int count1, count2, k;
char top, bot, hole;
} miArcSpanData;
static void fillSpans(DrawablePtr pDrawable, GCPtr pGC); static void fillSpans(DrawablePtr pDrawable, GCPtr pGC);
static void newFinalSpan(int y, int xmin, int xmax); static void newFinalSpan(int y, int xmin, int xmax);
static void drawArc(xArc * tarc, int l, int a0, int a1, miArcFacePtr right, static miArcSpanData *drawArc(xArc * tarc, int l, int a0, int a1,
miArcFacePtr left); miArcFacePtr right, miArcFacePtr left,
miArcSpanData *spdata);
static void drawZeroArc(DrawablePtr pDraw, GCPtr pGC, xArc * tarc, int lw, static void drawZeroArc(DrawablePtr pDraw, GCPtr pGC, xArc * tarc, int lw,
miArcFacePtr left, miArcFacePtr right); miArcFacePtr left, miArcFacePtr right);
static void miArcJoin(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pLeft, static void miArcJoin(DrawablePtr pDraw, GCPtr pGC, miArcFacePtr pLeft,
@ -244,9 +255,9 @@ static int miGetArcPts(SppArcPtr parc, int cpt, SppPointPtr * ppPts);
* draw one segment of the arc using the arc spans generation routines * draw one segment of the arc using the arc spans generation routines
*/ */
static void static miArcSpanData *
miArcSegment(DrawablePtr pDraw, miArcSegment(DrawablePtr pDraw, GCPtr pGC, xArc tarc, miArcFacePtr right,
GCPtr pGC, xArc tarc, miArcFacePtr right, miArcFacePtr left) miArcFacePtr left, miArcSpanData *spdata)
{ {
int l = pGC->lineWidth; int l = pGC->lineWidth;
int a0, a1, startAngle, endAngle; int a0, a1, startAngle, endAngle;
@ -257,7 +268,7 @@ miArcSegment(DrawablePtr pDraw,
if (tarc.width == 0 || tarc.height == 0) { if (tarc.width == 0 || tarc.height == 0) {
drawZeroArc(pDraw, pGC, &tarc, l, left, right); drawZeroArc(pDraw, pGC, &tarc, l, left, right);
return; return spdata;
} }
if (pGC->miTranslate) { if (pGC->miTranslate) {
@ -298,7 +309,7 @@ miArcSegment(DrawablePtr pDraw,
endAngle = FULLCIRCLE; endAngle = FULLCIRCLE;
} }
drawArc(&tarc, l, startAngle, endAngle, right, left); return drawArc(&tarc, l, startAngle, endAngle, right, left, spdata);
} }
/* /*
@ -364,16 +375,6 @@ correspond to the inner and outer boundaries.
*/ */
typedef struct {
short lx, lw, rx, rw;
} miArcSpan;
typedef struct {
miArcSpan *spans;
int count1, count2, k;
char top, bot, hole;
} miArcSpanData;
static void drawQuadrant(struct arc_def *def, struct accelerators *acc, static void drawQuadrant(struct arc_def *def, struct accelerators *acc,
int a0, int a1, int mask, miArcFacePtr right, int a0, int a1, int mask, miArcFacePtr right,
miArcFacePtr left, miArcSpanData * spdata); miArcFacePtr left, miArcSpanData * spdata);
@ -905,8 +906,11 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
int halfWidth; int halfWidth;
if (width == 0 && pGC->lineStyle == LineSolid) { if (width == 0 && pGC->lineStyle == LineSolid) {
for (i = narcs, parc = parcs; --i >= 0; parc++) for (i = narcs, parc = parcs; --i >= 0; parc++) {
miArcSegment(pDraw, pGC, *parc, NULL, NULL); miArcSpanData *spdata;
spdata = miArcSegment(pDraw, pGC, *parc, NULL, NULL, NULL);
free(spdata);
}
fillSpans(pDraw, pGC); fillSpans(pDraw, pGC);
return; return;
} }
@ -1016,6 +1020,7 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
cap[0] = cap[1] = 0; cap[0] = cap[1] = 0;
join[0] = join[1] = 0; join[0] = join[1] = 0;
for (iphase = (pGC->lineStyle == LineDoubleDash); iphase >= 0; iphase--) { for (iphase = (pGC->lineStyle == LineDoubleDash); iphase >= 0; iphase--) {
miArcSpanData *spdata = NULL;
ChangeGCVal gcval; ChangeGCVal gcval;
if (iphase == 1) { if (iphase == 1) {
@ -1032,9 +1037,10 @@ miWideArc(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc * parcs)
miArcDataPtr arcData; miArcDataPtr arcData;
arcData = &polyArcs[iphase].arcs[i]; arcData = &polyArcs[iphase].arcs[i];
miArcSegment(pDrawTo, pGCTo, arcData->arc, spdata = miArcSegment(pDrawTo, pGCTo, arcData->arc,
&arcData->bounds[RIGHT_END], &arcData->bounds[RIGHT_END],
&arcData->bounds[LEFT_END]); &arcData->bounds[LEFT_END], spdata);
free(spdata);
if (polyArcs[iphase].arcs[i].render) { if (polyArcs[iphase].arcs[i].render) {
fillSpans(pDrawTo, pGCTo); fillSpans(pDrawTo, pGCTo);
/* don't cap self-joining arcs */ /* don't cap self-joining arcs */
@ -3240,9 +3246,9 @@ mirrorSppPoint(int quadrant, SppPointPtr sppPoint)
* first quadrant. * first quadrant.
*/ */
static void static miArcSpanData *
drawArc(xArc * tarc, drawArc(xArc * tarc, int l, int a0, int a1, miArcFacePtr right,
int l, int a0, int a1, miArcFacePtr right, miArcFacePtr left) miArcFacePtr left, miArcSpanData *spdata)
{ /* save end line points */ { /* save end line points */
struct arc_def def; struct arc_def def;
struct accelerators acc; struct accelerators acc;
@ -3258,11 +3264,11 @@ drawArc(xArc * tarc,
int i, j; int i, j;
int flipRight = 0, flipLeft = 0; int flipRight = 0, flipLeft = 0;
int copyEnd = 0; int copyEnd = 0;
miArcSpanData *spdata;
spdata = miComputeWideEllipse(l, tarc);
if (!spdata) if (!spdata)
return; spdata = miComputeWideEllipse(l, tarc);
if (!spdata)
return NULL;
if (a1 < a0) if (a1 < a0)
a1 += 360 * 64; a1 += 360 * 64;
@ -3472,7 +3478,7 @@ drawArc(xArc * tarc,
left->counterClock = temp; left->counterClock = temp;
} }
} }
free(spdata); return spdata;
} }
static void static void