diff options
Diffstat (limited to 'src/share/native/sun/font/AccelGlyphCache.c')
-rw-r--r-- | src/share/native/sun/font/AccelGlyphCache.c | 180 |
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; +} + |