viewer#2411 LLFontGL::render optimizations #2
parent
2bae8dfb81
commit
a638d9610d
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ private:
|
|||
S32 mMaxLines;
|
||||
S32 mOffsetY;
|
||||
F32 mRadius;
|
||||
LLVector3 mLastRenderPosition;
|
||||
std::vector<LLHUDTextSegment> mTextSegments;
|
||||
std::vector<LLHUDTextSegment> mLabelSegments;
|
||||
// LLFrameTimer mResizeTimer;
|
||||
|
|
|
|||
Loading…
Reference in New Issue