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.
This commit is contained in:
Eric Anholt 2006-01-03 22:06:23 +00:00
parent 1729fc882c
commit 601ab861b4
8 changed files with 421 additions and 12 deletions

View File

@ -1,3 +1,20 @@
2006-01-03 Eric Anholt <anholt@FreeBSD.org>
* render/glyph.c: (ResetGlyphPrivates),
(AllocateGlyphPrivateIndex), (AllocateGlyphPrivate),
(SetGlyphScreenPrivateOffsets), (SetGlyphPrivatePointers),
(ReallocGlobalGlyphPrivate), (GlyphInit), (GlyphFinishInit),
(GlyphUninit), (FreeGlyph), (AddGlyph), (AllocateGlyph):
* render/glyphstr.h:
* render/miglyph.c: (miRealizeGlyph), (miUnrealizeGlyph):
* render/mipict.c: (miPictureInit):
* render/mipict.h:
* render/picture.c: (PictureCloseScreen), (PictureFinishInit):
* render/picturestr.h:
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.
2005-12-31 Eric Anholt <anholt@FreeBSD.org>
* hw/xgl/glx/xglx.c: (xglxWindowExposures):

View File

@ -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;
}

View File

@ -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);

View File

@ -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,

View File

@ -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 */

View File

@ -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,

View File

@ -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]);

View File

@ -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) { \