diff options
author | Robin Watts <robin.watts@artifex.com> | 2017-10-27 20:24:32 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2017-11-01 13:38:16 +0000 |
commit | 31cb4cf7aa88784219f6fc2be362a66df2f67289 (patch) | |
tree | 8a4248a377570f5a224ab25e23a70bda649eaaa3 /base/gxgstate.h | |
parent | de651aaa531a7eb6fa99c1ef97682ebe22a3cda7 (diff) | |
download | ghostpdl-31cb4cf7aa88784219f6fc2be362a66df2f67289.tar.gz |
Tweak cmap functions for speed.
In looking at the Advertising-PowerPoint-A4.pdf file, I noted that
cmap_gray_direct and cmap_gray_halftoned were taking a noticable
amount of time. This commit attempts to alleviate that.
Various observations:
1) Avoid unnecessary loop in cmap_gray_halftoned (and similar functions).
In some of the code, we do:
for (i = 0; i < n; i++)
if (i == k)
do_something_with(i)
why not just use:
if (k < n)
do_something_with(k)
2) Typically functions like cmap_gray_direct do a load of work,
culminating in trying to encode a color value. If that encoding fails,
it would fallback to trying to use a cmap_gray_halftoned, which would
do all the work a second time.
Tweak the code to avoid the call, and hence the repetition.
The downside to this is that the work is typically of the form:
for (i = 0; i < n; i++)
cv[i] = frac2cv(some_calculation_involving(cm_comps[i]));
and in order to be able to avoid the call to cmap_gray_halftoned, we
need to make it:
for (i = 0; i < n; i++) {
cm_comps[i] = some_calculation_involving(cm_comps[i]);
cv[i] = frac2cv(cm_comps[i]);
}
i.e. we have to do more stores than before. This can hurt us in some
cases, but it seems like a worthwhile win, especially in light of 3).
3) A lot of the work in these functions involves mapping colors through
the effective_transfer functions. This happens in code of the form:
for (i = 0; i < n; i++) {
cm_comps[i] = gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]);
}
If effective_transfer[i] is identity (as it almost always is), then
this whole loop is a nop.
We make some steps to optimise for this case by having the
gx_map_color_frac macro check for effective_transfer[i] being
gs_identity_transfer before calling it, but this doesn't help us
avoid the loop/load/store.
We therefore extend pgs with a count of the number of
'effective_transfer's that are non identity (essentially a flag
that enables us to know if we can skip this loop or not),
and use that to optimise our work.
Diffstat (limited to 'base/gxgstate.h')
-rw-r--r-- | base/gxgstate.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/base/gxgstate.h b/base/gxgstate.h index 7f0176eec..6d5663065 100644 --- a/base/gxgstate.h +++ b/base/gxgstate.h @@ -107,6 +107,7 @@ typedef struct gx_transfer_s { /* dictionaries. (In Level 1 systems, set_transfer and */\ /* effective_transfer are always the same.) */\ gx_transfer set_transfer; /* members are (RC) */\ + int effective_transfer_non_identity_count;\ gx_transfer_map *effective_transfer[GX_DEVICE_COLOR_MAX_COMPONENTS]; /* see below */\ \ /* Color caches: */\ |