[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