Open blake-r opened 13 years ago
Hi.
There are two issues in cache realization in FTSimpleLayout:
My patch to fix this:
From f33041e830d791cfaee2ef5847584429965efea8 Mon Sep 17 00:00:00 2001 From: Oleg aka Blake-R <blake-r@mail.ru> Date: Thu, 25 Aug 2011 09:09:13 +0400 Subject: [PATCH] Fix cache store and it's invalidation on change layout parameters. --- ftgles/src/FTLayout/FTSimpleLayout.cpp | 60 ++++++++++++++++++++--------- ftgles/src/FTLayout/FTSimpleLayoutImpl.h | 6 ++- 2 files changed, 45 insertions(+), 21 deletions(-) diff --git a/ftgles/src/FTLayout/FTSimpleLayout.cpp b/ftgles/src/FTLayout/FTSimpleLayout.cpp index ff2ec11..050d231 100755 --- a/ftgles/src/FTLayout/FTSimpleLayout.cpp +++ b/ftgles/src/FTLayout/FTSimpleLayout.cpp @@ -81,6 +81,7 @@ void FTSimpleLayout::Render(const wchar_t* string, const int len, FTPoint pos, void FTSimpleLayout::SetFont(FTFont *fontInit) { dynamic_cast<FTSimpleLayoutImpl*>(impl)->currentFont = fontInit; + dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate(); } @@ -93,6 +94,7 @@ FTFont *FTSimpleLayout::GetFont() void FTSimpleLayout::SetLineLength(const float LineLength) { dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineLength = LineLength; + dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate(); } @@ -105,6 +107,7 @@ float FTSimpleLayout::GetLineLength() const void FTSimpleLayout::SetAlignment(const FTGL::TextAlignment Alignment) { dynamic_cast<FTSimpleLayoutImpl*>(impl)->alignment = Alignment; + dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate(); } @@ -117,6 +120,7 @@ FTGL::TextAlignment FTSimpleLayout::GetAlignment() const void FTSimpleLayout::SetLineSpacing(const float LineSpacing) { dynamic_cast<FTSimpleLayoutImpl*>(impl)->lineSpacing = LineSpacing; + dynamic_cast<FTSimpleLayoutImpl*>(impl)->invalidate(); } @@ -137,6 +141,21 @@ FTSimpleLayoutImpl::FTSimpleLayoutImpl() lineLength = 100.0f; alignment = FTGL::ALIGN_LEFT; lineSpacing = 1.0f; + stringCache = NULL; + stringCacheCount = 0; +} + + +FTSimpleLayoutImpl::~FTSimpleLayoutImpl() +{ + free(stringCache); + stringCache = NULL; + stringCacheCount = 0; +} + + +inline void FTSimpleLayoutImpl::invalidate() +{ stringCacheCount = 0; } @@ -209,6 +228,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, { FTUnicodeStringItr<T> breakItr(buf); // points to the last break character FTUnicodeStringItr<T> lineStart(buf); // points to the line start + unsigned int new_stringCacheCount = 0; // length of buffer float nextStart = 0.0; // total width of the current line float breakWidth = 0.0; // width of the line up to the last word break float currentWidth = 0.0; // width of all characters on the current line @@ -228,31 +248,33 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, { bounds->Invalidate(); } - + + { + FTUnicodeStringItr<T> itr(buf); + for (; *itr; ++itr) {} + new_stringCacheCount = itr.getBufferFromHere() - buf + sizeof(T)/*terminator*/; + } + // Check if the incoming string is different to the previously // cached string. - unsigned int i = 0; - for (FTUnicodeStringItr<T> itr(buf); *itr; itr++) - { - if (i >= stringCacheCount || - stringCache[i++] != (unsigned int)*itr) - { - refresh = true; - break; - } + if (stringCache && stringCacheCount == new_stringCacheCount) refresh = !!memcmp(stringCache, buf, stringCacheCount); + else { + refresh = true; + stringCacheCount = new_stringCacheCount; + if (!stringCache) stringCache = (unsigned char *)malloc(stringCacheCount); + else stringCache = (unsigned char *)realloc(stringCache, stringCacheCount); + if (!stringCache) throw std::bad_alloc(); } - + if (refresh) { - stringCacheCount = 0; + memcpy(stringCache, buf, stringCacheCount); layoutGlyphCache.clear(); // Scan the input for all characters that need output FTUnicodeStringItr<T> prevItr(buf); for (FTUnicodeStringItr<T> itr(buf); *itr; prevItr = itr++, charCount++) - { - stringCache[stringCacheCount++] = (unsigned int)*itr; - + { // Find the width of the current glyph glyphBounds = currentFont->BBox(itr.getBufferFromHere(), 1); glyphWidth = glyphBounds.Upper().Xf() - glyphBounds.Lower().Xf(); @@ -296,7 +318,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, } layoutGlyphCacheItem_t cacheItem; - cacheItem.buf = (T*)lineStart.getBufferFromHere(); + cacheItem.buf = stringCache + ptrdiff_t(lineStart.getBufferFromHere() - buf); cacheItem.charCount = breakCharCount; cacheItem.position = FTPoint(position.X(), position.Y(), position.Z()); cacheItem.remainingWidth = remainingWidth; @@ -331,7 +353,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, wordLength += advance; } } - + float remainingWidth = lineLength - currentWidth; // Render any remaining text on the last line // Disable justification for the last row @@ -339,7 +361,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, { alignment = FTGL::ALIGN_LEFT; layoutGlyphCacheItem_t cacheItem; - cacheItem.buf = (T *)lineStart.getBufferFromHere(); + cacheItem.buf = stringCache + ptrdiff_t(lineStart.getBufferFromHere() - buf); cacheItem.charCount = -1; cacheItem.position = FTPoint(position.X(), position.Y(), position.Z()); cacheItem.penDiff = FTPoint(0,0,0); @@ -350,7 +372,7 @@ inline void FTSimpleLayoutImpl::WrapTextI(const T *buf, const int len, else { layoutGlyphCacheItem_t cacheItem; - cacheItem.buf = (T *)lineStart.getBufferFromHere(); + cacheItem.buf = stringCache + ptrdiff_t(lineStart.getBufferFromHere() - buf); cacheItem.charCount = -1; cacheItem.position = FTPoint(position.X(), position.Y(), position.Z()); cacheItem.penDiff = FTPoint(0,0,0); diff --git a/ftgles/src/FTLayout/FTSimpleLayoutImpl.h b/ftgles/src/FTLayout/FTSimpleLayoutImpl.h index 63b56cc..dd84234 100755 --- a/ftgles/src/FTLayout/FTSimpleLayoutImpl.h +++ b/ftgles/src/FTLayout/FTSimpleLayoutImpl.h @@ -50,7 +50,7 @@ class FTSimpleLayoutImpl : public FTLayoutImpl protected: FTSimpleLayoutImpl(); - virtual ~FTSimpleLayoutImpl() {}; + virtual ~FTSimpleLayoutImpl(); virtual FTBBox BBox(const char* string, const int len, FTPoint position); @@ -211,10 +211,12 @@ private: */ std::list<layoutGlyphCacheItem_t> layoutGlyphCache; - unsigned int stringCache[4096]; + unsigned char * stringCache; unsigned int stringCacheCount; + + void invalidate(); /* Internal generic BBox() implementation */ template <typename T> -- 1.7.6.1
Patch updated, make cache allocable instead of restricted.
Hi.
There are two issues in cache realization in FTSimpleLayout:
My patch to fix this: