diff options
| author | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-04-08 22:53:56 +0300 |
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2026-04-09 20:48:34 +0300 |
| commit | 5f91a3faf3ef0b9d0a6c3424fff119992dc0822a (patch) | |
| tree | 31fe46c41da8a3f691cbc0e456f1b5f95f039a1a /indra/llrender | |
| parent | 130c50cf8d4de021f510b17fd02fcac88a67c5e6 (diff) | |
#5626 LLTextBase optimization
by caching string width
Diffstat (limited to 'indra/llrender')
| -rw-r--r-- | indra/llrender/llfontvertexbuffer.cpp | 77 | ||||
| -rw-r--r-- | indra/llrender/llfontvertexbuffer.h | 46 |
2 files changed, 123 insertions, 0 deletions
diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp index a223509d30..2a0115265f 100644 --- a/indra/llrender/llfontvertexbuffer.cpp +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -237,3 +237,80 @@ void LLFontVertexBuffer::renderBuffers() gGL.popUIMatrix(); } +// LLFontWidthBuffer +bool LLFontWidthBuffer::sEnableBufferCollection = true; + +LLFontWidthBuffer::LLFontWidthBuffer() +{ +} + +LLFontWidthBuffer::~LLFontWidthBuffer() +{ +} + +void LLFontWidthBuffer::reset() +{ + mLastFont = nullptr; + mLastOffset = 0; + mLastMaxChars = 0; + mLastNoPadding = false; + mWidth = -1.f; + mLastScaleX = 1.f; + mLastScaleY = 1.f; + mLastVertDPI = 0.f; + mLastHorizDPI = 0.f; + mLastResGeneration = 0; + mLastFontCacheGen = 0; +} + +F32 LLFontWidthBuffer::getWidth( + const LLFontGL* fontp, + const llwchar* wchars, + S32 begin_offset, + S32 max_chars, + bool no_padding) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + if (!fontp || !wchars) + { + return 0.f; + } + + if (!sEnableBufferCollection) + { + return fontp->getWidthF32(wchars, begin_offset, max_chars, no_padding); + } + + // Check if we can use cached width + bool needs_recalc = (mWidth < 0.f) + || (mLastFont != fontp) + || (mLastOffset != begin_offset) + || (mLastMaxChars != max_chars) + || (mLastNoPadding != no_padding) + || (mLastScaleX != LLFontGL::sScaleX) + || (mLastScaleY != LLFontGL::sScaleY) + || (mLastVertDPI != LLFontGL::sVertDPI) + || (mLastHorizDPI != LLFontGL::sHorizDPI) + || (mLastResGeneration != LLFontGL::sResolutionGeneration) + || (mLastFontCacheGen != fontp->getCacheGeneration()); + + if (needs_recalc) + { + // Calculate width using the font + mWidth = fontp->getWidthF32(wchars, begin_offset, max_chars, no_padding); + + // Cache the parameters + mLastFont = fontp; + mLastOffset = begin_offset; + mLastMaxChars = max_chars; + mLastNoPadding = no_padding; + mLastScaleX = LLFontGL::sScaleX; + mLastScaleY = LLFontGL::sScaleY; + mLastVertDPI = LLFontGL::sVertDPI; + mLastHorizDPI = LLFontGL::sHorizDPI; + mLastResGeneration = LLFontGL::sResolutionGeneration; + mLastFontCacheGen = fontp->getCacheGeneration(); + } + + return mWidth; +} diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h index a9e1e2337c..94b833d227 100644 --- a/indra/llrender/llfontvertexbuffer.h +++ b/indra/llrender/llfontvertexbuffer.h @@ -32,6 +32,11 @@ class LLVertexBufferData; +// Rendering fonts is expensive, this class is intended to store +// vertex buffers for rendered text, so that they can be reused. +// LLFontVertexBuffer tracks font and rendering parameters, but +// expects caller to track text changes and call reset() when +// text changes. class LLFontVertexBuffer { public: @@ -127,4 +132,45 @@ private: static bool sEnableBufferCollection; }; +// Extracting width from a font is expensive, and due to +// mechanics of font rendering, we need width separately +// and usually before rendering. +// LLFontWidthBuffer tracks font and rendering parameters, +// but expects caller to track text changes and call reset() +// when text changes. +class LLFontWidthBuffer +{ +public: + LLFontWidthBuffer(); + ~LLFontWidthBuffer(); + + void reset(); + + F32 getWidth(const LLFontGL* fontp, + const llwchar* wchars, + S32 begin_offset, + S32 max_chars, + bool no_padding); + + static void enableBufferCollection(bool enable) { sEnableBufferCollection = enable; } +private: + const LLFontGL* mLastFont = nullptr; + S32 mLastOffset = 0; + S32 mLastMaxChars = 0; + bool mLastNoPadding = false; + F32 mWidth = -1.f; + + // LLFontGL's values that affect width calculation + F32 mLastScaleX = 1.f; + F32 mLastScaleY = 1.f; + F32 mLastVertDPI = 0.f; + F32 mLastHorizDPI = 0.f; + S32 mLastResGeneration = 0; + + // Cache generation tracking + S32 mLastFontCacheGen = 0; + + static bool sEnableBufferCollection; +}; + #endif |
