[PATCH 03/13] render: Reshuffle and resize GlyphRec
Adam Jackson
ajax at redhat.com
Tue Nov 23 11:45:38 PST 2010
Remove the rarely-used size field, move its computation to the users.
Move the sha1 hash to the front of the structure to eliminate an offset
computation per glyph lookup. Shrink the hash itself to 16 bytes. This
does raise the collision probability from 1 in 2^160 to 1 in 2^128, but
that's still quite rare enough. More importantly it gets us down to
nicely aligned sizes for hash matching - one instruction if you have
oword compares! - and makes sure that the Picture pointers after the
GlyphRec are qword-aligned on LP64.
GlyphRec ILP32 LP64
before 44 56
after 36 40
Signed-off-by: Adam Jackson <ajax at redhat.com>
---
exa/exa_priv.h | 2 +-
hw/dmx/dmxextension.c | 9 ++++++---
render/glyph.c | 13 +++++++------
render/glyphstr.h | 13 ++++++-------
render/render.c | 4 ++--
5 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index e5d90d4..8b3a4c5 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -106,7 +106,7 @@ enum ExaMigrationHeuristic {
};
typedef struct {
- unsigned char sha1[20];
+ unsigned char sha1[16];
} ExaCachedGlyphRec, *ExaCachedGlyphPtr;
typedef struct {
diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c
index 0092835..4497b15 100644
--- a/hw/dmx/dmxextension.c
+++ b/hw/dmx/dmxextension.c
@@ -1092,6 +1092,9 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
int len_images = 0;
int i;
int ctr;
+ int glyph_size = sizeof(GlyphRec)
+ + screenInfo.numScreens * sizeof (PicturePtr)
+ + dixPrivatesSize(PRIVATE_GLYPH);
if (glyphPriv->glyphSets[scrnNum]) {
/* Only restore glyphs on the screen we are attaching */
@@ -1114,7 +1117,7 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
GlyphPtr gl = gr->glyph;
if (!gl || gl == DeletedGlyph) continue;
- len_images += gl->size - sizeof(gl->info);
+ len_images += glyph_size - sizeof(gl->info);
}
/* Now allocate the memory we need */
@@ -1144,8 +1147,8 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
glyphs[ctr].yOff = gl->info.yOff;
/* Copy the images from the DIX's data into the buffer */
- memcpy(pos, gl+1, gl->size - sizeof(gl->info));
- pos += gl->size - sizeof(gl->info);
+ memcpy(pos, gl+1, glyph_size - sizeof(gl->info));
+ pos += glyph_size - sizeof(gl->info);
ctr++;
}
diff --git a/render/glyph.c b/render/glyph.c
index 7193d47..4556046 100644
--- a/render/glyph.c
+++ b/render/glyph.c
@@ -128,7 +128,7 @@ GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
- unsigned char sha1[20])
+ unsigned char sha1[16])
{
CARD32 elt, step, s;
GlyphPtr glyph;
@@ -159,7 +159,7 @@ FindGlyphRef (GlyphHashPtr hash,
}
else if (s == signature &&
(!match ||
- memcmp (glyph->sha1, sha1, 20) == 0))
+ memcmp (glyph->sha1, sha1, 16) == 0))
{
break;
}
@@ -180,10 +180,11 @@ int
HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
- unsigned char sha1[20])
+ unsigned char sha1[16])
{
void *ctx = x_sha1_init();
int success;
+ unsigned char digest[20];
if (!ctx)
return BadAlloc;
@@ -194,14 +195,15 @@ HashGlyph (xGlyphInfo *gi,
success = x_sha1_update(ctx, bits, size);
if (!success)
return BadAlloc;
- success = x_sha1_final(ctx, sha1);
+ success = x_sha1_final(ctx, digest);
if (!success)
return BadAlloc;
+ memcpy(sha1, digest, 16);
return Success;
}
GlyphPtr
-FindGlyphByHash (unsigned char sha1[20], int format)
+FindGlyphByHash (unsigned char sha1[16], int format)
{
GlyphRefPtr gr;
CARD32 signature = *(CARD32 *) sha1;
@@ -383,7 +385,6 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth)
if (!glyph)
return 0;
glyph->refcnt = 0;
- glyph->size = size + sizeof (xGlyphInfo);
glyph->info = *gi;
dixInitPrivates(glyph, (char *) glyph + head_size, PRIVATE_GLYPH);
diff --git a/render/glyphstr.h b/render/glyphstr.h
index 6c1a837..fb66b61 100644
--- a/render/glyphstr.h
+++ b/render/glyphstr.h
@@ -40,11 +40,10 @@
#define GlyphFormatNum 5
typedef struct _Glyph {
- CARD32 refcnt;
- PrivateRec *devPrivates;
- unsigned char sha1[20];
- CARD32 size; /* info + bitmap */
+ unsigned char sha1[16];
+ PrivateRec *devPrivates;
xGlyphInfo info;
+ CARD32 refcnt;
/* per-screen pixmaps follow */
} GlyphRec, *GlyphPtr;
@@ -104,16 +103,16 @@ extern _X_EXPORT GlyphRefPtr
FindGlyphRef (GlyphHashPtr hash,
CARD32 signature,
Bool match,
- unsigned char sha1[20]);
+ unsigned char sha1[16]);
extern _X_EXPORT GlyphPtr
-FindGlyphByHash (unsigned char sha1[20], int format);
+FindGlyphByHash (unsigned char sha1[16], int format);
extern _X_EXPORT int
HashGlyph (xGlyphInfo *gi,
CARD8 *bits,
unsigned long size,
- unsigned char sha1[20]);
+ unsigned char sha1[16]);
extern _X_EXPORT void
FreeGlyph (GlyphPtr glyph, int format);
diff --git a/render/render.c b/render/render.c
index 00241f9..ea059eb 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1019,7 +1019,7 @@ typedef struct _GlyphNew {
Glyph id;
GlyphPtr glyph;
Bool found;
- unsigned char sha1[20];
+ unsigned char sha1[16];
} GlyphNewRec, *GlyphNewPtr;
#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
@@ -1197,7 +1197,7 @@ ProcRenderAddGlyphs (ClientPtr client)
pSrcPix = NULL;
}
- memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20);
+ memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 16);
}
glyph_new->id = gids[i];
--
1.7.3.1
More information about the xorg-devel
mailing list