diff options
author | Robin Watts <robin.watts@artifex.com> | 2013-12-30 12:51:47 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-01-02 20:04:40 +0000 |
commit | 4f5e6c8d18ae2fe2c5aa7d0792aa6fa4e1c92719 (patch) | |
tree | eeedf3cdafdf77bedbd292787fa98e3e924f6f81 | |
parent | a80817d4fcc27239fb2efa769ae84c542cbae904 (diff) | |
download | mupdf-4f5e6c8d18ae2fe2c5aa7d0792aa6fa4e1c92719.tar.xz |
Bug 694585: Further improve mesh rendering times
Add a cached color converter mechanism. Use this for rendering meshes
to speed repeated conversions.
This reduces a (release build to ppm at default resolution) run from
23.5s to 13.2 seconds.
-rw-r--r-- | include/mupdf/fitz/colorspace.h | 4 | ||||
-rw-r--r-- | source/fitz/colorspace.c | 82 | ||||
-rw-r--r-- | source/fitz/draw-mesh.c | 8 |
3 files changed, 92 insertions, 2 deletions
diff --git a/include/mupdf/fitz/colorspace.h b/include/mupdf/fitz/colorspace.h index ee53e487..9b66ee9e 100644 --- a/include/mupdf/fitz/colorspace.h +++ b/include/mupdf/fitz/colorspace.h @@ -104,8 +104,12 @@ struct fz_color_converter_s fz_context *ctx; fz_colorspace *ds; fz_colorspace *ss; + void *opaque; }; void fz_lookup_color_converter(fz_color_converter *cc, fz_context *ctx, fz_colorspace *ds, fz_colorspace *ss); +void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ds, fz_colorspace *ss); +void fz_fin_cached_color_converter(fz_color_converter *cc); + #endif diff --git a/source/fitz/colorspace.c b/source/fitz/colorspace.c index 33fa07fb..3426e26f 100644 --- a/source/fitz/colorspace.c +++ b/source/fitz/colorspace.c @@ -1274,3 +1274,85 @@ fz_expand_indexed_pixmap(fz_context *ctx, fz_pixmap *src) return dst; } + +typedef struct fz_cached_color_converter +{ + fz_color_converter base; + fz_hash_table *hash; + +} +fz_cached_color_converter; + +static void fz_cached_color_convert(fz_color_converter *cc_, float *ds, float *ss) +{ + fz_cached_color_converter *cc = cc_->opaque; + fz_context *ctx = cc->base.ctx; + void *val = fz_hash_find(ctx, cc->hash, ss); + int n = cc->base.ds->n * sizeof(float); + fz_color_converter *base_cc = &cc->base; + + if (val) + { + memcpy(ds, val, n); + return; + } + + base_cc->convert(base_cc, ds, ss); + val = fz_malloc(ctx, n); + memcpy(val, ds, n); + fz_try(ctx) + { + fz_hash_insert(ctx, cc->hash, ss, val); + } + fz_catch(ctx) + { + fz_free(ctx, val); + } +} + +void fz_init_cached_color_converter(fz_context *ctx, fz_color_converter *cc, fz_colorspace *ds, fz_colorspace *ss) +{ + int n = ss->n; + fz_cached_color_converter *cached = fz_malloc_struct(ctx, fz_cached_color_converter); + + fz_try(ctx) + { + fz_lookup_color_converter(&cached->base, ctx, ds, ss); + cached->hash = fz_new_hash_table(ctx, 256, n * sizeof(float), -1); + cc->convert = fz_cached_color_convert; + cc->ctx = ctx; + cc->ds = ds; + cc->ss = ss; + cc->opaque = cached; + } + fz_catch(ctx) + { + fz_free_hash(ctx, cached->hash); + fz_rethrow(ctx); + } +} + +void fz_fin_cached_color_converter(fz_color_converter *cc_) +{ + fz_cached_color_converter *cc; + fz_context *ctx; + int i, n; + + if (cc_ == NULL) + return; + cc = cc_->opaque; + if (cc == NULL) + return; + cc_->opaque = NULL; + ctx = cc_->ctx; + + n = fz_hash_len(ctx, cc->hash); + for (i = 0; i < n; i++) + { + void *v = fz_hash_get_val(ctx, cc->hash, i); + if (v) + fz_free(ctx, v); + } + fz_free_hash(ctx, cc->hash); + fz_free(ctx, cc); +} diff --git a/source/fitz/draw-mesh.c b/source/fitz/draw-mesh.c index 26d496d2..1bb93369 100644 --- a/source/fitz/draw-mesh.c +++ b/source/fitz/draw-mesh.c @@ -205,7 +205,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap fz_pixmap *temp = NULL; fz_pixmap *conv = NULL; float color[FZ_MAX_COLORS]; - struct paint_tri_data ptd; + struct paint_tri_data ptd = { 0 }; int i, k; fz_matrix local_ctm; @@ -241,7 +241,7 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap ptd.shade = shade; ptd.bbox = bbox; - fz_lookup_color_converter(&ptd.cc, ctx, temp->colorspace, shade->colorspace); + fz_init_cached_color_converter(ctx, &ptd.cc, temp->colorspace, shade->colorspace); fz_process_mesh(ctx, shade, &local_ctm, &prepare_vertex, &do_paint_tri, &ptd); if (shade->use_function) @@ -262,6 +262,10 @@ fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap fz_drop_pixmap(ctx, temp); } } + fz_always(ctx) + { + fz_fin_cached_color_converter(&ptd.cc); + } fz_catch(ctx) { fz_drop_pixmap(ctx, conv); |