[Libreoffice-commits] core.git: vcl/inc vcl/unx

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Sat Oct 6 18:13:48 UTC 2018


 vcl/inc/unx/glyphcache.hxx                     |   35 -----------
 vcl/unx/generic/gdi/cairotextrender.cxx        |    4 -
 vcl/unx/generic/glyphs/freetype_glyphcache.cxx |   19 ++++--
 vcl/unx/generic/glyphs/glyphcache.cxx          |   79 -------------------------
 vcl/unx/generic/print/genpspgraphics.cxx       |    3 
 5 files changed, 20 insertions(+), 120 deletions(-)

New commits:
commit dd36db168c658ebe588396255ad61363cc4ea7af
Author:     Jan-Marek Glogowski <glogow at fbihome.de>
AuthorDate: Thu Oct 4 13:25:06 2018 +0000
Commit:     Jan-Marek Glogowski <glogow at fbihome.de>
CommitDate: Sat Oct 6 20:13:28 2018 +0200

    UNX use font cache based glyph rect cache
    
    Drop the special / duplicate glyph rect bound cache implementation
    for Freetype fonts. The GlyphCache class now looks a lot like the
    ImplFontCache class.
    
    The lru handling for Freetype fonts is based on the byte / memory
    size, including the glyth bound-rect caching. Using the new common
    cache is effectivly removing the bound-rects from this accounting,
    so the garbage collection won't free them anymore.
    
    Change-Id: Ie53226596ee2287e1059a74885f52c3d64bbccaa
    Reviewed-on: https://gerrit.libreoffice.org/61377
    Tested-by: Jenkins
    Reviewed-by: Jan-Marek Glogowski <glogow at fbihome.de>

diff --git a/vcl/inc/unx/glyphcache.hxx b/vcl/inc/unx/glyphcache.hxx
index 446acc2944af..9fe3bd3dc7cf 100644
--- a/vcl/inc/unx/glyphcache.hxx
+++ b/vcl/inc/unx/glyphcache.hxx
@@ -41,7 +41,6 @@
 class FreetypeFont;
 class FreetypeFontInstance;
 class FreetypeFontInfo;
-class GlyphData;
 class FontConfigFontOptions;
 class PhysicalFontCollection;
 class FreetypeFont;
@@ -71,13 +70,6 @@ public:
     void                    ClearFontOptions();
 
 private:
-    friend class FreetypeFont;
-    // used by FreetypeFont class only
-    void                    AddedGlyph( GlyphData& );
-    void                    RemovingGlyph();
-    void                    UsingGlyph( GlyphData const & );
-
-private:
     void                    InitFreetype();
     void                    GarbageCollect();
     FreetypeFont*           CreateFont(LogicalFontInstance* pLogicalFont);
@@ -92,32 +84,12 @@ private:
     FontList                maFontList;
     static constexpr sal_uLong gnMaxSize = 1500000;  // max overall cache size in bytes
     mutable sal_uLong       mnBytesUsed;
-    mutable long            mnLruIndex;
-    mutable int             mnGlyphCount;
     FreetypeFont*           mpCurrentGCFont;
 
     FontInfoList            m_aFontInfoList;
     sal_IntPtr              m_nMaxFontId;
 };
 
-class GlyphData
-{
-public:
-                            GlyphData() : mnLruValue(0) {}
-
-    const tools::Rectangle&        GetBoundRect() const        { return maBoundRect; }
-    void                    SetBoundRect(tools::Rectangle r)   { maBoundRect = r; }
-
-    void                    SetLruValue( int n ) const  { mnLruValue = n; }
-    long                    GetLruValue() const         { return mnLruValue;}
-
-private:
-    tools::Rectangle               maBoundRect;
-
-    // used by GlyphCache for cache LRU algorithm
-    mutable long            mnLruValue;
-};
-
 class VCL_DLLPUBLIC FreetypeFont final
 {
 public:
@@ -139,7 +111,7 @@ public:
     const FontCharMapRef    GetFontCharMap() const;
     bool                    GetFontCapabilities(vcl::FontCapabilities &) const;
 
-    const tools::Rectangle&        GetGlyphBoundRect(const GlyphItem& rGlyph);
+    bool                    GetGlyphBoundRect(const GlyphItem&, tools::Rectangle&);
     bool                    GetGlyphOutline(const GlyphItem& rGlyph, basegfx::B2DPolyPolygon&) const;
     bool                    GetAntialiasAdvice() const;
 
@@ -156,15 +128,10 @@ private:
     long                    Release() const;
     sal_uLong               GetByteCount() const { return mnBytesUsed; }
 
-    void                    InitGlyphData(const GlyphItem&, GlyphData&) const;
-    void                    GarbageCollect( long );
     void                    ReleaseFromGarbageCollect();
 
     void                    ApplyGlyphTransform(bool bVertical, FT_Glyph) const;
 
-    typedef std::unordered_map<sal_GlyphId, GlyphData> GlyphList;
-    mutable GlyphList       maGlyphList;
-
     rtl::Reference<FreetypeFontInstance> mpFontInstance;
 
     // used by GlyphCache for cache LRU algorithm
diff --git a/vcl/unx/generic/gdi/cairotextrender.cxx b/vcl/unx/generic/gdi/cairotextrender.cxx
index 11d4e94592c4..40e1c5a8db3b 100644
--- a/vcl/unx/generic/gdi/cairotextrender.cxx
+++ b/vcl/unx/generic/gdi/cairotextrender.cxx
@@ -451,7 +451,9 @@ bool CairoTextRender::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangl
     if( !pSF )
         return false;
 
-    tools::Rectangle aRect = pSF->GetGlyphBoundRect(rGlyph);
+    tools::Rectangle aRect;
+    if (!pSF->GetGlyphBoundRect(rGlyph, aRect))
+        return false;
 
     if ( pSF->mnCos != 0x10000 && pSF->mnSin != 0 )
     {
diff --git a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
index cfc91deb07e0..8a5314ff697b 100644
--- a/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/freetype_glyphcache.cxx
@@ -347,8 +347,7 @@ rtl::Reference<LogicalFontInstance> FreetypeFontFace::CreateFontInstance(const F
 // FreetypeFont
 
 FreetypeFont::FreetypeFont(LogicalFontInstance* pFontInstance, FreetypeFontInfo* pFI )
-:   maGlyphList( 0),
-    mpFontInstance(static_cast<FreetypeFontInstance*>(pFontInstance)),
+:   mpFontInstance(static_cast<FreetypeFontInstance*>(pFontInstance)),
     mnRefCount(1),
     mnBytesUsed( sizeof(FreetypeFont) ),
     mpPrevGCFont( nullptr ),
@@ -589,14 +588,18 @@ void FreetypeFont::ApplyGlyphTransform(bool bVertical, FT_Glyph pGlyphFT ) const
     }
 }
 
-void FreetypeFont::InitGlyphData(const GlyphItem& rGlyph, GlyphData& rGD ) const
+bool FreetypeFont::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle& rRect)
 {
+    assert(mpFontInstance.is());
+    if (mpFontInstance.is() && mpFontInstance->GetCachedGlyphBoundRect(rGlyph.maGlyphId, rRect))
+        return true;
+
     FT_Activate_Size( maSizeFT );
 
     FT_Error rc = FT_Load_Glyph(maFaceFT, rGlyph.maGlyphId, mnLoadFlags);
 
     if (rc != FT_Err_Ok)
-        return;
+        return false;
 
     if (mbArtBold)
         FT_GlyphSlot_Embolden(maFaceFT->glyph);
@@ -604,16 +607,20 @@ void FreetypeFont::InitGlyphData(const GlyphItem& rGlyph, GlyphData& rGD ) const
     FT_Glyph pGlyphFT;
     rc = FT_Get_Glyph(maFaceFT->glyph, &pGlyphFT);
     if (rc != FT_Err_Ok)
-        return;
+        return false;
 
     ApplyGlyphTransform(rGlyph.IsVertical(), pGlyphFT);
 
     FT_BBox aBbox;
     FT_Glyph_Get_CBox( pGlyphFT, FT_GLYPH_BBOX_PIXELS, &aBbox );
 
-    rGD.SetBoundRect(tools::Rectangle(aBbox.xMin, -aBbox.yMax, aBbox.xMax, -aBbox.yMin));
+    rRect = tools::Rectangle(aBbox.xMin, -aBbox.yMax, aBbox.xMax, -aBbox.yMin);
+    if (mpFontInstance.is())
+        mpFontInstance->CacheGlyphBoundRect(rGlyph.maGlyphId, rRect);
 
     FT_Done_Glyph( pGlyphFT );
+
+    return true;
 }
 
 bool FreetypeFont::GetAntialiasAdvice() const
diff --git a/vcl/unx/generic/glyphs/glyphcache.cxx b/vcl/unx/generic/glyphs/glyphcache.cxx
index 5bdcf9ac7491..c4bf10ac76c0 100644
--- a/vcl/unx/generic/glyphs/glyphcache.cxx
+++ b/vcl/unx/generic/glyphs/glyphcache.cxx
@@ -33,8 +33,6 @@
 
 GlyphCache::GlyphCache()
 :   mnBytesUsed(sizeof(GlyphCache)),
-    mnLruIndex(0),
-    mnGlyphCount(0),
     mpCurrentGCFont(nullptr)
     , m_nMaxFontId(0)
 {
@@ -48,14 +46,6 @@ GlyphCache::~GlyphCache()
 
 void GlyphCache::ClearFontCache()
 {
-    for (auto& font : maFontList)
-    {
-        FreetypeFont* pFreetypeFont = font.second.get();
-        // free all pFreetypeFont related data
-        pFreetypeFont->GarbageCollect( mnLruIndex+0x10000000 );
-        font.second.reset();
-    }
-
     maFontList.clear();
     mpCurrentGCFont = nullptr;
     m_aFontInfoList.clear();
@@ -206,10 +196,7 @@ FreetypeFont* GlyphCache::CacheFont(LogicalFontInstance* pFontInstance)
 void GlyphCache::UncacheFont( FreetypeFont& rFreetypeFont )
 {
     if( (rFreetypeFont.Release() <= 0) && (gnMaxSize <= mnBytesUsed) )
-    {
         mpCurrentGCFont = &rFreetypeFont;
-        GarbageCollect();
-    }
 }
 
 void GlyphCache::GarbageCollect()
@@ -230,19 +217,13 @@ void GlyphCache::GarbageCollect()
     FreetypeFont* const pFreetypeFont = mpCurrentGCFont;
     mpCurrentGCFont = pFreetypeFont->mpNextGCFont;
 
-    if( (pFreetypeFont == mpCurrentGCFont)    // no other fonts
-    ||  (pFreetypeFont->GetRefCount() > 0) )  // font still used
-    {
-        // try to garbage collect at least a few bytes
-        pFreetypeFont->GarbageCollect( mnLruIndex - mnGlyphCount/2 );
-    }
-    else // current GC font is unreferenced
+    if( (pFreetypeFont != mpCurrentGCFont)    // no other fonts
+    &&  (pFreetypeFont->GetRefCount() <= 0) )  // font still used
     {
         SAL_WARN_IF( (pFreetypeFont->GetRefCount() != 0), "vcl",
             "GlyphCache::GC detected RefCount underflow" );
 
         // free all pFreetypeFont related data
-        pFreetypeFont->GarbageCollect( mnLruIndex+0x10000000 );
         if( pFreetypeFont == mpCurrentGCFont )
             mpCurrentGCFont = nullptr;
         mnBytesUsed -= pFreetypeFont->GetByteCount();
@@ -259,26 +240,6 @@ void GlyphCache::GarbageCollect()
     }
 }
 
-inline void GlyphCache::UsingGlyph( GlyphData const & rGlyphData )
-{
-    rGlyphData.SetLruValue( mnLruIndex++ );
-}
-
-inline void GlyphCache::AddedGlyph( GlyphData& rGlyphData )
-{
-    ++mnGlyphCount;
-    mnBytesUsed += sizeof( rGlyphData );
-    UsingGlyph( rGlyphData );
-    if( mnBytesUsed > gnMaxSize )
-        GarbageCollect();
-}
-
-inline void GlyphCache::RemovingGlyph()
-{
-    mnBytesUsed -= sizeof( GlyphData );
-    --mnGlyphCount;
-}
-
 void FreetypeFont::ReleaseFromGarbageCollect()
 {
     // remove from GC list
@@ -296,42 +257,6 @@ long FreetypeFont::Release() const
     return --mnRefCount;
 }
 
-const tools::Rectangle& FreetypeFont::GetGlyphBoundRect(const GlyphItem& rGlyph)
-{
-    // usually the GlyphData is cached
-    GlyphList::iterator it = maGlyphList.find(rGlyph.maGlyphId);
-    if( it != maGlyphList.end() ) {
-        GlyphData& rGlyphData = it->second;
-        GlyphCache::GetInstance().UsingGlyph( rGlyphData );
-        return rGlyphData.GetBoundRect();
-    }
-
-    // sometimes not => we need to create and initialize it ourselves
-    GlyphData& rGlyphData = maGlyphList[rGlyph.maGlyphId];
-    mnBytesUsed += sizeof( GlyphData );
-    InitGlyphData(rGlyph, rGlyphData);
-    GlyphCache::GetInstance().AddedGlyph( rGlyphData );
-    return rGlyphData.GetBoundRect();
-}
-
-void FreetypeFont::GarbageCollect( long nMinLruIndex )
-{
-    GlyphList::iterator it = maGlyphList.begin();
-    while( it != maGlyphList.end() )
-    {
-        GlyphData& rGD = it->second;
-        if( (nMinLruIndex - rGD.GetLruValue()) > 0 )
-        {
-            OSL_ASSERT( mnBytesUsed >= sizeof(GlyphData) );
-            mnBytesUsed -= sizeof( GlyphData );
-            GlyphCache::GetInstance().RemovingGlyph();
-            it = maGlyphList.erase( it );
-        }
-        else
-            ++it;
-    }
-}
-
 FreetypeFontInstance::FreetypeFontInstance(const PhysicalFontFace& rPFF, const FontSelectPattern& rFSP)
     : LogicalFontInstance(rPFF, rFSP)
     , mpFreetypeFont(nullptr)
diff --git a/vcl/unx/generic/print/genpspgraphics.cxx b/vcl/unx/generic/print/genpspgraphics.cxx
index 88e7fcdf901a..ae30cfad6286 100644
--- a/vcl/unx/generic/print/genpspgraphics.cxx
+++ b/vcl/unx/generic/print/genpspgraphics.cxx
@@ -742,8 +742,7 @@ bool GenPspGraphics::GetGlyphBoundRect(const GlyphItem& rGlyph, tools::Rectangle
     if( !pSF )
         return false;
 
-    rRect = pSF->GetGlyphBoundRect(rGlyph);
-    return true;
+    return pSF->GetGlyphBoundRect(rGlyph, rRect);
 }
 
 bool GenPspGraphics::GetGlyphOutline(const GlyphItem& rGlyph,


More information about the Libreoffice-commits mailing list