summaryrefslogtreecommitdiff
path: root/base/gxgstate.h
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2017-10-27 20:24:32 +0100
committerRobin Watts <robin.watts@artifex.com>2017-11-01 13:38:16 +0000
commit31cb4cf7aa88784219f6fc2be362a66df2f67289 (patch)
tree8a4248a377570f5a224ab25e23a70bda649eaaa3 /base/gxgstate.h
parentde651aaa531a7eb6fa99c1ef97682ebe22a3cda7 (diff)
downloadghostpdl-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.h1
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: */\