From 601ab861b46a62b0742ffd3e937c4fab129664f0 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Tue, 3 Jan 2006 22:06:23 +0000 Subject: 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. --- render/glyph.c | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++-- render/glyphstr.h | 23 ++++ render/miglyph.c | 13 ++ render/mipict.c | 4 +- render/mipict.h | 8 ++ render/picture.c | 3 + render/picturestr.h | 17 +++ 7 files changed, 404 insertions(+), 12 deletions(-) (limited to 'render') 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; } diff --git a/render/glyphstr.h b/render/glyphstr.h index f4777a248..5f38bc9cf 100644 --- a/render/glyphstr.h +++ b/render/glyphstr.h @@ -29,6 +29,8 @@ #include #include "picture.h" #include "screenint.h" +#include "regionstr.h" +#include "miscstruct.h" #define GlyphFormat1 0 #define GlyphFormat4 1 @@ -39,6 +41,7 @@ typedef struct _Glyph { CARD32 refcnt; + DevUnion *devPrivates; CARD32 size; /* info + bitmap */ xGlyphInfo info; /* bits follow */ @@ -103,9 +106,29 @@ ResetGlyphSetPrivateIndex (void); Bool _GlyphSetSetNewPrivate (GlyphSetPtr glyphSet, int n, pointer ptr); +void +ResetGlyphPrivates (void); + +int +AllocateGlyphPrivateIndex (void); + +Bool +AllocateGlyphPrivate (ScreenPtr pScreen, + int index2, + unsigned amount); + Bool GlyphInit (ScreenPtr pScreen); +Bool +GlyphFinishInit (ScreenPtr pScreen); + +void +GlyphUninit (ScreenPtr pScreen); + +GlyphHashSetPtr +FindGlyphHashSet (CARD32 filled); + GlyphRefPtr FindGlyphRef (GlyphHashPtr hash, CARD32 signature, Bool match, GlyphPtr compare); diff --git a/render/miglyph.c b/render/miglyph.c index 237ec13a4..9880217a4 100644 --- a/render/miglyph.c +++ b/render/miglyph.c @@ -35,6 +35,19 @@ #include "picturestr.h" #include "mipict.h" +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ + return TRUE; +} + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph) +{ +} + void miGlyphExtents (int nlist, GlyphListPtr list, diff --git a/render/mipict.c b/render/mipict.c index 59707ea70..c7b6c6b25 100644 --- a/render/mipict.c +++ b/render/mipict.c @@ -1,4 +1,4 @@ -/* + /* * $XFree86: xc/programs/Xserver/render/mipict.c,v 1.15tsi Exp $ * * Copyright © 1999 Keith Packard @@ -629,6 +629,8 @@ miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) ps->UpdateIndexed = miUpdateIndexed; ps->ChangePictureTransform = miChangePictureTransform; ps->ChangePictureFilter = miChangePictureFilter; + ps->RealizeGlyph = miRealizeGlyph; + ps->UnrealizeGlyph = miUnrealizeGlyph; /* MI rendering routines */ ps->Composite = 0; /* requires DDX support */ diff --git a/render/mipict.h b/render/mipict.h index 0c2ed04d5..0d76aaf54 100644 --- a/render/mipict.h +++ b/render/mipict.h @@ -106,6 +106,14 @@ miComputeCompositeRegion (RegionPtr pRegion, Bool miPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats); +Bool +miRealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph); + +void +miUnrealizeGlyph (ScreenPtr pScreen, + GlyphPtr glyph); + void miGlyphExtents (int nlist, GlyphListPtr list, diff --git a/render/picture.c b/render/picture.c index f421c8fb5..3ce191345 100644 --- a/render/picture.c +++ b/render/picture.c @@ -136,6 +136,7 @@ PictureCloseScreen (int index, ScreenPtr pScreen) for (n = 0; n < ps->nformats; n++) if (ps->formats[n].type == PictTypeIndexed) (*ps->CloseIndexed) (pScreen, &ps->formats[n]); + GlyphUninit (pScreen); SetPictureScreen(pScreen, 0); if (ps->PicturePrivateSizes) xfree (ps->PicturePrivateSizes); @@ -493,6 +494,8 @@ PictureFinishInit (void) for (s = 0; s < screenInfo.numScreens; s++) { + if (!GlyphFinishInit (screenInfo.screens[s])) + return FALSE; if (!PictureInitIndexedFormats (screenInfo.screens[s])) return FALSE; (void) AnimCurInit (screenInfo.screens[s]); diff --git a/render/picturestr.h b/render/picturestr.h index ab6785c33..e81d769d5 100644 --- a/render/picturestr.h +++ b/render/picturestr.h @@ -306,6 +306,12 @@ typedef void (*AddTrianglesProcPtr) (PicturePtr pPicture, int ntri, xTriangle *tris); +typedef Bool (*RealizeGlyphProcPtr) (ScreenPtr pScreen, + GlyphPtr glyph); + +typedef void (*UnrealizeGlyphProcPtr) (ScreenPtr pScreen, + GlyphPtr glyph); + typedef struct _PictureScreen { int totalPictureSize; unsigned int *PicturePrivateSizes; @@ -358,6 +364,14 @@ typedef struct _PictureScreen { AddTrapsProcPtr AddTraps; + int totalGlyphPrivateSize; + unsigned int *glyphPrivateSizes; + int glyphPrivateLen; + int glyphPrivateOffset; + + RealizeGlyphProcPtr RealizeGlyph; + UnrealizeGlyphProcPtr UnrealizeGlyph; + } PictureScreenRec, *PictureScreenPtr; extern int PictureScreenPrivateIndex; @@ -372,6 +386,9 @@ extern RESTYPE GlyphSetType; #define GetPictureWindow(w) ((PicturePtr) ((w)->devPrivates[PictureWindowPrivateIndex].ptr)) #define SetPictureWindow(w,p) ((w)->devPrivates[PictureWindowPrivateIndex].ptr = (pointer) (p)) +#define GetGlyphPrivatesForScreen(glyph, s) \ + ((glyph)->devPrivates + (GetPictureScreen (s))->glyphPrivateOffset) + #define VERIFY_PICTURE(pPicture, pid, client, mode, err) {\ pPicture = SecurityLookupIDByType(client, pid, PictureType, mode);\ if (!pPicture) { \ -- cgit v1.2.3