diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-04-03 14:48:36 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-12 20:54:49 +0100 |
commit | b9f7a4b5261b6d4e7bdbb5cc56d78d50ad1bd4a7 (patch) | |
tree | 99b27c4b2ea120b1d1eb97b648a8fd37ec2606ea /util | |
parent | a85c6c1e36273d534f01ade0714b0592b6bed5ab (diff) |
script: Don't hash the entire image.
The reuse hit rate is very small, and most images are quickly
distinguished in the first few bytes... Though perhaps not for video as
in the swfdec-youtube case...
Diffstat (limited to 'util')
-rw-r--r-- | util/cairo-script/cairo-script-operators.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index 754a27e0..e583120f 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -126,19 +126,17 @@ _csi_proxy_destroy (void *closure) cairo_script_interpreter_destroy (ctx); } -static unsigned long -_csi_blob_hash (const uint8_t *bytes, int len) +static void +_csi_blob_hash (csi_blob_t *blob, const uint32_t *data, int len) { + unsigned long hash = blob->hash; /* very simple! */ - unsigned long hash = 5381; - unsigned long *data = (unsigned long *) bytes; - len /= sizeof (unsigned long); while (len--) { unsigned long c = *data++; hash *= 33; hash ^= c; } - return hash; + blob->hash = hash; } static csi_boolean_t @@ -152,10 +150,6 @@ _csi_blob_equal (const csi_list_t *link, void *data) if (A->len != B->len) return FALSE; - if (A->hash == 0) - A->hash = _csi_blob_hash (A->bytes, A->len); - if (B->hash == 0) - B->hash = _csi_blob_hash (B->bytes, B->len); if (A->hash != B->hash) return FALSE; @@ -165,7 +159,7 @@ _csi_blob_equal (const csi_list_t *link, void *data) static void _csi_blob_init (csi_blob_t *blob, uint8_t *bytes, int len) { - blob->hash = 0; + blob->hash = 5381; blob->len = len; blob->bytes = bytes; } @@ -1760,6 +1754,7 @@ _ft_create_for_source (csi_t *ctx, /* check for an existing FT_Face (kept alive by the font cache) */ /* XXX index/flags */ _csi_blob_init (&tmpl, (uint8_t *) source->string, source->len); + _csi_blob_hash (&tmpl, (uint32_t *) source->string, source->len / sizeof (uint32_t)); link = _csi_list_find (ctx->_faces, _csi_blob_equal, &tmpl); if (link) { if (--source->base.ref == 0) @@ -1869,6 +1864,7 @@ _ft_create_for_pattern (csi_t *ctx, void *bytes; _csi_blob_init (&tmpl, (uint8_t *) string->string, string->len); + _csi_blob_hash (&tmpl, (uint32_t *) string->string, string->len / sizeof (uint32_t)); link = _csi_list_find (ctx->_faces, _csi_blob_equal, &tmpl); if (link) { if (--string->base.ref == 0) @@ -3082,6 +3078,22 @@ _image_tag_done (void *closure) cairo_script_interpreter_destroy (ctx); } +static void +_image_hash (csi_blob_t *blob, + cairo_surface_t *surface) +{ + uint32_t value; + + value = cairo_image_surface_get_width (surface); + _csi_blob_hash (blob, &value, 1); + + value = cairo_image_surface_get_height (surface); + _csi_blob_hash (blob, &value, 1); + + value = cairo_image_surface_get_format (surface); + _csi_blob_hash (blob, &value, 1); +} + static cairo_surface_t * _image_cached (csi_t *ctx, cairo_surface_t *surface) { @@ -3097,6 +3109,7 @@ _image_cached (csi_t *ctx, cairo_surface_t *surface) stride = cairo_image_surface_get_stride (surface); height = cairo_image_surface_get_height (surface); _csi_blob_init (&tmpl, data, stride * height); + _image_hash (&tmpl, surface); link = _csi_list_find (ctx->_images, _csi_blob_equal, &tmpl); if (link) { cairo_surface_destroy (surface); |