viewer#2411 LLFontGL::render optimizations #2

master
Andrey Kleshchev 2024-08-29 18:49:10 +03:00 committed by Andrey Kleshchev
parent 2bae8dfb81
commit a638d9610d
7 changed files with 192 additions and 72 deletions

View File

@ -490,6 +490,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
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();

View File

@ -53,7 +53,8 @@ S32 LLFontVertexBuffer::render(
F32 x, F32 y,
const LLColor4& color,
LLFontGL::HAlign halign, LLFontGL::VAlign valign,
U8 style, LLFontGL::ShadowType shadow,
U8 style,
LLFontGL::ShadowType shadow,
S32 max_chars , S32 max_pixels,
F32* right_x,
bool use_ellipses,
@ -64,62 +65,33 @@ S32 LLFontVertexBuffer::render(
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
else if (mLastX != x || mLastY != y
|| mLastFont != fontp
|| mLastColor != color // alphas change often
|| mLastHalign != halign
|| mLastValign != valign
|| mLastOffset != begin_offset
|| mLastMaxChars != max_chars
|| mLastMaxPixels != max_pixels
|| mLastStyle != style
|| mLastShadow != shadow) // ex: buttons change shadow state
{
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?
else if (mTrackStringChanges && mLastStringHash != sStringHasher._Do_hash(text))
{
genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
}
else
{
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);
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;
}
@ -141,6 +113,7 @@ void LLFontVertexBuffer::genBuffers(
mChars = fontp->render(text, begin_offset, x, y, color, halign, valign,
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color, &mBufferList);
mLastFont = fontp;
mLastOffset = begin_offset;
mLastMaxChars = max_chars;
mLastMaxPixels = max_pixels;
@ -148,6 +121,10 @@ void LLFontVertexBuffer::genBuffers(
mLastX = x;
mLastY = y;
mLastColor = color;
mLastHalign = halign;
mLastValign = valign;
mLastStyle = style;
mLastShadow = shadow;
if (right_x)
{
@ -155,3 +132,61 @@ void LLFontVertexBuffer::genBuffers(
}
}
void render_buffers(LLFontVertexBuffer::buffer_list_t::iterator iter, LLFontVertexBuffer::buffer_list_t::iterator end)
{
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)
{
gGL.pushUIMatrix();
render_buffers(iter, end);
gGL.popUIMatrix();
}
gGL.popUIMatrix();
}
void LLFontVertexBuffer::renderBuffers()
{
gGL.flush(); // deliberately empty pending verts
render_buffers(mBufferList.begin(), mBufferList.end());
}

View File

@ -46,12 +46,14 @@ public:
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,
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);
typedef std::list<LLFontGL::LLVertexBufferData> buffer_list_t;
private:
void genBuffers(const LLFontGL* fontp,
@ -60,15 +62,18 @@ private:
F32 x, F32 y,
const LLColor4& color,
LLFontGL::HAlign halign, LLFontGL::VAlign valign,
U8 style, LLFontGL::ShadowType shadow,
U8 style,
LLFontGL::ShadowType shadow,
S32 max_chars, S32 max_pixels,
F32* right_x,
bool use_ellipses,
bool use_color);
void renderBuffers();
std::list<LLFontGL::LLVertexBufferData> mBufferList;
buffer_list_t mBufferList;
S32 mChars = 0;
const LLFontGL *mLastFont = nullptr;
S32 mLastOffset = 0;
S32 mLastMaxChars = 0;
S32 mLastMaxPixels = 0;
@ -76,6 +81,10 @@ private:
F32 mLastX = 0.f;
F32 mLastY = 0.f;
LLColor4 mLastColor;
LLFontGL::HAlign mLastHalign = LLFontGL::LEFT;
LLFontGL::VAlign mLastValign = LLFontGL::BASELINE;
U8 mLastStyle = LLFontGL::NORMAL;
LLFontGL::ShadowType mLastShadow = LLFontGL::NO_SHADOW;
F32 mLastRightX = 0.f;
bool mTrackStringChanges = true;

View File

@ -125,7 +125,6 @@ LLButton::LLButton(const LLButton::Params& p)
mFontBuffer(false),
mMouseDownFrame(0),
mMouseHeldDownCount(0),
mBorderEnabled( false ),
mFlashing( false ),
mCurGlowStrength(0.f),
mNeedsHighlight(false),
@ -423,11 +422,38 @@ bool LLButton::postBuild()
void LLButton::onVisibilityChange(bool new_visibility)
{
if (!new_visibility)
mFontBuffer.reset();
return LLUICtrl::onVisibilityChange(new_visibility);
}
void LLButton::reshape(S32 width, S32 height, bool called_from_parent)
{
S32 delta_width = width - getRect().getWidth();
S32 delta_height = height - getRect().getHeight();
if (delta_width || delta_height || sForceReshape)
{
LLUICtrl::reshape(width, height, called_from_parent);
mFontBuffer.reset();
}
return LLUICtrl::onVisibilityChange(new_visibility);
}
void LLButton::translate(S32 x, S32 y)
{
LLUICtrl::translate(x, y);
mFontBuffer.reset();
}
void LLButton::setRect(const LLRect& rect)
{
LLUICtrl::setRect(rect);
mFontBuffer.reset();
}
void LLButton::dirtyRect()
{
LLUICtrl::dirtyRect();
mFontBuffer.reset();
}
bool LLButton::handleUnicodeCharHere(llwchar uni_char)
@ -616,19 +642,25 @@ void LLButton::onMouseLeave(S32 x, S32 y, MASK mask)
{
LLUICtrl::onMouseLeave(x, y, mask);
mNeedsHighlight = false;
setHighlight(false);
}
void LLButton::setHighlight(bool b)
{
mNeedsHighlight = b;
if (mNeedsHighlight != b)
{
mNeedsHighlight = b;
mFontBuffer.reset();
}
}
bool LLButton::handleHover(S32 x, S32 y, MASK mask)
{
if (isInEnabledChain()
&& (!gFocusMgr.getMouseCapture() || gFocusMgr.getMouseCapture() == this))
mNeedsHighlight = true;
{
setHighlight(true);
}
if (!childrenHandleHover(x, y, mask))
{
@ -1096,6 +1128,18 @@ void LLButton::setLabelSelected( const LLStringExplicit& label )
mFontBuffer.reset();
}
void LLButton::setDisabledLabelColor(const LLUIColor& c)
{
mDisabledLabelColor = c;
mFontBuffer.reset();
}
void LLButton::setFont(const LLFontGL* font)
{
mGLFont = (font ? font : LLFontGL::getFontSansSerif());
mFontBuffer.reset();
}
bool LLButton::labelIsTruncated() const
{
return getCurrentLabel().getString().size() > mLastDrawCharsCount;
@ -1106,6 +1150,12 @@ const LLUIString& LLButton::getCurrentLabel() const
return getToggleState() ? mSelectedLabel : mUnselectedLabel;
}
void LLButton::setDropShadowedText(bool b)
{
mDropShadowedText = b;
mFontBuffer.reset();
}
void LLButton::setImageUnselected(LLPointer<LLUIImage> image)
{
mImageUnselected = image;
@ -1153,7 +1203,6 @@ void LLButton::resize(const LLUIString& label)
if (btn_width < min_width)
{
reshape(min_width, getRect().getHeight());
mFontBuffer.reset();
}
}
}
@ -1190,6 +1239,7 @@ void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image)
mImageDisabledSelected = image;
mDisabledImageColor = mImageColor;
mFadeWhenDisabled = true;
mFontBuffer.reset();
}
void LLButton::setImagePressed(LLPointer<LLUIImage> image)

View File

@ -157,23 +157,27 @@ public:
void addImageAttributeToXML(LLXMLNodePtr node, const std::string& imageName,
const LLUUID& imageID,const std::string& xmlTagName) const;
virtual bool handleUnicodeCharHere(llwchar uni_char);
virtual bool handleKeyHere(KEY key, MASK mask);
virtual bool handleMouseDown(S32 x, S32 y, MASK mask);
virtual bool handleMouseUp(S32 x, S32 y, MASK mask);
virtual bool handleHover(S32 x, S32 y, MASK mask);
virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual bool handleRightMouseUp(S32 x, S32 y, MASK mask);
virtual bool handleDoubleClick(S32 x, S32 y, MASK mask);
virtual void draw();
/*virtual*/ bool postBuild();
virtual bool handleUnicodeCharHere(llwchar uni_char) override;
virtual bool handleKeyHere(KEY key, MASK mask) override;
virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override;
virtual bool handleMouseUp(S32 x, S32 y, MASK mask) override;
virtual bool handleHover(S32 x, S32 y, MASK mask) override;
virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask) override;
virtual bool handleRightMouseUp(S32 x, S32 y, MASK mask) override;
virtual bool handleDoubleClick(S32 x, S32 y, MASK mask) override;
virtual void draw() override;
/*virtual*/ bool postBuild() override;
/*virtual*/ void onVisibilityChange(bool visible);
void onVisibilityChange(bool visible) override;
void reshape(S32 width, S32 height, bool called_from_parent = true) override;
void translate(S32 x, S32 y) override;
void setRect(const LLRect& rect) override;
void dirtyRect() override;
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
virtual void onMouseCaptureLost();
virtual void onMouseLeave(S32 x, S32 y, MASK mask) override;
virtual void onMouseCaptureLost() override;
virtual void onCommit();
virtual void onCommit() override;
void setUnselectedLabelColor(const LLUIColor& c);
void setSelectedLabelColor(const LLUIColor& c);
@ -227,7 +231,7 @@ public:
const std::string getLabelSelected() const { return wstring_to_utf8str(mSelectedLabel); }
void setImageColor(const LLUIColor& c);
/*virtual*/ void setColor(const LLUIColor& c);
/*virtual*/ void setColor(const LLUIColor& c) override;
void setImages(const std::string &image_name, const std::string &selected_name);
@ -245,13 +249,12 @@ public:
void setLabel(const std::string& label);
void setLabel(const LLUIString& label);
void setLabel( const LLStringExplicit& label);
virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text );
virtual bool setLabelArg( const std::string& key, const LLStringExplicit& text ) override;
void setLabelUnselected(const LLStringExplicit& label);
void setLabelSelected(const LLStringExplicit& label);
void setDisabledLabelColor( const LLUIColor& c ) { mDisabledLabelColor = c; }
void setDisabledLabelColor(const LLUIColor& c);
void setFont(const LLFontGL *font)
{ mGLFont = ( font ? font : LLFontGL::getFontSansSerif()); }
void setFont(const LLFontGL* font);
const LLFontGL* getFont() const { return mGLFont; }
const std::string& getText() const { return getCurrentLabel().getString(); }
@ -262,7 +265,7 @@ public:
void setScaleImage(bool scale) { mScaleImage = scale; }
bool getScaleImage() const { return mScaleImage; }
void setDropShadowedText(bool b) { mDropShadowedText = b; }
void setDropShadowedText(bool b);
void setHoverGlowStrength(F32 strength) { mHoverGlowStrength = strength; }

View File

@ -290,6 +290,15 @@ void LLHUDNameTag::renderText()
LLVector3 render_position = mPositionAgent
+ (x_pixel_vec * screen_offset.mV[VX])
+ (y_pixel_vec * screen_offset.mV[VY]);
bool reset_buffers = false;
const F32 treshold = 0.000001f;
if (abs(mLastRenderPosition.mV[VX] - render_position.mV[VX]) > treshold
|| abs(mLastRenderPosition.mV[VY] - render_position.mV[VY]) > treshold
|| abs(mLastRenderPosition.mV[VZ] - render_position.mV[VZ]) > treshold)
{
reset_buffers = true;
mLastRenderPosition = render_position;
}
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
LLRect screen_rect;
@ -313,6 +322,11 @@ void LLHUDNameTag::renderText()
for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin();
segment_iter != mLabelSegments.end(); ++segment_iter )
{
if (reset_buffers)
{
segment_iter->mFontBufferLabel.reset();
}
// Label segments use default font
const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp;
y_offset -= fontp->getLineHeight();
@ -350,6 +364,11 @@ void LLHUDNameTag::renderText()
for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment;
segment_iter != mTextSegments.end(); ++segment_iter )
{
if (reset_buffers)
{
segment_iter->mFontBufferText.reset();
}
const LLFontGL* fontp = segment_iter->mFont;
y_offset -= fontp->getLineHeight();
y_offset -= LINE_PADDING;

View File

@ -177,6 +177,7 @@ private:
S32 mMaxLines;
S32 mOffsetY;
F32 mRadius;
LLVector3 mLastRenderPosition;
std::vector<LLHUDTextSegment> mTextSegments;
std::vector<LLHUDTextSegment> mLabelSegments;
// LLFrameTimer mResizeTimer;