[gs-cvs] rev 7892 - trunk/gs/src
leonardo at ghostscript.com
leonardo at ghostscript.com
Wed May 2 05:33:09 PDT 2007
Author: leonardo
Date: 2007-05-02 05:33:09 -0700 (Wed, 02 May 2007)
New Revision: 7892
Modified:
trunk/gs/src/gxshade6.c
Log:
Fix (shadings) : Early skip parts that fall outside the clipping box.
DETAILS :
This improves performance for the test case of
the bug 689189 "PDF fails with /unregistered in --shfill--".
The patch implements a bbox intersection code pattern to
several decomposition functions. It speeds up those shadings,
in which the shading area is significantly larger
than the clipping box.
Rather it speeds up the test case,
it needs a further improvement for shading functions.
A small noize (being lesser than shading smoothness) to be ignored
while a function monotonity check.
Minor changes :
1. In some functions the old bbox intersection code
becomes more uniform.
2. bbox_of_points moved up.
EXPECTED DIFFERENCES :
None.
Modified: trunk/gs/src/gxshade6.c
===================================================================
--- trunk/gs/src/gxshade6.c 2007-05-01 23:55:23 UTC (rev 7891)
+++ trunk/gs/src/gxshade6.c 2007-05-02 12:33:09 UTC (rev 7892)
@@ -1047,8 +1047,32 @@
It is important for intersection_of_small_bars to compute faster. */
int code;
patch_color_t *c;
- byte *color_stack_ptr = reserve_colors_inline(pfs, &c, 1);
+ byte *color_stack_ptr;
+ bool save_inside = pfs->inside;
+ if (!pfs->inside) {
+ gs_fixed_rect r, r1;
+
+ if(swap_axes) {
+ r.p.y = min(le->start.x, le->end.x);
+ r.p.x = min(le->start.y, le->end.y);
+ r.q.y = max(re->start.x, re->end.x);
+ r.q.x = max(re->start.y, re->end.y);
+ } else {
+ r.p.x = min(le->start.x, le->end.x);
+ r.p.y = min(le->start.y, le->end.y);
+ r.q.x = max(re->start.x, re->end.x);
+ r.q.y = max(re->start.y, re->end.y);
+ }
+ r1 = r;
+ rect_intersect(r, pfs->rect);
+ if (r.q.x <= r.p.x || r.q.y <= r.p.y)
+ return 0;
+ if (r1.p.x == r.p.x && r1.p.y == r.p.y &&
+ r1.q.x == r.q.x && r1.q.y == r.q.y)
+ pfs->inside = true;
+ }
+ color_stack_ptr = reserve_colors_inline(pfs, &c, 1);
if (color_stack_ptr == NULL)
return_error(gs_error_unregistered); /* Must not happen. */
/* Use the recursive decomposition due to isnt_color_monotonic
@@ -1136,6 +1160,7 @@
pfs->linear_color = linear_color_save;
}
out:
+ pfs->inside = save_inside;
release_colors_inline(pfs, color_stack_ptr, 1);
return code;
}
@@ -1851,6 +1876,45 @@
*/
}
+private inline void
+bbox_of_points(gs_fixed_rect *r,
+ const gs_fixed_point *p0, const gs_fixed_point *p1,
+ const gs_fixed_point *p2, const gs_fixed_point *p3)
+{
+ r->p.x = r->q.x = p0->x;
+ r->p.y = r->q.y = p0->y;
+
+ if (r->p.x > p1->x)
+ r->p.x = p1->x;
+ if (r->q.x < p1->x)
+ r->q.x = p1->x;
+ if (r->p.y > p1->y)
+ r->p.y = p1->y;
+ if (r->q.y < p1->y)
+ r->q.y = p1->y;
+
+ if (r->p.x > p2->x)
+ r->p.x = p2->x;
+ if (r->q.x < p2->x)
+ r->q.x = p2->x;
+ if (r->p.y > p2->y)
+ r->p.y = p2->y;
+ if (r->q.y < p2->y)
+ r->q.y = p2->y;
+
+ if (p3 == NULL)
+ return;
+
+ if (r->p.x > p3->x)
+ r->p.x = p3->x;
+ if (r->q.x < p3->x)
+ r->q.x = p3->x;
+ if (r->p.y > p3->y)
+ r->p.y = p3->y;
+ if (r->q.y < p3->y)
+ r->q.y = p3->y;
+}
+
private int
fill_wedges_aux(patch_fill_state_t *pfs, int k, int ka,
const gs_fixed_point pole[4], const patch_color_t *c0, const patch_color_t *c1,
@@ -1861,8 +1925,26 @@
if (k > 1) {
gs_fixed_point q[2][4];
patch_color_t *c;
- byte *color_stack_ptr = reserve_colors_inline(pfs, &c, 1);
+ bool save_inside = pfs->inside;
+ byte *color_stack_ptr;
+ if (!pfs->inside) {
+ gs_fixed_rect r, r1;
+
+ bbox_of_points(&r, &pole[0], &pole[1], &pole[2], &pole[3]);
+ r.p.x -= INTERPATCH_PADDING;
+ r.p.y -= INTERPATCH_PADDING;
+ r.q.x += INTERPATCH_PADDING;
+ r.q.y += INTERPATCH_PADDING;
+ r1 = r;
+ rect_intersect(r, pfs->rect);
+ if (r.q.x <= r.p.x || r.q.y <= r.p.y)
+ return 0;
+ if (r1.p.x == r.p.x && r1.p.y == r.p.y &&
+ r1.q.x == r.q.x && r1.q.y == r.q.y)
+ pfs->inside = true;
+ }
+ color_stack_ptr = reserve_colors_inline(pfs, &c, 1);
if (color_stack_ptr == NULL)
return_error(gs_error_unregistered); /* Must not happen. */
patch_interpolate_color(c, c0, c1, pfs, 0.5);
@@ -1871,6 +1953,7 @@
if (code >= 0)
code = fill_wedges_aux(pfs, k / 2, ka, q[1], c, c1, wedge_type);
release_colors_inline(pfs, color_stack_ptr, 1);
+ pfs->inside = save_inside;
return code;
} else {
if (INTERPATCH_PADDING && (wedge_type & interpatch_padding)) {
@@ -2313,45 +2396,6 @@
patch_interpolate_color(c, p0->c, p1->c, pfs, (double)(radix - 1) / radix);
}
-private inline void
-bbox_of_points(gs_fixed_rect *r,
- const gs_fixed_point *p0, const gs_fixed_point *p1,
- const gs_fixed_point *p2, const gs_fixed_point *p3)
-{
- r->p.x = r->q.x = p0->x;
- r->p.y = r->q.y = p0->y;
-
- if (r->p.x > p1->x)
- r->p.x = p1->x;
- if (r->q.x < p1->x)
- r->q.x = p1->x;
- if (r->p.y > p1->y)
- r->p.y = p1->y;
- if (r->q.y < p1->y)
- r->q.y = p1->y;
-
- if (r->p.x > p2->x)
- r->p.x = p2->x;
- if (r->q.x < p2->x)
- r->q.x = p2->x;
- if (r->p.y > p2->y)
- r->p.y = p2->y;
- if (r->q.y < p2->y)
- r->q.y = p2->y;
-
- if (p3 == NULL)
- return;
-
- if (r->p.x > p3->x)
- r->p.x = p3->x;
- if (r->q.x < p3->x)
- r->q.x = p3->x;
- if (r->p.y > p3->y)
- r->p.y = p3->y;
- if (r->q.y < p3->y)
- r->q.y = p3->y;
-}
-
private int
triangle_by_4(patch_fill_state_t *pfs,
const shading_vertex_t *p0, const shading_vertex_t *p1, const shading_vertex_t *p2,
@@ -2364,22 +2408,20 @@
bool inside_save = pfs->inside;
gs_fixed_rect r, r1;
int code = 0;
- byte *color_stack_ptr = reserve_colors_inline(pfs, c, 3);
-
+ byte *color_stack_ptr;
+ if (!pfs->inside) {
+ bbox_of_points(&r, &p0->p, &p1->p, &p2->p, NULL);
+ r1 = r;
+ rect_intersect(r, pfs->rect);
+ if (r.q.x <= r.p.x || r.q.y <= r.p.y)
+ return 0;
+ }
+ color_stack_ptr = reserve_colors_inline(pfs, c, 3);
if(color_stack_ptr == NULL)
return_error(gs_error_unregistered);
p01.c = c[0];
p12.c = c[1];
p20.c = c[2];
- if (!pfs->inside) {
- bbox_of_points(&r, &p0->p, &p1->p, &p2->p, NULL);
- r1 = r;
- rect_intersect(r, pfs->rect);
- if (r.q.x <= r.p.x || r.q.y <= r.p.y) { /* Outside. */
- code = 0;
- goto out;
- }
- }
code = try_device_linear_color(pfs, false, p0, p1, p2);
switch(code) {
case 0: /* The area is filled. */
@@ -3108,6 +3150,29 @@
s1->c[1][1] = p->c[1][1];
}
+private inline void
+tensor_patch_bbox(gs_fixed_rect *r, const tensor_patch *p)
+{
+ int i, j;
+
+ r->p.x = r->q.x = p->pole[0][0].x;
+ r->p.y = r->q.y = p->pole[0][0].y;
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ const gs_fixed_point *q = &p->pole[i][j];
+
+ if (r->p.x > q->x)
+ r->p.x = q->x;
+ if (r->p.y > q->y)
+ r->p.y = q->y;
+ if (r->q.x < q->x)
+ r->q.x = q->x;
+ if (r->q.y < q->y)
+ r->q.y = q->y;
+ }
+ }
+}
+
private int
decompose_stripe(patch_fill_state_t *pfs, const tensor_patch *p, int ku)
{
@@ -3115,8 +3180,22 @@
tensor_patch s0, s1;
patch_color_t *c[2];
int code;
- byte *color_stack_ptr = reserve_colors_inline(pfs, c, 2);
+ byte *color_stack_ptr;
+ bool save_inside = pfs->inside;
+ if (!pfs->inside) {
+ gs_fixed_rect r, r1;
+
+ tensor_patch_bbox(&r, p);
+ r1 = r;
+ rect_intersect(r, pfs->rect);
+ if (r.q.x <= r.p.x || r.q.y <= r.p.y)
+ return 0;
+ if (r1.p.x == r.p.x && r1.p.y == r.p.y &&
+ r1.q.x == r.q.x && r1.q.y == r.q.y)
+ pfs->inside = true;
+ }
+ color_stack_ptr = reserve_colors_inline(pfs, c, 2);
if(color_stack_ptr == NULL)
return_error(gs_error_unregistered); /* Must not happen. */
split_stripe(pfs, &s0, &s1, p, c);
@@ -3128,6 +3207,7 @@
if (code >= 0)
code = decompose_stripe(pfs, &s1, ku / 2);
release_colors_inline(pfs, color_stack_ptr, 2);
+ pfs->inside = save_inside;
return code;
} else {
quadrangle_patch q;
@@ -3382,9 +3462,27 @@
patch_color_t *c[2];
shading_vertex_t q0, q1, q2;
int code = 0;
- byte *color_stack_ptr = reserve_colors_inline(pfs, c, 2);
+ byte *color_stack_ptr;
+ bool save_inside = pfs->inside;
- if (color_stack_ptr == NULL)
+ if (!pfs->inside) {
+ gs_fixed_rect r, r1;
+
+ tensor_patch_bbox(&r, p);
+ r.p.x -= INTERPATCH_PADDING;
+ r.p.y -= INTERPATCH_PADDING;
+ r.q.x += INTERPATCH_PADDING;
+ r.q.y += INTERPATCH_PADDING;
+ r1 = r;
+ rect_intersect(r, pfs->rect);
+ if (r.q.x <= r.p.x || r.q.y <= r.p.y)
+ return 0;
+ if (r1.p.x == r.p.x && r1.p.y == r.p.y &&
+ r1.q.x == r.q.x && r1.q.y == r.q.y)
+ pfs->inside = true;
+ }
+ color_stack_ptr = reserve_colors_inline(pfs, c, 2);
+ if(color_stack_ptr == NULL)
return_error(gs_error_unregistered); /* Must not happen. */
split_patch(pfs, &s0, &s1, p, c);
if (kv0 <= 1) {
@@ -3429,6 +3527,7 @@
Delaying this improvement because it is low important.
*/
release_colors_inline(pfs, color_stack_ptr, 2);
+ pfs->inside = save_inside;
return code;
}
}
More information about the gs-cvs
mailing list