summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-04-03 14:48:36 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-12 20:54:49 +0100
commitb9f7a4b5261b6d4e7bdbb5cc56d78d50ad1bd4a7 (patch)
tree99b27c4b2ea120b1d1eb97b648a8fd37ec2606ea /util
parenta85c6c1e36273d534f01ade0714b0592b6bed5ab (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.c35
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);