Use strong hash (SHA1) for glyphs

Using a cryptographically strong hash means that comparing the
hash alone is sufficient for determining glyph equality (no need
to compare the glyph bits directly). This will allow us to replace
system-memory copies of the glyph bits, (which we've only been
holding onto for comparisons), with Pixmaps.
This commit is contained in:
Carl Worth 2007-07-31 17:04:13 -07:00
parent 516b96387b
commit 19b3b1fd8f
4 changed files with 65 additions and 66 deletions

View File

@ -621,7 +621,7 @@ PIXMAN="[pixman >= 0.9.2]"
dnl Core modules for most extensions, et al. dnl Core modules for most extensions, et al.
REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]" REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto [xproto >= 7.0.9] xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
REQUIRED_LIBS="xfont xau fontenc $PIXMAN" REQUIRED_LIBS="xfont xau fontenc $PIXMAN openssl"
dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas dnl HAVE_DBUS is true if we actually have the D-Bus library, whereas
dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config dnl CONFIG_DBUS_API is true if we want to enable the D-Bus config

View File

@ -26,6 +26,8 @@
#include <dix-config.h> #include <dix-config.h>
#endif #endif
#include <openssl/sha.h>
#include "misc.h" #include "misc.h"
#include "scrnintstr.h" #include "scrnintstr.h"
#include "os.h" #include "os.h"
@ -412,7 +414,10 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr)
} }
GlyphRefPtr GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
unsigned char sha1[20])
{ {
CARD32 elt, step, s; CARD32 elt, step, s;
GlyphPtr glyph; GlyphPtr glyph;
@ -443,7 +448,7 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
} }
else if (s == signature && else if (s == signature &&
(!match || (!match ||
memcmp (&compare->info, &glyph->info, compare->size) == 0)) memcmp (glyph->sha1, sha1, 20) == 0))
{ {
break; break;
} }
@ -460,54 +465,42 @@ FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare)
return gr; return gr;
} }
CARD32 int
HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size) HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
unsigned char sha1[20])
{ {
CARD32 *bits; SHA_CTX ctx;
CARD32 hash; int success;
int n;
hash = 0; success = SHA1_Init (&ctx);
if (! success)
return BadAlloc;
bits = (CARD32 *) gi; success = SHA1_Update (&ctx, gi, sizeof (xGlyphInfo));
n = sizeof (xGlyphInfo) / sizeof (CARD32); if (! success)
while (n--) return BadAlloc;
hash ^= *bits++;
bits = (CARD32 *) data; success = SHA1_Update (&ctx, bits, size);
n = size / sizeof (CARD32); if (! success)
while (n--) return BadAlloc;
hash ^= *bits++;
return hash; success = SHA1_Final (sha1, &ctx);
} if (! success)
return BadAlloc;
CARD32 return Success;
HashGlyph (GlyphPtr glyph)
{
return HashGlyphInfoAndBits (&glyph->info,
(CARD8 *) (&glyph->info + 1),
glyph->size - sizeof (xGlyphInfo));
} }
GlyphPtr GlyphPtr
FindGlyphByHash (CARD32 hash, FindGlyphByHash (unsigned char sha1[20], int format)
xGlyphInfo *gi,
CARD8 *bits,
int format)
{ {
GlyphRefPtr gr; GlyphRefPtr gr;
GlyphPtr template; CARD32 signature = *(CARD32 *) sha1;
/* XXX: Should handle out-of-memory here */
template = AllocateGlyph (gi, format);
memcpy ((CARD8 *) (template + 1), bits,
template->size - sizeof (xGlyphInfo));
gr = FindGlyphRef (&globalGlyphs[format], gr = FindGlyphRef (&globalGlyphs[format],
hash, TRUE, template); signature, TRUE, sha1);
xfree (template);
if (gr->glyph && gr->glyph != DeletedGlyph) if (gr->glyph && gr->glyph != DeletedGlyph)
return gr->glyph; return gr->glyph;
@ -553,6 +546,7 @@ FreeGlyph (GlyphPtr glyph, int format)
GlyphRefPtr gr; GlyphRefPtr gr;
int i; int i;
int first; int first;
CARD32 signature;
first = -1; first = -1;
for (i = 0; i < globalGlyphs[format].hashSet->size; i++) for (i = 0; i < globalGlyphs[format].hashSet->size; i++)
@ -563,8 +557,9 @@ FreeGlyph (GlyphPtr glyph, int format)
first = i; first = i;
} }
gr = FindGlyphRef (&globalGlyphs[format], signature = *(CARD32 *) glyph->sha1;
HashGlyph (glyph), TRUE, glyph); gr = FindGlyphRef (&globalGlyphs[format], signature,
TRUE, glyph->sha1);
if (gr - globalGlyphs[format].table != first) if (gr - globalGlyphs[format].table != first)
DuplicateRef (glyph, "Found wrong one"); DuplicateRef (glyph, "Found wrong one");
if (gr->glyph && gr->glyph != DeletedGlyph) if (gr->glyph && gr->glyph != DeletedGlyph)
@ -591,12 +586,13 @@ void
AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
{ {
GlyphRefPtr gr; GlyphRefPtr gr;
CARD32 hash; CARD32 signature;
CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global"); CheckDuplicates (&globalGlyphs[glyphSet->fdepth], "AddGlyph top global");
/* Locate existing matching glyph */ /* Locate existing matching glyph */
hash = HashGlyph (glyph); signature = *(CARD32 *) glyph->sha1;
gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], signature,
TRUE, glyph->sha1);
if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph) if (gr->glyph && gr->glyph != DeletedGlyph && gr->glyph != glyph)
{ {
PictureScreenPtr ps; PictureScreenPtr ps;
@ -616,7 +612,7 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id)
else if (gr->glyph != glyph) else if (gr->glyph != glyph)
{ {
gr->glyph = glyph; gr->glyph = glyph;
gr->signature = hash; gr->signature = signature;
globalGlyphs[glyphSet->fdepth].tableEntries++; globalGlyphs[glyphSet->fdepth].tableEntries++;
} }
@ -753,7 +749,7 @@ ResizeGlyphHash (GlyphHashPtr hash, CARD32 change, Bool global)
if (glyph && glyph != DeletedGlyph) if (glyph && glyph != DeletedGlyph)
{ {
s = hash->table[i].signature; s = hash->table[i].signature;
gr = FindGlyphRef (&newHash, s, global, glyph); gr = FindGlyphRef (&newHash, s, global, glyph->sha1);
gr->signature = s; gr->signature = s;
gr->glyph = glyph; gr->glyph = glyph;
++newHash.tableEntries; ++newHash.tableEntries;

View File

@ -39,10 +39,11 @@
#define GlyphFormatNum 5 #define GlyphFormatNum 5
typedef struct _Glyph { typedef struct _Glyph {
CARD32 refcnt; CARD32 refcnt;
DevUnion *devPrivates; DevUnion *devPrivates;
CARD32 size; /* info + bitmap */ unsigned char sha1[20];
xGlyphInfo info; CARD32 size; /* info + bitmap */
xGlyphInfo info;
/* bits follow */ /* bits follow */
} GlyphRec, *GlyphPtr; } GlyphRec, *GlyphPtr;
@ -127,19 +128,19 @@ GlyphHashSetPtr
FindGlyphHashSet (CARD32 filled); FindGlyphHashSet (CARD32 filled);
GlyphRefPtr GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
unsigned char sha1[20]);
GlyphPtr GlyphPtr
FindGlyphByHash (CARD32 hash, FindGlyphByHash (unsigned char sha1[20], int format);
xGlyphInfo *gi,
CARD8 *bits,
int format);
CARD32 int
HashGlyphInfoAndBits (xGlyphInfo *gi, CARD8 *data, unsigned int size); HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
CARD32 unsigned long size,
HashGlyph (GlyphPtr glyph); unsigned char sha1[20]);
void void
FreeGlyph (GlyphPtr glyph, int format); FreeGlyph (GlyphPtr glyph, int format);

View File

@ -1080,10 +1080,10 @@ ProcRenderFreeGlyphSet (ClientPtr client)
} }
typedef struct _GlyphNew { typedef struct _GlyphNew {
Glyph id; Glyph id;
GlyphPtr glyph; GlyphPtr glyph;
Bool found; Bool found;
CARD32 hash; unsigned char sha1[20];
} GlyphNewRec, *GlyphNewPtr; } GlyphNewRec, *GlyphNewPtr;
static int static int
@ -1143,10 +1143,11 @@ ProcRenderAddGlyphs (ClientPtr client)
if (remain < size) if (remain < size)
break; break;
glyph_new->hash = HashGlyphInfoAndBits (&gi[i], bits, size); err = HashGlyph (&gi[i], bits, size, glyph_new->sha1);
if (err)
goto bail;
glyph_new->glyph = FindGlyphByHash (glyph_new->hash, glyph_new->glyph = FindGlyphByHash (glyph_new->sha1,
&gi[i], bits,
glyphSet->fdepth); glyphSet->fdepth);
if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph)
@ -1164,6 +1165,7 @@ ProcRenderAddGlyphs (ClientPtr client)
} }
memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size); memcpy ((CARD8 *) (glyph_new->glyph + 1), bits, size);
memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
} }
glyph_new->id = gids[i]; glyph_new->id = gids[i];