Skip to content

Commit

Permalink
viewer#2411 LLFontGL::render optimizations #3
Browse files Browse the repository at this point in the history
  • Loading branch information
akleshchev committed Sep 4, 2024
1 parent a638d96 commit 5c64e5e
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 245 deletions.
118 changes: 13 additions & 105 deletions indra/llrender/llfontgl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
#include "lltexture.h"
#include "lldir.h"
#include "llstring.h"
#include "llvertexbuffer.h"

// Third party library includes
#include <boost/tokenizer.hpp>
Expand Down Expand Up @@ -145,8 +144,7 @@ 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,
std::list<LLVertexBufferData> *buffer_list) const
ShadowType shadow, S32 max_chars, S32 max_pixels, F32* right_x, bool use_ellipses, bool use_color) const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;

Expand All @@ -160,7 +158,6 @@ 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);
Expand Down Expand Up @@ -286,9 +283,6 @@ 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];
Expand All @@ -312,35 +306,16 @@ 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)
{
if (buffer_list)
gGL.begin(LLRender::QUADS);
{
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;
font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
gGL.getTexUnit(0)->bind(font_image);
}

Expand All @@ -364,28 +339,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons

if (glyph_count >= GLYPH_BATCH_SIZE)
{
if (buffer_list)
gGL.begin(LLRender::QUADS);
{
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;
}
Expand Down Expand Up @@ -418,29 +376,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
cur_render_x = cur_x;
cur_render_y = cur_y;
}

if (buffer_list)
gGL.begin(LLRender::QUADS);
{
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)
Expand All @@ -454,45 +394,14 @@ 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);
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);
}
gGL.begin(LLRender::LINES);
gGL.vertex2f(start_x, cur_y - descender);
gGL.vertex2f(cur_x, cur_y - descender);
gGL.end();
}

if (draw_ellipses)
{
// signal a separate context
buffer_list->emplace_back(nullptr, nullptr, 0, 0);

// recursively render ellipses at end of string
// we've already reserved enough room
gGL.pushUIMatrix();
Expand All @@ -507,8 +416,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
S32_MAX, max_pixels,
right_x,
false,
use_color,
buffer_list);
use_color);
gGL.popUIMatrix();
}

Expand Down
15 changes: 1 addition & 14 deletions indra/llrender/llfontgl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "llimagegl.h"
#include "llpointer.h"
#include "llrect.h"
#include "llvertexbuffer.h"
#include "v2math.h"

class LLColor4;
Expand All @@ -43,7 +42,6 @@ class LLFontFreetype;

// Structure used to store previously requested fonts.
class LLFontRegistry;
class LLVertexBuffer;

class LLFontGL
{
Expand Down Expand Up @@ -81,16 +79,6 @@ class LLFontGL
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();

Expand Down Expand Up @@ -131,8 +119,7 @@ class LLFontGL
S32 max_chars = S32_MAX, S32 max_pixels = S32_MAX,
F32* right_x=NULL,
bool use_ellipses = false,
bool use_color = true,
std::list<LLVertexBufferData>* buffer_list = nullptr) const;
bool use_color = true) const;

S32 render(const LLWString &text, S32 begin_offset, F32 x, F32 y, const LLColor4 &color) const;

Expand Down
75 changes: 22 additions & 53 deletions indra/llrender/llfontvertexbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,17 @@ S32 LLFontVertexBuffer::render(
bool use_ellipses,
bool use_color )
{
if (!LLFontGL::sDisplayFont) //do not display texts
{
return static_cast<S32>(text.length());
}
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
else if (mLastX != x
|| mLastY != y
|| mLastFont != fontp
|| mLastColor != color // alphas change often
|| mLastHalign != halign
Expand All @@ -74,7 +79,10 @@ S32 LLFontVertexBuffer::render(
|| mLastMaxChars != max_chars
|| mLastMaxPixels != max_pixels
|| mLastStyle != style
|| mLastShadow != shadow) // ex: buttons change shadow state
|| mLastShadow != shadow // ex: buttons change shadow state
|| mLastScaleX != LLFontGL::sScaleX
|| mLastScaleY != LLFontGL::sScaleY
|| mLastOrigin != LLFontGL::sCurOrigin)
{
genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
Expand Down Expand Up @@ -110,8 +118,11 @@ void LLFontVertexBuffer::genBuffers(
bool use_color)
{
mBufferList.clear();

gGL.beginList(&mBufferList);
mChars = fontp->render(text, begin_offset, x, y, color, halign, valign,
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color, &mBufferList);
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
gGL.endList();

mLastFont = fontp;
mLastOffset = begin_offset;
Expand All @@ -126,67 +137,25 @@ void LLFontVertexBuffer::genBuffers(
mLastStyle = style;
mLastShadow = shadow;

mLastScaleX = LLFontGL::sScaleX;
mLastScaleY = LLFontGL::sScaleY;
mLastOrigin = LLFontGL::sCurOrigin;

if (right_x)
{
mLastRightX = *right_x;
}
}

void render_buffers(LLFontVertexBuffer::buffer_list_t::iterator iter, LLFontVertexBuffer::buffer_list_t::iterator end)
void LLFontVertexBuffer::renderBuffers()
{
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);

while (iter != end)
{
if (iter->mBuffer == nullptr)
{
// elipses indicator
iter++;
break;
}
if (iter->mImage)
{
gGL.getTexUnit(0)->bind(iter->mImage);
}
else
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
iter->mBuffer->setBuffer();

if (LLRender::sGLCoreProfile && iter->mMode == LLRender::QUADS)
{
iter->mBuffer->drawArrays(LLRender::TRIANGLES, 0, iter->mCount);
}
else
{
iter->mBuffer->drawArrays(iter->mMode, 0, iter->mCount);
}
iter++;
}

if (iter != end)
for (LLVertexBufferData& buffer : mBufferList)
{
gGL.pushUIMatrix();
render_buffers(iter, end);
gGL.popUIMatrix();
buffer.draw();
}

gGL.popUIMatrix();
}

void LLFontVertexBuffer::renderBuffers()
{
gGL.flush(); // deliberately empty pending verts
render_buffers(mBufferList.begin(), mBufferList.end());
}

Loading

0 comments on commit 5c64e5e

Please sign in to comment.