diff options
author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2024-09-04 13:42:11 +0300 |
---|---|---|
committer | Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> | 2024-09-05 06:55:53 +0300 |
commit | 238a2a64b31e6a0b431309e363067a7fe57125ae (patch) | |
tree | 99244c8e7cb542c9dc37f551e7aaf15720f5c478 | |
parent | 49abe2c8bc23e306d304d02704e2b883648baea6 (diff) |
viewer#2411 Use font buffer in text segments
-rw-r--r-- | indra/llrender/llfontvertexbuffer.cpp | 2 | ||||
-rw-r--r-- | indra/llui/lltextbase.cpp | 55 | ||||
-rw-r--r-- | indra/llui/lltextbase.h | 9 | ||||
-rw-r--r-- | indra/llui/llviewmodel.cpp | 10 | ||||
-rw-r--r-- | indra/llui/llviewmodel.h | 4 | ||||
-rw-r--r-- | indra/newview/llpanelmaininventory.cpp | 102 | ||||
-rw-r--r-- | indra/newview/llpanelmaininventory.h | 5 |
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; |