summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2024-09-04 13:42:11 +0300
committerAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2024-09-05 06:55:53 +0300
commit238a2a64b31e6a0b431309e363067a7fe57125ae (patch)
tree99244c8e7cb542c9dc37f551e7aaf15720f5c478
parent49abe2c8bc23e306d304d02704e2b883648baea6 (diff)
viewer#2411 Use font buffer in text segments
-rw-r--r--indra/llrender/llfontvertexbuffer.cpp2
-rw-r--r--indra/llui/lltextbase.cpp55
-rw-r--r--indra/llui/lltextbase.h9
-rw-r--r--indra/llui/llviewmodel.cpp10
-rw-r--r--indra/llui/llviewmodel.h4
-rw-r--r--indra/newview/llpanelmaininventory.cpp102
-rw-r--r--indra/newview/llpanelmaininventory.h5
7 files changed, 137 insertions, 50 deletions
diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp
index 96ec94fe0f..392f235aad 100644
--- a/indra/llrender/llfontvertexbuffer.cpp
+++ b/indra/llrender/llfontvertexbuffer.cpp
@@ -42,6 +42,8 @@ LLFontVertexBuffer::~LLFontVertexBuffer()
void LLFontVertexBuffer::reset()
{
+ // Todo: some form of debug only frequecy check&assert to see if this is happening too often.
+ // Regenerating this list is expensive
mBufferList.clear();
}
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 0aebf7543c..6d480e8e00 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -948,7 +948,6 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
{
-
beforeValueChange();
segment_set_t::iterator seg_iter = getSegIterContaining(pos);
while(seg_iter != mSegments.end())
@@ -1325,6 +1324,7 @@ void LLTextBase::reshape(S32 width, S32 height, bool called_from_parent)
//virtual
void LLTextBase::draw()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
// reflow if needed, on demand
reflow();
@@ -2586,6 +2586,11 @@ const LLWString& LLTextBase::getWText() const
return getViewModel()->getDisplay();
}
+S32 LLTextBase::getTextGeneration() const
+{
+ return getViewModel()->getDisplayGeneration();
+}
+
// If round is true, if the position is on the right half of a character, the cursor
// will be put to its right. If round is false, the cursor will always be put to the
// character's left.
@@ -3280,7 +3285,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
: LLTextSegment(start, end),
mStyle( style ),
mToken(NULL),
- mEditor(editor)
+ mEditor(editor),
+ mLastGeneration(-1)
{
mFontHeight = mStyle->getFont()->getLineHeight();
@@ -3294,7 +3300,8 @@ LLNormalTextSegment::LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 e
LLNormalTextSegment::LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible)
: LLTextSegment(start, end),
mToken(NULL),
- mEditor(editor)
+ mEditor(editor),
+ mLastGeneration(-1)
{
mStyle = new LLStyle(LLStyle::Params().visible(is_visible).color(color));
@@ -3313,22 +3320,38 @@ F32 LLNormalTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selec
{
return drawClippedSegment( getStart() + start, getStart() + end, selection_start, selection_end, draw_rect);
}
+ else
+ {
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+ }
return draw_rect.mLeft;
}
// Draws a single text segment, reversing the color for selection if needed.
F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRectf rect)
{
- F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
-
- const LLWString &text = getWText();
-
F32 right_x = rect.mLeft;
if (!mStyle->isVisible())
{
return right_x;
}
+ F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
+
+ const LLWString& text = getWText();
+ S32 text_gen = mEditor.getTextGeneration();
+
+ if (text_gen != mLastGeneration)
+ {
+ mLastGeneration = text_gen;
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+ }
+
const LLFontGL* font = mStyle->getFont();
LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor()) % (alpha * mStyle->getAlpha());
@@ -3339,7 +3362,8 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 start = seg_start;
S32 end = llmin( selection_start, seg_end );
S32 length = end - start;
- font->render(text, start,
+ mFontBufferPreSelection.render(font,
+ text, start,
rect,
color,
LLFontGL::LEFT, mEditor.mTextVAlign,
@@ -3359,7 +3383,8 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 end = llmin( selection_end, seg_end );
S32 length = end - start;
- font->render(text, start,
+ mFontBufferSelection.render(font,
+ text, start,
rect,
mStyle->getSelectedColor().get(),
LLFontGL::LEFT, mEditor.mTextVAlign,
@@ -3377,7 +3402,8 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
S32 start = llmax( selection_end, seg_start );
S32 end = seg_end;
S32 length = end - start;
- font->render(text, start,
+ mFontBufferPostSelection.render(font,
+ text, start,
rect,
color,
LLFontGL::LEFT, mEditor.mTextVAlign,
@@ -3573,6 +3599,15 @@ S32 LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
return num_chars;
}
+void LLNormalTextSegment::updateLayout(const class LLTextBase& editor)
+{
+ LLTextSegment::updateLayout(editor);
+
+ mFontBufferPreSelection.reset();
+ mFontBufferSelection.reset();
+ mFontBufferPostSelection.reset();
+}
+
void LLNormalTextSegment::dump() const
{
LL_INFOS() << "Segment [" <<
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 00cf66b134..e2981c2637 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -30,6 +30,7 @@
#include "v4color.h"
#include "lleditmenuhandler.h"
+#include "llfontvertexbuffer.h"
#include "llspellcheckmenuhandler.h"
#include "llstyle.h"
#include "llkeywords.h"
@@ -131,6 +132,7 @@ public:
/*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const;
/*virtual*/ S32 getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
/*virtual*/ S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const;
+ /*virtual*/ void updateLayout(const class LLTextBase& editor);
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
/*virtual*/ bool canEdit() const { return true; }
/*virtual*/ const LLUIColor& getColor() const { return mStyle->getColor(); }
@@ -161,6 +163,12 @@ protected:
LLKeywordToken* mToken;
std::string mTooltip;
boost::signals2::connection mImageLoadedConnection;
+
+ // font rendering
+ LLFontVertexBuffer mFontBufferPreSelection;
+ LLFontVertexBuffer mFontBufferSelection;
+ LLFontVertexBuffer mFontBufferPostSelection;
+ S32 mLastGeneration = -1;
};
// This text segment is the same as LLNormalTextSegment, the only difference
@@ -432,6 +440,7 @@ public:
// wide-char versions
void setWText(const LLWString& text);
const LLWString& getWText() const;
+ S32 getTextGeneration() const;
void appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
diff --git a/indra/llui/llviewmodel.cpp b/indra/llui/llviewmodel.cpp
index 93106b344f..35963c2b99 100644
--- a/indra/llui/llviewmodel.cpp
+++ b/indra/llui/llviewmodel.cpp
@@ -82,11 +82,20 @@ void LLTextViewModel::setValue(const LLSD& value)
// approximate LLSD storage usage
LLViewModel::setValue(value);
mDisplay = utf8str_to_wstring(mStringValue = value.asString());
+ mDisplayGeneration++;
// mDisplay and mValue agree
mUpdateFromDisplay = false;
}
+LLWString& LLTextViewModel::getEditableDisplay()
+{
+ mDirty = true;
+ mDisplayGeneration++;
+ mUpdateFromDisplay = true;
+ return mDisplay;
+}
+
void LLTextViewModel::setDisplay(const LLWString& value)
{
// This is the strange way to alter the value. Normally we'd setValue()
@@ -94,6 +103,7 @@ void LLTextViewModel::setDisplay(const LLWString& value)
// value. But a text editor might want to edit the display string
// directly, then convert back to UTF8 on commit.
mDisplay = value;
+ mDisplayGeneration++;
mDirty = true;
// Don't immediately convert to UTF8 -- do it lazily -- we expect many
// more setDisplay() calls than getValue() calls. Just flag that it needs
diff --git a/indra/llui/llviewmodel.h b/indra/llui/llviewmodel.h
index 6cf2200a81..16b0800ce2 100644
--- a/indra/llui/llviewmodel.h
+++ b/indra/llui/llviewmodel.h
@@ -105,7 +105,8 @@ public:
// New functions
/// Get the stored value in string form
const LLWString& getDisplay() const { return mDisplay; }
- LLWString& getEditableDisplay() { mDirty = true; mUpdateFromDisplay = true; return mDisplay; }
+ S32 getDisplayGeneration() const { return mDisplayGeneration; }
+ LLWString& getEditableDisplay();
/**
* Set the display string directly (see LLTextEditor). What the user is
@@ -120,6 +121,7 @@ private:
/// To avoid converting every widget's stored value from LLSD to LLWString
/// every frame, cache the converted value
LLWString mDisplay;
+ S32 mDisplayGeneration = -1;
/// As the user edits individual characters (setDisplay()), defer
/// LLWString-to-UTF8 conversions until s/he's done.
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 2466ee5973..0c068ff993 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -963,59 +963,87 @@ void LLPanelMainInventory::draw()
void LLPanelMainInventory::updateItemcountText()
{
- if(mItemCount != gInventory.getItemCount())
- {
- mItemCount = gInventory.getItemCount();
- mItemCountString = "";
- LLLocale locale(LLLocale::USER_LOCALE);
- LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
- }
-
- if(mCategoryCount != gInventory.getCategoryCount())
+ bool update = false;
+ if (mSingleFolderMode)
{
- mCategoryCount = gInventory.getCategoryCount();
- mCategoryCountString = "";
- LLLocale locale(LLLocale::USER_LOCALE);
- LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
- }
-
- LLStringUtil::format_map_t string_args;
- string_args["[ITEM_COUNT]"] = mItemCountString;
- string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
- string_args["[FILTER]"] = getFilterText();
+ LLInventoryModel::cat_array_t* cats;
+ LLInventoryModel::item_array_t* items;
- std::string text = "";
+ gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items);
+ S32 item_count = items ? (S32)items->size() : 0;
+ S32 cat_count = cats ? (S32)cats->size() : 0;
- if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
- {
- text = getString("ItemcountFetching", string_args);
+ if (mItemCount != item_count)
+ {
+ mItemCount = item_count;
+ update = true;
+ }
+ if (mCategoryCount != cat_count)
+ {
+ mCategoryCount = cat_count;
+ update = true;
+ }
}
- else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ else
{
- text = getString("ItemcountCompleted", string_args);
+ if (mItemCount != gInventory.getItemCount())
+ {
+ mItemCount = gInventory.getItemCount();
+ update = true;
+ }
+
+ if (mCategoryCount != gInventory.getCategoryCount())
+ {
+ mCategoryCount = gInventory.getCategoryCount();
+ update = true;
+ }
}
- else
+
+ if (mLastFilterText != getFilterText())
{
- text = getString("ItemcountUnknown", string_args);
+ mLastFilterText = getFilterText();
+ update = true;
}
- if (mSingleFolderMode)
+ if (update)
{
- LLInventoryModel::cat_array_t *cats;
- LLInventoryModel::item_array_t *items;
+ mItemCountString = "";
+ LLLocale locale(LLLocale::USER_LOCALE);
+ LLResMgr::getInstance()->getIntegerString(mItemCountString, mItemCount);
- gInventory.getDirectDescendentsOf(getCurrentSFVRoot(), cats, items);
+ mCategoryCountString = "";
+ LLResMgr::getInstance()->getIntegerString(mCategoryCountString, mCategoryCount);
- if (items && cats)
+ LLStringUtil::format_map_t string_args;
+ string_args["[ITEM_COUNT]"] = mItemCountString;
+ string_args["[CATEGORY_COUNT]"] = mCategoryCountString;
+ string_args["[FILTER]"] = mLastFilterText;
+
+ std::string text = "";
+
+ if (mSingleFolderMode)
{
- string_args["[ITEM_COUNT]"] = llformat("%d", items->size());
- string_args["[CATEGORY_COUNT]"] = llformat("%d", cats->size());
text = getString("ItemcountCompleted", string_args);
}
- }
+ else
+ {
+ if (LLInventoryModelBackgroundFetch::instance().folderFetchActive())
+ {
+ text = getString("ItemcountFetching", string_args);
+ }
+ else if (LLInventoryModelBackgroundFetch::instance().isEverythingFetched())
+ {
+ text = getString("ItemcountCompleted", string_args);
+ }
+ else
+ {
+ text = getString("ItemcountUnknown", string_args);
+ }
+ }
- mCounterCtrl->setValue(text);
- mCounterCtrl->setToolTip(text);
+ mCounterCtrl->setValue(text);
+ mCounterCtrl->setToolTip(text);
+ }
}
void LLPanelMainInventory::onFocusReceived()
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 3347ab904b..d28daddd73 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -196,9 +196,10 @@ private:
LLSaveFolderState* mSavedFolderState;
std::string mFilterText;
std::string mFilterSubString;
- S32 mItemCount;
+ S32 mItemCount = 0;
+ std::string mLastFilterText;
std::string mItemCountString;
- S32 mCategoryCount;
+ S32 mCategoryCount = 0;
std::string mCategoryCountString;
LLComboBox* mSearchTypeCombo;