diff options
author | Eric Anholt <anholt@freebsd.org> | 2006-01-03 22:06:23 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2006-01-03 22:06:23 +0000 |
commit | 601ab861b46a62b0742ffd3e937c4fab129664f0 (patch) | |
tree | a3d9c641c83283e941302a9495d4d5234b493eed /render/glyph.c | |
parent | 1729fc882ceec392331566c95efd5968fe9e97fd (diff) |
Add glyph privates for Xgl, which uses them to implement a glyph cache. EXA
would probably also like to do this. This breaks module ABI for EXA and
XAA, and likely breaks proprietary drivers as well.
Diffstat (limited to 'render/glyph.c')
-rw-r--r-- | render/glyph.c | 348 |
1 files changed, 337 insertions, 11 deletions
diff --git a/render/glyph.c b/render/glyph.c index 45c5dd975..fd9bae3ac 100644 --- a/render/glyph.c +++ b/render/glyph.c @@ -82,6 +82,281 @@ const CARD8 glyphDepths[GlyphFormatNum] = { 1, 4, 8, 16, 32 }; GlyphHashRec globalGlyphs[GlyphFormatNum]; +int globalTotalGlyphPrivateSize = 0; + +static int glyphPrivateCount = 0; + +void +ResetGlyphPrivates () +{ + glyphPrivateCount = 0; +} + +int +AllocateGlyphPrivateIndex () +{ + return glyphPrivateCount++; +} + +Bool +AllocateGlyphPrivate (ScreenPtr pScreen, + int index2, + unsigned amount) +{ + PictureScreenPtr ps; + unsigned oldamount; + + ps = GetPictureScreenIfSet (pScreen); + if (!ps) + return FALSE; + + /* Round up sizes for proper alignment */ + amount = ((amount + (sizeof (DevUnion) - 1)) / sizeof (DevUnion)) * + sizeof (DevUnion); + + if (index2 >= ps->glyphPrivateLen) + { + unsigned *nsizes; + nsizes = (unsigned *) xrealloc (ps->glyphPrivateSizes, + (index2 + 1) * sizeof (unsigned)); + if (!nsizes) + return FALSE; + + while (ps->glyphPrivateLen <= index2) + { + nsizes[ps->glyphPrivateLen++] = 0; + ps->totalGlyphPrivateSize += sizeof (DevUnion); + } + ps->glyphPrivateSizes = nsizes; + } + oldamount = ps->glyphPrivateSizes[index2]; + if (amount > oldamount) + { + ps->glyphPrivateSizes[index2] = amount; + ps->totalGlyphPrivateSize += (amount - oldamount); + } + ps->totalGlyphPrivateSize = BitmapBytePad (ps->totalGlyphPrivateSize * 8); + + return TRUE; +} + +static void +SetGlyphScreenPrivateOffsets (void) +{ + PictureScreenPtr ps; + int offset = 0; + int i; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps && ps->totalGlyphPrivateSize) + { + ps->glyphPrivateOffset = offset; + offset += ps->totalGlyphPrivateSize / sizeof (DevUnion); + } + } +} + +static void +SetGlyphPrivatePointers (GlyphPtr glyph) +{ + PictureScreenPtr ps; + int i; + char *ptr; + DevUnion *ppriv; + unsigned *sizes; + unsigned size; + int len; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps && ps->totalGlyphPrivateSize) + { + ppriv = glyph->devPrivates + ps->glyphPrivateOffset; + sizes = ps->glyphPrivateSizes; + ptr = (char *) (ppriv + ps->glyphPrivateLen); + for (len = ps->glyphPrivateLen; --len >= 0; ppriv++, sizes++) + { + if ((size = *sizes) != 0) + { + ppriv->ptr = (pointer) ptr; + ptr += size; + } + else + ppriv->ptr = (pointer) 0; + } + } + } +} + +static Bool +ReallocGlobalGlyphPrivate (GlyphPtr glyph) +{ + PictureScreenPtr ps; + DevUnion *devPrivates; + char *ptr; + int i; + + devPrivates = xalloc (globalTotalGlyphPrivateSize); + if (!devPrivates) + return FALSE; + + ptr = (char *) devPrivates; + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps && ps->totalGlyphPrivateSize) + { + if (ps->glyphPrivateOffset != -1) + { + memcpy (ptr, glyph->devPrivates + ps->glyphPrivateOffset, + ps->totalGlyphPrivateSize); + } + else if (ps->totalGlyphPrivateSize) + { + memset (ptr, 0, ps->totalGlyphPrivateSize); + } + + ptr += ps->totalGlyphPrivateSize; + } + } + + if (glyph->devPrivates) + xfree (glyph->devPrivates); + + glyph->devPrivates = devPrivates; + + return TRUE; +} + +Bool +GlyphInit (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen (pScreen); + + ps->totalGlyphPrivateSize = 0; + ps->glyphPrivateSizes = 0; + ps->glyphPrivateLen = 0; + ps->glyphPrivateOffset = -1; + + return TRUE; +} + +Bool +GlyphFinishInit (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen (pScreen); + + if (ps->totalGlyphPrivateSize) + { + GlyphPtr glyph; + int fdepth, i; + + globalTotalGlyphPrivateSize += ps->totalGlyphPrivateSize; + + for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) + { + if (!globalGlyphs[fdepth].hashSet) + continue; + + for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) + { + glyph = globalGlyphs[fdepth].table[i].glyph; + if (glyph && glyph != DeletedGlyph) + { + if (!ReallocGlobalGlyphPrivate (glyph)) + return FALSE; + } + } + } + + SetGlyphScreenPrivateOffsets (); + + for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) + { + if (!globalGlyphs[fdepth].hashSet) + continue; + + for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) + { + glyph = globalGlyphs[fdepth].table[i].glyph; + if (glyph && glyph != DeletedGlyph) + { + SetGlyphPrivatePointers (glyph); + + if (!(*ps->RealizeGlyph) (pScreen, glyph)) + return FALSE; + } + } + } + } + else + ps->glyphPrivateOffset = 0; + + return TRUE; +} + +void +GlyphUninit (ScreenPtr pScreen) +{ + PictureScreenPtr ps = GetPictureScreen (pScreen); + GlyphPtr glyph; + int fdepth, i; + + globalTotalGlyphPrivateSize -= ps->totalGlyphPrivateSize; + + for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) + { + if (!globalGlyphs[fdepth].hashSet) + continue; + + for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) + { + glyph = globalGlyphs[fdepth].table[i].glyph; + if (glyph && glyph != DeletedGlyph) + { + (*ps->UnrealizeGlyph) (pScreen, glyph); + + if (globalTotalGlyphPrivateSize) + { + if (!ReallocGlobalGlyphPrivate (glyph)) + return; + } + else + { + if (glyph->devPrivates) + xfree (glyph->devPrivates); + glyph->devPrivates = NULL; + } + } + } + } + + if (globalTotalGlyphPrivateSize) + SetGlyphScreenPrivateOffsets (); + + for (fdepth = 0; fdepth < GlyphFormatNum; fdepth++) + { + if (!globalGlyphs[fdepth].hashSet) + continue; + + for (i = 0; i < globalGlyphs[fdepth].hashSet->size; i++) + { + glyph = globalGlyphs[fdepth].table[i].glyph; + if (glyph && glyph != DeletedGlyph) + { + if (globalTotalGlyphPrivateSize) + SetGlyphPrivatePointers (glyph); + } + } + } + + if (ps->glyphPrivateSizes) + xfree (ps->glyphPrivateSizes); +} + GlyphHashSetPtr FindGlyphHashSet (CARD32 filled) { @@ -137,12 +412,6 @@ _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr) return TRUE; } -Bool -GlyphInit (ScreenPtr pScreen) -{ - return TRUE; -} - GlyphRefPtr FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare) { @@ -239,9 +508,10 @@ FreeGlyph (GlyphPtr glyph, int format) CheckDuplicates (&globalGlyphs[format], "FreeGlyph"); if (--glyph->refcnt == 0) { - GlyphRefPtr gr; - int i; - int first; + PictureScreenPtr ps; + GlyphRefPtr gr; + int i; + int first; first = -1; for (i = 0; i < globalGlyphs[format].hashSet->size; i++) @@ -262,6 +532,16 @@ FreeGlyph (GlyphPtr glyph, int format) gr->signature = 0; globalGlyphs[format].tableEntries--; } + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + if (glyph->devPrivates) + xfree (glyph->devPrivates); xfree (glyph); } } @@ -278,6 +558,17 @@ AddGlyph (GlyphSetPtr glyphSet, GlyphPtr glyph, Glyph id) gr = FindGlyphRef (&globalGlyphs[glyphSet->fdepth], hash, TRUE, glyph); if (gr->glyph && gr->glyph != DeletedGlyph) { + PictureScreenPtr ps; + int i; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + if (glyph->devPrivates) + xfree (glyph->devPrivates); xfree (glyph); glyph = gr->glyph; } @@ -332,8 +623,10 @@ FindGlyph (GlyphSetPtr glyphSet, Glyph id) GlyphPtr AllocateGlyph (xGlyphInfo *gi, int fdepth) { - int size; - GlyphPtr glyph; + PictureScreenPtr ps; + int size; + GlyphPtr glyph; + int i; size = gi->height * PixmapBytePad (gi->width, glyphDepths[fdepth]); glyph = (GlyphPtr) xalloc (size + sizeof (GlyphRec)); @@ -342,6 +635,39 @@ AllocateGlyph (xGlyphInfo *gi, int fdepth) glyph->refcnt = 0; glyph->size = size + sizeof (xGlyphInfo); glyph->info = *gi; + + if (globalTotalGlyphPrivateSize) + { + glyph->devPrivates = xalloc (globalTotalGlyphPrivateSize); + if (!glyph->devPrivates) + return 0; + + SetGlyphPrivatePointers (glyph); + } else + glyph->devPrivates = NULL; + + for (i = 0; i < screenInfo.numScreens; i++) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + { + if (!(*ps->RealizeGlyph) (screenInfo.screens[i], glyph)) + { + while (i--) + { + ps = GetPictureScreenIfSet (screenInfo.screens[i]); + if (ps) + (*ps->UnrealizeGlyph) (screenInfo.screens[i], glyph); + } + + if (glyph->devPrivates) + xfree (glyph->devPrivates); + xfree (glyph); + return 0; + } + } + } + return glyph; } |