diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-08-28 23:05:58 +0300 | 
|---|---|---|
| committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-09-04 10:16:46 +0300 | 
| commit | 4ae1de1f8a78d795958d67afab8356f9a13f707d (patch) | |
| tree | ea0fe05983562f061a4748a6f4af7253018f9660 /indra | |
| parent | 36423bd6603c5708028c6e8e9705587b961a4bb2 (diff) | |
viewer#2411 LLFontGL::render optimizations
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.cpp | 124 | ||||
| -rw-r--r-- | indra/llrender/llfontgl.h | 15 | ||||
| -rw-r--r-- | indra/llrender/llfontvertexbuffer.cpp | 157 | ||||
| -rw-r--r-- | indra/llrender/llfontvertexbuffer.h | 85 | ||||
| -rw-r--r-- | indra/llrender/llrender.cpp | 197 | ||||
| -rw-r--r-- | indra/llrender/llrender.h | 10 | ||||
| -rw-r--r-- | indra/llui/llbutton.cpp | 45 | ||||
| -rw-r--r-- | indra/llui/llbutton.h | 14 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llhudnametag.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llhudnametag.h | 3 | ||||
| -rw-r--r-- | indra/newview/llhudrender.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/llhudrender.h | 5 | ||||
| -rw-r--r-- | indra/newview/llhudtext.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llhudtext.h | 2 | ||||
| -rw-r--r-- | indra/newview/llmanip.cpp | 10 | ||||
| -rw-r--r-- | indra/newview/llmaniprotate.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llmanipscale.cpp | 4 | ||||
| -rw-r--r-- | indra/newview/llmaniptranslate.cpp | 4 | 
20 files changed, 627 insertions, 77 deletions
| diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt index 7f881c8bb3..ccff7c7a8c 100644 --- a/indra/llrender/CMakeLists.txt +++ b/indra/llrender/CMakeLists.txt @@ -17,6 +17,7 @@ set(llrender_SOURCE_FILES      llfontfreetype.cpp      llfontfreetypesvg.cpp      llfontgl.cpp +    llfontvertexbuffer.cpp      llfontregistry.cpp      llgl.cpp      llglslshader.cpp @@ -43,6 +44,7 @@ set(llrender_HEADER_FILES      llcubemap.h      llcubemaparray.h      llfontgl.h +    llfontvertexbuffer.h      llfontfreetype.h      llfontfreetypesvg.h      llfontbitmapcache.h diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index b6cdb81b33..481e35c16a 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -34,6 +34,7 @@  #include "llfontbitmapcache.h"  #include "llfontregistry.h"  #include "llgl.h" +#include "llglslshader.h"  #include "llimagegl.h"  #include "llrender.h"  #include "llstl.h" @@ -41,6 +42,7 @@  #include "lltexture.h"  #include "lldir.h"  #include "llstring.h" +#include "llvertexbuffer.h"  // Third party library includes  #include <boost/tokenizer.hpp> @@ -143,7 +145,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRectf& rec  S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, -                     ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, bool use_ellipses, bool use_color) const +                     ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, bool use_ellipses, bool use_color, +                     std::list<LLVertexBufferData> *buffer_list) const  {      LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; @@ -157,6 +160,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons          return 0;      } +    gGL.flush(); // deliberately empty pending verts      gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);      S32 scaled_max_pixels = max_pixels == S32_MAX ? S32_MAX : llceil((F32)max_pixels * sScaleX); @@ -270,10 +274,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      const LLFontGlyphInfo* next_glyph = NULL; -    const S32 GLYPH_BATCH_SIZE = 30; -    LLVector3 vertices[GLYPH_BATCH_SIZE * 4]; -    LLVector2 uvs[GLYPH_BATCH_SIZE * 4]; -    LLColor4U colors[GLYPH_BATCH_SIZE * 4]; +    static constexpr S32 GLYPH_BATCH_SIZE = 30; +    static thread_local LLVector3 vertices[GLYPH_BATCH_SIZE * 4]; +    static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 4]; +    static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 4];      LLColor4U text_color(color);      // Preserve the transparency to render fading emojis in fading text (e.g. @@ -282,6 +286,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons      std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);      S32 glyph_count = 0; +    S32 buffer_count = 0; +    LLVertexBuffer* vb; +    LLImageGL* font_image = nullptr;      for (i = begin_offset; i < begin_offset + length; i++)      {          llwchar wch = wstr[i]; @@ -305,16 +312,35 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons              // otherwise the queued glyphs will be taken from wrong textures.              if (glyph_count > 0)              { -                gGL.begin(LLRender::QUADS); +                if (buffer_list)                  { +                    vb = gGL.beginNoCache(LLRender::QUADS, buffer_count); +                    if (vb) +                    { +                        buffer_list->emplace_back(vb, font_image, LLRender::QUADS, buffer_count); +                    } +                      gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); + +                    vb = gGL.getBuffer(buffer_count); // instead of endNoCache to draw now +                    if (vb) +                    { +                        buffer_list->emplace_back(vb, font_image, LLRender::QUADS, buffer_count); +                    } +                } +                else +                { +                    gGL.begin(LLRender::QUADS); +                    { +                        gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +                    } +                    gGL.end();                  } -                gGL.end();                  glyph_count = 0;              }              bitmap_entry = next_bitmap_entry; -            LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second); +            font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);              gGL.getTexUnit(0)->bind(font_image);          } @@ -338,11 +364,28 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons          if (glyph_count >= GLYPH_BATCH_SIZE)          { -            gGL.begin(LLRender::QUADS); +            if (buffer_list)              { +                vb = gGL.beginNoCache(LLRender::QUADS, buffer_count); +                if (vb) +                { +                    buffer_list->emplace_back(vb, font_image, LLRender::QUADS, buffer_count); +                }                  gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +                vb = gGL.endNoCache(buffer_count); +                if (vb) +                { +                    buffer_list->emplace_back(vb, font_image, LLRender::QUADS, buffer_count); +                } +            } +            else +            { +                gGL.begin(LLRender::QUADS); +                { +                    gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +                } +                gGL.end();              } -            gGL.end();              glyph_count = 0;          } @@ -376,11 +419,28 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons          cur_render_y = cur_y;      } -    gGL.begin(LLRender::QUADS); +    if (buffer_list)      { +        vb = gGL.beginNoCache(LLRender::QUADS, buffer_count); +        if (vb) +        { +            buffer_list->emplace_back(vb, font_image, LLRender::QUADS, buffer_count); +        }          gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +        vb = gGL.endNoCache(buffer_count); +        if (vb) +        { +            buffer_list->emplace_back(vb, font_image, LLRender::QUADS, buffer_count); +        } +    } +    else +    { +        gGL.begin(LLRender::QUADS); +        { +            gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); +        } +        gGL.end();      } -    gGL.end();      if (right_x) @@ -394,15 +454,42 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons          F32 descender = (F32)llfloor(mFontFreetype->getDescenderHeight());          gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -        gGL.begin(LLRender::LINES); -        gGL.vertex2f(start_x, cur_y - descender); -        gGL.vertex2f(cur_x, cur_y - descender); -        gGL.end(); +        if (buffer_list) +        { +            vb = gGL.beginNoCache(LLRender::LINES, buffer_count); +            if (vb) +            { +                buffer_list->emplace_back(vb, nullptr, LLRender::QUADS, buffer_count); +            } + +            gGL.vertex2f(start_x, cur_y - descender); +            gGL.vertex2f(cur_x, cur_y - descender); + +            vb = gGL.getBuffer(buffer_count); +            if (vb) +            { +                buffer_list->emplace_back(vb, nullptr, LLRender::LINES, buffer_count); +            } +        } +        else +        { +            gGL.begin(LLRender::LINES); +            gGL.vertex2f(start_x, cur_y - descender); +            gGL.vertex2f(cur_x, cur_y - descender); +            gGL.end(); +        } +    } +    else if (buffer_list) +    { +        vb = gGL.getBuffer(buffer_count); +        if (vb) +        { +            buffer_list->emplace_back(vb, font_image, gGL.getMode(), buffer_count); +        }      }      if (draw_ellipses)      { -          // recursively render ellipses at end of string          // we've already reserved enough room          gGL.pushUIMatrix(); @@ -417,7 +504,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons                  S32_MAX, max_pixels,                  right_x,                  false, -                use_color); +                use_color, +                buffer_list);          gGL.popUIMatrix();      } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index de7529a583..5015601cf6 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -33,6 +33,7 @@  #include "llimagegl.h"  #include "llpointer.h"  #include "llrect.h" +#include "llvertexbuffer.h"  #include "v2math.h"  class LLColor4; @@ -42,6 +43,7 @@ class LLFontFreetype;  // Structure used to store previously requested fonts.  class LLFontRegistry; +class LLVertexBuffer;  class LLFontGL  { @@ -79,6 +81,16 @@ public:          DROP_SHADOW_SOFT      }; +    struct LLVertexBufferData +    { +        LLVertexBufferData() : mBuffer(nullptr), mImage(nullptr), mMode(0), mCount(0) {} +        LLVertexBufferData(LLVertexBuffer* buffer, LLImageGL* image, U8 mode, U32 count) : mBuffer(buffer), mImage(image), mMode(mode), mCount(count) {} +        LLPointer<LLVertexBuffer> mBuffer; +        LLPointer <LLImageGL> mImage; // might be a better idea to store +        U8 mMode; +        U32 mCount; +    }; +      LLFontGL();      ~LLFontGL(); @@ -119,7 +131,8 @@ public:                  S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,                  F32* right_x=NULL,                  bool use_ellipses = false, -                bool use_color = true) const; +                bool use_color = true, +                std::list<LLVertexBufferData>* buffer_list = nullptr) const;      S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const; diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp new file mode 100644 index 0000000000..3ff0771795 --- /dev/null +++ b/indra/llrender/llfontvertexbuffer.cpp @@ -0,0 +1,157 @@ +/** + * @file llfontvertexbuffer.cpp + * @brief Buffer storage for font rendering. + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2024, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llfontvertexbuffer.h" + +#include "llvertexbuffer.h" + + +LLFontVertexBuffer::LLFontVertexBuffer(bool track_changes) +: mTrackStringChanges(track_changes) +{ +} + +LLFontVertexBuffer::~LLFontVertexBuffer() +{ +    reset(); +} + +void LLFontVertexBuffer::reset() +{ +    mBufferList.clear(); +} + +S32 LLFontVertexBuffer::render( +    const LLFontGL* fontp, +    const LLWString& text, +    S32 begin_offset, +    F32 x, F32 y, +    const LLColor4& color, +    LLFontGL::HAlign halign, LLFontGL::VAlign valign, +    U8 style, LLFontGL::ShadowType shadow, +    S32 max_chars , S32 max_pixels, +    F32* right_x, +    bool use_ellipses, +    bool use_color ) +{ +    if (mBufferList.empty()) +    { +        genBuffers(fontp, text, begin_offset, x, y, color, halign, valign, +            style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); +    } +    else if (mLastX != x || mLastY != y || mLastColor != color) // always track position and alphs +    { +        genBuffers(fontp, text, begin_offset, x, y, color, halign, valign, +            style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); +    } +    else if (true //mTrackStringChanges +             && (mLastOffset != begin_offset +                 || mLastMaxChars != max_chars +                 || mLastMaxPixels != max_pixels +                 || mLastStringHash != sStringHasher._Do_hash(text))) // todo, track all parameters? +    { +        genBuffers(fontp, text, begin_offset, x, y, color, halign, valign, +            style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color); +    } +    else +    { + +        gGL.flush(); // deliberately empty pending verts +        gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); +        gGL.pushUIMatrix(); + +        gGL.loadUIIdentity(); + +        // Depth translation, so that floating text appears 'in-world' +        // and is correctly occluded. +        gGL.translatef(0.f, 0.f, LLFontGL::sCurDepth); + +        gGL.setSceneBlendType(LLRender::BT_ALPHA); + +        for (auto &buf_data : mBufferList) +        { +            if (buf_data.mImage) +            { +                gGL.getTexUnit(0)->bind(buf_data.mImage); +            } +            else +            { +                gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); +            } +            buf_data.mBuffer->setBuffer(); + +            if (LLRender::sGLCoreProfile && buf_data.mMode == LLRender::QUADS) +            { +                buf_data.mBuffer->drawArrays(LLRender::TRIANGLES, 0, buf_data.mCount); +            } +            else +            { +                buf_data.mBuffer->drawArrays(buf_data.mMode, 0, buf_data.mCount); +            } +        } +        if (right_x) +        { +            *right_x = mLastRightX; +        } + +        gGL.popUIMatrix(); +    } +    return mChars; +} + +void LLFontVertexBuffer::genBuffers( +    const LLFontGL* fontp, +    const LLWString& text, +    S32 begin_offset, +    F32 x, F32 y, +    const LLColor4& color, +    LLFontGL::HAlign halign, LLFontGL::VAlign valign, +    U8 style, LLFontGL::ShadowType shadow, +    S32 max_chars, S32 max_pixels, +    F32* right_x, +    bool use_ellipses, +    bool use_color) +{ +    mBufferList.clear(); +    mChars = fontp->render(text, begin_offset, x, y, color, halign, valign, +        style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color, &mBufferList); + +    mLastOffset = begin_offset; +    mLastMaxChars = max_chars; +    mLastMaxPixels = max_pixels; +    mLastStringHash = sStringHasher._Do_hash(text); +    mLastX = x; +    mLastY = y; +    mLastColor = color; + +    if (right_x) +    { +        mLastRightX = *right_x; +    } +} + diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h new file mode 100644 index 0000000000..bd42cf6c2d --- /dev/null +++ b/indra/llrender/llfontvertexbuffer.h @@ -0,0 +1,85 @@ +/** + * @file llfontgl.h + * @author Andrii Kleshchev + * @brief Buffer storage for font rendering. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLFONTVERTEXBUFFER_H +#define LL_LLFONTVERTEXBUFFER_H + +#include "llfontgl.h" + +class LLVertexBuffer; + +class LLFontVertexBuffer +{ +public: +    LLFontVertexBuffer(bool track_changes = true); +    ~LLFontVertexBuffer(); + +    void reset(); + +    S32 render(const LLFontGL* fontp, +        const LLWString& text, +        S32 begin_offset, +        F32 x, F32 y, +        const LLColor4& color, +        LLFontGL::HAlign halign = LLFontGL::LEFT, LLFontGL::VAlign valign = LLFontGL::BASELINE, +        U8 style = LLFontGL::NORMAL, LLFontGL::ShadowType shadow = LLFontGL::NO_SHADOW, +        S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX, +        F32* right_x = NULL, +        bool use_ellipses = false, +        bool use_color = true); + +private: + +    void genBuffers(const LLFontGL* fontp, +         const LLWString& text, +         S32 begin_offset, +         F32 x, F32 y, +         const LLColor4& color, +         LLFontGL::HAlign halign, LLFontGL::VAlign valign, +         U8 style, LLFontGL::ShadowType shadow, +         S32 max_chars, S32 max_pixels, +         F32* right_x, +         bool use_ellipses, +         bool use_color); + + +    std::list<LLFontGL::LLVertexBufferData> mBufferList; +    S32 mChars = 0; +    S32 mLastOffset = 0; +    S32 mLastMaxChars = 0; +    S32 mLastMaxPixels = 0; +    size_t mLastStringHash = 0; +    F32 mLastX = 0.f; +    F32 mLastY = 0.f; +    LLColor4 mLastColor; +    F32 mLastRightX = 0.f; +    bool mTrackStringChanges = true; + +    static std::hash<LLWString> sStringHasher; +}; + +#endif diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 7a52f9cfb5..8cd2d9cc15 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1570,6 +1570,51 @@ void LLRender::end()          flush();      }  } + +LLVertexBuffer* LLRender::beginNoCache(const GLuint& mode, S32& count) +{ +    if (mode != mMode) +    { +        if (mode == LLRender::QUADS) +        { +            mQuadCycle = 1; +        } + +        if (mMode == LLRender::QUADS || +            mMode == LLRender::LINES || +            mMode == LLRender::TRIANGLES || +            mMode == LLRender::POINTS) +        { +            return getBuffer(count); +        } +        else if (mCount != 0) +        { +            LL_ERRS() << "gGL.begin() called redundantly." << LL_ENDL; +        } +        mMode = mode; +    } +    return nullptr; +} + +LLVertexBuffer* LLRender::endNoCache(S32& count) +{ +    if (mCount == 0) +    { +        return nullptr; +        //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL; +    } + +    if ((mMode != LLRender::QUADS && +        mMode != LLRender::LINES && +        mMode != LLRender::TRIANGLES && +        mMode != LLRender::POINTS) || +        mCount > 2048) +    { +        return getBuffer(count); +    } +    return nullptr; +} +  void LLRender::flush()  {      STOP_GLERROR; @@ -1664,27 +1709,7 @@ void LLRender::flush()              else              {                  LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss"); -                vb = new LLVertexBuffer(attribute_mask); -                vb->allocateBuffer(count, 0); - -                vb->setBuffer(); - -                vb->setPositionData((LLVector4a*) mVerticesp.get()); - -                if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0) -                { -                    vb->setTexCoord0Data(mTexcoordsp.get()); -                } - -                if (attribute_mask & LLVertexBuffer::MAP_COLOR) -                { -                    vb->setColorData(mColorsp.get()); -                } - -#if LL_DARWIN -                vb->unmapBuffer(); -#endif -                vb->unbind(); +                vb = genBuffer(attribute_mask, count);                  sVBCache[vhash] = { vb , std::chrono::steady_clock::now() }; @@ -1712,31 +1737,137 @@ void LLRender::flush()                  }              } -            vb->setBuffer(); +            drawBuffer(vb, mMode, count); +        } +        else +        { +            // mBuffer is present in main thread and not present in an image thread +            LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL; +        } + +        resetStriders(count); +    } +} + +LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count) +{ +    LLVertexBuffer * vb = new LLVertexBuffer(attribute_mask); +    vb->allocateBuffer(count, 0); + +    vb->setBuffer(); + +    vb->setPositionData((LLVector4a*)mVerticesp.get()); + +    if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0) +    { +        vb->setTexCoord0Data(mTexcoordsp.get()); +    } -            if (mMode == LLRender::QUADS && sGLCoreProfile) +    if (attribute_mask & LLVertexBuffer::MAP_COLOR) +    { +        vb->setColorData(mColorsp.get()); +    } + +#if LL_DARWIN +    vb->unmapBuffer(); +#endif +    vb->unbind(); + +    return vb; +} + +void LLRender::drawBuffer(LLVertexBuffer* vb, U32 mode, S32 count) +{ +    vb->setBuffer(); + +    if (mode == LLRender::QUADS && sGLCoreProfile) +    { +        vb->drawArrays(LLRender::TRIANGLES, 0, count); +        mQuadCycle = 1; +    } +    else +    { +        vb->drawArrays(mode, 0, count); +    } +} + +void LLRender::resetStriders(S32 count) +{ +    mVerticesp[0] = mVerticesp[count]; +    mTexcoordsp[0] = mTexcoordsp[count]; +    mColorsp[0] = mColorsp[count]; + +    mCount = 0; +} + +LLVertexBuffer* LLRender::getBuffer(S32 & count) +{ +    STOP_GLERROR; +    LLVertexBuffer *vb; +    if (mCount > 0) +    { +        LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; +        llassert(LLGLSLShader::sCurBoundShaderPtr != nullptr); +        if (!mUIOffset.empty()) +        { +            sUICalls++; +            sUIVerts += mCount; +        } + +        //store mCount in a local variable to avoid re-entrance (drawArrays may call flush) +        count = mCount; + +        if (mMode == LLRender::QUADS && !sGLCoreProfile) +        { +            if (mCount % 4 != 0)              { -                vb->drawArrays(LLRender::TRIANGLES, 0, count); -                mQuadCycle = 1; +                count -= (mCount % 4); +                LL_WARNS() << "Incomplete quad requested." << LL_ENDL;              } -            else +        } + +        if (mMode == LLRender::TRIANGLES) +        { +            if (mCount % 3 != 0)              { -                vb->drawArrays(mMode, 0, count); +                count -= (mCount % 3); +                LL_WARNS() << "Incomplete triangle requested." << LL_ENDL;              }          } + +        if (mMode == LLRender::LINES) +        { +            if (mCount % 2 != 0) +            { +                count -= (mCount % 2); +                LL_WARNS() << "Incomplete line requested." << LL_ENDL; +            } +        } + +        mCount = 0; + +        if (mBuffer) +        { +            LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss"); + +            U32 attribute_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; +            vb = genBuffer(attribute_mask, count); +            drawBuffer(vb, mMode, count); +        }          else          {              // mBuffer is present in main thread and not present in an image thread              LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL;          } - -        mVerticesp[0] = mVerticesp[count]; -        mTexcoordsp[0] = mTexcoordsp[count]; -        mColorsp[0] = mColorsp[count]; - -        mCount = 0; +        resetStriders(count);      } +    else +    { +        count = 0; +    } + +    return vb;  }  void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 4aa33b7427..5f84a4a275 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -417,6 +417,12 @@ public:      void begin(const GLuint& mode);      void end(); + +    LLVertexBuffer* beginNoCache(const GLuint& mode, S32& count); +    LLVertexBuffer* endNoCache(S32& count); +    LLVertexBuffer* getBuffer(S32& count); +    U8 getMode() const { return mMode; } +      void vertex2i(const GLint& x, const GLint& y);      void vertex2f(const GLfloat& x, const GLfloat& y);      void vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z); @@ -485,6 +491,10 @@ public:  private:      friend class LLLightState; +    LLVertexBuffer* genBuffer(U32 attribute_mask, S32 count); +    void drawBuffer(LLVertexBuffer* vb, U32 mode, S32 count); +    void resetStriders(S32 count); +      eMatrixMode mMatrixMode;      U32 mMatIdx[NUM_MATRIX_MODES];      U32 mMatHash[NUM_MATRIX_MODES]; diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 30968225a8..3df7f83d49 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -120,8 +120,9 @@ LLButton::Params::Params()  LLButton::LLButton(const LLButton::Params& p) -:   LLUICtrl(p), +    : LLUICtrl(p),      LLBadgeOwner(getHandle()), +    mFontBuffer(false),      mMouseDownFrame(0),      mMouseHeldDownCount(0),      mBorderEnabled( false ), @@ -329,6 +330,30 @@ void LLButton::onCommit()      LLUICtrl::onCommit();  } +void LLButton::setUnselectedLabelColor(const LLUIColor& c) +{ +    mUnselectedLabelColor = c; +    mFontBuffer.reset(); +} + +void LLButton::setSelectedLabelColor(const LLUIColor& c) +{ +    mSelectedLabelColor = c; +    mFontBuffer.reset(); +} + +void LLButton::setUseEllipses(bool use_ellipses) +{ +    mUseEllipses = use_ellipses; +    mFontBuffer.reset(); +} + +void LLButton::setUseFontColor(bool use_font_color) +{ +    mUseFontColor = use_font_color; +    mFontBuffer.reset(); +} +  boost::signals2::connection LLButton::setClickedCallback(const CommitCallbackParam& cb)  {      return setClickedCallback(initCommitCallback(cb)); @@ -396,6 +421,15 @@ bool LLButton::postBuild()      return LLUICtrl::postBuild();  } +void LLButton::onVisibilityChange(bool new_visibility) +{ +    if (!new_visibility) +    { +        mFontBuffer.reset(); +    } +    return LLUICtrl::onVisibilityChange(new_visibility); +} +  bool LLButton::handleUnicodeCharHere(llwchar uni_char)  {      bool handled = false; @@ -954,7 +988,7 @@ void LLButton::draw()          // LLFontGL::render expects S32 max_chars variable but process in a separate way -1 value.          // Due to U32_MAX is equal to S32 -1 value I have rest this value for non-ellipses mode.          // Not sure if it is really needed. Probably S32_MAX should be always passed as max_chars. -        mLastDrawCharsCount = mGLFont->render(label, 0, +        mLastDrawCharsCount = mFontBuffer.render(mGLFont, label, 0,              (F32)x,              (F32)(getRect().getHeight() / 2 + mBottomVPad),              label_color % alpha, @@ -996,6 +1030,7 @@ void LLButton::setToggleState(bool b)          setFlashing(false); // stop flash state whenever the selected/unselected state if reset          // Unselected label assignments          autoResize(); +        mFontBuffer.reset();      }  } @@ -1025,11 +1060,13 @@ bool LLButton::toggleState()  void LLButton::setLabel( const std::string& label )  {      mUnselectedLabel = mSelectedLabel = label; +    mFontBuffer.reset();  }  void LLButton::setLabel( const LLUIString& label )  {      mUnselectedLabel = mSelectedLabel = label; +    mFontBuffer.reset();  }  void LLButton::setLabel( const LLStringExplicit& label ) @@ -1043,17 +1080,20 @@ bool LLButton::setLabelArg( const std::string& key, const LLStringExplicit& text  {      mUnselectedLabel.setArg(key, text);      mSelectedLabel.setArg(key, text); +    mFontBuffer.reset();      return true;  }  void LLButton::setLabelUnselected( const LLStringExplicit& label )  {      mUnselectedLabel = label; +    mFontBuffer.reset();  }  void LLButton::setLabelSelected( const LLStringExplicit& label )  {      mSelectedLabel = label; +    mFontBuffer.reset();  }  bool LLButton::labelIsTruncated() const @@ -1113,6 +1153,7 @@ void LLButton::resize(const LLUIString& label)          if (btn_width < min_width)          {              reshape(min_width, getRect().getHeight()); +            mFontBuffer.reset();          }      }  } diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 4ecea6d473..f522281e30 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -35,6 +35,7 @@  #include "v4color.h"  #include "llframetimer.h"  #include "llfontgl.h" +#include "llfontvertexbuffer.h"  #include "lluiimage.h"  #include "lluistring.h" @@ -167,15 +168,17 @@ public:      virtual void    draw();      /*virtual*/ bool postBuild(); +    /*virtual*/ void onVisibilityChange(bool visible); +      virtual void    onMouseLeave(S32 x, S32 y, MASK mask);      virtual void    onMouseCaptureLost();      virtual void    onCommit(); -    void            setUnselectedLabelColor( const LLUIColor& c )        { mUnselectedLabelColor = c; } -    void            setSelectedLabelColor( const LLUIColor& c )          { mSelectedLabelColor = c; } -    void            setUseEllipses( bool use_ellipses )                 { mUseEllipses = use_ellipses; } -    void            setUseFontColor( bool use_font_color)               { mUseFontColor = use_font_color; } +    void            setUnselectedLabelColor(const LLUIColor& c); +    void            setSelectedLabelColor(const LLUIColor& c); +    void            setUseEllipses(bool use_ellipses); +    void            setUseFontColor(bool use_font_color);      boost::signals2::connection setClickedCallback(const CommitCallbackParam& cb); @@ -223,7 +226,6 @@ public:      const std::string   getLabelUnselected() const { return wstring_to_utf8str(mUnselectedLabel); }      const std::string   getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); } -    void            setImageColor(const std::string& color_control);      void            setImageColor(const LLUIColor& c);      /*virtual*/ void    setColor(const LLUIColor& c); @@ -278,7 +280,6 @@ public:      void            setCommitOnReturn(bool commit) { mCommitOnReturn = commit; }      bool            getCommitOnReturn() const { return mCommitOnReturn; } -    static void     onHeldDown(void *userdata);  // to be called by gIdleCallbacks      static void     toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);      static void     setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);      static void     setDockableFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname); @@ -306,6 +307,7 @@ protected:      commit_signal_t*            mHeldDownSignal;      const LLFontGL*             mGLFont; +    LLFontVertexBuffer          mFontBuffer;      S32                         mMouseDownFrame;      S32                         mMouseHeldDownCount;    // Counter for parameter passed to held-down callback diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 76abf5eaa2..25ef1336c8 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3710,6 +3710,10 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t      //      // "This is why I'm doing it this way, instead of what you would think would be more obvious..."      // (C) Nat Goodspeed +    if (!IsWindow(sWindowHandleForMessageBox)) +    { +        sWindowHandleForMessageBox = NULL; +    }      int retval_win = MessageBoxW(sWindowHandleForMessageBox, // HWND                                   ll_convert_string_to_wide(text).c_str(),                                   ll_convert_string_to_wide(caption).c_str(), diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp index 11f049564a..0c56582ea6 100644 --- a/indra/newview/llhudnametag.cpp +++ b/indra/newview/llhudnametag.cpp @@ -328,7 +328,7 @@ void LLHUDNameTag::renderText()              }              LLColor4 label_color(0.f, 0.f, 0.f, alpha_factor); -            hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, false); +            hud_render_text(segment_iter->getText(), render_position, &segment_iter->mFontBufferLabel, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, false);          }      } @@ -373,7 +373,7 @@ void LLHUDNameTag::renderText()              text_color = segment_iter->mColor;              text_color.mV[VALPHA] *= alpha_factor; -            hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, false); +            hud_render_text(segment_iter->getText(), render_position, &segment_iter->mFontBufferText, *fontp, style, shadow, x_offset, y_offset, text_color, false);          }      }      /// Reset the default color to white.  The renderer expects this to be the default. diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h index 5cb7fa877e..ee315f47af 100644 --- a/indra/newview/llhudnametag.h +++ b/indra/newview/llhudnametag.h @@ -37,6 +37,7 @@  #include "llrect.h"  //#include "llframetimer.h"  #include "llfontgl.h" +#include "llfontvertexbuffer.h"  #include <set>  #include <vector> @@ -67,6 +68,8 @@ protected:          LLColor4                mColor;          LLFontGL::StyleFlags    mStyle;          const LLFontGL*         mFont; +        LLFontVertexBuffer      mFontBufferLabel; +        LLFontVertexBuffer      mFontBufferText;      private:          LLWString               mText;          std::map<const LLFontGL*, F32> mFontWidthMap; diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp index 5608ab763f..f027aa5552 100644 --- a/indra/newview/llhudrender.cpp +++ b/indra/newview/llhudrender.cpp @@ -39,6 +39,7 @@  #include "llui.h"  void hud_render_utf8text(const std::string &str, const LLVector3 &pos_agent, +                     LLFontVertexBuffer *font_buffer,                       const LLFontGL &font,                       const U8 style,                       const LLFontGL::ShadowType shadow, @@ -47,10 +48,11 @@ void hud_render_utf8text(const std::string &str, const LLVector3 &pos_agent,                       const bool orthographic)  {      LLWString wstr(utf8str_to_wstring(str)); -    hud_render_text(wstr, pos_agent, font, style, shadow, x_offset, y_offset, color, orthographic); +    hud_render_text(wstr, pos_agent, font_buffer, font, style, shadow, x_offset, y_offset, color, orthographic);  }  void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent, +                    LLFontVertexBuffer *font_buffer,                      const LLFontGL &font,                      const U8 style,                      const LLFontGL::ShadowType shadow, @@ -138,7 +140,14 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,      LLUI::translate((F32) winX*1.0f/LLFontGL::sScaleX, (F32) winY*1.0f/(LLFontGL::sScaleY), -(((F32) winZ*2.f)-1.f));      F32 right_x; -    font.render(wstr, 0, 0, 1, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, static_cast<S32>(wstr.length()), 1000, &right_x, /*use_ellipses*/false, /*use_color*/true); +    if (font_buffer) +    { +        font_buffer->render(&font, wstr, 0, 0, 1, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, static_cast<S32>(wstr.length()), 1000, &right_x, /*use_ellipses*/false, /*use_color*/true); +    } +    else +    { +        font.render(wstr, 0, 0, 1, color, LLFontGL::LEFT, LLFontGL::BASELINE, style, shadow, static_cast<S32>(wstr.length()), 1000, &right_x, /*use_ellipses*/false, /*use_color*/true); +    }      LLUI::popMatrix();      gGL.popMatrix(); diff --git a/indra/newview/llhudrender.h b/indra/newview/llhudrender.h index eb8f07e4d4..be9fc7f084 100644 --- a/indra/newview/llhudrender.h +++ b/indra/newview/llhudrender.h @@ -28,6 +28,7 @@  #define LL_LLHUDRENDER_H  #include "llfontgl.h" +#include "llfontvertexbuffer.h"  class LLVector3;  class LLFontGL; @@ -35,6 +36,7 @@ class LLFontGL;  // Utility classes for rendering HUD elements  void hud_render_text(const LLWString &wstr,                       const LLVector3 &pos_agent, +                     LLFontVertexBuffer *font_buffer,                       const LLFontGL &font,                       const U8 style,                       const LLFontGL::ShadowType, @@ -46,9 +48,10 @@ void hud_render_text(const LLWString &wstr,  // Legacy, slower  void hud_render_utf8text(const std::string &str,                           const LLVector3 &pos_agent, +                         LLFontVertexBuffer *font_buffer,                           const LLFontGL &font,                           const U8 style, -                        const LLFontGL::ShadowType, +                         const LLFontGL::ShadowType,                           const F32 x_offset,                           const F32 y_offset,                           const LLColor4& color, diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index fd0d8b696f..92f09c34a0 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -231,7 +231,7 @@ void LLHUDText::renderText()              }              text_color.mV[VALPHA] *= alpha_factor; -            hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, mOnHUDAttachment); +            hud_render_text(segment_iter->getText(), render_position, &mFontBuffer, *fontp, style, shadow, x_offset, y_offset, text_color, mOnHUDAttachment);          }      }      /// Reset the default color to white.  The renderer expects this to be the default. diff --git a/indra/newview/llhudtext.h b/indra/newview/llhudtext.h index a81fdebb17..224677736c 100644 --- a/indra/newview/llhudtext.h +++ b/indra/newview/llhudtext.h @@ -35,6 +35,7 @@  #include "v2math.h"  #include "llrect.h"  #include "llfontgl.h" +#include "llfontvertexbuffer.h"  #include <set>  #include <vector> @@ -161,6 +162,7 @@ private:      ETextAlignment  mTextAlignment;      EVertAlignment  mVertAlignment;      bool            mHidden; +    LLFontVertexBuffer   mFontBuffer;      static bool    sDisplayText ;      static std::set<LLPointer<LLHUDText> > sTextObjects; diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 0d617753c8..9a0b1bfcd6 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -519,9 +519,9 @@ void LLManip::renderTickText(const LLVector3& pos, const std::string& text, cons      LLColor4 shadow_color = LLColor4::black;      shadow_color.mV[VALPHA] = color.mV[VALPHA] * 0.5f;      gViewerWindow->setup3DViewport(1, -1); -    hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); +    hud_render_utf8text(text, render_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  -0.5f * big_fontp->getWidthF32(text), 3.f, shadow_color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);      gViewerWindow->setup3DViewport(); -    hud_render_utf8text(text, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD); +    hud_render_utf8text(text, render_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(text), 3.f, color, mObjectSelection->getSelectType() == SELECT_TYPE_HUD);      gGL.popMatrix();  } @@ -581,12 +581,12 @@ void LLManip::renderTickValue(const LLVector3& pos, F32 value, const std::string          {              fraction_string = llformat("%c%02d%s", LLResMgr::getInstance()->getDecimalPoint(), fractional_portion, suffix.c_str()); -            hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); -            hud_render_utf8text(fraction_string, render_pos, *small_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, 1.f, 3.f, color, hud_selection); +            hud_render_utf8text(val_string, render_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -1.f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); +            hud_render_utf8text(fraction_string, render_pos, nullptr, *small_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, 1.f, 3.f, color, hud_selection);          }          else          { -            hud_render_utf8text(val_string, render_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection); +            hud_render_utf8text(val_string, render_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, -0.5f * big_fontp->getWidthF32(val_string), 3.f, color, hud_selection);          }      }      gGL.popMatrix(); diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index 5bdf3f81b5..0d80b8d8ba 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -1169,10 +1169,10 @@ void LLManipRotate::renderSnapGuides()              std::string help_text =  LLTrans::getString("manip_hint1");              LLColor4 help_text_color = LLColor4::white;              help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); -            hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); +            hud_render_utf8text(help_text, help_text_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);              help_text =  LLTrans::getString("manip_hint2");              help_text_pos -= offset_dir * mRadiusMeters * 0.4f; -            hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); +            hud_render_utf8text(help_text, help_text_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);          }      }  } diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index ffb66dc6cc..19868f3c3e 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -1865,10 +1865,10 @@ void LLManipScale::renderSnapGuides(const LLBBox& bbox)                  std::string help_text = LLTrans::getString("manip_hint1");                  LLColor4 help_text_color = LLColor4::white;                  help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, grid_alpha, 0.f); -                hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); +                hud_render_utf8text(help_text, help_text_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);                  help_text = LLTrans::getString("manip_hint2");                  help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapRegimeOffset * 0.4f; -                hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); +                hud_render_utf8text(help_text, help_text_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);              }          }      } diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index c11a98be50..c9c7d26d33 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -1449,10 +1449,10 @@ void LLManipTranslate::renderSnapGuides()                  std::string help_text = LLTrans::getString("manip_hint1");                  LLColor4 help_text_color = LLColor4::white;                  help_text_color.mV[VALPHA] = clamp_rescale(mHelpTextTimer.getElapsedTimeF32(), sHelpTextVisibleTime, sHelpTextVisibleTime + sHelpTextFadeTime, line_alpha, 0.f); -                hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); +                hud_render_utf8text(help_text, help_text_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);                  help_text = LLTrans::getString("manip_hint2");                  help_text_pos -= LLViewerCamera::getInstance()->getUpAxis() * mSnapOffsetMeters * 0.2f; -                hud_render_utf8text(help_text, help_text_pos, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false); +                hud_render_utf8text(help_text, help_text_pos, nullptr, *big_fontp, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -0.5f * big_fontp->getWidthF32(help_text), 3.f, help_text_color, false);              }          }      } | 
