From bc654f8007769083bc42d818e97817ec9359dcb3 Mon Sep 17 00:00:00 2001 From: reuk Date: Wed, 28 Feb 2024 13:04:41 +0000 Subject: [PATCH] RenderingHelpers: Reduce templating of GlyphCache --- .../native/juce_RenderingHelpers.h | 162 +++++++++--------- .../opengl/juce_OpenGLGraphicsContext.cpp | 6 +- 2 files changed, 82 insertions(+), 86 deletions(-) diff --git a/modules/juce_graphics/native/juce_RenderingHelpers.h b/modules/juce_graphics/native/juce_RenderingHelpers.h index 2401c286f8..b6c86c493b 100644 --- a/modules/juce_graphics/native/juce_RenderingHelpers.h +++ b/modules/juce_graphics/native/juce_RenderingHelpers.h @@ -35,49 +35,6 @@ namespace juce::RenderingHelpers { -template -void drawGlyphImpl (Context& context, int glyphNumber, const AffineTransform& trans) -{ - using GlyphCacheType = typename Context::GlyphCacheType; - using EdgeTableRegionType = typename Context::EdgeTableRegionType; - - if (context.clip == nullptr) - return; - - if (trans.isOnlyTranslation() && ! context.transform.isRotated) - { - auto& cache = GlyphCacheType::getInstance(); - const Point pos (trans.getTranslationX(), trans.getTranslationY()); - - if (context.transform.isOnlyTranslated) - { - cache.drawGlyph (context, context.font, glyphNumber, pos + context.transform.offset.toFloat()); - } - else - { - auto f = context.font; - f.setHeight (f.getHeight() * context.transform.complexTransform.mat11); - - auto xScale = context.transform.complexTransform.mat00 / context.transform.complexTransform.mat11; - - if (std::abs (xScale - 1.0f) > 0.01f) - f.setHorizontalScale (xScale); - - cache.drawGlyph (context, f, glyphNumber, context.transform.transformed (pos)); - } - } - else - { - const auto fontHeight = context.font.getHeight(); - const auto fontTransform = AffineTransform::scale (fontHeight * context.font.getHorizontalScale(), - fontHeight).followedBy (trans); - const auto fullTransform = context.transform.getTransformWith (fontTransform); - - if (auto et = rawToUniquePtr (context.font.getTypefacePtr()->getEdgeTableForGlyph (glyphNumber, fullTransform, fontHeight))) - context.fillShape (*new EdgeTableRegionType (*et), false); - } -} - JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4127) //============================================================================== @@ -185,12 +142,48 @@ public: bool isOnlyTranslated = true, isRotated = false; }; +//============================================================================== +/** Caches a glyph as an edge-table. + + @tags{Graphics} +*/ +class CachedGlyphEdgeTable : public ReferenceCountedObject +{ +public: + CachedGlyphEdgeTable() = default; + + template + void draw (RendererType& state, Point pos) const + { + if (edgeTable != nullptr) + state.fillEdgeTable (*edgeTable, pos.x, roundToInt (pos.y)); + } + + void generate (const Font& newFont, int glyphNumber) + { + font = newFont; + glyph = glyphNumber; + + auto fontHeight = font.getHeight(); + auto typeface = newFont.getTypefacePtr(); + edgeTable.reset (typeface->getEdgeTableForGlyph (glyphNumber, + AffineTransform::scale (fontHeight * font.getHorizontalScale(), + fontHeight), + fontHeight)); + } + + Font font; + std::unique_ptr edgeTable; + int glyph = 0, lastAccessCount = 0; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable) +}; + //============================================================================== /** Holds a cache of recently-used glyph objects of some type. @tags{Graphics} */ -template class GlyphCache : private DeletedAtShutdown { public: @@ -224,6 +217,7 @@ public: misses = 0; } + template void drawGlyph (RenderTargetType& target, const Font& font, const int glyphNumber, Point pos) { if (auto glyph = findOrCreateGlyph (font, glyphNumber)) @@ -234,11 +228,11 @@ public: } private: - ReferenceCountedArray glyphs; + ReferenceCountedArray glyphs; Atomic accessCounter, hits, misses; CriticalSection lock; - ReferenceCountedObjectPtr findOrCreateGlyph (const Font& font, int glyphNumber) + ReferenceCountedObjectPtr findOrCreateGlyph (const Font& font, int glyphNumber) { const ScopedLock sl (lock); @@ -255,7 +249,7 @@ private: return g; } - ReferenceCountedObjectPtr findExistingGlyph (const Font& font, int glyphNumber) const noexcept + ReferenceCountedObjectPtr findExistingGlyph (const Font& font, int glyphNumber) const noexcept { for (auto g : glyphs) if (g->glyph == glyphNumber && g->font == font) @@ -264,7 +258,7 @@ private: return {}; } - ReferenceCountedObjectPtr getGlyphForReuse() + ReferenceCountedObjectPtr getGlyphForReuse() { if (hits.get() + misses.get() > glyphs.size() * 16) { @@ -287,12 +281,12 @@ private: glyphs.ensureStorageAllocated (glyphs.size() + num); while (--num >= 0) - glyphs.add (new CachedGlyphType()); + glyphs.add (new CachedGlyphEdgeTable()); } - CachedGlyphType* findLeastRecentlyUsedGlyph() const noexcept + CachedGlyphEdgeTable* findLeastRecentlyUsedGlyph() const noexcept { - CachedGlyphType* oldest = nullptr; + CachedGlyphEdgeTable* oldest = nullptr; auto oldestCounter = std::numeric_limits::max(); for (auto* g : glyphs) @@ -317,41 +311,47 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GlyphCache) }; -//============================================================================== -/** Caches a glyph as an edge-table. - - @tags{Graphics} -*/ -class CachedGlyphEdgeTable : public ReferenceCountedObject +template +void drawGlyphImpl (Context& context, int glyphNumber, const AffineTransform& trans) { -public: - CachedGlyphEdgeTable() = default; + using EdgeTableRegionType = typename Context::EdgeTableRegionType; - template - void draw (RendererType& state, Point pos) const + if (context.clip == nullptr) + return; + + if (trans.isOnlyTranslation() && ! context.transform.isRotated) { - if (edgeTable != nullptr) - state.fillEdgeTable (*edgeTable, pos.x, roundToInt (pos.y)); - } + auto& cache = RenderingHelpers::GlyphCache::getInstance(); + const Point pos (trans.getTranslationX(), trans.getTranslationY()); - void generate (const Font& newFont, int glyphNumber) + if (context.transform.isOnlyTranslated) + { + cache.drawGlyph (context, context.font, glyphNumber, pos + context.transform.offset.toFloat()); + } + else + { + auto f = context.font; + f.setHeight (f.getHeight() * context.transform.complexTransform.mat11); + + auto xScale = context.transform.complexTransform.mat00 / context.transform.complexTransform.mat11; + + if (std::abs (xScale - 1.0f) > 0.01f) + f.setHorizontalScale (xScale); + + cache.drawGlyph (context, f, glyphNumber, context.transform.transformed (pos)); + } + } + else { - font = newFont; - auto typeface = newFont.getTypefacePtr(); - glyph = glyphNumber; + const auto fontHeight = context.font.getHeight(); + const auto fontTransform = AffineTransform::scale (fontHeight * context.font.getHorizontalScale(), + fontHeight).followedBy (trans); + const auto fullTransform = context.transform.getTransformWith (fontTransform); - auto fontHeight = font.getHeight(); - edgeTable.reset (typeface->getEdgeTableForGlyph (glyphNumber, - AffineTransform::scale (fontHeight * font.getHorizontalScale(), - fontHeight), fontHeight)); + if (auto et = rawToUniquePtr (context.font.getTypefacePtr()->getEdgeTableForGlyph (glyphNumber, fullTransform, fontHeight))) + context.fillShape (*new EdgeTableRegionType (*et), false); } - - Font font; - std::unique_ptr edgeTable; - int glyph = 0, lastAccessCount = 0; - - JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CachedGlyphEdgeTable) -}; +} //============================================================================== /** Calculates the alpha values and positions for rendering the edges of a @@ -2570,11 +2570,9 @@ public: } } - using GlyphCacheType = GlyphCache; - static void clearGlyphCache() { - GlyphCacheType::getInstance().reset(); + GlyphCache::getInstance().reset(); } //============================================================================== diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 6180233673..6a49ee42c5 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -1753,15 +1753,13 @@ struct SavedState final : public RenderingHelpers::SavedStateBase } } - using GlyphCacheType = RenderingHelpers::GlyphCache, SavedState>; - void drawGlyph (int glyphNumber, const AffineTransform& trans) { if (clip != nullptr) { if (trans.isOnlyTranslation() && ! transform.isRotated) { - auto& cache = GlyphCacheType::getInstance(); + auto& cache = RenderingHelpers::GlyphCache::getInstance(); Point pos (trans.getTranslationX(), trans.getTranslationY()); if (transform.isOnlyTranslated) @@ -1937,7 +1935,7 @@ private: static void clearOpenGLGlyphCacheCallback() { - SavedState::GlyphCacheType::getInstance().reset(); + RenderingHelpers::GlyphCache::getInstance().reset(); } static std::unique_ptr createOpenGLContext (const Target& target)