[PATCH xserver 2/4] EXA: Hardcode glyph cache dimensions to allow more efficient code generation.
Michel Dänzer
michel at daenzer.net
Wed May 18 08:15:34 PDT 2011
From: Michel Dänzer <daenzer at vmware.com>
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
---
exa/exa_glyphs.c | 45 +++++++++++++++++++++------------------------
exa/exa_priv.h | 3 ---
2 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 5c46ec9..66e4abf 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -60,7 +60,10 @@
* max texture size of the driver; this may need to actually come from
* the driver.
*/
-#define CACHE_PICTURE_WIDTH 1024
+#define CACHE_COLUMNS (1024 / 32)
+
+#define CACHE_SIZE 256
+#define HASH_SIZE 557
/* Maximum number of glyphs we buffer on the stack before flushing
* rendering to the mask or destination surface.
@@ -101,12 +104,6 @@ exaGlyphsInit(ScreenPtr pScreen)
i++;
assert(i == EXA_NUM_GLYPH_CACHES);
-
- for (i = 0; i < EXA_NUM_GLYPH_CACHES; i++) {
- pExaScr->glyphCaches[i].columns = CACHE_PICTURE_WIDTH / pExaScr->glyphCaches[i].glyphWidth;
- pExaScr->glyphCaches[i].size = 256;
- pExaScr->glyphCaches[i].hashSize = 557;
- }
}
static void
@@ -178,13 +175,13 @@ exaRealizeGlyphCaches(ScreenPtr pScreen,
cache->yOffset = height;
- rows = (cache->size + cache->columns - 1) / cache->columns;
+ rows = (CACHE_SIZE + CACHE_COLUMNS - 1) / CACHE_COLUMNS;
height += rows * cache->glyphHeight;
}
/* Now allocate the pixmap and picture */
pPixmap = (*pScreen->CreatePixmap) (pScreen,
- CACHE_PICTURE_WIDTH,
+ CACHE_COLUMNS * 32,
height, depth, 0);
if (!pPixmap)
return FALSE;
@@ -209,17 +206,17 @@ exaRealizeGlyphCaches(ScreenPtr pScreen,
cache->picture = pPicture;
cache->picture->refcnt++;
- cache->hashEntries = malloc(sizeof(int) * cache->hashSize);
- cache->glyphs = malloc(sizeof(ExaCachedGlyphRec) * cache->size);
+ cache->hashEntries = malloc(sizeof(int) * HASH_SIZE);
+ cache->glyphs = malloc(sizeof(ExaCachedGlyphRec) * CACHE_SIZE);
cache->glyphCount = 0;
if (!cache->hashEntries || !cache->glyphs)
goto bail;
- for (j = 0; j < cache->hashSize; j++)
+ for (j = 0; j < HASH_SIZE; j++)
cache->hashEntries[j] = -1;
- cache->evictionPosition = rand() % cache->size;
+ cache->evictionPosition = rand() & (CACHE_SIZE - 1);
}
/* Each cache references the picture individually */
@@ -251,7 +248,7 @@ exaGlyphCacheHashLookup(ExaGlyphCachePtr cache,
{
int slot;
- slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
+ slot = (*(CARD32 *) pGlyph->sha1) % HASH_SIZE;
while (TRUE) { /* hash table can never be full */
int entryPos = cache->hashEntries[slot];
@@ -264,7 +261,7 @@ exaGlyphCacheHashLookup(ExaGlyphCachePtr cache,
slot--;
if (slot < 0)
- slot = cache->hashSize - 1;
+ slot = HASH_SIZE - 1;
}
}
@@ -277,7 +274,7 @@ exaGlyphCacheHashInsert(ExaGlyphCachePtr cache,
memcpy(cache->glyphs[pos].sha1, pGlyph->sha1, sizeof(pGlyph->sha1));
- slot = (*(CARD32 *) pGlyph->sha1) % cache->hashSize;
+ slot = (*(CARD32 *) pGlyph->sha1) % HASH_SIZE;
while (TRUE) { /* hash table can never be full */
if (cache->hashEntries[slot] == -1) {
@@ -287,7 +284,7 @@ exaGlyphCacheHashInsert(ExaGlyphCachePtr cache,
slot--;
if (slot < 0)
- slot = cache->hashSize - 1;
+ slot = HASH_SIZE - 1;
}
}
@@ -298,7 +295,7 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache,
int slot;
int emptiedSlot = -1;
- slot = (*(CARD32 *) cache->glyphs[pos].sha1) % cache->hashSize;
+ slot = (*(CARD32 *) cache->glyphs[pos].sha1) % HASH_SIZE;
while (TRUE) { /* hash table can never be full */
int entryPos = cache->hashEntries[slot];
@@ -326,7 +323,7 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache,
* (Knuth 6.4R)
*/
- int entrySlot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % cache->hashSize;
+ int entrySlot = (*(CARD32 *) cache->glyphs[entryPos].sha1) % HASH_SIZE;
if (!((entrySlot >= slot && entrySlot < emptiedSlot) ||
(emptiedSlot < slot && (entrySlot < emptiedSlot || entrySlot >= slot))))
@@ -339,12 +336,12 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache,
slot--;
if (slot < 0)
- slot = cache->hashSize - 1;
+ slot = HASH_SIZE - 1;
}
}
-#define CACHE_X(pos) (((pos) % cache->columns) * cache->glyphWidth)
-#define CACHE_Y(pos) (cache->yOffset + ((pos) / cache->columns) * cache->glyphHeight)
+#define CACHE_X(pos) (((pos) & (CACHE_COLUMNS - 1)) * cache->glyphWidth)
+#define CACHE_Y(pos) (cache->yOffset + ((pos) / CACHE_COLUMNS) * cache->glyphHeight)
/* The most efficient thing to way to upload the glyph to the screen
* is to use the UploadToScreen() driver hook; this allows us to
@@ -463,7 +460,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
x = CACHE_X(pos);
y = CACHE_Y(pos);
} else {
- if (cache->glyphCount < cache->size) {
+ if (cache->glyphCount < CACHE_SIZE) {
/* Space remaining; we fill from the start */
pos = cache->glyphCount;
x = CACHE_X(pos);
@@ -500,7 +497,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
exaGlyphCacheHashInsert(cache, pGlyph, pos);
/* And pick a new eviction position */
- cache->evictionPosition = rand() % cache->size;
+ cache->evictionPosition = rand() & (CACHE_SIZE - 1);
}
exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 70de4bd..faed327 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -115,8 +115,6 @@ typedef struct {
int glyphWidth;
int glyphHeight;
- int size; /* Size of cache; eventually this should be dynamically determined */
-
/* Hash table mapping from glyph sha1 to position in the glyph; we use
* open addressing with a hash table size determined based on size and large
* enough so that we always have a good amount of free space, so we can
@@ -124,7 +122,6 @@ typedef struct {
* here because it allows us to easily remove entries.)
*/
int *hashEntries;
- int hashSize;
ExaCachedGlyphPtr glyphs;
int glyphCount; /* Current number of glyphs */
--
1.7.5.1
More information about the xorg-devel
mailing list