From 1bc67a9d725b88a0ebdde77cef928abd33fa9cf6 Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 4 Feb 2010 10:25:31 -0800 Subject: EXT-4625 - Chat bar doesn't display trailing character on some strings reviewed by Leyla --- indra/llrender/llfontgl.cpp | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 1de1d6ded4..b6a6b448ee 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -601,14 +601,20 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ { llwchar wch = wchars[i]; - F32 char_width = mFontFreetype->getXAdvance(wch); + const LLFontGlyphInfo* fgi= mFontFreetype->getGlyphInfo(wch); + + // last character uses character width, since the whole character needs to be visible + // other characters just use advance + F32 width = (i == start) + ? (F32)(fgi->mWidth + fgi->mXBearing) // use actual width for last character + : fgi->mXAdvance; // use advance for all other characters - if( scaled_max_pixels < (total_width + char_width) ) + if( scaled_max_pixels < (total_width + width) ) { break; } - total_width += char_width; + total_width += width; drawable_chars++; if( max_chars >= 0 && drawable_chars >= max_chars ) @@ -626,7 +632,17 @@ S32 LLFontGL::firstDrawableChar(const llwchar* wchars, F32 max_pixels, S32 text_ total_width = llround(total_width); } - return start_pos - drawable_chars; + if (drawable_chars == 0) + { + return start_pos; // just draw last character + } + else + { + // if only 1 character is drawable, we want to return start_pos as the first character to draw + // if 2 are drawable, return start_pos and character before start_pos, etc. + return start_pos + 1 - drawable_chars; + } + } S32 LLFontGL::charFromPixelOffset(const llwchar* wchars, S32 begin_offset, F32 target_x, F32 max_pixels, S32 max_chars, BOOL round) const -- cgit v1.2.3 From 979ddb2ec952f836f7cde7cbc85559b8e9582416 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 4 Feb 2010 23:41:54 -0600 Subject: No more matrix ops in UI code. --- indra/llrender/llfontgl.cpp | 30 +++++-------- indra/llrender/llrender.cpp | 106 ++++++++++++++++++++++++++++++++++++++++++-- indra/llrender/llrender.h | 18 +++++++- 3 files changed, 131 insertions(+), 23 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 1de1d6ded4..129f3e7999 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -151,14 +151,16 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } } - gGL.pushMatrix(); - glLoadIdentity(); - gGL.translatef(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); + gGL.pushUIMatrix(); + + gGL.loadUIIdentity(); + + gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); // this code snaps the text origin to a pixel grid to start with F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); - gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f); + gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f); LLFastTimer t(FTM_RENDER_FONTS); @@ -246,9 +248,6 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } - // Remember last-used texture to avoid unnecesssary bind calls. - LLImageGL *last_bound_texture = NULL; - for (i = begin_offset; i < begin_offset + length; i++) { llwchar wch = wstr[i]; @@ -261,12 +260,8 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } // Per-glyph bitmap texture. LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); - if (last_bound_texture != image_gl) - { - gGL.getTexUnit(0)->bind(image_gl); - last_bound_texture = image_gl; - } - + gGL.getTexUnit(0)->bind(image_gl); + if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) { // Not enough room for this character. @@ -330,10 +325,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons // recursively render ellipses at end of string // we've already reserved enough room - gGL.pushMatrix(); - //glLoadIdentity(); - //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); - //glScalef(sScaleX, sScaleY, 1.f); + gGL.pushUIMatrix(); renderUTF8(std::string("..."), 0, cur_x / sScaleX, (F32)y, @@ -344,10 +336,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons S32_MAX, max_pixels, right_x, FALSE); - gGL.popMatrix(); + gGL.popUIMatrix(); } - gGL.popMatrix(); + gGL.popUIMatrix(); return chars_drawn; } diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index f97d81126e..cde60b7e25 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -49,6 +49,9 @@ F64 gGLLastProjection[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; +U32 LLRender::sUICalls = 0; +U32 LLRender::sUIVerts = 0; + static const U32 LL_NUM_TEXTURE_LAYERS = 16; static GLenum sGLTextureType[] = @@ -255,10 +258,9 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) return false ; } - gGL.flush(); - if ((mCurrTexture != texture->getTexName()) || forceBind) { + gGL.flush(); activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); @@ -445,6 +447,8 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type) return; } + gGL.flush(); + activate(); mCurrBlendType = type; S32 scale_amount = 1; @@ -756,6 +760,7 @@ LLRender::LLRender() mCurrAlphaFunc = CF_DEFAULT; mCurrAlphaFuncVal = 0.01f; + mCurrSceneBlendType = BT_ALPHA; } LLRender::~LLRender() @@ -818,6 +823,80 @@ void LLRender::popMatrix() glPopMatrix(); } +void LLRender::translateUI(F32 x, F32 y, F32 z) +{ + if (mUIOffset.empty()) + { + llerrs << "Need to push a UI translation frame before offsetting" << llendl; + } + + mUIOffset.front().mV[0] += x; + mUIOffset.front().mV[1] += y; + mUIOffset.front().mV[2] += z; +} + +void LLRender::scaleUI(F32 x, F32 y, F32 z) +{ + if (mUIScale.empty()) + { + llerrs << "Need to push a UI transformation frame before scaling." << llendl; + } + + mUIScale.front().scaleVec(LLVector3(x,y,z)); +} + +void LLRender::pushUIMatrix() +{ + mUIOffset.push_front(mUIOffset.front()); + if (mUIScale.empty()) + { + mUIScale.push_front(LLVector3(1,1,1)); + } + else + { + mUIScale.push_front(mUIScale.front()); + } +} + +void LLRender::popUIMatrix() +{ + if (mUIOffset.empty()) + { + llerrs << "UI offset stack blown." << llendl; + } + mUIOffset.pop_front(); + mUIScale.pop_front(); +} + +LLVector3 LLRender::getUITranslation() +{ + if (mUIOffset.empty()) + { + llerrs << "UI offset stack empty." << llendl; + } + return mUIOffset.front(); +} + +LLVector3 LLRender::getUIScale() +{ + if (mUIScale.empty()) + { + llerrs << "UI scale stack empty." << llendl; + } + return mUIScale.front(); +} + + +void LLRender::loadUIIdentity() +{ + if (mUIOffset.empty()) + { + llerrs << "Need to push UI translation frame before clearing offset." << llendl; + } + mUIOffset.front().setVec(0,0,0); + mUIScale.front().setVec(1,1,1); +} + void LLRender::setColorMask(bool writeColor, bool writeAlpha) { setColorMask(writeColor, writeColor, writeColor, writeAlpha); @@ -840,6 +919,11 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB void LLRender::setSceneBlendType(eBlendType type) { + if (mCurrSceneBlendType == type) + { + return; + } + flush(); switch (type) { @@ -868,6 +952,7 @@ void LLRender::setSceneBlendType(eBlendType type) llerrs << "Unknown Scene Blend Type: " << type << llendl; break; } + mCurrSceneBlendType = type; } void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) @@ -1009,6 +1094,12 @@ void LLRender::flush() } #endif + if (!mUIOffset.empty()) + { + sUICalls++; + sUIVerts += mCount; + } + mBuffer->setBuffer(immediate_mask); mBuffer->drawArrays(mMode, 0, mCount); @@ -1028,7 +1119,16 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) return; } - mVerticesp[mCount] = LLVector3(x,y,z); + if (mUIOffset.empty()) + { + mVerticesp[mCount] = LLVector3(x,y,z); + } + else + { + LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front()); + mVerticesp[mCount] = vert; + } + mCount++; if (mCount < 4096) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 0121a190ee..6e38fac67b 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -286,6 +286,14 @@ public: void pushMatrix(); void popMatrix(); + void translateUI(F32 x, F32 y, F32 z); + void scaleUI(F32 x, F32 y, F32 z); + void pushUIMatrix(); + void popUIMatrix(); + void loadUIIdentity(); + LLVector3 getUITranslation(); + LLVector3 getUIScale(); + void flush(); void begin(const GLuint& mode); @@ -333,7 +341,9 @@ public: }; public: - + static U32 sUICalls; + static U32 sUIVerts; + private: bool mDirty; U32 mCount; @@ -350,7 +360,13 @@ private: std::vector mTexUnits; LLTexUnit* mDummyTexUnit; + U32 mCurrSceneBlendType; + F32 mMaxAnisotropy; + + std::list mUIOffset; + std::list mUIScale; + }; extern F64 gGLModelView[16]; -- cgit v1.2.3 From a35d61a6ec2545940f69b10e3e9111f21010a30a Mon Sep 17 00:00:00 2001 From: Andrew Dyukov Date: Mon, 8 Feb 2010 18:01:45 +0200 Subject: Fixed critical bug EXT-4971 (Crash when attemping to change UI size) - Adding default glyph for fallback fonts is now skipped in LLFontFreetype::resetBitmapCache(). --HG-- branch : product-engine --- indra/llrender/llfontfreetype.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 59e7d890f4..22fad792da 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -504,8 +504,13 @@ void LLFontFreetype::resetBitmapCache() mCharGlyphInfoMap.clear(); mFontBitmapCachep->reset(); - // Add the empty glyph - addGlyphFromFont(this, 0, 0); + // Adding default glyph is skipped for fallback fonts here as well as in loadFace(). + // This if was added as fix for EXT-4971. + if(!mIsFallback) + { + // Add the empty glyph + addGlyphFromFont(this, 0, 0); + } } void LLFontFreetype::destroyGL() -- cgit v1.2.3 From 651b14fcae01b089522f3672bbf35bfbe7268aac Mon Sep 17 00:00:00 2001 From: Palmer Truelson Date: Fri, 12 Feb 2010 21:04:51 -0800 Subject: Backed out davep's UI optimization. changeset 3134cb7bb181 --- indra/llrender/llfontgl.cpp | 30 ++++++++----- indra/llrender/llrender.cpp | 106 ++------------------------------------------ indra/llrender/llrender.h | 18 +------- 3 files changed, 23 insertions(+), 131 deletions(-) (limited to 'indra/llrender') diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 129f3e7999..1de1d6ded4 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -151,16 +151,14 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } } - gGL.pushUIMatrix(); - - gGL.loadUIIdentity(); - - gGL.translateUI(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); + gGL.pushMatrix(); + glLoadIdentity(); + gGL.translatef(floorf(sCurOrigin.mX*sScaleX), floorf(sCurOrigin.mY*sScaleY), sCurOrigin.mZ); // this code snaps the text origin to a pixel grid to start with F32 pixel_offset_x = llround((F32)sCurOrigin.mX) - (sCurOrigin.mX); F32 pixel_offset_y = llround((F32)sCurOrigin.mY) - (sCurOrigin.mY); - gGL.translateUI(-pixel_offset_x, -pixel_offset_y, 0.f); + gGL.translatef(-pixel_offset_x, -pixel_offset_y, 0.f); LLFastTimer t(FTM_RENDER_FONTS); @@ -248,6 +246,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } + // Remember last-used texture to avoid unnecesssary bind calls. + LLImageGL *last_bound_texture = NULL; + for (i = begin_offset; i < begin_offset + length; i++) { llwchar wch = wstr[i]; @@ -260,8 +261,12 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons } // Per-glyph bitmap texture. LLImageGL *image_gl = mFontFreetype->getFontBitmapCache()->getImageGL(fgi->mBitmapNum); - gGL.getTexUnit(0)->bind(image_gl); - + if (last_bound_texture != image_gl) + { + gGL.getTexUnit(0)->bind(image_gl); + last_bound_texture = image_gl; + } + if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth)) { // Not enough room for this character. @@ -325,7 +330,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons // recursively render ellipses at end of string // we've already reserved enough room - gGL.pushUIMatrix(); + gGL.pushMatrix(); + //glLoadIdentity(); + //gGL.translatef(sCurOrigin.mX, sCurOrigin.mY, 0.0f); + //glScalef(sScaleX, sScaleY, 1.f); renderUTF8(std::string("..."), 0, cur_x / sScaleX, (F32)y, @@ -336,10 +344,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons S32_MAX, max_pixels, right_x, FALSE); - gGL.popUIMatrix(); + gGL.popMatrix(); } - gGL.popUIMatrix(); + gGL.popMatrix(); return chars_drawn; } diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index cde60b7e25..f97d81126e 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -49,9 +49,6 @@ F64 gGLLastProjection[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; -U32 LLRender::sUICalls = 0; -U32 LLRender::sUIVerts = 0; - static const U32 LL_NUM_TEXTURE_LAYERS = 16; static GLenum sGLTextureType[] = @@ -258,9 +255,10 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) return false ; } + gGL.flush(); + if ((mCurrTexture != texture->getTexName()) || forceBind) { - gGL.flush(); activate(); enable(texture->getTarget()); mCurrTexture = texture->getTexName(); @@ -447,8 +445,6 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type) return; } - gGL.flush(); - activate(); mCurrBlendType = type; S32 scale_amount = 1; @@ -760,7 +756,6 @@ LLRender::LLRender() mCurrAlphaFunc = CF_DEFAULT; mCurrAlphaFuncVal = 0.01f; - mCurrSceneBlendType = BT_ALPHA; } LLRender::~LLRender() @@ -823,80 +818,6 @@ void LLRender::popMatrix() glPopMatrix(); } -void LLRender::translateUI(F32 x, F32 y, F32 z) -{ - if (mUIOffset.empty()) - { - llerrs << "Need to push a UI translation frame before offsetting" << llendl; - } - - mUIOffset.front().mV[0] += x; - mUIOffset.front().mV[1] += y; - mUIOffset.front().mV[2] += z; -} - -void LLRender::scaleUI(F32 x, F32 y, F32 z) -{ - if (mUIScale.empty()) - { - llerrs << "Need to push a UI transformation frame before scaling." << llendl; - } - - mUIScale.front().scaleVec(LLVector3(x,y,z)); -} - -void LLRender::pushUIMatrix() -{ - mUIOffset.push_front(mUIOffset.front()); - if (mUIScale.empty()) - { - mUIScale.push_front(LLVector3(1,1,1)); - } - else - { - mUIScale.push_front(mUIScale.front()); - } -} - -void LLRender::popUIMatrix() -{ - if (mUIOffset.empty()) - { - llerrs << "UI offset stack blown." << llendl; - } - mUIOffset.pop_front(); - mUIScale.pop_front(); -} - -LLVector3 LLRender::getUITranslation() -{ - if (mUIOffset.empty()) - { - llerrs << "UI offset stack empty." << llendl; - } - return mUIOffset.front(); -} - -LLVector3 LLRender::getUIScale() -{ - if (mUIScale.empty()) - { - llerrs << "UI scale stack empty." << llendl; - } - return mUIScale.front(); -} - - -void LLRender::loadUIIdentity() -{ - if (mUIOffset.empty()) - { - llerrs << "Need to push UI translation frame before clearing offset." << llendl; - } - mUIOffset.front().setVec(0,0,0); - mUIScale.front().setVec(1,1,1); -} - void LLRender::setColorMask(bool writeColor, bool writeAlpha) { setColorMask(writeColor, writeColor, writeColor, writeAlpha); @@ -919,11 +840,6 @@ void LLRender::setColorMask(bool writeColorR, bool writeColorG, bool writeColorB void LLRender::setSceneBlendType(eBlendType type) { - if (mCurrSceneBlendType == type) - { - return; - } - flush(); switch (type) { @@ -952,7 +868,6 @@ void LLRender::setSceneBlendType(eBlendType type) llerrs << "Unknown Scene Blend Type: " << type << llendl; break; } - mCurrSceneBlendType = type; } void LLRender::setAlphaRejectSettings(eCompareFunc func, F32 value) @@ -1094,12 +1009,6 @@ void LLRender::flush() } #endif - if (!mUIOffset.empty()) - { - sUICalls++; - sUIVerts += mCount; - } - mBuffer->setBuffer(immediate_mask); mBuffer->drawArrays(mMode, 0, mCount); @@ -1119,16 +1028,7 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) return; } - if (mUIOffset.empty()) - { - mVerticesp[mCount] = LLVector3(x,y,z); - } - else - { - LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.front()).scaledVec(mUIScale.front()); - mVerticesp[mCount] = vert; - } - + mVerticesp[mCount] = LLVector3(x,y,z); mCount++; if (mCount < 4096) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 6e38fac67b..0121a190ee 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -286,14 +286,6 @@ public: void pushMatrix(); void popMatrix(); - void translateUI(F32 x, F32 y, F32 z); - void scaleUI(F32 x, F32 y, F32 z); - void pushUIMatrix(); - void popUIMatrix(); - void loadUIIdentity(); - LLVector3 getUITranslation(); - LLVector3 getUIScale(); - void flush(); void begin(const GLuint& mode); @@ -341,9 +333,7 @@ public: }; public: - static U32 sUICalls; - static U32 sUIVerts; - + private: bool mDirty; U32 mCount; @@ -360,13 +350,7 @@ private: std::vector mTexUnits; LLTexUnit* mDummyTexUnit; - U32 mCurrSceneBlendType; - F32 mMaxAnisotropy; - - std::list mUIOffset; - std::list mUIScale; - }; extern F64 gGLModelView[16]; -- cgit v1.2.3