summaryrefslogtreecommitdiff
path: root/indra/llrender
diff options
context:
space:
mode:
authorJonathan "Geenz" Goodman <geenz@geenzo.com>2025-03-11 22:44:49 -0400
committerJonathan "Geenz" Goodman <geenz@geenzo.com>2025-03-11 22:44:49 -0400
commite0d14e02e152b4e75ff8bdd974677f9669163d68 (patch)
tree3379d14c9c5d8c188d2fb716e61edd09fc1219a9 /indra/llrender
parent179b29252d8bb28e11686a1852c8e8ffcd98ecc0 (diff)
parentb50ad90febda24d2296541f46ea1a129232aad70 (diff)
Merge branch 'release/2025.03' into rye/forevermac
Diffstat (limited to 'indra/llrender')
-rw-r--r--indra/llrender/llcubemaparray.cpp2
-rw-r--r--indra/llrender/llfontbitmapcache.cpp6
-rw-r--r--indra/llrender/llfontbitmapcache.h2
-rw-r--r--indra/llrender/llfontfreetype.cpp12
-rw-r--r--indra/llrender/llfontfreetype.h1
-rw-r--r--indra/llrender/llfontgl.cpp27
-rw-r--r--indra/llrender/llfontgl.h1
-rw-r--r--indra/llrender/llfontvertexbuffer.cpp6
-rw-r--r--indra/llrender/llfontvertexbuffer.h4
-rw-r--r--indra/llrender/llgl.cpp15
-rw-r--r--indra/llrender/llglslshader.h1
-rw-r--r--indra/llrender/llimagegl.cpp1
-rw-r--r--indra/llrender/llshadermgr.cpp8
13 files changed, 61 insertions, 25 deletions
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index 635f079581..d0a97dc2c6 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -127,7 +127,7 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us
bind(0);
free_cur_tex_image();
- U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F;
+ U32 format = components == 4 ? GL_RGBA16F : GL_R11F_G11F_B10F;
if (!hdr)
{
format = components == 4 ? GL_RGBA8 : GL_RGB8;
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index ee9cfd0719..6a3af1e608 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -107,7 +107,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
mBitmapHeight = image_height;
S32 num_components = getNumComponents(bitmap_type);
- mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
+ mImageRawVec[bitmap_idx].emplace_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1;
LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num);
@@ -117,7 +117,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
}
// Make corresponding GL image.
- mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false, false));
+ mImageGLVec[bitmap_idx].emplace_back(new LLImageGL(image_raw, false, false));
LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);
// Start at beginning of the new image.
@@ -141,6 +141,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
bitmap_num = getNumBitmaps(bitmap_type) - 1;
mCurrentOffsetX[bitmap_idx] += width + 1;
+ mGeneration++;
return true;
}
@@ -168,6 +169,7 @@ void LLFontBitmapCache::reset()
mBitmapWidth = 0;
mBitmapHeight = 0;
+ mGeneration++;
}
//static
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index f2dfd87877..0ae4e6bed0 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -63,6 +63,7 @@ public:
U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? static_cast<U32>(mImageRawVec[static_cast<U32>(bitmapType)].size()) : 0U; }
S32 getBitmapWidth() const { return mBitmapWidth; }
S32 getBitmapHeight() const { return mBitmapHeight; }
+ S32 getCacheGeneration() const { return mGeneration; }
protected:
static U32 getNumComponents(EFontGlyphType bitmap_type);
@@ -74,6 +75,7 @@ private:
S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)] = { 1 };
S32 mMaxCharWidth = 0;
S32 mMaxCharHeight = 0;
+ S32 mGeneration = 0;
std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)];
std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)];
};
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index bab721615b..97f01da084 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -143,7 +143,6 @@ LLFontFreetype::LLFontFreetype()
mIsFallback(false),
mFTFace(nullptr),
mRenderGlyphCount(0),
- mAddGlyphCount(0),
mStyle(0),
mPointSize(0)
{
@@ -502,7 +501,6 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l
S32 pos_x, pos_y;
U32 bitmap_num;
mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num);
- mAddGlyphCount++;
LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type);
gi->mXBitmapOffset = pos_x;
@@ -643,7 +641,7 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, ll
if (error == FT_Err_Out_Of_Memory)
{
LLError::LLUserWarningMsg::showOutOfMemory();
- LL_ERRS() << "Out of memory loading glyph for character " << U32(wch) << LL_ENDL;
+ LL_ERRS() << "Out of memory loading glyph for character " << llformat("U+%xu", U32(wch)) << LL_ENDL;
}
std::string message = llformat(
@@ -655,11 +653,11 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, ll
|| FT_Err_Invalid_Composite == error
|| (FT_Err_Ok != error && LLStringOps::isEmoji(wch)))
{
- glyph_index = FT_Get_Char_Index(mFTFace, '?');
- // if '?' is not present, potentially can use last index, that's supposed to be null glyph
- if (glyph_index > 0)
+ // value~0 always corresponds to the 'missing glyph'
+ error = FT_Load_Glyph(mFTFace, 0, FT_LOAD_FORCE_AUTOHINT);
+ if (FT_Err_Ok != error)
{
- error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
+ LL_ERRS() << "Loading fallback for char '" << (U32)wch << "', glyph " << glyph_index << " failed with error : " << (S32)error << LL_ENDL;
}
}
llassert_always_msg(FT_Err_Ok == error, message.c_str());
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index 3977911fe5..a9b3a944ee 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -190,7 +190,6 @@ private:
mutable LLFontBitmapCache* mFontBitmapCachep;
mutable S32 mRenderGlyphCount;
- mutable S32 mAddGlyphCount;
};
#endif // LL_FONTFREETYPE_H
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 91242f4947..16eec1fdd2 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -110,6 +110,12 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
return mFontFreetype->getNumFaces(filename);
}
+S32 LLFontGL::getCacheGeneration() const
+{
+ const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+ return font_bitmap_cache->getCacheGeneration();
+}
+
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const
{
@@ -250,6 +256,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+ // This looks wrong, value is dynamic.
+ // LLFontBitmapCache::nextOpenPos can alter these values when
+ // new characters get added to cache, which affects whole string.
+ // Todo: Perhaps value should update after symbols were added?
F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
@@ -271,12 +281,14 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const LLFontGlyphInfo* next_glyph = NULL;
+ // string can have more than one glyph per char (ex: bold or shadow),
+ // make sure that GLYPH_BATCH_SIZE won't end up with half a symbol.
+ // See drawGlyph.
+ // Ex: with shadows it's 6 glyps per char. 30 fits exactly 5 chars.
static constexpr S32 GLYPH_BATCH_SIZE = 30;
- // string can have more than one glyph per char, make sure last one can fit
- static constexpr S32 BUFFER_SIZE = GLYPH_BATCH_SIZE * 2;
- static thread_local LLVector4a vertices[BUFFER_SIZE * 6];
- static thread_local LLVector2 uvs[BUFFER_SIZE * 6];
- static thread_local LLColor4U colors[BUFFER_SIZE * 6];
+ static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6];
+ static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6];
+ static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 6];
LLColor4U text_color(color);
// Preserve the transparency to render fading emojis in fading text (e.g.
@@ -321,8 +333,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
gGL.getTexUnit(0)->bind(font_image);
- // For multi-byte characters just draw each time character changes
- // Might be overkill and might be better to detect multybyte
+ // For some reason it's not enough to compare by bitmap_entry.
+ // Issue hits emojis, japenese and chinese glyphs, only on first run.
+ // Todo: figure it out, there might be a bug with raw image data.
last_char = wch;
}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 9b63fc7c38..1c8e036f58 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -90,6 +90,7 @@ public:
bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
S32 getNumFaces(const std::string& filename);
+ S32 getCacheGeneration() const;
S32 render(const LLWString &text, S32 begin_offset,
const LLRect& rect,
diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp
index 17b23c420d..a223509d30 100644
--- a/indra/llrender/llfontvertexbuffer.cpp
+++ b/indra/llrender/llfontvertexbuffer.cpp
@@ -147,7 +147,8 @@ S32 LLFontVertexBuffer::render(
|| mLastVertDPI != LLFontGL::sVertDPI
|| mLastHorizDPI != LLFontGL::sHorizDPI
|| mLastOrigin != LLFontGL::sCurOrigin
- || mLastResGeneration != LLFontGL::sResolutionGeneration)
+ || mLastResGeneration != LLFontGL::sResolutionGeneration
+ || mLastFontCacheGen != fontp->getCacheGeneration())
{
genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
@@ -179,6 +180,9 @@ void LLFontVertexBuffer::genBuffers(
{
// todo: add a debug build assert if this triggers too often for to long?
mBufferList.clear();
+ // Save before rendreing, it can change mid-render,
+ // so will need to rerender previous characters
+ mLastFontCacheGen = fontp->getCacheGeneration();
gGL.beginList(&mBufferList);
mChars = fontp->render(text, begin_offset, x, y, color, halign, valign,
diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h
index f244e7fefa..a9e1e2337c 100644
--- a/indra/llrender/llfontvertexbuffer.h
+++ b/indra/llrender/llfontvertexbuffer.h
@@ -120,6 +120,10 @@ private:
S32 mLastResGeneration = 0;
LLCoordGL mLastOrigin;
+ // Adding new characters to bitmap cache can alter value from getBitmapWidth();
+ // which alters whole string. So rerender when new characters were added to cache.
+ S32 mLastFontCacheGen = 0;
+
static bool sEnableBufferCollection;
};
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index fbd4b0f9c4..2be2bfbf7e 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -2452,12 +2452,15 @@ void LLGLState::checkStates(GLboolean writeAlpha)
return;
}
- GLint src;
- GLint dst;
- glGetIntegerv(GL_BLEND_SRC, &src);
- glGetIntegerv(GL_BLEND_DST, &dst);
- llassert_always(src == GL_SRC_ALPHA);
- llassert_always(dst == GL_ONE_MINUS_SRC_ALPHA);
+ GLint srcRGB, dstRGB, srcAlpha, dstAlpha;
+ glGetIntegerv(GL_BLEND_SRC_RGB, &srcRGB);
+ glGetIntegerv(GL_BLEND_DST_RGB, &dstRGB);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcAlpha);
+ glGetIntegerv(GL_BLEND_DST_ALPHA, &dstAlpha);
+ llassert_always(srcRGB == GL_SRC_ALPHA);
+ llassert_always(srcAlpha == GL_SRC_ALPHA);
+ llassert_always(dstRGB == GL_ONE_MINUS_SRC_ALPHA);
+ llassert_always(dstAlpha == GL_ONE_MINUS_SRC_ALPHA);
// disable for now until usage is consistent
//GLboolean colorMask[4];
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index cade888a83..4702a27cc5 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -59,6 +59,7 @@ public:
bool attachNothing = false;
bool hasHeroProbes = false;
bool isPBRTerrain = false;
+ bool hasTonemap = false;
};
// ============= Structure for caching shader uniforms ===============
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 0bfcb5d9d2..3f8903ca09 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -330,6 +330,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
case GL_RGB: return 24;
case GL_SRGB: return 24;
case GL_RGB8: return 24;
+ case GL_R11F_G11F_B10F: return 32;
case GL_RGBA: return 32;
case GL_RGBA8: return 32;
case GL_RGB10_A2: return 32;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index b1e2114156..725380b4b2 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -291,6 +291,14 @@ bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
+ if (features->hasTonemap)
+ {
+ if (!shader->attachFragmentObject("deferred/tonemapUtilF.glsl"))
+ {
+ return false;
+ }
+ }
+
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->hasAtmospherics)
{