aboutsummaryrefslogtreecommitdiff
path: root/src/share/native/sun/font/AccelGlyphCache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/native/sun/font/AccelGlyphCache.c')
-rw-r--r--src/share/native/sun/font/AccelGlyphCache.c180
1 files changed, 167 insertions, 13 deletions
diff --git a/src/share/native/sun/font/AccelGlyphCache.c b/src/share/native/sun/font/AccelGlyphCache.c
index abd2d881a..73e94a91c 100644
--- a/src/share/native/sun/font/AccelGlyphCache.c
+++ b/src/share/native/sun/font/AccelGlyphCache.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,19 @@
* list describing the cache as new glyphs are added. Platform specific
* glyph caching code is responsible for actually creating the accelerated
* memory surface that will contain the individual glyph images.
+ *
+ * Each glyph contains a reference to a list of cell infos - one per glyph
+ * cache. There may be multiple glyph caches (for example, one per graphics
+ * adapter), so if the glyph is cached on two devices its cell list will
+ * consists of two elements corresponding to different glyph caches.
+ *
+ * The platform-specific glyph caching code is supposed to use
+ * GetCellInfoForCache method for retrieving cache infos from the glyph's list.
+ *
+ * Note that if it is guaranteed that there will be only one global glyph
+ * cache then it one does not have to use AccelGlyphCache_GetCellInfoForCache
+ * for retrieving cell info for the glyph, but instead just use the struct's
+ * field directly.
*/
GlyphCacheInfo *
AccelGlyphCache_Init(jint width, jint height,
@@ -86,8 +99,11 @@ AccelGlyphCache_Init(jint width, jint height,
* "virtual" glyph cache is available for the glyph image. Platform specific
* glyph caching code is responsible for actually caching the glyph image
* in the associated accelerated memory surface.
+ *
+ * Returns created cell info if it was successfully created and added to the
+ * cache and glyph's cell lists, NULL otherwise.
*/
-void
+CacheCellInfo *
AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
{
CacheCellInfo *cellinfo = NULL;
@@ -99,7 +115,7 @@ AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
if ((glyph->width > cache->cellWidth) ||
(glyph->height > cache->cellHeight))
{
- return;
+ return NULL;
}
if (!cache->isFull) {
@@ -126,9 +142,8 @@ AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
// create new CacheCellInfo
cellinfo = (CacheCellInfo *)malloc(sizeof(CacheCellInfo));
if (cellinfo == NULL) {
- glyph->cellInfo = NULL;
J2dTraceLn(J2D_TRACE_ERROR, "could not allocate CellInfo");
- return;
+ return NULL;
}
cellinfo->cacheInfo = cache;
@@ -136,6 +151,8 @@ AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
cellinfo->timesRendered = 0;
cellinfo->x = x;
cellinfo->y = y;
+ cellinfo->leftOff = 0;
+ cellinfo->rightOff = 0;
cellinfo->tx1 = (jfloat)cellinfo->x / cache->width;
cellinfo->ty1 = (jfloat)cellinfo->y / cache->height;
cellinfo->tx2 = cellinfo->tx1 + ((jfloat)w / cache->width);
@@ -152,6 +169,7 @@ AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
// add the new cell to the end of the list
cache->tail = cellinfo;
cellinfo->next = NULL;
+ cellinfo->nextGCI = NULL;
}
}
@@ -210,9 +228,9 @@ AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
cache->Flush();
}
- // if the cell is occupied, notify the base glyph that its
- // cached version is about to be kicked out
- cellinfo->glyphInfo->cellInfo = NULL;
+ // if the cell is occupied, notify the base glyph that the
+ // cached version for this cache is about to be kicked out
+ AccelGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
}
// update cellinfo with glyph's occupied region information
@@ -221,8 +239,9 @@ AccelGlyphCache_AddGlyph(GlyphCacheInfo *cache, GlyphInfo *glyph)
cellinfo->ty2 = cellinfo->ty1 + ((jfloat)h / cache->height);
}
- // update the glyph's reference to its cache cell
- glyph->cellInfo = cellinfo;
+ // add cache cell to the glyph's cells list
+ AccelGlyphCache_AddCellInfo(glyph, cellinfo);
+ return cellinfo;
}
/**
@@ -251,10 +270,145 @@ AccelGlyphCache_Invalidate(GlyphCacheInfo *cache)
while (cellinfo != NULL) {
if (cellinfo->glyphInfo != NULL) {
// if the cell is occupied, notify the base glyph that its
- // cached version is about to be invalidated
- cellinfo->glyphInfo->cellInfo = NULL;
- cellinfo->glyphInfo = NULL;
+ // cached version for this cache is about to be invalidated
+ AccelGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
}
cellinfo = cellinfo->next;
}
}
+
+/**
+ * Invalidates and frees all cells and the cache itself. The "cache" pointer
+ * becomes invalid after this function returns.
+ */
+void
+AccelGlyphCache_Free(GlyphCacheInfo *cache)
+{
+ CacheCellInfo *cellinfo;
+
+ J2dTraceLn(J2D_TRACE_INFO, "AccelGlyphCache_Free");
+
+ if (cache == NULL) {
+ return;
+ }
+
+ // flush any pending vertices that may be depending on the current
+ // glyph cache
+ if (cache->Flush != NULL) {
+ cache->Flush();
+ }
+
+ while (cache->head != NULL) {
+ cellinfo = cache->head;
+ if (cellinfo->glyphInfo != NULL) {
+ // if the cell is occupied, notify the base glyph that its
+ // cached version for this cache is about to be invalidated
+ AccelGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
+ }
+ cache->head = cellinfo->next;
+ free(cellinfo);
+ }
+ free(cache);
+}
+
+/**
+ * Add cell info to the head of the glyph's list of cached cells.
+ */
+void
+AccelGlyphCache_AddCellInfo(GlyphInfo *glyph, CacheCellInfo *cellInfo)
+{
+ // assert (glyph != NULL && cellInfo != NULL)
+ J2dTraceLn(J2D_TRACE_INFO, "AccelGlyphCache_AddCellInfo");
+ J2dTraceLn2(J2D_TRACE_VERBOSE, " glyph 0x%x: adding cell 0x%x to the list",
+ glyph, cellInfo);
+
+ cellInfo->glyphInfo = glyph;
+ cellInfo->nextGCI = glyph->cellInfo;
+ glyph->cellInfo = cellInfo;
+}
+
+/**
+ * Removes cell info from the glyph's list of cached cells.
+ */
+void
+AccelGlyphCache_RemoveCellInfo(GlyphInfo *glyph, CacheCellInfo *cellInfo)
+{
+ CacheCellInfo *currCellInfo = glyph->cellInfo;
+ CacheCellInfo *prevInfo = NULL;
+ // assert (glyph!= NULL && glyph->cellInfo != NULL && cellInfo != NULL)
+ J2dTraceLn(J2D_TRACE_INFO, "AccelGlyphCache_RemoveCellInfo");
+ do {
+ if (currCellInfo == cellInfo) {
+ J2dTraceLn2(J2D_TRACE_VERBOSE,
+ " glyph 0x%x: removing cell 0x%x from glyph's list",
+ glyph, currCellInfo);
+ if (prevInfo == NULL) { // it's the head, chop-chop
+ glyph->cellInfo = currCellInfo->nextGCI;
+ } else {
+ prevInfo->nextGCI = currCellInfo->nextGCI;
+ }
+ currCellInfo->glyphInfo = NULL;
+ currCellInfo->nextGCI = NULL;
+ return;
+ }
+ prevInfo = currCellInfo;
+ currCellInfo = currCellInfo->nextGCI;
+ } while (currCellInfo != NULL);
+ J2dTraceLn2(J2D_TRACE_WARNING, "AccelGlyphCache_RemoveCellInfo: "\
+ "no cell 0x%x in glyph 0x%x's cell list",
+ cellInfo, glyph);
+}
+
+/**
+ * Removes cell info from the glyph's list of cached cells.
+ */
+JNIEXPORT void
+AccelGlyphCache_RemoveAllCellInfos(GlyphInfo *glyph)
+{
+ CacheCellInfo *currCell, *prevCell;
+
+ J2dTraceLn(J2D_TRACE_INFO, "AccelGlyphCache_RemoveAllCellInfos");
+
+ if (glyph == NULL || glyph->cellInfo == NULL) {
+ return;
+ }
+
+ // invalidate all of this glyph's accelerated cache cells
+ currCell = glyph->cellInfo;
+ do {
+ currCell->glyphInfo = NULL;
+ prevCell = currCell;
+ currCell = currCell->nextGCI;
+ prevCell->nextGCI = NULL;
+ } while (currCell != NULL);
+
+ glyph->cellInfo = NULL;
+}
+
+/**
+ * Returns cell info associated with particular cache from the glyph's list of
+ * cached cells.
+ */
+CacheCellInfo *
+AccelGlyphCache_GetCellInfoForCache(GlyphInfo *glyph, GlyphCacheInfo *cache)
+{
+ // assert (glyph != NULL && cache != NULL)
+ J2dTraceLn(J2D_TRACE_VERBOSE2, "AccelGlyphCache_GetCellInfoForCache");
+
+ if (glyph->cellInfo != NULL) {
+ CacheCellInfo *cellInfo = glyph->cellInfo;
+ do {
+ if (cellInfo->cacheInfo == cache) {
+ J2dTraceLn3(J2D_TRACE_VERBOSE2,
+ " glyph 0x%x: found cell 0x%x for cache 0x%x",
+ glyph, cellInfo, cache);
+ return cellInfo;
+ }
+ cellInfo = cellInfo->nextGCI;
+ } while (cellInfo != NULL);
+ }
+ J2dTraceLn2(J2D_TRACE_VERBOSE2, " glyph 0x%x: no cell for cache 0x%x",
+ glyph, cache);
+ return NULL;
+}
+