summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2006-01-03 22:06:23 +0000
committerEric Anholt <anholt@freebsd.org>2006-01-03 22:06:23 +0000
commit601ab861b46a62b0742ffd3e937c4fab129664f0 (patch)
treea3d9c641c83283e941302a9495d4d5234b493eed /render
parent1729fc882ceec392331566c95efd5968fe9e97fd (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')
-rw-r--r--render/glyph.c348
-rw-r--r--render/glyphstr.h23
-rw-r--r--render/miglyph.c13
-rw-r--r--render/mipict.c4
-rw-r--r--render/mipict.h8
-rw-r--r--render/picture.c3
-rw-r--r--render/picturestr.h17
7 files changed, 404 insertions, 12 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;
}
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 <X11/extensions/renderproto.h>
#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) { \