summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas E. Dickey <dickey@invisible-island.net>2022-07-01 04:25:10 -0400
committerThomas E. Dickey <dickey@invisible-island.net>2022-07-06 04:27:42 -0400
commit114db90eac2c0f32f6b662d916a5af6a8990bf36 (patch)
tree7a9ee5c06c7b79101377b29f5a2f8ac75d8e80e2
parent442bbb084a1316aa6b25b29e17889bc71c1e4235 (diff)
downloadxorg-lib-libXft-114db90eac2c0f32f6b662d916a5af6a8990bf36.tar.gz
add option for tracking glyph memory-usage on a linked list
Signed-off-by: Thomas E. Dickey <dickey@invisible-island.net>
-rw-r--r--src/xftcore.c12
-rw-r--r--src/xftextent.c4
-rw-r--r--src/xftfreetype.c9
-rw-r--r--src/xftglyphs.c70
-rw-r--r--src/xftint.h4
-rw-r--r--src/xftrender.c12
6 files changed, 91 insertions, 20 deletions
diff --git a/src/xftcore.c b/src/xftcore.c
index 55c2c46..1c47270 100644
--- a/src/xftcore.c
+++ b/src/xftcore.c
@@ -1036,7 +1036,7 @@ XftGlyphCore (XftDraw *draw,
while (n--)
{
glyph = *g++;
- if (glyph >= (FT_UInt) font->num_glyphs || !(xftg = font->glyphs[glyph]))
+ if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
xftg = _XftGlyphDefault (dpy, public);
if (xftg)
{
@@ -1057,7 +1057,7 @@ XftGlyphCore (XftDraw *draw,
while (n--)
{
glyph = *g++;
- if (glyph >= (FT_UInt) font->num_glyphs || !(xftg = font->glyphs[glyph]))
+ if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
xftg = _XftGlyphDefault (dpy, public);
if (xftg)
{
@@ -1192,7 +1192,7 @@ XftGlyphSpecCore (XftDraw *draw,
for (i = 0; i < nglyphs; i++)
{
FT_UInt glyph = glyphs[i].glyph;
- if (glyph >= (FT_UInt) font->num_glyphs || !(xftg = font->glyphs[glyph]))
+ if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
xftg = _XftGlyphDefault (dpy, public);
if (xftg)
{
@@ -1212,7 +1212,7 @@ XftGlyphSpecCore (XftDraw *draw,
for (i = 0; i < nglyphs; i++)
{
FT_UInt glyph = glyphs[i].glyph;
- if (glyph >= (FT_UInt) font->num_glyphs || !(xftg = font->glyphs[glyph]))
+ if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
xftg = _XftGlyphDefault (dpy, public);
if (xftg)
(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
@@ -1357,7 +1357,7 @@ XftGlyphFontSpecCore (XftDraw *draw,
XftSmoothGlyph smooth = _XftSmoothGlyphFind (draw, public);
FT_UInt glyph = glyphs[i].glyph;
- if (glyph >= (FT_UInt) font->num_glyphs || !(xftg = font->glyphs[glyph]))
+ if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
xftg = _XftGlyphDefault (dpy, public);
if (xftg)
{
@@ -1380,7 +1380,7 @@ XftGlyphFontSpecCore (XftDraw *draw,
XftSharpGlyph sharp = _XftSharpGlyphFind (draw, public);
FT_UInt glyph = glyphs[i].glyph;
- if (glyph >= (FT_UInt) font->num_glyphs || !(xftg = font->glyphs[glyph]))
+ if (glyph >= font->num_glyphs || !(xftg = font->glyphs[glyph]))
xftg = _XftGlyphDefault (dpy, public);
if (xftg)
(*sharp) (draw, xftg, glyphs[i].x, glyphs[i].y);
diff --git a/src/xftextent.c b/src/xftextent.c
index 920edf1..20d52db 100644
--- a/src/xftextent.c
+++ b/src/xftextent.c
@@ -58,7 +58,7 @@ XftGlyphExtents (Display *dpy,
{
glyph = *g++;
n--;
- if (glyph < (FT_UInt) font->num_glyphs &&
+ if (glyph < font->num_glyphs &&
(xftg = font->glyphs[glyph]))
break;
}
@@ -82,7 +82,7 @@ XftGlyphExtents (Display *dpy,
while (n--)
{
glyph = *g++;
- if (glyph < (FT_UInt) font->num_glyphs && (xftg = font->glyphs[glyph]))
+ if (glyph < font->num_glyphs && (xftg = font->glyphs[glyph]))
{
left = x - xftg->metrics.x;
top = y - xftg->metrics.y;
diff --git a/src/xftfreetype.c b/src/xftfreetype.c
index 6a66442..fd0c483 100644
--- a/src/xftfreetype.c
+++ b/src/xftfreetype.c
@@ -779,7 +779,7 @@ XftFontOpenInfo (Display *dpy,
size_t alloc_size;
int ascent, descent, height;
int i;
- int num_glyphs;
+ FT_UInt num_glyphs;
if (!info)
return NULL;
@@ -878,7 +878,7 @@ XftFontOpenInfo (Display *dpy,
* Sometimes the glyphs are numbered 1..n, other times 0..n-1,
* accept either numbering scheme by making room in the table
*/
- num_glyphs = (int)face->num_glyphs + 1;
+ num_glyphs = (FT_UInt)face->num_glyphs + 1;
alloc_size = (sizeof (XftFontInt) +
(size_t)num_glyphs * sizeof (XftGlyph *) +
hash_value * sizeof (XftUcsHash));
@@ -980,6 +980,11 @@ XftFontOpenInfo (Display *dpy,
memset (font->glyphs, '\0', (size_t)num_glyphs * sizeof (XftGlyph *));
font->num_glyphs = num_glyphs;
/*
+ * Memory-usage tracking
+ */
+ font->newest = FT_UINT_MAX;
+ font->total_inuse = 0;
+ /*
* Unicode hash table information
*/
font->hash_table = (XftUcsHash *) (font->glyphs + font->num_glyphs);
diff --git a/src/xftglyphs.c b/src/xftglyphs.c
index 9d37644..de78918 100644
--- a/src/xftglyphs.c
+++ b/src/xftglyphs.c
@@ -39,7 +39,7 @@ _XftFontValidateMemory (Display *dpy _X_UNUSED, XftFont *public)
XftGlyph *xftg;
glyph_memory = 0;
- for (glyphindex = 0; glyphindex < (FT_UInt) font->num_glyphs; glyphindex++)
+ for (glyphindex = 0; glyphindex < font->num_glyphs; glyphindex++)
{
xftg = font->glyphs[glyphindex];
if (xftg)
@@ -714,6 +714,31 @@ XftFontLoadGlyphs (Display *dpy,
if (XftDebug() & XFT_DBG_CACHEV)
printf ("Caching glyph 0x%x size %ld\n", glyphindex,
xftg->glyph_memory);
+
+ if (font->track_mem_usage) {
+ XftGlyphUsage *xnew = (XftGlyphUsage *) xftg;
+
+ if (font->newest == FT_UINT_MAX) {
+ xnew->older = glyphindex;
+ xnew->newer = glyphindex;
+ } else {
+ XftGlyphUsage *xold;
+
+ xold = (XftGlyphUsage *) font->glyphs[font->newest];
+
+ xnew->older = font->newest;
+ xnew->newer = xold->newer;
+ xold->newer = glyphindex;
+ if (XftDebug() & XFT_DBG_CACHEV)
+ printf("alloc %p NEW %d.%d, OLD %d.%d\n", xnew,
+ xnew->older, xnew->newer,
+ xold->older, xold->newer);
+ }
+
+ font->newest = glyphindex;
+ font->total_inuse++;
+ // FIXME - validate
+ }
}
if (bufBitmap != bufLocal)
free (bufBitmap);
@@ -763,6 +788,38 @@ XftFontUnloadGlyphs (Display *dpy,
if (info)
info->glyph_memory -= xftg->glyph_memory;
}
+
+ if (font->track_mem_usage) {
+ XftGlyphUsage *xuse = (XftGlyphUsage *) xftg;
+ XftGlyphUsage *xtmp;
+
+ if (XftDebug() & XFT_DBG_CACHEV)
+ printf("free %p USE %d.%d\n", xuse, xuse->older, xuse->newer);
+
+ if (xuse->older != FT_UINT_MAX) {
+ xtmp = (XftGlyphUsage *) font->glyphs[xuse->older];
+ if (xtmp != NULL) {
+ /* update link around to oldest glyph */
+ xtmp->newer = xuse->newer;
+ }
+ if (font->newest == glyphindex)
+ font->newest = xuse->older;
+ }
+ if (xuse->newer != FT_UINT_MAX) {
+ xtmp = (XftGlyphUsage *) font->glyphs[xuse->newer];
+ if (xtmp != NULL) {
+ /* update link around to newest glyph */
+ xtmp->older = xuse->older;
+ }
+ }
+ if (font->total_inuse) {
+ font->total_inuse--;
+ } else {
+ fprintf (stderr, "Xft: glyph count error\n");
+ }
+ // FIXME - validate
+ }
+
free (xftg);
XftMemFree (XFT_MEM_GLYPH, font->sizeof_glyph);
font->glyphs[glyphindex] = NULL;
@@ -783,7 +840,7 @@ XftFontCheckGlyph (Display *dpy,
XftGlyph *xftg;
int n;
- if (glyph >= (FT_UInt) font->num_glyphs)
+ if (glyph >= font->num_glyphs)
return FcFalse;
xftg = font->glyphs[glyph];
if (!xftg || (need_bitmaps && !xftg->glyph_memory))
@@ -794,9 +851,16 @@ XftFontCheckGlyph (Display *dpy,
if (!xftg)
return FcFalse;
XftMemAlloc (XFT_MEM_GLYPH, font->sizeof_glyph);
+
xftg->bitmap = NULL;
xftg->glyph_memory = 0;
font->glyphs[glyph] = xftg;
+
+ if (font->track_mem_usage) {
+ XftGlyphUsage *xuse = (XftGlyphUsage *) xftg;
+ xuse->older = FT_UINT_MAX;
+ xuse->newer = FT_UINT_MAX;
+ }
}
n = *nmissing;
missing[n++] = glyph;
@@ -894,7 +958,7 @@ _XftFontUncacheGlyph (Display *dpy, XftFont *pub)
if (XftDebug() & XFT_DBG_CACHE)
_XftFontValidateMemory (dpy, pub);
- for (glyphindex = 0; glyphindex < (FT_UInt) font->num_glyphs; glyphindex++)
+ for (glyphindex = 0; glyphindex < font->num_glyphs; glyphindex++)
{
xftg = font->glyphs[glyphindex];
if (xftg)
diff --git a/src/xftint.h b/src/xftint.h
index 3687d6f..3304217 100644
--- a/src/xftint.h
+++ b/src/xftint.h
@@ -173,7 +173,7 @@ typedef struct _XftFontInt {
* This array follows the font in memory
*/
XftGlyph **glyphs;
- int num_glyphs; /* size of glyphs/bitmaps arrays */
+ FT_UInt num_glyphs; /* size of glyphs/bitmaps arrays */
/*
* Hash table to get from Unicode value to glyph ID
* This array follows the glyphs in memory
@@ -192,6 +192,8 @@ typedef struct _XftFontInt {
unsigned long glyph_memory;
unsigned long max_glyph_memory;
unsigned sizeof_glyph; /* sizeof(XftGlyph) or XftGlyphUsage */
+ FT_UInt newest; /* index, for tracking usage */
+ FT_UInt total_inuse; /* total, for verifying usage */
FcBool track_mem_usage; /* Use XftGlyphUsage */
FcBool use_free_glyphs; /* Use XRenderFreeGlyphs */
} XftFontInt;
diff --git a/src/xftrender.c b/src/xftrender.c
index 37bb499..dd605c3 100644
--- a/src/xftrender.c
+++ b/src/xftrender.c
@@ -233,7 +233,7 @@ XftGlyphSpecRender (Display *dpy,
{
g = glyphs[i].glyph;
/* Substitute default for non-existent glyphs */
- if (g >= (FT_UInt) font->num_glyphs || !font->glyphs[g])
+ if (g >= font->num_glyphs || !font->glyphs[g])
g = 0;
if (font->glyphs[g])
break;
@@ -247,7 +247,7 @@ XftGlyphSpecRender (Display *dpy,
{
g = glyphs[i].glyph;
/* Substitute default for non-existent glyphs */
- if (g >= (FT_UInt) font->num_glyphs || !font->glyphs[g])
+ if (g >= font->num_glyphs || !font->glyphs[g])
g = 0;
/*
* check to see if the glyph is placed where it would
@@ -285,7 +285,7 @@ XftGlyphSpecRender (Display *dpy,
{
g = glyphs[i].glyph;
/* Substitute default for non-existent glyphs */
- if (g >= (FT_UInt) font->num_glyphs || !font->glyphs[g])
+ if (g >= font->num_glyphs || !font->glyphs[g])
g = 0;
if ((glyph = font->glyphs[g]))
{
@@ -511,7 +511,7 @@ XftGlyphFontSpecRender (Display *dpy,
XftFontInt *font = (XftFontInt *) pub;
g = glyphs[i].glyph;
/* Substitute default for non-existent glyphs */
- if (g >= (FT_UInt) font->num_glyphs || !font->glyphs[g])
+ if (g >= font->num_glyphs || !font->glyphs[g])
g = 0;
if (font->glyphs[g])
{
@@ -532,7 +532,7 @@ XftGlyphFontSpecRender (Display *dpy,
XftFontInt *font = (XftFontInt *) pub;
g = glyphs[i].glyph;
/* Substitute default for non-existent glyphs */
- if (g >= (FT_UInt) font->num_glyphs || !font->glyphs[g])
+ if (g >= font->num_glyphs || !font->glyphs[g])
g = 0;
/*
* check to see if the glyph is placed where it would
@@ -577,7 +577,7 @@ XftGlyphFontSpecRender (Display *dpy,
g = glyphs[i].glyph;
/* Substitute default for non-existent glyphs */
- if (g >= (FT_UInt) font->num_glyphs || !font->glyphs[g])
+ if (g >= font->num_glyphs || !font->glyphs[g])
g = 0;
if ((glyph = font->glyphs[g]))
{