[gs-cvs] gs/src

Igor Melichev igor at ghostscript.com
Thu Apr 21 02:28:25 PDT 2005


Update of /cvs/ghostscript/gs/src
In directory casper2:/tmp/cvs-serv1672/gs/src

Modified Files:
	gxshade6.c 
Log Message:
Speed up shadings with optimizing fn_Sd_is_monotonic.

DETAILS :

This change is a fifth partial fix for the bug 687948  
"Performance of shading fill much worse than 8.00".

Implemented a new function fn_Sd_1arg_linear_monotonic,
which optimizes fn_Sd_is_monotonic in the case of
1-argument linear sampled function. 
It doesn't use the pole cache and the tensor-based algorithm,
saving significant time from the cache allocation,
which otherwise happens once per shfill.

We would like to optimise 1-argument cubic sampled function.
For now delaying it due to the absence of practical cases 
which need a high performance.

Minor change : Renamed fn_is_monotonic into fn_Sd_is_monotonic_aux.

EXPECTED DIFFERENCES :

None.


Index: gxshade6.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gxshade6.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- gxshade6.c	19 Apr 2005 12:22:08 -0000	1.97
+++ gxshade6.c	21 Apr 2005 09:28:23 -0000	1.98
@@ -2683,7 +2683,8 @@
 } color_change_type_t;
 
 private inline color_change_type_t
-quadrangle_color_change(const patch_fill_state_t *pfs, const quadrangle_patch *p, bool *divide_u, bool *divide_v)
+quadrangle_color_change(const patch_fill_state_t *pfs, const quadrangle_patch *p, 
+			bool is_big_u, bool is_big_v, bool *divide_u, bool *divide_v)
 {
     patch_color_t d0001, d1011, d;
     double D, D0001, D1011, D0010, D0111, D0011, D0110;
@@ -2703,10 +2704,18 @@
 	    D0011 <= pfs->smoothness && D0110 <= pfs->smoothness)
 	    return color_change_small;
 	if (D0001 <= pfs->smoothness && D1011 <= pfs->smoothness) {
+	    if (!is_big_v) {
+		/* The color function looks uncontiguous. */
+		return color_change_small;
+	    }
 	    *divide_v = true;
 	    return color_change_gradient;
 	}
 	if (D0010 <= pfs->smoothness && D0111 <= pfs->smoothness) {
+	    if (!is_big_u) {
+		/* The color function looks uncontiguous. */
+		return color_change_small;
+	    }
 	    *divide_u = true;
 	    return color_change_gradient;
 	}
@@ -2723,15 +2732,30 @@
     D = color_norm(pfs, &d);
     if (D <= pfs->smoothness)
 	return color_change_bilinear;
+#if 0 /* Disabled due to a 0.5% slowdown with the test file of the Bug 687948. */
+    if (Du > Dv && is_big_u)
+	*divide_u = true;
+    else if (Du < Dv && is_big_v)
+	*divide_v = true;
+    else if (is_big_u)
+	*divide_u = true;
+    else if (is_big_v)
+	*divide_v = true;
+    else {
+	/* The color function looks uncontiguous. */
+	return color_change_small;
+    }
+#else
     if (Du > Dv)
 	*divide_u = true;
     else
 	*divide_v = true;
+#endif
     return color_change_general;
 }
 
 private int 
-fill_quadrangle(patch_fill_state_t *pfs, const quadrangle_patch *p, bool big)
+fill_quadrangle(patch_fill_state_t *pfs, const quadrangle_patch *p, bool big, int level)
 {
     /* The quadrangle is flattened enough by V and U, so ignore inner poles. */
     /* Assuming the XY span is restricted with curve_samples. 
@@ -2747,6 +2771,8 @@
     gs_fixed_rect r, r1;
     /* Warning : pfs->monotonic_color is not restored on error. */
 
+    if (level > 100)
+	return_error(gs_error_unregistered); /* Safety. */
     if (!pfs->inside) {
 	bbox_of_points(&r, &p->p[0][0]->p, &p->p[0][1]->p, &p->p[1][0]->p, &p->p[1][1]->p);
 	r1 = r;
@@ -2853,7 +2879,7 @@
 	}
 	if (!pfs->linear_color) {
 	    /* go to divide. */
-	} else switch(quadrangle_color_change(pfs, p, &divide_u, &divide_v)) {
+	} else switch(quadrangle_color_change(pfs, p, is_big_u, is_big_v, &divide_u, &divide_v)) {
 	    case color_change_small: 
 		code = (QUADRANGLES || !pfs->maybe_self_intersecting ? 
 			    constant_color_quadrangle : triangles4)(pfs, p, 
@@ -2905,7 +2931,7 @@
 	    if (code < 0)
 		return code;
 	}
-	code = fill_quadrangle(pfs, &s0, big);
+	code = fill_quadrangle(pfs, &s0, big, level + 1);
 	if (code < 0)
 	    return code;
 	if (LAZY_WEDGES) {
@@ -2913,7 +2939,7 @@
 	    move_wedge(&l1, p->l0111, true);
 	    move_wedge(&l2, p->l1000, false);
 	}
-	code = fill_quadrangle(pfs, &s1, big1);
+	code = fill_quadrangle(pfs, &s1, big1, level + 1);
 	if (LAZY_WEDGES) {
 	    if (code < 0)
 		return code;
@@ -2943,7 +2969,7 @@
 	    if (code < 0)
 		return code;
 	}
-	code = fill_quadrangle(pfs, &s0, big1);
+	code = fill_quadrangle(pfs, &s0, big1, level + 1);
 	if (code < 0)
 	    return code;
 	if (LAZY_WEDGES) {
@@ -2951,7 +2977,7 @@
 	    move_wedge(&l1, p->l0001, true);
 	    move_wedge(&l2, p->l1110, false);
 	}
-	code = fill_quadrangle(pfs, &s1, big1);
+	code = fill_quadrangle(pfs, &s1, big1, level + 1);
 	if (LAZY_WEDGES) {
 	    if (code < 0)
 		return code;
@@ -3036,7 +3062,7 @@
 #	if SKIP_TEST
 	    dbg_quad_cnt++;
 #	endif
-	code = fill_quadrangle(pfs, &q, true);
+	code = fill_quadrangle(pfs, &q, true, 0);
 	if (LAZY_WEDGES) {
 	    code = terminate_wedge_vertex_list(pfs, &l[0], &q.p[0][0]->c, &q.p[0][1]->c);
 	    if (code < 0)



More information about the gs-cvs mailing list