From 70908de17a69aaeb9ea9a2ad15d45bda12671bdf Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor.andersson@artifex.com>
Date: Mon, 17 Feb 2014 16:19:30 +0100
Subject: Simplify shade vertex preparation and remove redundant memcpy calls.

---
 include/mupdf/fitz/shade.h |   2 +-
 source/fitz/draw-mesh.c    |  10 ++--
 source/fitz/shade.c        | 145 +++++++++++++++++++--------------------------
 3 files changed, 67 insertions(+), 90 deletions(-)

diff --git a/include/mupdf/fitz/shade.h b/include/mupdf/fitz/shade.h
index b33b832e..3cd43bd7 100644
--- a/include/mupdf/fitz/shade.h
+++ b/include/mupdf/fitz/shade.h
@@ -92,7 +92,7 @@ struct fz_vertex_s
 
 typedef struct fz_mesh_processor_s fz_mesh_processor;
 
-typedef void (fz_mesh_prepare_fn)(void *arg, fz_vertex *v);
+typedef void (fz_mesh_prepare_fn)(void *arg, fz_vertex *v, const float *c);
 typedef void (fz_mesh_process_fn)(void *arg, fz_vertex *av, fz_vertex *bv, fz_vertex *cv);
 
 struct fz_mesh_processor_s {
diff --git a/source/fitz/draw-mesh.c b/source/fitz/draw-mesh.c
index 1bb93369..8b0d80a3 100644
--- a/source/fitz/draw-mesh.c
+++ b/source/fitz/draw-mesh.c
@@ -165,21 +165,21 @@ struct paint_tri_data
 };
 
 static void
-prepare_vertex(void *arg, fz_vertex *v)
+prepare_vertex(void *arg, fz_vertex *v, const float *input)
 {
 	struct paint_tri_data *ptd = (struct paint_tri_data *)arg;
-	float local[MAXN];
 	fz_shade *shade = ptd->shade;
 	fz_pixmap *dest = ptd->dest;
+	float *output = v->c;
 	int i;
 
 	if (shade->use_function)
-		v->c[0] *= 255;
+		output[0] = input[0] * 255;
 	else
 	{
-		ptd->cc.convert(&ptd->cc, &local[0], v->c);
+		ptd->cc.convert(&ptd->cc, output, input);
 		for (i = 0; i < dest->colorspace->n; i++)
-			v->c[i] = local[i] * 255;
+			output[i] *= 255;
 	}
 }
 
diff --git a/source/fitz/shade.c b/source/fitz/shade.c
index 892f1887..419c44f0 100644
--- a/source/fitz/shade.c
+++ b/source/fitz/shade.c
@@ -34,6 +34,19 @@ paint_quad(fz_mesh_processor *painter, fz_vertex *v0, fz_vertex *v1, fz_vertex *
 	painter->process(painter->process_arg, v3, v2, v1);
 }
 
+static inline void
+fz_prepare_color(fz_mesh_processor *painter, fz_vertex *v, float *c)
+{
+	painter->prepare(painter->process_arg, v, c);
+}
+
+static inline void
+fz_prepare_vertex(fz_mesh_processor *painter, fz_vertex *v, const fz_matrix *ctm, float x, float y, float *c)
+{
+	fz_transform_point_xy(&v->p, ctm, x, y);
+	painter->prepare(painter->process_arg, v, c);
+}
+
 static void
 fz_process_mesh_type1(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_mesh_processor *painter)
 {
@@ -60,28 +73,18 @@ fz_process_mesh_type1(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 		yn = y0 + (y1 - y0) * (yy + 1) / ydivs;
 
 		x = x0;
-		v[0].p.x = x; v[0].p.y = y;
-		fz_transform_point(&v[0].p, &local_ctm);
-		memcpy(v[0].c, p, n*sizeof(float));
+
+		fz_prepare_vertex(painter, &v[0], &local_ctm, x, y, p);
 		p += n;
-		painter->prepare(painter->process_arg, &v[0]);
-		v[1].p.x = x; v[1].p.y = yn;
-		fz_transform_point(&v[1].p, &local_ctm);
-		memcpy(v[1].c, p + xdivs*n, n*sizeof(float));
-		painter->prepare(painter->process_arg, &v[1]);
+		fz_prepare_vertex(painter, &v[1], &local_ctm, x, yn, p + xdivs * n);
+
 		for (xx = 0; xx < xdivs; xx++)
 		{
 			x = x0 + (x1 - x0) * (xx + 1) / xdivs;
 
-			vn[0].p.x = x; vn[0].p.y = y;
-			fz_transform_point(&vn[0].p, &local_ctm);
-			memcpy(vn[0].c, p, n*sizeof(float));
+			fz_prepare_vertex(painter, &vn[0], &local_ctm, x, y, p);
 			p += n;
-			painter->prepare(painter->process_arg, &vn[0]);
-			vn[1].p.x = x; vn[1].p.y = yn;
-			fz_transform_point(&vn[1].p, &local_ctm);
-			memcpy(vn[1].c, p + xdivs*n, n*sizeof(float));
-			painter->prepare(painter->process_arg, &vn[1]);
+			fz_prepare_vertex(painter, &vn[1], &local_ctm, x, yn, p + xdivs * n);
 
 			paint_quad(painter, &v[0], &vn[0], &vn[1], &v[1]);
 			SWAP(v,vn);
@@ -98,7 +101,6 @@ fz_point_on_circle(fz_point p, float r, float theta)
 {
 	p.x = p.x + cosf(theta) * r;
 	p.y = p.y + sinf(theta) * r;
-
 	return p;
 }
 
@@ -109,6 +111,8 @@ fz_process_mesh_type2(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 	fz_vertex v0, v1, v2, v3;
 	fz_vertex e0, e1;
 	float theta;
+	float zero = 0;
+	float one = 1;
 
 	p0.x = shade->u.l_or_r.coords[0][0];
 	p0.y = shade->u.l_or_r.coords[0][1];
@@ -126,30 +130,23 @@ fz_process_mesh_type2(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 	v2.p = fz_point_on_circle(p0, -HUGENUM, theta);
 	v3.p = fz_point_on_circle(p1, -HUGENUM, theta);
 
-	v0.c[0] = 0;
-	v1.c[0] = 1;
-	v2.c[0] = 0;
-	v3.c[0] = 1;
+	fz_prepare_color(painter, &v0, &zero);
+	fz_prepare_color(painter, &v1, &one);
+	fz_prepare_color(painter, &v2, &zero);
+	fz_prepare_color(painter, &v3, &one);
 
-	painter->prepare(painter->process_arg, &v0);
-	painter->prepare(painter->process_arg, &v1);
-	painter->prepare(painter->process_arg, &v2);
-	painter->prepare(painter->process_arg, &v3);
 	paint_quad(painter, &v0, &v2, &v3, &v1);
 
 	if (shade->u.l_or_r.extend[0])
 	{
 		e0.p.x = v0.p.x - (p1.x - p0.x) * HUGENUM;
 		e0.p.y = v0.p.y - (p1.y - p0.y) * HUGENUM;
+		fz_prepare_color(painter, &e0, &zero);
 
 		e1.p.x = v2.p.x - (p1.x - p0.x) * HUGENUM;
 		e1.p.y = v2.p.y - (p1.y - p0.y) * HUGENUM;
+		fz_prepare_color(painter, &e1, &zero);
 
-		e0.c[0] = 0;
-		e1.c[0] = 0;
-
-		painter->prepare(painter->process_arg, &e0);
-		painter->prepare(painter->process_arg, &e1);
 		paint_quad(painter, &e0, &v0, &v2, &e1);
 	}
 
@@ -157,15 +154,12 @@ fz_process_mesh_type2(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 	{
 		e0.p.x = v1.p.x + (p1.x - p0.x) * HUGENUM;
 		e0.p.y = v1.p.y + (p1.y - p0.y) * HUGENUM;
+		fz_prepare_color(painter, &e0, &one);
 
 		e1.p.x = v3.p.x + (p1.x - p0.x) * HUGENUM;
 		e1.p.y = v3.p.y + (p1.y - p0.y) * HUGENUM;
+		fz_prepare_color(painter, &e1, &one);
 
-		e0.c[0] = 1;
-		e1.c[0] = 1;
-
-		painter->prepare(painter->process_arg, &e0);
-		painter->prepare(painter->process_arg, &e1);
 		paint_quad(painter, &e0, &v1, &v3, &e1);
 	}
 }
@@ -206,23 +200,15 @@ fz_paint_annulus(const fz_matrix *ctm,
 		fz_transform_point(&b2.p, ctm);
 		fz_transform_point(&b3.p, ctm);
 
-		t0.c[0] = c0;
-		t1.c[0] = c0;
-		t2.c[0] = c1;
-		t3.c[0] = c1;
-		b0.c[0] = c0;
-		b1.c[0] = c0;
-		b2.c[0] = c1;
-		b3.c[0] = c1;
-
-		painter->prepare(painter->process_arg, &t0);
-		painter->prepare(painter->process_arg, &t1);
-		painter->prepare(painter->process_arg, &t2);
-		painter->prepare(painter->process_arg, &t3);
-		painter->prepare(painter->process_arg, &b0);
-		painter->prepare(painter->process_arg, &b1);
-		painter->prepare(painter->process_arg, &b2);
-		painter->prepare(painter->process_arg, &b3);
+		fz_prepare_color(painter, &t0, &c0);
+		fz_prepare_color(painter, &t1, &c0);
+		fz_prepare_color(painter, &t2, &c1);
+		fz_prepare_color(painter, &t3, &c1);
+		fz_prepare_color(painter, &b0, &c0);
+		fz_prepare_color(painter, &b1, &c0);
+		fz_prepare_color(painter, &b2, &c1);
+		fz_prepare_color(painter, &b3, &c1);
+
 		paint_quad(painter, &t0, &t2, &t3, &t1);
 		paint_quad(painter, &b0, &b2, &b3, &b1);
 	}
@@ -301,18 +287,18 @@ fz_process_mesh_type4(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 	float y1 = shade->u.m.y1;
 	float *c0 = shade->u.m.c0;
 	float *c1 = shade->u.m.c1;
+	float x, y, c[FZ_MAX_COLORS];
 
 	fz_try(ctx)
 	{
 		while (!fz_is_eof_bits(stream))
 		{
 			flag = fz_read_bits(stream, bpflag);
-			vd->p.x = read_sample(stream, bpcoord, x0, x1);
-			vd->p.y = read_sample(stream, bpcoord, y0, y1);
-			fz_transform_point(&vd->p, ctm);
+			x = read_sample(stream, bpcoord, x0, x1);
+			y = read_sample(stream, bpcoord, y0, y1);
 			for (i = 0; i < ncomp; i++)
-				vd->c[i] = read_sample(stream, bpcomp, c0[i], c1[i]);
-			painter->prepare(painter->process_arg, vd);
+				c[i] = read_sample(stream, bpcomp, c0[i], c1[i]);
+			fz_prepare_vertex(painter, vd, ctm, x, y, c);
 
 			switch (flag)
 			{
@@ -320,20 +306,18 @@ fz_process_mesh_type4(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 				SWAP(va, vd);
 
 				fz_read_bits(stream, bpflag);
-				vb->p.x = read_sample(stream, bpcoord, x0, x1);
-				vb->p.y = read_sample(stream, bpcoord, y0, y1);
-				fz_transform_point(&vb->p, ctm);
+				x = read_sample(stream, bpcoord, x0, x1);
+				y = read_sample(stream, bpcoord, y0, y1);
 				for (i = 0; i < ncomp; i++)
-					vb->c[i] = read_sample(stream, bpcomp, c0[i], c1[i]);
-				painter->prepare(painter->process_arg, vb);
+					c[i] = read_sample(stream, bpcomp, c0[i], c1[i]);
+				fz_prepare_vertex(painter, vb, ctm, x, y, c);
 
 				fz_read_bits(stream, bpflag);
-				vc->p.x = read_sample(stream, bpcoord, x0, x1);
-				vc->p.y = read_sample(stream, bpcoord, y0, y1);
-				fz_transform_point(&vc->p, ctm);
+				x = read_sample(stream, bpcoord, x0, x1);
+				y = read_sample(stream, bpcoord, y0, y1);
 				for (i = 0; i < ncomp; i++)
-					vc->c[i] = read_sample(stream, bpcomp, c0[i], c1[i]);
-				painter->prepare(painter->process_arg, vc);
+					c[i] = read_sample(stream, bpcomp, c0[i], c1[i]);
+				fz_prepare_vertex(painter, vc, ctm, x, y, c);
 
 				paint_tri(painter, va, vb, vc);
 				break;
@@ -381,6 +365,7 @@ fz_process_mesh_type5(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 	float y1 = shade->u.m.y1;
 	float *c0 = shade->u.m.c0;
 	float *c1 = shade->u.m.c1;
+	float x, y, c[FZ_MAX_COLORS];
 
 	fz_var(buf);
 	fz_var(ref);
@@ -395,12 +380,11 @@ fz_process_mesh_type5(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz
 		{
 			for (i = 0; i < vprow; i++)
 			{
-				buf[i].p.x = read_sample(stream, bpcoord, x0, x1);
-				buf[i].p.y = read_sample(stream, bpcoord, y0, y1);
-				fz_transform_point(&buf[i].p, ctm);
+				x = read_sample(stream, bpcoord, x0, x1);
+				y = read_sample(stream, bpcoord, y0, y1);
 				for (k = 0; k < ncomp; k++)
-					buf[i].c[k] = read_sample(stream, bpcomp, c0[k], c1[k]);
-				painter->prepare(painter->process_arg, &buf[i]);
+					c[k] = read_sample(stream, bpcomp, c0[k], c1[k]);
+				fz_prepare_vertex(painter, &buf[i], ctm, x, y, c);
 			}
 
 			if (!first)
@@ -437,24 +421,17 @@ static void
 triangulate_patch(fz_mesh_processor *painter, tensor_patch p)
 {
 	fz_vertex v0, v1, v2, v3;
-	int col_len = painter->ncomp * sizeof(v0.c[0]);
 
 	v0.p = p.pole[0][0];
-	memcpy(v0.c, p.color[0], col_len);
-
 	v1.p = p.pole[0][3];
-	memcpy(v1.c, p.color[1], col_len);
-
 	v2.p = p.pole[3][3];
-	memcpy(v2.c, p.color[2], col_len);
-
 	v3.p = p.pole[3][0];
-	memcpy(v3.c, p.color[3], col_len);
 
-	painter->prepare(painter->process_arg, &v0);
-	painter->prepare(painter->process_arg, &v1);
-	painter->prepare(painter->process_arg, &v2);
-	painter->prepare(painter->process_arg, &v3);
+	fz_prepare_color(painter, &v0, p.color[0]);
+	fz_prepare_color(painter, &v1, p.color[1]);
+	fz_prepare_color(painter, &v2, p.color[2]);
+	fz_prepare_color(painter, &v3, p.color[3]);
+
 	paint_quad(painter, &v0, &v1, &v2, &v3);
 }
 
-- 
cgit v1.2.3