From 314d694855774eef907c65f8f304056dcc87de6a Mon Sep 17 00:00:00 2001 From: Julien Gouesse Date: Tue, 1 Feb 2011 04:12:57 +0100 Subject: Fixes the problem of high memory consumption in TextRenderer (single merged w/o whitespace) --- .../com/jogamp/opengl/util/awt/TextRenderer.java | 45 +++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java index f22e11cb7..1cc31ec11 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java @@ -1558,6 +1558,8 @@ public class TextRenderer { final int undefined = -2; FontRenderContext fontRenderContext; List/**/ glyphsOutput = new ArrayList/**/(); + HashMap/**/fullGlyphVectorCache = new HashMap/**/(); + HashMap/**/glyphMetricsCache = new HashMap/**/(); // The mapping from unicode character to font-specific glyph ID int[] unicodes2Glyphs; // The mapping from glyph ID to Glyph @@ -1573,8 +1575,13 @@ public class TextRenderer { public List/**/ getGlyphs(CharSequence inString) { glyphsOutput.clear(); - iter.initFromCharSequence(inString); - GlyphVector fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + GlyphVector fullRunGlyphVector; + fullRunGlyphVector = (GlyphVector) fullGlyphVectorCache.get(inString.toString()); + if (fullRunGlyphVector == null) { + iter.initFromCharSequence(inString); + fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter); + fullGlyphVectorCache.put(inString.toString(), fullRunGlyphVector); + } boolean complex = (fullRunGlyphVector.getLayoutFlags() != 0); if (complex || DISABLE_GLYPH_CACHE) { // Punt to the robust version of the renderer @@ -1585,7 +1592,13 @@ public class TextRenderer { int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs(); int i = 0; while (i < lengthInGlyphs) { - Glyph glyph = getGlyph(inString, fullRunGlyphVector, i); + Character letter = CharacterCache.valueOf(inString.charAt(i)); + GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter); + if (metrics == null) { + metrics = fullRunGlyphVector.getGlyphMetrics(i); + glyphMetricsCache.put(letter, metrics); + } + Glyph glyph = getGlyph(inString, metrics, i); if (glyph != null) { glyphsOutput.add(glyph); i++; @@ -1594,7 +1607,7 @@ public class TextRenderer { // the cache StringBuffer buf = new StringBuffer(); while (i < lengthInGlyphs && - getGlyph(inString, fullRunGlyphVector, i) == null) { + getGlyph(inString, fullRunGlyphVector.getGlyphMetrics(i), i) == null) { buf.append(inString.charAt(i++)); } glyphsOutput.add(new Glyph(buf.toString(), @@ -1645,7 +1658,7 @@ public class TextRenderer { // if the unicode or glyph ID would be out of bounds of the // glyph cache. private Glyph getGlyph(CharSequence inString, - GlyphVector fullRunGlyphVector, + GlyphMetrics glyphMetrics, int index) { char unicodeID = inString.charAt(index); @@ -1661,7 +1674,7 @@ public class TextRenderer { // Must fabricate the glyph singleUnicode[0] = unicodeID; GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode); - return getGlyph(unicodeID, gv, fullRunGlyphVector.getGlyphMetrics(index)); + return getGlyph(unicodeID, gv, glyphMetrics); } // It's unclear whether this variant might produce less @@ -1698,6 +1711,26 @@ public class TextRenderer { return glyph; } } + + private static class CharacterCache { + private CharacterCache() { + } + + static final Character cache[] = new Character[127 + 1]; + + static { + for (int i = 0; i < cache.length; i++) { + cache[i] = new Character((char) i); + } + } + + public static Character valueOf(char c) { + if (c <= 127) { // must cache + return CharacterCache.cache[c]; + } + return new Character(c); + } + } class Pipelined_QuadRenderer { int mOutstandingGlyphsVerticesPipeline = 0; -- cgit v1.2.3