Skip to content

Commit 695a53f

Browse files
committed
#3068 Experience names are displayed incompletely (fix batch rendering)
1 parent a0e5e23 commit 695a53f

File tree

1 file changed

+45
-26
lines changed

1 file changed

+45
-26
lines changed

indra/llrender/llfontgl.cpp

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
147147
{
148148
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
149149

150-
if(!sDisplayFont) //do not display texts
150+
if (!sDisplayFont) //do not display texts
151151
{
152152
return static_cast<S32>(wstr.length());
153153
}
@@ -181,23 +181,27 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
181181

182182
gGL.loadUIIdentity();
183183

184-
LLVector2 origin(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY));
184+
LLVector2 origin(floorf(sCurOrigin.mX * sScaleX), floorf(sCurOrigin.mY * sScaleY));
185185

186186
// Depth translation, so that floating text appears 'in-world'
187187
// and is correctly occluded.
188-
gGL.translatef(0.f,0.f,sCurDepth);
188+
gGL.translatef(0.f, 0.f, sCurDepth);
189189

190190
S32 chars_drawn = 0;
191-
S32 i;
192-
S32 length;
191+
S32 length = (S32)wstr.length() - begin_offset;
193192

194-
if (-1 == max_chars)
193+
if (max_chars < 0)
195194
{
196-
max_chars = length = (S32)wstr.length() - begin_offset;
195+
max_chars = length;
197196
}
198-
else
197+
else if (max_chars < length)
199198
{
200-
length = llmin((S32)wstr.length() - begin_offset, max_chars );
199+
length = max_chars;
200+
}
201+
202+
if (length < 1)
203+
{
204+
return 0;
201205
}
202206

203207
F32 cur_x, cur_y, cur_render_x, cur_render_y;
@@ -270,7 +274,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
270274

271275
const LLFontGlyphInfo* next_glyph = NULL;
272276

277+
// Maximum number of queued glyphs
273278
static constexpr U32 GLYPH_BATCH_SIZE = 30;
279+
// Each glyph uses 2 triangles == 6 vertices/uvs/colors
274280
static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6];
275281
static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6];
276282
static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 6];
@@ -280,11 +286,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
280286
// for the chat console)... HB
281287
LLColor4U emoji_color(255, 255, 255, text_color.mV[VALPHA]);
282288

283-
std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
284289
U32 glyph_count = 0;
285-
auto draw_queued_glyphs = [&]()
290+
auto render_queued_glyphs = [&](U32 max_glyph_count = 0)
286291
{
287-
if (glyph_count)
292+
if (glyph_count > max_glyph_count)
288293
{
289294
gGL.begin(LLRender::TRIANGLES);
290295
{
@@ -295,30 +300,33 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
295300
}
296301
};
297302

298-
for (i = begin_offset; i < begin_offset + length; i++)
303+
llwchar last_wch = 0;
304+
U32 glyph_per_char = 0; // This value can be 1, 2 or 6 depending on shadow
305+
// It will be set after the first call of drawGlyph
306+
for (S32 i = 0; i < length; i++)
299307
{
300-
llwchar wch = wstr[i];
308+
llwchar wch = wstr[begin_offset + i];
301309

302310
const LLFontGlyphInfo* fgi = next_glyph;
303311
next_glyph = NULL;
304312
if (!fgi)
305313
{
306-
fgi = mFontFreetype->getGlyphInfo(wch, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
314+
fgi = mFontFreetype->getGlyphInfo(wch, use_color ? EFontGlyphType::Color : EFontGlyphType::Grayscale);
307315
}
308316
if (!fgi)
309317
{
310318
LL_ERRS() << "Missing Glyph Info" << LL_ENDL;
311319
break;
312320
}
321+
313322
// Per-glyph bitmap texture.
314-
std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry;
315-
if (next_bitmap_entry != bitmap_entry)
323+
const std::pair<EFontGlyphType, S32>& bitmap_entry = fgi->mBitmapEntry;
324+
if (wch != last_wch || i == 0)
316325
{
317326
// Actually draw the queued glyphs before switching their texture;
318327
// otherwise the queued glyphs will be taken from wrong textures.
319-
draw_queued_glyphs();
328+
render_queued_glyphs();
320329

321-
bitmap_entry = next_bitmap_entry;
322330
LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
323331
gGL.getTexUnit(0)->bind(font_image);
324332
}
@@ -341,24 +349,35 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
341349
(F32)ll_round(cur_render_x + (F32)fgi->mXBearing) + (F32)fgi->mWidth,
342350
(F32)ll_round(cur_render_y + (F32)fgi->mYBearing) - (F32)fgi->mHeight);
343351

344-
draw_queued_glyphs();
352+
// Prevent the buffer overflow
353+
render_queued_glyphs(GLYPH_BATCH_SIZE - glyph_per_char);
345354

346355
const LLColor4U& col =
347356
bitmap_entry.first == EFontGlyphType::Grayscale ? text_color
348357
: emoji_color;
358+
// This function emplaces data to arrays vertices, uvs, colors
359+
// and increases glyph_count on 1, 2 or 6 depending on shadow
349360
drawGlyph(glyph_count, vertices, uvs, colors, screen_rect, uv_rect,
350361
col, style_to_add, shadow, drop_shadow_strength);
362+
llassert(glyph_count <= GLYPH_BATCH_SIZE);
363+
if (!glyph_per_char)
364+
{
365+
glyph_per_char = glyph_count;
366+
}
351367

352368
chars_drawn++;
353369
cur_x += fgi->mXAdvance;
354370
cur_y += fgi->mYAdvance;
355371

356-
llwchar next_char = wstr[i+1];
357-
if (next_char && (next_char < LAST_CHARACTER))
372+
if (i + 1 < length)
358373
{
359-
// Kern this puppy.
360-
next_glyph = mFontFreetype->getGlyphInfo(next_char, (!use_color) ? EFontGlyphType::Grayscale : EFontGlyphType::Color);
361-
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
374+
llwchar next_char = wstr[begin_offset + i + 1];
375+
if (next_char && (next_char < LAST_CHARACTER))
376+
{
377+
// Kern this puppy.
378+
next_glyph = mFontFreetype->getGlyphInfo(next_char, use_color ? EFontGlyphType::Color : EFontGlyphType::Grayscale);
379+
cur_x += mFontFreetype->getXKerning(fgi, next_glyph);
380+
}
362381
}
363382

364383
// Round after kerning.
@@ -372,7 +391,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
372391
cur_render_y = cur_y;
373392
}
374393

375-
draw_queued_glyphs();
394+
render_queued_glyphs();
376395

377396
if (right_x)
378397
{

0 commit comments

Comments
 (0)