From ee870fcc9b2c9c8e56e74f2ff32632e3231d1670 Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 28 Mar 2019 10:20:15 +0100 Subject: [PATCH 1/3] Bring back font caching. --- indra/llrender/llfontfreetype.cpp | 151 +++++++++++++++++++++++++----- indra/llrender/llfontfreetype.h | 18 ++++ 2 files changed, 146 insertions(+), 23 deletions(-) diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 34a2e33bd0..1e76c67a4c 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -49,6 +49,8 @@ #include "llfontbitmapcache.h" #include "llgl.h" +#include "llapr.h" + FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; LLFontManager *gFontManagerp = NULL; @@ -86,6 +88,7 @@ LLFontManager::LLFontManager() LLFontManager::~LLFontManager() { FT_Done_FreeType(gFTLibrary); + unloadAllFonts(); // FIRE-7570. Only load/mmap fonts once. Release everything here. } @@ -181,20 +184,37 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v } int error; -#ifdef LL_WINDOWS - error = ftOpenFace(filename, face_n); -#else - error = FT_New_Face( gFTLibrary, - filename.c_str(), - 0, - &mFTFace); -#endif + +// FIRE-7570. Only load/mmap fonts once. + +// #ifdef LL_WINDOWS +// error = ftOpenFace(filename, face_n); +// #else +// error = FT_New_Face( gFTLibrary, +// filename.c_str(), +// 0, +// &mFTFace); +//#endif + + FT_Open_Args openArgs; + memset( &openArgs, 0, sizeof( openArgs ) ); + openArgs.memory_base = gFontManagerp->loadFont( filename, openArgs.memory_size ); + + if( !openArgs.memory_base ) + return FALSE; + + openArgs.flags = FT_OPEN_MEMORY; + + error = FT_Open_Face( gFTLibrary, &openArgs, 0, &mFTFace ); +// if (error) { -#ifdef LL_WINDOWS - clearFontStreams(); -#endif +// FIRE-7570. Only load/mmap fonts once. +// #ifdef LL_WINDOWS +// clearFontStreams(); +// #endif +// return FALSE; } @@ -211,9 +231,11 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v { // Clean up freetype libs. FT_Done_Face(mFTFace); -#ifdef LL_WINDOWS - clearFontStreams(); -#endif +// FIRE-7570. Only load/mmap fonts once. +// #ifdef LL_WINDOWS +// clearFontStreams(); +// #endif +// mFTFace = NULL; return FALSE; } @@ -280,23 +302,43 @@ S32 LLFontFreetype::getNumFaces(const std::string& filename) S32 num_faces = 1; -#ifdef LL_WINDOWS - int error = ftOpenFace(filename, 0); - - if (error) - { +// FIRE-7570. Only load/mmap fonts once. + FT_Open_Args openArgs; + memset( &openArgs, 0, sizeof( openArgs ) ); + openArgs.memory_base = gFontManagerp->loadFont( filename, openArgs.memory_size ); + if( !openArgs.memory_base ) + return 0; + + openArgs.flags = FT_OPEN_MEMORY; + + int error = FT_Open_Face( gFTLibrary, &openArgs, 0, &mFTFace ); + if (error) return 0; - } else - { num_faces = mFTFace->num_faces; - } FT_Done_Face(mFTFace); clearFontStreams(); mFTFace = NULL; -#endif +// #ifdef LL_WINDOWS +// int error = ftOpenFace(filename, 0); +// +// if (error) +// { +// return 0; +// } +// else +// { +// num_faces = mFTFace->num_faces; +// } +// +// FT_Done_Face(mFTFace); +// clearFontStreams(); +// mFTFace = NULL; +// #endif + +// return num_faces; } @@ -771,3 +813,66 @@ void LLFontFreetype::setSubImageLuminanceAlpha(U32 x, U32 y, U32 bitmap_num, U32 } } +// FIRE-7570. Only load/mmap fonts once. + +namespace nd +{ + namespace fonts + { + class LoadedFont + { + public: + LoadedFont( std::string aName , std::vector const &aAddress, long aSize ) + : mAddress( aAddress ) + { + mName = aName; + mSize = aSize; + mRefs = 1; + } + + std::string mName; + std::vector mAddress; + long mSize; + U32 mRefs; + }; + } +} + +U8 const* LLFontManager::loadFont( std::string const &aFilename, long &a_Size) +{ + a_Size = 0; + + std::map< std::string, std::shared_ptr >::iterator itr = m_LoadedFonts.find( aFilename ); + if( itr != m_LoadedFonts.end() ) + { + ++itr->second->mRefs; + a_Size = itr->second->mSize; + return &itr->second->mAddress[0]; + } + + llstat oStat; + + if( 0 != LLFile::stat( aFilename, &oStat ) || 0 == oStat.st_size ) + return 0; + + a_Size = oStat.st_size; + std::vector< U8 > pBuffer; + pBuffer.resize( a_Size ); + + if( a_Size != LLAPRFile::readEx( aFilename, &pBuffer[0], 0, a_Size ) ) + { + a_Size = 0; + return nullptr; + } + + auto pCache = std::make_shared( aFilename, pBuffer, a_Size ); + itr = m_LoadedFonts.insert( std::make_pair( aFilename, pCache ) ).first; + return &itr->second->mAddress[ 0 ]; +} + +void LLFontManager::unloadAllFonts() +{ + m_LoadedFonts.clear(); +} +// + diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index 4c9f36c033..632fdac767 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -43,6 +43,16 @@ typedef struct FT_FaceRec_* LLFT_Face; struct FT_StreamRec_; typedef struct FT_StreamRec_ LLFT_Stream; +// FIRE-7570. Only load/mmap fonts once. +namespace nd +{ + namespace fonts + { + class LoadedFont; + } +} +// + class LLFontManager { public: @@ -52,6 +62,14 @@ public: private: LLFontManager(); ~LLFontManager(); +// FIRE-7570. Only load/mmap fonts once. +public: + U8 const *loadFont( std::string const &aFilename, long &a_Size ); + +private: + void unloadAllFonts(); + std::map< std::string, std::shared_ptr > m_LoadedFonts; +// }; struct LLFontGlyphInfo From 8b6f0ef3cd49c969c429b3166cf09090388ae847 Mon Sep 17 00:00:00 2001 From: Nicky Date: Thu, 28 Mar 2019 10:27:29 +0100 Subject: [PATCH 2/3] Remove clearFontStreams which was not supposed to be there. --- indra/llrender/llfontfreetype.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 1e76c67a4c..5244379cb8 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -318,7 +318,6 @@ S32 LLFontFreetype::getNumFaces(const std::string& filename) num_faces = mFTFace->num_faces; FT_Done_Face(mFTFace); - clearFontStreams(); mFTFace = NULL; // #ifdef LL_WINDOWS From 6a19b2195c4f518a1d9946fc6a66b3d48dd59abf Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Thu, 28 Mar 2019 15:07:58 +0000 Subject: [PATCH 3/3] Open requested font face --- indra/llrender/llfontfreetype.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 5244379cb8..7b5e09def1 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -205,7 +205,7 @@ BOOL LLFontFreetype::loadFace(const std::string& filename, F32 point_size, F32 v openArgs.flags = FT_OPEN_MEMORY; - error = FT_Open_Face( gFTLibrary, &openArgs, 0, &mFTFace ); + error = FT_Open_Face( gFTLibrary, &openArgs, face_n, &mFTFace ); // if (error)