From d6eafa1bdbcfa69d60d2d7340c331e34d6915500 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 10 Sep 2024 19:26:16 +0300 Subject: Make updateKeyboardFocus a bit more efficient --- indra/newview/llviewerwindow.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8ea8fbf905..e24fb35acb 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3888,7 +3888,9 @@ void LLViewerWindow::updateKeyboardFocus() LLUICtrl* cur_focus = dynamic_cast(gFocusMgr.getKeyboardFocus()); if (cur_focus) { - if (!cur_focus->isInVisibleChain() || !cur_focus->isInEnabledChain()) + bool is_in_visible_chain = cur_focus->isInVisibleChain(); + bool is_in_enabled_chain = cur_focus->isInEnabledChain(); + if (!is_in_visible_chain || !is_in_enabled_chain) { // don't release focus, just reassign so that if being given // to a sibling won't call onFocusLost on all the ancestors @@ -3899,11 +3901,19 @@ void LLViewerWindow::updateKeyboardFocus() bool new_focus_found = false; while(parent) { + if (!is_in_visible_chain) + { + is_in_visible_chain = parent->isInVisibleChain(); + } + if (!is_in_enabled_chain) + { + is_in_enabled_chain = parent->isInEnabledChain(); + } if (parent->isCtrl() && (parent->hasTabStop() || parent == focus_root) && !parent->getIsChrome() - && parent->isInVisibleChain() - && parent->isInEnabledChain()) + && is_in_visible_chain + && is_in_enabled_chain) { if (!parent->focusFirstItem()) { -- cgit v1.2.3 From 047eb16f4c8fdfb1826136db9ee2eed83cb95416 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 10 Sep 2024 23:07:07 +0300 Subject: viewer#2529 Optimize updateGLVariablesForSettings Intent is to eventually use only stored variables for everything. LLSD operations are far too expensive. --- indra/llinventory/llsettingsbase.cpp | 89 ++++-- indra/llinventory/llsettingsbase.h | 109 ++++---- indra/llinventory/llsettingsdaycycle.cpp | 45 ++-- indra/llinventory/llsettingsdaycycle.h | 12 +- indra/llinventory/llsettingssky.cpp | 447 +++++++++++++++++++++++-------- indra/llinventory/llsettingssky.h | 67 ++++- indra/llinventory/llsettingswater.cpp | 53 +++- indra/llinventory/llsettingswater.h | 87 ++++-- indra/newview/llenvironment.cpp | 105 +------- indra/newview/llsettingsvo.cpp | 80 +++++- indra/newview/llsettingsvo.h | 10 +- 11 files changed, 767 insertions(+), 337 deletions(-) diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 4aab3dee3b..8575ac6920 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -69,25 +69,80 @@ const U32 LLSettingsBase::Validator::VALIDATION_PARTIAL(0x01 << 0); LLSettingsBase::LLSettingsBase(): mSettings(LLSD::emptyMap()), mDirty(true), - mBlendedFactor(0.0) + mLLSDDirty(false), + mReplaced(false), + mBlendedFactor(0.0), + mSettingFlags(0) { + loadValuesFromLLSD(); } LLSettingsBase::LLSettingsBase(const LLSD setting) : mSettings(setting), + mLLSDDirty(false), mDirty(true), - mBlendedFactor(0.0) + mReplaced(false), + mBlendedFactor(0.0), + mSettingFlags(0) { + loadValuesFromLLSD(); +} + +//virtual +void LLSettingsBase::loadValuesFromLLSD() +{ + mLLSDDirty = false; + + mAssetId = mSettings[SETTING_ASSETID].asUUID(); + mSettingId = getValue(SETTING_ID).asUUID(); + mSettingName = getValue(SETTING_NAME).asString(); + if (mSettings.has(SETTING_FLAGS)) + { + mSettingFlags = (U32)mSettings[SETTING_FLAGS].asInteger(); + } + else + { + mSettingFlags = 0; + } +} + +//virtual +void LLSettingsBase::saveValuesToLLSD() +{ + mLLSDDirty = false; + + mSettings[SETTING_NAME] = mSettingName; + if (mAssetId.isNull()) + { + mSettings.erase(SETTING_ASSETID); + } + else + { + mSettings[SETTING_ASSETID] = mAssetId; + } + mSettings[SETTING_FLAGS] = LLSD::Integer(mSettingFlags); +} + +void LLSettingsBase::saveValuesIfNeeded() +{ + if (mLLSDDirty) + { + saveValuesToLLSD(); + } } //========================================================================= -void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix) +void LLSettingsBase::lerpSettings(LLSettingsBase &other, F64 mix) { - mSettings = interpolateSDMap(mSettings, other.mSettings, other.getParameterMap(), mix); + saveValuesIfNeeded(); + stringset_t skip = getSkipInterpolateKeys(); + stringset_t slerps = getSlerpKeys(); + mSettings = interpolateSDMap(mSettings, other.getSettings(), other.getParameterMap(), mix, skip, slerps); setDirtyFlag(true); + loadValuesFromLLSD(); } -LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const +LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) { LLSD newSettings; @@ -161,13 +216,10 @@ LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) cons return newSettings; } -LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, F64 mix) const +LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, F64 mix, const stringset_t& skip, const stringset_t& slerps) { LLSD newSettings; - stringset_t skip = getSkipInterpolateKeys(); - stringset_t slerps = getSlerpKeys(); - llassert(mix >= 0.0f && mix <= 1.0f); for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it) @@ -204,7 +256,7 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c } } - newSettings[key_name] = interpolateSDValue(key_name, value, other_value, defaults, mix, slerps); + newSettings[key_name] = interpolateSDValue(key_name, value, other_value, defaults, mix, skip, slerps); } // Special handling cases @@ -233,12 +285,12 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c if (def_iter != defaults.end()) { // Blend against default value - newSettings[key_name] = interpolateSDValue(key_name, def_iter->second.getDefaultValue(), (*it).second, defaults, mix, slerps); + newSettings[key_name] = interpolateSDValue(key_name, def_iter->second.getDefaultValue(), (*it).second, defaults, mix, skip, slerps); } else if ((*it).second.type() == LLSD::TypeMap) { // interpolate in case there are defaults inside (part of legacy) - newSettings[key_name] = interpolateSDValue(key_name, LLSDMap(), (*it).second, defaults, mix, slerps); + newSettings[key_name] = interpolateSDValue(key_name, LLSDMap(), (*it).second, defaults, mix, skip, slerps); } // else do nothing when no known defaults // TODO: Should I blend this out instead? @@ -260,7 +312,7 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c return newSettings; } -LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD &value, const LLSD &other_value, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const +LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD &value, const LLSD &other_value, const parammapping_t& defaults, BlendFactor mix, const stringset_t& skip, const stringset_t& slerps) { LLSD new_value; @@ -286,7 +338,7 @@ LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD break; case LLSD::TypeMap: // deep copy. - new_value = interpolateSDMap(value, other_value, defaults, mix); + new_value = interpolateSDMap(value, other_value, defaults, mix, skip, slerps); break; case LLSD::TypeArray: @@ -348,13 +400,15 @@ LLSettingsBase::stringset_t LLSettingsBase::getSkipInterpolateKeys() const return skipSet; } -LLSD LLSettingsBase::getSettings() const +LLSD& LLSettingsBase::getSettings() { + saveValuesIfNeeded(); return mSettings; } -LLSD LLSettingsBase::cloneSettings() const +LLSD LLSettingsBase::cloneSettings() { + saveValuesIfNeeded(); LLSD settings(combineSDMaps(getSettings(), LLSD())); if (U32 flags = getFlags()) { @@ -363,7 +417,7 @@ LLSD LLSettingsBase::cloneSettings() const return settings; } -size_t LLSettingsBase::getHash() const +size_t LLSettingsBase::getHash() { // get a shallow copy of the LLSD filtering out values to not include in the hash LLSD hash_settings = llsd_shallow(getSettings(), LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true)); @@ -381,6 +435,7 @@ bool LLSettingsBase::validate() mSettings[SETTING_TYPE] = getSettingsType(); } + saveValuesIfNeeded(); LLSD result = LLSettingsBase::settingValidation(mSettings, validations); if (result["errors"].size() > 0) diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 9d8d746b7e..c2867f32d9 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -110,71 +110,55 @@ public: virtual bool isVeryDirty() const { return mReplaced; } inline void setDirtyFlag(bool dirty) { mDirty = dirty; clearAssetId(); } - size_t getHash() const; // Hash will not include Name, ID or a previously stored Hash + size_t getHash(); // Hash will not include Name, ID or a previously stored Hash inline LLUUID getId() const { - return getValue(SETTING_ID).asUUID(); + return mSettingId; } inline std::string getName() const { - return getValue(SETTING_NAME).asString(); + return mSettingName; } inline void setName(std::string val) { - setValue(SETTING_NAME, val); + mSettingName = val; + setLLSDDirty(); } inline LLUUID getAssetId() const { - if (mSettings.has(SETTING_ASSETID)) - return mSettings[SETTING_ASSETID].asUUID(); - return LLUUID(); + return mAssetId; } inline U32 getFlags() const { - if (mSettings.has(SETTING_FLAGS)) - return static_cast(mSettings[SETTING_FLAGS].asInteger()); - return 0; + return mSettingFlags; } inline void setFlags(U32 value) { - setLLSD(SETTING_FLAGS, LLSD::Integer(value)); + mSettingFlags = value; + setLLSDDirty(); } inline bool getFlag(U32 flag) const { - if (mSettings.has(SETTING_FLAGS)) - return ((U32)mSettings[SETTING_FLAGS].asInteger() & flag) == flag; - return false; + return (mSettingFlags & flag) == flag; } inline void setFlag(U32 flag) { - U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0); - - flags |= flag; - - if (flags) - mSettings[SETTING_FLAGS] = LLSD::Integer(flags); - else - mSettings.erase(SETTING_FLAGS); + mSettingFlags |= flag; + setLLSDDirty(); } inline void clearFlag(U32 flag) { - U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0); - - flags &= ~flag; - - if (flags) - mSettings[SETTING_FLAGS] = LLSD::Integer(flags); - else - mSettings.erase(SETTING_FLAGS); + mSettingFlags &= ~flag; + setLLSDDirty(); } virtual void replaceSettings(LLSD settings) @@ -183,14 +167,31 @@ public: setDirtyFlag(true); mReplaced = true; mSettings = settings; + loadValuesFromLLSD(); + } + + void setSettings(LLSD settings) + { + setDirtyFlag(true); + mSettings = settings; + loadValuesFromLLSD(); } - virtual LLSD getSettings() const; + // if you are using getSettings to edit them, call setSettings(settings), + // replaceSettings(settings) or loadValuesFromLLSD() afterwards + virtual LLSD& getSettings(); + virtual void setLLSDDirty() + { + mLLSDDirty = true; + mDirty = true; + clearAssetId(); + } //--------------------------------------------------------------------- // inline void setLLSD(const std::string &name, const LLSD &value) { + saveValuesIfNeeded(); mSettings[name] = value; mDirty = true; if (name != SETTING_ASSETID) @@ -202,8 +203,9 @@ public: setLLSD(name, value); } - inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const + inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) { + saveValuesIfNeeded(); if (!mSettings.has(name)) return deflt; return mSettings[name]; @@ -259,11 +261,11 @@ public: (const_cast(this))->updateSettings(); } - virtual void blend(const ptr_t &end, BlendFactor blendf) = 0; + virtual void blend(ptr_t &end, BlendFactor blendf) = 0; virtual bool validate(); - virtual ptr_t buildDerivedClone() const = 0; + virtual ptr_t buildDerivedClone() = 0; class Validator { @@ -310,17 +312,20 @@ public: inline void setAssetId(LLUUID value) { // note that this skips setLLSD - mSettings[SETTING_ASSETID] = value; + mAssetId = value; + mLLSDDirty = true; } inline void clearAssetId() { - if (mSettings.has(SETTING_ASSETID)) - mSettings.erase(SETTING_ASSETID); + mAssetId.setNull(); + mLLSDDirty = true; } // Calculate any custom settings that may need to be cached. virtual void updateSettings() { mDirty = false; mReplaced = false; } + LLSD cloneSettings(); + protected: LLSettingsBase(); @@ -331,7 +336,7 @@ protected: typedef std::set stringset_t; // combining settings objects. Customize for specific setting types - virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix); + virtual void lerpSettings(LLSettingsBase &other, BlendFactor mix); // combining settings maps where it can based on mix rate // @settings initial value (mix==0) @@ -339,8 +344,8 @@ protected: // @defaults list of default values for legacy fields and (re)setting shaders // @mix from 0 to 1, ratio or rate of transition from initial 'settings' to 'other' // return interpolated and combined LLSD map - LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix) const; - LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const; + static LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& skip, const stringset_t& slerps); + static LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& skip, const stringset_t& slerps); /// when lerping between settings, some may require special handling. /// Get a list of these key to be skipped by the default settings lerp. @@ -353,32 +358,40 @@ protected: virtual validation_list_t getValidationList() const = 0; - // Apply any settings that need special handling. - virtual void applySpecial(void *, bool force = false) { }; + // Apply settings. + virtual void applyToUniforms(void *) { }; + virtual void applySpecial(void*, bool force = false) { }; virtual parammapping_t getParameterMap() const { return parammapping_t(); } - LLSD mSettings; - - LLSD cloneSettings() const; - inline void setBlendFactor(BlendFactor blendfactor) { mBlendedFactor = blendfactor; } - void replaceWith(LLSettingsBase::ptr_t other) + virtual void replaceWith(LLSettingsBase::ptr_t other) { replaceSettings(other->cloneSettings()); setBlendFactor(other->getBlendFactor()); } + virtual void loadValuesFromLLSD(); + virtual void saveValuesToLLSD(); + void saveValuesIfNeeded(); + + LLUUID mAssetId; + LLUUID mSettingId; + std::string mSettingName; + U32 mSettingFlags; + private: + bool mLLSDDirty; bool mDirty; bool mReplaced; // super dirty! - LLSD combineSDMaps(const LLSD &first, const LLSD &other) const; + static LLSD combineSDMaps(const LLSD &first, const LLSD &other); + LLSD mSettings; BlendFactor mBlendedFactor; }; diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp index 1e7de94414..19d1bb1907 100644 --- a/indra/llinventory/llsettingsdaycycle.cpp +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -124,33 +124,40 @@ static const F32 DEFAULT_MULTISLIDER_INCREMENT(0.005f); //========================================================================= LLSettingsDay::LLSettingsDay(const LLSD &data) : LLSettingsBase(data), - mInitialized(false) + mInitialized(false), + mDaySettings(LLSD::emptyMap()) { mDayTracks.resize(TRACK_MAX); } LLSettingsDay::LLSettingsDay() : LLSettingsBase(), - mInitialized(false) + mInitialized(false), + mDaySettings(LLSD::emptyMap()) { mDayTracks.resize(TRACK_MAX); } //========================================================================= -LLSD LLSettingsDay::getSettings() const +LLSD& LLSettingsDay::getSettings() { - LLSD settings(LLSD::emptyMap()); + if (!mDaySettings.emptyMap()) + { + return mDaySettings; + } + mDaySettings = LLSD::emptyMap(); + LLSD& settings = LLSettingsBase::getSettings(); - if (mSettings.has(SETTING_NAME)) - settings[SETTING_NAME] = mSettings[SETTING_NAME]; + if (settings.has(SETTING_NAME)) + mDaySettings[SETTING_NAME] = settings[SETTING_NAME]; - if (mSettings.has(SETTING_ID)) - settings[SETTING_ID] = mSettings[SETTING_ID]; + if (settings.has(SETTING_ID)) + mDaySettings[SETTING_ID] = settings[SETTING_ID]; - if (mSettings.has(SETTING_ASSETID)) - settings[SETTING_ASSETID] = mSettings[SETTING_ASSETID]; + if (settings.has(SETTING_ASSETID)) + mDaySettings[SETTING_ASSETID] = settings[SETTING_ASSETID]; - settings[SETTING_TYPE] = getSettingsType(); + mDaySettings[SETTING_TYPE] = getSettingsType(); std::map in_use; @@ -174,7 +181,7 @@ LLSD LLSettingsDay::getSettings() const } tracks.append(trackout); } - settings[SETTING_TRACKS] = tracks; + mDaySettings[SETTING_TRACKS] = tracks; LLSD frames(LLSD::emptyMap()); for (std::map::iterator itFrame = in_use.begin(); itFrame != in_use.end(); ++itFrame) @@ -184,9 +191,15 @@ LLSD LLSettingsDay::getSettings() const frames[(*itFrame).first] = framesettings; } - settings[SETTING_FRAMES] = frames; + mDaySettings[SETTING_FRAMES] = frames; - return settings; + return mDaySettings; +} + +void LLSettingsDay::setLLSDDirty() +{ + mDaySettings = LLSD::emptyMap(); + LLSettingsBase::setLLSDDirty(); } bool LLSettingsDay::initialize(bool validate_frames) @@ -392,6 +405,8 @@ bool LLSettingsDay::initialize(bool validate_frames) mSettings[SETTING_ASSETID] = assetid; } + loadValuesFromLLSD(); + mInitialized = true; return true; } @@ -449,7 +464,7 @@ LLSD LLSettingsDay::defaults() return dfltsetting; } -void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 mix) +void LLSettingsDay::blend(LLSettingsBase::ptr_t &other, F64 mix) { LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL; } diff --git a/indra/llinventory/llsettingsdaycycle.h b/indra/llinventory/llsettingsdaycycle.h index 917b0870f2..d37423ea9a 100644 --- a/indra/llinventory/llsettingsdaycycle.h +++ b/indra/llinventory/llsettingsdaycycle.h @@ -81,9 +81,10 @@ public: bool initialize(bool validate_frames = false); - virtual ptr_t buildClone() const = 0; - virtual ptr_t buildDeepCloneAndUncompress() const = 0; - virtual LLSD getSettings() const SETTINGS_OVERRIDE; + virtual ptr_t buildClone() = 0; + virtual ptr_t buildDeepCloneAndUncompress() = 0; + virtual LLSD& getSettings() SETTINGS_OVERRIDE; + virtual void setLLSDDirty() override; virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_DAYCYCLE; } @@ -91,7 +92,7 @@ public: virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("daycycle"); } // Settings status - virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE; + virtual void blend(LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE; static LLSD defaults(); @@ -127,7 +128,7 @@ public: virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE; static validation_list_t validationList(); - virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); } + virtual LLSettingsBase::ptr_t buildDerivedClone() SETTINGS_OVERRIDE { return buildClone(); } LLSettingsBase::TrackPosition getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe); LLSettingsBase::TrackPosition getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe); @@ -143,6 +144,7 @@ protected: private: CycleList_t mDayTracks; + LLSD mDaySettings; LLSettingsBase::Seconds mLastUpdateTime; diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index cbec2f4906..272219c02d 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -443,7 +443,7 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) mNextHaloTextureId = pother->mNextHaloTextureId; } -void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) +void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; llassert(getSettingsType() == end->getSettingsType()); @@ -451,24 +451,29 @@ void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast(end); if (other) { - if (other->mSettings.has(SETTING_LEGACY_HAZE)) + LLSD& settings = getSettings(); + LLSD& other_settings = other->getSettings(); + if (other_settings.has(SETTING_LEGACY_HAZE)) { - if (!mSettings.has(SETTING_LEGACY_HAZE) || !mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) + if (!settings.has(SETTING_LEGACY_HAZE) || !settings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) { // Special case since SETTING_AMBIENT is both in outer and legacy maps, we prioritize legacy one - // see getAmbientColor(), we are about to replaceSettings(), so we are free to set it - setAmbientColor(getAmbientColor()); + // see getColor(), we are about to replaceSettings(), so we are free to set it + LLColor3 ambient = getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); + setAmbientColor(ambient); + settings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = ambient.getValue(); } } else { - if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) + if (settings.has(SETTING_LEGACY_HAZE) && settings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) { // Special case due to ambient's duality // We need to match 'other's' structure for interpolation. // We are free to change mSettings, since we are about to reset it - mSettings[SETTING_AMBIENT] = getAmbientColor().getValue(); - mSettings[SETTING_LEGACY_HAZE].erase(SETTING_AMBIENT); + LLColor3 ambient = getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); + settings[SETTING_AMBIENT] = ambient.getValue(); + settings[SETTING_LEGACY_HAZE].erase(SETTING_AMBIENT); } } @@ -480,22 +485,24 @@ void LLSettingsSky::blend(const LLSettingsBase::ptr_t &end, F64 blendf) // If there is no cloud texture in destination, reduce coverage to imitate disappearance // See LLDrawPoolWLSky::renderSkyClouds... we don't blend present texture with null // Note: Probably can be done by shader - cloud_shadow = lerp((F32)mSettings[SETTING_CLOUD_SHADOW].asReal(), 0.f, (F32)blendf); + cloud_shadow = lerp((F32)settings[SETTING_CLOUD_SHADOW].asReal(), 0.f, (F32)blendf); cloud_noise_id_next = cloud_noise_id; } else if (cloud_noise_id.isNull() && !cloud_noise_id_next.isNull()) { // Source has no cloud texture, reduce initial coverage to imitate appearance // use same texture as destination - cloud_shadow = lerp(0.f, (F32)other->mSettings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf); + cloud_shadow = lerp(0.f, (F32)other_settings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf); setCloudNoiseTextureId(cloud_noise_id_next); } else { - cloud_shadow = lerp((F32)mSettings[SETTING_CLOUD_SHADOW].asReal(), (F32)other->mSettings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf); + cloud_shadow = lerp((F32)settings[SETTING_CLOUD_SHADOW].asReal(), (F32)other_settings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf); } + stringset_t skip = getSkipInterpolateKeys(); + stringset_t slerps = getSlerpKeys(); - LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf); + LLSD blenddata = interpolateSDMap(settings, other_settings, other->getParameterMap(), blendf, skip, slerps); blenddata[SETTING_CLOUD_SHADOW] = LLSD::Real(cloud_shadow); replaceSettings(blenddata); mNextSunTextureId = other->getSunTextureId(); @@ -955,6 +962,180 @@ void LLSettingsSky::updateSettings() calculateLightSettings(); } + +F32 get_float(bool &use_legacy, LLSD& settings, std::string key, F32 default_value) +{ + if (settings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && settings[LLSettingsSky::SETTING_LEGACY_HAZE].has(key)) + { + use_legacy = true; + return (F32)settings[LLSettingsSky::SETTING_LEGACY_HAZE][key].asReal(); + } + if (settings.has(key)) + { + return (F32)settings[key].asReal(); + } + return default_value; +} + +LLColor3 get_color(bool& use_legacy, LLSD& settings, const std::string& key, const LLColor3& default_value) +{ + if (settings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && settings[LLSettingsSky::SETTING_LEGACY_HAZE].has(key)) + { + use_legacy = true; + return LLColor3(settings[LLSettingsSky::SETTING_LEGACY_HAZE][key]); + } + use_legacy = false; + if (settings.has(key)) + { + return LLColor3(settings[key]); + } + return default_value; +} + + +void LLSettingsSky::loadValuesFromLLSD() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; + + LLSettingsBase::loadValuesFromLLSD(); + + LLSD& settings = getSettings(); + mCanAutoAdjust = !settings.has(SETTING_REFLECTION_PROBE_AMBIANCE); + if (mCanAutoAdjust) + { + mReflectionProbeAmbiance = 0; + } + else + { + mReflectionProbeAmbiance = (F32)settings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal(); + } + + mSunTextureId = settings[SETTING_SUN_TEXTUREID].asUUID(); + mMoonTextureId = settings[SETTING_MOON_TEXTUREID].asUUID(); + mCloudTextureId = settings[SETTING_CLOUD_TEXTUREID].asUUID(); + mHaloTextureId = settings[SETTING_HALO_TEXTUREID].asUUID(); + mRainbowTextureId = settings[SETTING_RAINBOW_TEXTUREID].asUUID(); + mBloomTextureId = settings[SETTING_BLOOM_TEXTUREID].asUUID(); + + mSunScale = (F32)settings[SETTING_SUN_SCALE].asReal(); + mSunRotation = LLQuaternion(settings[SETTING_SUN_ROTATION]); + mSunlightColor = LLColor3(settings[SETTING_SUNLIGHT_COLOR]); + mStarBrightness = (F32)settings[SETTING_STAR_BRIGHTNESS].asReal(); + mMoonBrightness = (F32)settings[SETTING_MOON_BRIGHTNESS].asReal(); + mMoonScale = (F32)settings[SETTING_MOON_SCALE].asReal(); + mMoonRotation = LLQuaternion(settings[SETTING_MOON_ROTATION]); + mMaxY = (F32)settings[SETTING_MAX_Y].asReal(); + mGlow = LLColor3(settings[SETTING_GLOW]); + mGamma = (F32)settings[SETTING_GAMMA].asReal(); + mCloudVariance = (F32)settings[SETTING_CLOUD_VARIANCE].asReal(); + mCloudShadow = (F32)settings[SETTING_CLOUD_SHADOW].asReal(); + mScrollRate = LLVector2(settings[SETTING_CLOUD_SCROLL_RATE]); + mCloudScale = (F32)settings[SETTING_CLOUD_SCALE].asReal(); + mCloudPosDensity1 = LLColor3(settings[SETTING_CLOUD_POS_DENSITY1]); + mCloudPosDensity2 = LLColor3(settings[SETTING_CLOUD_POS_DENSITY2]); + mCloudColor = LLColor3(settings[SETTING_CLOUD_COLOR]); + mAbsorptionConfigs = settings[SETTING_ABSORPTION_CONFIG]; + mMieConfigs = settings[SETTING_MIE_CONFIG]; + mRayleighConfigs = settings[SETTING_RAYLEIGH_CONFIG]; + mSunArcRadians = (F32)settings[SETTING_SUN_ARC_RADIANS].asReal(); + mSkyTopRadius = (F32)settings[SETTING_SKY_TOP_RADIUS].asReal(); + mSkyBottomRadius = (F32)settings[SETTING_SKY_BOTTOM_RADIUS].asReal(); + mSkyMoistureLevel = (F32)settings[SETTING_SKY_MOISTURE_LEVEL].asReal(); + mSkyDropletRadius = (F32)settings[SETTING_SKY_DROPLET_RADIUS].asReal(); + mSkyIceLevel = (F32)settings[SETTING_SKY_ICE_LEVEL].asReal(); + mPlanetRadius = (F32)settings[SETTING_PLANET_RADIUS].asReal(); + + // special case for legacy handling + mDistanceMultiplier = get_float(mLegacyDistanceMultiplier, settings, SETTING_DISTANCE_MULTIPLIER, 0.8f); + mDensityMultiplier = get_float(mLegacyDensityMultiplier, settings, SETTING_DENSITY_MULTIPLIER, 0.0001f); + mHazeHorizon = get_float(mLegacyHazeHorizon, settings, SETTING_HAZE_HORIZON, 0.19f); + mHazeDensity = get_float(mLegacyHazeDensity, settings, SETTING_HAZE_DENSITY, 0.7f); + mBlueHorizon = get_color(mLegacyBlueHorizon, settings, SETTING_BLUE_HORIZON, LLColor3(0.4954f, 0.4954f, 0.6399f)); + mBlueDensity = get_color(mLegacyBlueDensity, settings, SETTING_BLUE_DENSITY, LLColor3(0.2447f, 0.4487f, 0.7599f)); + mAmbientColor = get_color(mLegacyAmbientColor, settings, SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); +} + +void LLSettingsSky::saveValuesToLLSD() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; + + LLSettingsBase::saveValuesToLLSD(); + + LLSD& settings = getSettings(); + + if (mCanAutoAdjust) + { + settings.erase(SETTING_REFLECTION_PROBE_AMBIANCE); + } + else + { + settings[SETTING_REFLECTION_PROBE_AMBIANCE] = mReflectionProbeAmbiance; + } + settings[SETTING_SUN_TEXTUREID] = mSunTextureId; + settings[SETTING_MOON_TEXTUREID] = mMoonTextureId; + settings[SETTING_CLOUD_TEXTUREID] = mCloudTextureId; + settings[SETTING_HALO_TEXTUREID] = mHaloTextureId; + settings[SETTING_RAINBOW_TEXTUREID] = mRainbowTextureId; + settings[SETTING_BLOOM_TEXTUREID] = mBloomTextureId; + + settings[SETTING_SUN_SCALE] = mSunScale; + settings[SETTING_SUN_ROTATION] = mSunRotation.getValue(); + settings[SETTING_SUNLIGHT_COLOR] = mSunlightColor.getValue(); + settings[SETTING_STAR_BRIGHTNESS] = mStarBrightness; + settings[SETTING_MOON_BRIGHTNESS] = mMoonBrightness; + settings[SETTING_MOON_SCALE] = mMoonScale; + settings[SETTING_MOON_ROTATION] = mMoonRotation.getValue(); + settings[SETTING_MAX_Y] = mMaxY; + settings[SETTING_GLOW] = mGlow.getValue(); + settings[SETTING_GAMMA] = mGamma; + settings[SETTING_CLOUD_VARIANCE] = mCloudVariance; + settings[SETTING_CLOUD_SHADOW] = mCloudShadow; + settings[SETTING_CLOUD_SCROLL_RATE] = mScrollRate.getValue(); + settings[SETTING_CLOUD_SCALE] = mCloudScale; + settings[SETTING_CLOUD_POS_DENSITY1] = mCloudPosDensity1.getValue(); + settings[SETTING_CLOUD_POS_DENSITY2] = mCloudPosDensity2.getValue(); + settings[SETTING_CLOUD_COLOR] = mCloudColor.getValue(); + settings[SETTING_ABSORPTION_CONFIG] = mAbsorptionConfigs; + settings[SETTING_MIE_CONFIG] = mMieConfigs; + settings[SETTING_RAYLEIGH_CONFIG] = mRayleighConfigs; + settings[SETTING_SUN_ARC_RADIANS] = mSunArcRadians; + settings[SETTING_SKY_TOP_RADIUS] = mSkyTopRadius; + settings[SETTING_SKY_BOTTOM_RADIUS] = mSkyBottomRadius; + settings[SETTING_SKY_MOISTURE_LEVEL] = mSkyMoistureLevel; + settings[SETTING_SKY_DROPLET_RADIUS] = mSkyDropletRadius; + settings[SETTING_SKY_ICE_LEVEL] = mSkyIceLevel; + settings[SETTING_PLANET_RADIUS] = mPlanetRadius; + LLSD& legacy = settings[SETTING_LEGACY_HAZE]; + if (mLegacyDistanceMultiplier) + { + legacy[SETTING_DISTANCE_MULTIPLIER] = mDistanceMultiplier; + } + if (mLegacyDensityMultiplier) + { + legacy[SETTING_DENSITY_MULTIPLIER] = mDensityMultiplier; + } + if (mLegacyHazeHorizon) + { + legacy[SETTING_HAZE_HORIZON] = mHazeHorizon; + } + if (mLegacyHazeDensity) + { + legacy[SETTING_HAZE_DENSITY] = mHazeDensity; + } + if (mLegacyBlueHorizon) + { + legacy[SETTING_BLUE_HORIZON] = mBlueHorizon.getValue(); + } + if (mLegacyBlueDensity) + { + legacy[SETTING_BLUE_DENSITY] = mBlueDensity.getValue(); + } + if (mLegacyAmbientColor) + { + legacy[SETTING_AMBIENT] = mAmbientColor.getValue(); + } +} + F32 LLSettingsSky::getSunMoonGlowFactor() const { return getIsSunUp() ? 1.0f : @@ -1024,37 +1205,40 @@ LLColor3 LLSettingsSky::getLightDiffuse() const return LLColor3::white; } -LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) const +LLColor3 LLSettingsSky::getColor(const std::string& key, const LLColor3& default_value) { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; - if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key)) + LLSD& settings = getSettings(); + if (settings.has(SETTING_LEGACY_HAZE) && settings[SETTING_LEGACY_HAZE].has(key)) { - return LLColor3(mSettings[SETTING_LEGACY_HAZE][key]); + return LLColor3(settings[SETTING_LEGACY_HAZE][key]); } - if (mSettings.has(key)) + if (settings.has(key)) { - return LLColor3(mSettings[key]); + return LLColor3(settings[key]); } return default_value; } -F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) const +F32 LLSettingsSky::getFloat(const std::string& key, F32 default_value) { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; - if (mSettings.has(SETTING_LEGACY_HAZE) && mSettings[SETTING_LEGACY_HAZE].has(key)) + + LLSD& settings = getSettings(); + if (settings.has(SETTING_LEGACY_HAZE) && settings[SETTING_LEGACY_HAZE].has(key)) { - return (F32)mSettings[SETTING_LEGACY_HAZE][key].asReal(); + return (F32)settings[SETTING_LEGACY_HAZE][key].asReal(); } - if (mSettings.has(key)) + if (settings.has(key)) { - return (F32)mSettings[key].asReal(); + return (F32)settings[key].asReal(); } return default_value; } LLColor3 LLSettingsSky::getAmbientColor() const { - return getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); + return mAmbientColor; } LLColor3 LLSettingsSky::getAmbientColorClamped() const @@ -1072,118 +1256,135 @@ LLColor3 LLSettingsSky::getAmbientColorClamped() const LLColor3 LLSettingsSky::getBlueDensity() const { - return getColor(SETTING_BLUE_DENSITY, LLColor3(0.2447f, 0.4487f, 0.7599f)); + return mBlueDensity; } LLColor3 LLSettingsSky::getBlueHorizon() const { - return getColor(SETTING_BLUE_HORIZON, LLColor3(0.4954f, 0.4954f, 0.6399f)); + return mBlueHorizon; } F32 LLSettingsSky::getHazeDensity() const { - return getFloat(SETTING_HAZE_DENSITY, 0.7f); + return mHazeDensity; } F32 LLSettingsSky::getHazeHorizon() const { - return getFloat(SETTING_HAZE_HORIZON, 0.19f); + return mHazeHorizon; } F32 LLSettingsSky::getDensityMultiplier() const { - return getFloat(SETTING_DENSITY_MULTIPLIER, 0.0001f); + return mDensityMultiplier; } F32 LLSettingsSky::getDistanceMultiplier() const { - return getFloat(SETTING_DISTANCE_MULTIPLIER, 0.8f); + return mDistanceMultiplier; } void LLSettingsSky::setPlanetRadius(F32 radius) { - mSettings[SETTING_PLANET_RADIUS] = radius; + mPlanetRadius = radius; + setDirtyFlag(true); } void LLSettingsSky::setSkyBottomRadius(F32 radius) { - mSettings[SETTING_SKY_BOTTOM_RADIUS] = radius; + mSkyBottomRadius = radius; + setDirtyFlag(true); } void LLSettingsSky::setSkyTopRadius(F32 radius) { - mSettings[SETTING_SKY_TOP_RADIUS] = radius; + mSkyTopRadius = radius; + setDirtyFlag(true); } void LLSettingsSky::setSunArcRadians(F32 radians) { - mSettings[SETTING_SUN_ARC_RADIANS] = radians; + mSunArcRadians = radians; + setDirtyFlag(true); } void LLSettingsSky::setMieAnisotropy(F32 aniso_factor) { getMieConfig()[SETTING_MIE_ANISOTROPY_FACTOR] = aniso_factor; + setDirtyFlag(true); } void LLSettingsSky::setSkyMoistureLevel(F32 moisture_level) { - setValue(SETTING_SKY_MOISTURE_LEVEL, moisture_level); + mSkyMoistureLevel = moisture_level; + setDirtyFlag(true); } void LLSettingsSky::setSkyDropletRadius(F32 radius) { - setValue(SETTING_SKY_DROPLET_RADIUS,radius); + mSkyDropletRadius = radius; + setDirtyFlag(true); } void LLSettingsSky::setSkyIceLevel(F32 ice_level) { - setValue(SETTING_SKY_ICE_LEVEL, ice_level); + mSkyIceLevel = ice_level; + setDirtyFlag(true); } void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance) { - setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance); + mReflectionProbeAmbiance = ambiance; + mCanAutoAdjust = false; + setLLSDDirty(); } void LLSettingsSky::setAmbientColor(const LLColor3 &val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = val.getValue(); + mAmbientColor = val; + mLegacyAmbientColor = true; setDirtyFlag(true); } void LLSettingsSky::setBlueDensity(const LLColor3 &val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_DENSITY] = val.getValue(); + mBlueDensity = val; + mLegacyBlueDensity = true; setDirtyFlag(true); } void LLSettingsSky::setBlueHorizon(const LLColor3 &val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_BLUE_HORIZON] = val.getValue(); + mBlueHorizon = val; + mLegacyBlueHorizon = true; setDirtyFlag(true); } void LLSettingsSky::setDensityMultiplier(F32 val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_DENSITY_MULTIPLIER] = val; + mDensityMultiplier = val; + mLegacyDensityMultiplier = true; setDirtyFlag(true); } void LLSettingsSky::setDistanceMultiplier(F32 val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_DISTANCE_MULTIPLIER] = val; + mDistanceMultiplier = val; + mLegacyDistanceMultiplier = true; setDirtyFlag(true); } void LLSettingsSky::setHazeDensity(F32 val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_DENSITY] = val; + mHazeDensity = val; + mLegacyHazeDensity = true; setDirtyFlag(true); } void LLSettingsSky::setHazeHorizon(F32 val) { - mSettings[SETTING_LEGACY_HAZE][SETTING_HAZE_HORIZON] = val; + mHazeHorizon = val; + mLegacyHazeHorizon = true; setDirtyFlag(true); } @@ -1299,7 +1500,7 @@ LLColor3 LLSettingsSky::getMoonlightColor() const return getSunlightColor(); //moon and sun share light color } -void LLSettingsSky::clampColor(LLColor3& color, F32 gamma, F32 scale) const +void LLSettingsSky::clampColor(LLColor3& color, F32 gamma, F32 scale) { F32 max_color = llmax(color.mV[0], color.mV[1], color.mV[2]); if (max_color > scale) @@ -1415,22 +1616,22 @@ LLUUID LLSettingsSky::GetDefaultHaloTextureId() F32 LLSettingsSky::getPlanetRadius() const { - return (F32)mSettings[SETTING_PLANET_RADIUS].asReal(); + return mPlanetRadius; } F32 LLSettingsSky::getSkyMoistureLevel() const { - return (F32)mSettings[SETTING_SKY_MOISTURE_LEVEL].asReal(); + return mSkyMoistureLevel; } F32 LLSettingsSky::getSkyDropletRadius() const { - return (F32)mSettings[SETTING_SKY_DROPLET_RADIUS].asReal(); + return mSkyDropletRadius; } F32 LLSettingsSky::getSkyIceLevel() const { - return (F32)mSettings[SETTING_SKY_ICE_LEVEL].asReal(); + return mSkyIceLevel; } F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const @@ -1440,22 +1641,22 @@ F32 LLSettingsSky::getReflectionProbeAmbiance(bool auto_adjust) const return sAutoAdjustProbeAmbiance; } - return (F32)mSettings[SETTING_REFLECTION_PROBE_AMBIANCE].asReal(); + return mReflectionProbeAmbiance; } F32 LLSettingsSky::getSkyBottomRadius() const { - return (F32)mSettings[SETTING_SKY_BOTTOM_RADIUS].asReal(); + return mSkyBottomRadius; } F32 LLSettingsSky::getSkyTopRadius() const { - return (F32)mSettings[SETTING_SKY_TOP_RADIUS].asReal(); + return mSkyTopRadius; } F32 LLSettingsSky::getSunArcRadians() const { - return (F32)mSettings[SETTING_SUN_ARC_RADIANS].asReal(); + return mSunArcRadians; } F32 LLSettingsSky::getMieAnisotropy() const @@ -1465,158 +1666,169 @@ F32 LLSettingsSky::getMieAnisotropy() const LLSD LLSettingsSky::getRayleighConfig() const { - LLSD copy = *(mSettings[SETTING_RAYLEIGH_CONFIG].beginArray()); + LLSD copy = *(mRayleighConfigs.beginArray()); return copy; } LLSD LLSettingsSky::getMieConfig() const { - LLSD copy = *(mSettings[SETTING_MIE_CONFIG].beginArray()); + LLSD copy = *(mMieConfigs.beginArray()); return copy; } LLSD LLSettingsSky::getAbsorptionConfig() const { - LLSD copy = *(mSettings[SETTING_ABSORPTION_CONFIG].beginArray()); + LLSD copy = *(mAbsorptionConfigs.beginArray()); return copy; } LLSD LLSettingsSky::getRayleighConfigs() const { - return mSettings[SETTING_RAYLEIGH_CONFIG]; + return mRayleighConfigs; } LLSD LLSettingsSky::getMieConfigs() const { - return mSettings[SETTING_MIE_CONFIG]; + return mMieConfigs; } LLSD LLSettingsSky::getAbsorptionConfigs() const { - return mSettings[SETTING_ABSORPTION_CONFIG]; + return mAbsorptionConfigs; } void LLSettingsSky::setRayleighConfigs(const LLSD& rayleighConfig) { - mSettings[SETTING_RAYLEIGH_CONFIG] = rayleighConfig; + mRayleighConfigs = rayleighConfig; + setLLSDDirty(); } void LLSettingsSky::setMieConfigs(const LLSD& mieConfig) { - mSettings[SETTING_MIE_CONFIG] = mieConfig; + mMieConfigs = mieConfig; + setLLSDDirty(); } void LLSettingsSky::setAbsorptionConfigs(const LLSD& absorptionConfig) { - mSettings[SETTING_ABSORPTION_CONFIG] = absorptionConfig; + mAbsorptionConfigs = absorptionConfig; + setLLSDDirty(); } LLUUID LLSettingsSky::getBloomTextureId() const { - return mSettings[SETTING_BLOOM_TEXTUREID].asUUID(); + return mBloomTextureId; } LLUUID LLSettingsSky::getRainbowTextureId() const { - return mSettings[SETTING_RAINBOW_TEXTUREID].asUUID(); + return mRainbowTextureId; } LLUUID LLSettingsSky::getHaloTextureId() const { - return mSettings[SETTING_HALO_TEXTUREID].asUUID(); + return mHaloTextureId; } //--------------------------------------------------------------------- LLColor3 LLSettingsSky::getCloudColor() const { - return LLColor3(mSettings[SETTING_CLOUD_COLOR]); + return mCloudColor; } void LLSettingsSky::setCloudColor(const LLColor3 &val) { - setValue(SETTING_CLOUD_COLOR, val); + mCloudColor = val; + setLLSDDirty(); } LLUUID LLSettingsSky::getCloudNoiseTextureId() const { - return mSettings[SETTING_CLOUD_TEXTUREID].asUUID(); + return mCloudTextureId; } void LLSettingsSky::setCloudNoiseTextureId(const LLUUID &id) { - setValue(SETTING_CLOUD_TEXTUREID, id); + mCloudTextureId = id; + setLLSDDirty(); } LLColor3 LLSettingsSky::getCloudPosDensity1() const { - return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY1]); + return mCloudPosDensity1; } void LLSettingsSky::setCloudPosDensity1(const LLColor3 &val) { - setValue(SETTING_CLOUD_POS_DENSITY1, val); + mCloudPosDensity1 = val; + setLLSDDirty(); } LLColor3 LLSettingsSky::getCloudPosDensity2() const { - return LLColor3(mSettings[SETTING_CLOUD_POS_DENSITY2]); + return mCloudPosDensity2; } void LLSettingsSky::setCloudPosDensity2(const LLColor3 &val) { - setValue(SETTING_CLOUD_POS_DENSITY2, val); + mCloudPosDensity2 = val; + setLLSDDirty(); } F32 LLSettingsSky::getCloudScale() const { - return (F32)mSettings[SETTING_CLOUD_SCALE].asReal(); + return mCloudScale; } void LLSettingsSky::setCloudScale(F32 val) { - setValue(SETTING_CLOUD_SCALE, val); + mCloudScale = val; + setLLSDDirty(); } LLVector2 LLSettingsSky::getCloudScrollRate() const { - return LLVector2(mSettings[SETTING_CLOUD_SCROLL_RATE]); + return mScrollRate; } void LLSettingsSky::setCloudScrollRate(const LLVector2 &val) { - setValue(SETTING_CLOUD_SCROLL_RATE, val); + mScrollRate = val; + setLLSDDirty(); } void LLSettingsSky::setCloudScrollRateX(F32 val) { - mSettings[SETTING_CLOUD_SCROLL_RATE][0] = val; - setDirtyFlag(true); + mScrollRate.mV[0] = val; + setLLSDDirty(); } void LLSettingsSky::setCloudScrollRateY(F32 val) { - mSettings[SETTING_CLOUD_SCROLL_RATE][1] = val; - setDirtyFlag(true); + mScrollRate.mV[1] = val; + setLLSDDirty(); } F32 LLSettingsSky::getCloudShadow() const { - return (F32)mSettings[SETTING_CLOUD_SHADOW].asReal(); + return mCloudShadow; } void LLSettingsSky::setCloudShadow(F32 val) { - setValue(SETTING_CLOUD_SHADOW, val); + mCloudShadow = val; + setLLSDDirty(); } F32 LLSettingsSky::getCloudVariance() const { - return (F32)mSettings[SETTING_CLOUD_VARIANCE].asReal(); + return mCloudVariance; } void LLSettingsSky::setCloudVariance(F32 val) { - setValue(SETTING_CLOUD_VARIANCE, val); + mCloudVariance = val; + setLLSDDirty(); } F32 LLSettingsSky::getDomeOffset() const @@ -1633,88 +1845,94 @@ F32 LLSettingsSky::getDomeRadius() const F32 LLSettingsSky::getGamma() const { - return (F32)mSettings[SETTING_GAMMA].asReal(); + return mGamma; } void LLSettingsSky::setGamma(F32 val) { - mSettings[SETTING_GAMMA] = LLSD::Real(val); - setDirtyFlag(true); + mGamma = val; + setLLSDDirty(); } - LLColor3 LLSettingsSky::getGlow() const { - return LLColor3(mSettings[SETTING_GLOW]); + return mGlow; } void LLSettingsSky::setGlow(const LLColor3 &val) { - setValue(SETTING_GLOW, val); + mGlow = val; + setLLSDDirty(); } F32 LLSettingsSky::getMaxY() const { - return (F32)mSettings[SETTING_MAX_Y].asReal(); + return mMaxY; } void LLSettingsSky::setMaxY(F32 val) { - setValue(SETTING_MAX_Y, val); + mMaxY = val; + setLLSDDirty(); } LLQuaternion LLSettingsSky::getMoonRotation() const { - return LLQuaternion(mSettings[SETTING_MOON_ROTATION]); + return mMoonRotation; } void LLSettingsSky::setMoonRotation(const LLQuaternion &val) { - setValue(SETTING_MOON_ROTATION, val); + mMoonRotation = val; + setLLSDDirty(); } F32 LLSettingsSky::getMoonScale() const { - return (F32)mSettings[SETTING_MOON_SCALE].asReal(); + return mMoonScale; } void LLSettingsSky::setMoonScale(F32 val) { - setValue(SETTING_MOON_SCALE, val); + mMoonScale = val; + setLLSDDirty(); } LLUUID LLSettingsSky::getMoonTextureId() const { - return mSettings[SETTING_MOON_TEXTUREID].asUUID(); + return mMoonTextureId; } void LLSettingsSky::setMoonTextureId(LLUUID id) { - setValue(SETTING_MOON_TEXTUREID, id); + mMoonTextureId = id; + setLLSDDirty(); } F32 LLSettingsSky::getMoonBrightness() const { - return (F32)mSettings[SETTING_MOON_BRIGHTNESS].asReal(); + return mMoonBrightness; } void LLSettingsSky::setMoonBrightness(F32 brightness_factor) { - setValue(SETTING_MOON_BRIGHTNESS, brightness_factor); + mMoonBrightness = brightness_factor; + setLLSDDirty(); } F32 LLSettingsSky::getStarBrightness() const { - return (F32)mSettings[SETTING_STAR_BRIGHTNESS].asReal(); + return mStarBrightness; } void LLSettingsSky::setStarBrightness(F32 val) { - setValue(SETTING_STAR_BRIGHTNESS, val); + mStarBrightness = val; + setLLSDDirty(); } LLColor3 LLSettingsSky::getSunlightColor() const { - return LLColor3(mSettings[SETTING_SUNLIGHT_COLOR]); + return mSunlightColor; } LLColor3 LLSettingsSky::getSunlightColorClamped() const @@ -1733,38 +1951,41 @@ LLColor3 LLSettingsSky::getSunlightColorClamped() const void LLSettingsSky::setSunlightColor(const LLColor3 &val) { - setValue(SETTING_SUNLIGHT_COLOR, val); + mSunlightColor = val; + setLLSDDirty(); } LLQuaternion LLSettingsSky::getSunRotation() const { - return LLQuaternion(mSettings[SETTING_SUN_ROTATION]); + return mSunRotation; } void LLSettingsSky::setSunRotation(const LLQuaternion &val) { - setValue(SETTING_SUN_ROTATION, val); + mSunRotation = val; + setLLSDDirty(); } - F32 LLSettingsSky::getSunScale() const { - return (F32)mSettings[SETTING_SUN_SCALE].asReal(); + return mSunScale; } void LLSettingsSky::setSunScale(F32 val) { - setValue(SETTING_SUN_SCALE, val); + mSunScale = val; + setLLSDDirty(); } LLUUID LLSettingsSky::getSunTextureId() const { - return mSettings[SETTING_SUN_TEXTUREID].asUUID(); + return mSunTextureId; } void LLSettingsSky::setSunTextureId(LLUUID id) { - setValue(SETTING_SUN_TEXTUREID, id); + mSunTextureId = id; + setLLSDDirty(); } LLUUID LLSettingsSky::getNextSunTextureId() const @@ -1790,5 +2011,5 @@ LLUUID LLSettingsSky::getNextBloomTextureId() const // if true, this sky is a candidate for auto-adjustment bool LLSettingsSky::canAutoAdjust() const { - return !mSettings.has(SETTING_REFLECTION_PROBE_AMBIANCE); + return mCanAutoAdjust; } diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 40bb337a48..dc8e620f47 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -111,20 +111,23 @@ public: LLSettingsSky(const LLSD &data); virtual ~LLSettingsSky() { }; - virtual ptr_t buildClone() const = 0; + virtual ptr_t buildClone() = 0; //--------------------------------------------------------------------- virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); } virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; } // Settings status - virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; + virtual void blend(LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE; void replaceWithSky(LLSettingsSky::ptr_t pother); static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f); + void loadValuesFromLLSD() override; + void saveValuesToLLSD() override; + F32 getPlanetRadius() const; F32 getSkyBottomRadius() const; F32 getSkyTopRadius() const; @@ -306,7 +309,7 @@ public: LLColor3 getSunlightColorClamped() const; LLColor3 getAmbientColorClamped() const; - virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); } + virtual LLSettingsBase::ptr_t buildDerivedClone() SETTINGS_OVERRIDE { return buildClone(); } static LLUUID GetDefaultAssetId(); static LLUUID GetDefaultSunTextureId(); @@ -348,6 +351,12 @@ protected: virtual stringset_t getSlerpKeys() const SETTINGS_OVERRIDE; virtual stringset_t getSkipInterpolateKeys() const SETTINGS_OVERRIDE; + LLUUID mSunTextureId; + LLUUID mMoonTextureId; + LLUUID mCloudTextureId; + LLUUID mBloomTextureId; + LLUUID mRainbowTextureId; + LLUUID mHaloTextureId; LLUUID mNextSunTextureId; LLUUID mNextMoonTextureId; LLUUID mNextCloudTextureId; @@ -355,17 +364,63 @@ protected: LLUUID mNextRainbowTextureId; LLUUID mNextHaloTextureId; + bool mCanAutoAdjust; + F32 mReflectionProbeAmbiance; + F32 mSunScale; + LLQuaternion mSunRotation; + LLColor3 mSunlightColor; + F32 mStarBrightness; + F32 mMoonBrightness; + F32 mMoonScale; + LLQuaternion mMoonRotation; + F32 mMaxY; + LLColor3 mGlow; + F32 mGamma; + F32 mCloudVariance; + F32 mCloudShadow; + LLVector2 mScrollRate; + F32 mCloudScale; + LLColor3 mCloudPosDensity1; + LLColor3 mCloudPosDensity2; + LLColor3 mCloudColor; + LLSD mAbsorptionConfigs; + LLSD mMieConfigs; + LLSD mRayleighConfigs; + F32 mSunArcRadians; + F32 mSkyTopRadius; + F32 mSkyBottomRadius; + F32 mSkyMoistureLevel; + F32 mSkyDropletRadius; + F32 mSkyIceLevel; + F32 mPlanetRadius; + + F32 mHazeHorizon; + F32 mHazeDensity; + F32 mDistanceMultiplier; + F32 mDensityMultiplier; + LLColor3 mBlueHorizon; + LLColor3 mBlueDensity; + LLColor3 mAmbientColor; + + bool mLegacyHazeHorizon; + bool mLegacyHazeDensity; + bool mLegacyDistanceMultiplier; + bool mLegacyDensityMultiplier; + bool mLegacyBlueHorizon; + bool mLegacyBlueDensity; + bool mLegacyAmbientColor; + private: static LLSD rayleighConfigDefault(); static LLSD absorptionConfigDefault(); static LLSD mieConfigDefault(); - LLColor3 getColor(const std::string& key, const LLColor3& default_value) const; - F32 getFloat(const std::string& key, F32 default_value) const; + LLColor3 getColor(const std::string& key, const LLColor3& default_value); + F32 getFloat(const std::string& key, F32 default_value); void calculateHeavenlyBodyPositions() const; void calculateLightSettings() const; - void clampColor(LLColor3& color, F32 gamma, const F32 scale = 1.0f) const; + static void clampColor(LLColor3& color, F32 gamma, const F32 scale = 1.0f); mutable LLVector3 mSunDirection; mutable LLVector3 mMoonDirection; diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index 161b8cda25..6127a523ae 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -109,6 +109,53 @@ LLSD LLSettingsWater::defaults(const LLSettingsBase::TrackPosition& position) return dfltsetting; } +void LLSettingsWater::loadValuesFromLLSD() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; + + LLSettingsBase::loadValuesFromLLSD(); + + LLSD& settings = getSettings(); + + mBlurMultiplier = (F32)settings[SETTING_BLUR_MULTIPLIER].asReal(); + mWaterFogColor = LLColor3(settings[SETTING_FOG_COLOR]); + mWaterFogDensity = (F32)settings[SETTING_FOG_DENSITY].asReal(); + mFogMod = (F32)settings[SETTING_FOG_MOD].asReal(); + mFresnelOffset = (F32)settings[SETTING_FRESNEL_OFFSET].asReal(); + mFresnelScale = (F32)settings[SETTING_FRESNEL_SCALE].asReal(); + mNormalScale = LLVector3(settings[SETTING_NORMAL_SCALE]); + mScaleAbove = (F32)settings[SETTING_SCALE_ABOVE].asReal(); + mScaleBelow = (F32)settings[SETTING_SCALE_BELOW].asReal(); + mWave1Dir = LLVector2(settings[SETTING_WAVE1_DIR]); + mWave2Dir = LLVector2(settings[SETTING_WAVE2_DIR]); + + mNormalMapID = getNormalMapID(); + mTransparentTextureID = getTransparentTextureID(); +} + +void LLSettingsWater::saveValuesToLLSD() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; + + LLSettingsBase::saveValuesToLLSD(); + + LLSD & settings = getSettings(); + settings[SETTING_BLUR_MULTIPLIER] = LLSD::Real(mBlurMultiplier); + settings[SETTING_FOG_COLOR] = mWaterFogColor.getValue(); + settings[SETTING_FOG_DENSITY] = LLSD::Real(mWaterFogDensity); + settings[SETTING_FOG_MOD] = LLSD::Real(mFogMod); + settings[SETTING_FRESNEL_OFFSET] = LLSD::Real(mFresnelOffset); + settings[SETTING_FRESNEL_SCALE] = LLSD::Real(mFresnelScale); + settings[SETTING_NORMAL_SCALE] = mNormalScale.getValue(); + settings[SETTING_SCALE_ABOVE] = LLSD::Real(mScaleAbove); + settings[SETTING_SCALE_BELOW] = LLSD::Real(mScaleBelow); + settings[SETTING_WAVE1_DIR] = mWave1Dir.getValue(); + settings[SETTING_WAVE2_DIR] = mWave2Dir.getValue(); + + settings[SETTING_NORMAL_MAP] = mNormalMapID; + settings[SETTING_TRANSPARENT_TEXTURE] = mTransparentTextureID; +} + LLSD LLSettingsWater::translateLegacySettings(LLSD legacy) { bool converted_something(false); @@ -180,12 +227,14 @@ LLSD LLSettingsWater::translateLegacySettings(LLSD legacy) return newsettings; } -void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf) +void LLSettingsWater::blend(LLSettingsBase::ptr_t &end, F64 blendf) { LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast(end); if (other) { - LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf); + stringset_t skip = getSkipInterpolateKeys(); + stringset_t slerps = getSlerpKeys(); + LLSD blenddata = interpolateSDMap(getSettings(), other->getSettings(), other->getParameterMap(), blendf, skip, slerps); replaceSettings(blenddata); mNextNormalMapID = other->getNormalMapID(); mNextTransparentTextureID = other->getTransparentTextureID(); diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h index 9e7ff61272..0f2a62bba2 100644 --- a/indra/llinventory/llsettingswater.h +++ b/indra/llinventory/llsettingswater.h @@ -55,151 +55,167 @@ public: LLSettingsWater(const LLSD &data); virtual ~LLSettingsWater() { }; - virtual ptr_t buildClone() const = 0; + virtual ptr_t buildClone() = 0; //--------------------------------------------------------------------- virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("water"); } virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_WATER; } // Settings status - virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; + virtual void blend(LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE; void replaceWithWater(LLSettingsWater::ptr_t other); static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f); + void loadValuesFromLLSD() override; + void saveValuesToLLSD() override; + //--------------------------------------------------------------------- F32 getBlurMultiplier() const { - return (F32)mSettings[SETTING_BLUR_MULTIPLIER].asReal(); + return mBlurMultiplier; } void setBlurMultiplier(F32 val) { - setValue(SETTING_BLUR_MULTIPLIER, val); + mBlurMultiplier = val; + setLLSDDirty(); } LLColor3 getWaterFogColor() const { - return LLColor3(mSettings[SETTING_FOG_COLOR]); + return mWaterFogColor; } void setWaterFogColor(LLColor3 val) { - setValue(SETTING_FOG_COLOR, val); + mWaterFogColor = val; + setLLSDDirty(); } F32 getWaterFogDensity() const { - return (F32)mSettings[SETTING_FOG_DENSITY].asReal(); + return mWaterFogDensity; } F32 getModifiedWaterFogDensity(bool underwater) const; void setWaterFogDensity(F32 val) { - setValue(SETTING_FOG_DENSITY, val); + mWaterFogDensity = val; + setLLSDDirty(); } F32 getFogMod() const { - return (F32)mSettings[SETTING_FOG_MOD].asReal(); + return mFogMod; } void setFogMod(F32 val) { - setValue(SETTING_FOG_MOD, val); + mFogMod = val; + setLLSDDirty(); } F32 getFresnelOffset() const { - return (F32)mSettings[SETTING_FRESNEL_OFFSET].asReal(); + return mFresnelOffset; } void setFresnelOffset(F32 val) { - setValue(SETTING_FRESNEL_OFFSET, val); + mFresnelOffset = val; + setLLSDDirty(); } F32 getFresnelScale() const { - return (F32)mSettings[SETTING_FRESNEL_SCALE].asReal(); + return mFresnelScale; } void setFresnelScale(F32 val) { - setValue(SETTING_FRESNEL_SCALE, val); + mFresnelScale = val; + setLLSDDirty(); } LLUUID getTransparentTextureID() const { - return mSettings[SETTING_TRANSPARENT_TEXTURE].asUUID(); + return mTransparentTextureID; } void setTransparentTextureID(LLUUID val) { - setValue(SETTING_TRANSPARENT_TEXTURE, val); + mTransparentTextureID = val; + setLLSDDirty(); } LLUUID getNormalMapID() const { - return mSettings[SETTING_NORMAL_MAP].asUUID(); + return mNormalMapID; } void setNormalMapID(LLUUID val) { - setValue(SETTING_NORMAL_MAP, val); + mNormalMapID = val; + setLLSDDirty(); } LLVector3 getNormalScale() const { - return LLVector3(mSettings[SETTING_NORMAL_SCALE]); + return mNormalScale; } void setNormalScale(LLVector3 val) { - setValue(SETTING_NORMAL_SCALE, val); + mNormalScale = val; + setLLSDDirty(); } F32 getScaleAbove() const { - return (F32)mSettings[SETTING_SCALE_ABOVE].asReal(); + return mScaleAbove; } void setScaleAbove(F32 val) { - setValue(SETTING_SCALE_ABOVE, val); + mScaleAbove = val; + setLLSDDirty(); } F32 getScaleBelow() const { - return (F32)mSettings[SETTING_SCALE_BELOW].asReal(); + return mScaleBelow; } void setScaleBelow(F32 val) { - setValue(SETTING_SCALE_BELOW, val); + mScaleBelow = val; + setLLSDDirty(); } LLVector2 getWave1Dir() const { - return LLVector2(mSettings[SETTING_WAVE1_DIR]); + return mWave1Dir; } void setWave1Dir(LLVector2 val) { - setValue(SETTING_WAVE1_DIR, val); + mWave1Dir = val; + setLLSDDirty(); } LLVector2 getWave2Dir() const { - return LLVector2(mSettings[SETTING_WAVE2_DIR]); + return mWave2Dir; } void setWave2Dir(LLVector2 val) { - setValue(SETTING_WAVE2_DIR, val); + mWave2Dir = val; + setLLSDDirty(); } //------------------------------------------- @@ -218,7 +234,7 @@ public: static LLSD translateLegacySettings(LLSD legacy); - virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); } + virtual LLSettingsBase::ptr_t buildDerivedClone() SETTINGS_OVERRIDE { return buildClone(); } static LLUUID GetDefaultAssetId(); static LLUUID GetDefaultWaterNormalAssetId(); @@ -241,9 +257,22 @@ protected: LLSettingsWater(); + LLUUID mTransparentTextureID; + LLUUID mNormalMapID; LLUUID mNextTransparentTextureID; LLUUID mNextNormalMapID; + F32 mBlurMultiplier; + LLColor3 mWaterFogColor; + F32 mWaterFogDensity; + F32 mFogMod; + F32 mFresnelOffset; + F32 mFresnelScale; + LLVector3 mNormalScale; + F32 mScaleAbove; + F32 mScaleBelow; + LLVector2 mWave1Dir; + LLVector2 mWave2Dir; }; #endif diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 0b4630dfc3..05bd704556 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -453,11 +453,11 @@ namespace void applyInjections(LLSettingsBase::Seconds delta) { - this->mSettings = this->mSource->getSettings(); + LLSD settings = this->mSource->cloneSettings(); for (auto ito = mOverrideValues.beginMap(); ito != mOverrideValues.endMap(); ++ito) { - this->mSettings[(*ito).first] = (*ito).second; + settings[(*ito).first] = (*ito).second; } const LLSettingsBase::stringset_t &slerps = this->getSlerpKeys(); @@ -469,7 +469,7 @@ namespace { std::string key_name = (*it)->mKeyName; - LLSD value = this->mSettings[key_name]; + LLSD value = settings[key_name]; LLSD target = (*it)->mValue; if ((*it)->mFirstTime) @@ -485,11 +485,11 @@ namespace { mOverrideValues[key_name] = target; mOverrideExps[key_name] = (*it)->mExperience; - this->mSettings[key_name] = target; + settings[key_name] = target; } else { - this->mSettings.erase(key_name); + settings.erase(key_name); } } else if (specials.find(key_name) != specials.end()) @@ -500,8 +500,8 @@ namespace { if (!(*it)->mBlendIn) mix = 1.0 - mix; - (*it)->mLastValue = this->interpolateSDValue(key_name, value, target, this->getParameterMap(), mix, slerps); - this->mSettings[key_name] = (*it)->mLastValue; + (*it)->mLastValue = this->interpolateSDValue(key_name, value, target, this->getParameterMap(), mix, skips, slerps); + settings[key_name] = (*it)->mLastValue; } } @@ -520,7 +520,7 @@ namespace { mInjections.erase(mInjections.begin(), mInjections.end()); } - + this->setSettings(settings); } bool hasInjections() const @@ -685,7 +685,8 @@ namespace if (!injection->mBlendIn) mix = 1.0 - mix; stringset_t dummy; - F64 value = this->mSettings[injection->mKeyName].asReal(); + LLSD settings = this->cloneSettings(); + F64 value = settings[injection->mKeyName].asReal(); if (this->getCloudNoiseTextureId().isNull()) { value = 0; // there was no texture so start from zero coverage @@ -695,7 +696,8 @@ namespace // with different transitions, don't ignore it F64 result = lerp((F32)value, (F32)injection->mValue.asReal(), (F32)mix); injection->mLastValue = LLSD::Real(result); - this->mSettings[injection->mKeyName] = injection->mLastValue; + settings[injection->mKeyName] = injection->mLastValue; + this->setSettings(settings); } // Unfortunately I don't have a per texture blend factor. We'll just pick the one that is furthest along. @@ -1740,90 +1742,9 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con { uniforms[i].clear(); } - - LLShaderUniforms* shader = &uniforms[LLGLSLShader::SG_ANY]; - //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; - LLSettingsBase::parammapping_t params = psetting->getParameterMap(); - for (auto &it: params) - { - LLSD value; - // legacy first since it contains ambient color and we prioritize value from legacy, see getAmbientColor() - if (psetting->mSettings.has(LLSettingsSky::SETTING_LEGACY_HAZE) && psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE].has(it.first)) - { - value = psetting->mSettings[LLSettingsSky::SETTING_LEGACY_HAZE][it.first]; - } - else if (psetting->mSettings.has(it.first)) - { - value = psetting->mSettings[it.first]; - } - else - { - // We need to reset shaders, use defaults - value = it.second.getDefaultValue(); - } - - LLSD::Type setting_type = value.type(); - stop_glerror(); - switch (setting_type) - { - case LLSD::TypeInteger: - shader->uniform1i(it.second.getShaderKey(), value.asInteger()); - //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL; - break; - case LLSD::TypeReal: - shader->uniform1f(it.second.getShaderKey(), (F32)value.asReal()); - //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL; - break; - - case LLSD::TypeBoolean: - shader->uniform1i(it.second.getShaderKey(), value.asBoolean() ? 1 : 0); - //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << value << LL_ENDL; - break; - - case LLSD::TypeArray: - { - LLVector4 vect4(value); - // always identify as a radiance pass if desaturating irradiance is disabled - static LLCachedControl desaturate_irradiance(gSavedSettings, "RenderDesaturateIrradiance", true); - - if (desaturate_irradiance && gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass()) - { // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color - auto max_vec = [](LLVector4 col) - { - LLColor3 color(col); - F32 h, s, l; - color.calcHSL(&h, &s, &l); - - col.mV[0] = col.mV[1] = col.mV[2] = l; - return col; - }; - - switch (it.second.getShaderKey()) - { - case LLShaderMgr::BLUE_HORIZON: - case LLShaderMgr::BLUE_DENSITY: - vect4 = max_vec(vect4); - break; - } - } - - //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL; - shader->uniform3fv(it.second.getShaderKey(), LLVector3(vect4.mV) ); - break; - } - - // case LLSD::TypeMap: - // case LLSD::TypeString: - // case LLSD::TypeUUID: - // case LLSD::TypeURI: - // case LLSD::TypeBinary: - // case LLSD::TypeDate: - default: - break; - } - } //_WARNS("RIDER") << "----------------------------------------------------------------" << LL_ENDL; + psetting->applyToUniforms(uniforms); psetting->applySpecial(uniforms); } diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index e05b6f3736..be891213a7 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -549,7 +549,7 @@ LLSettingsSky::ptr_t LLSettingsVOSky::buildDefaultSky() return skyp; } -LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() const +LLSettingsSky::ptr_t LLSettingsVOSky::buildClone() { LLSD settings = cloneSettings(); U32 flags = getFlags(); @@ -684,6 +684,68 @@ void LLSettingsVOSky::updateSettings() gSky.setMoonScale(getMoonScale()); } +void draw_color(LLShaderUniforms* shader, const LLColor3& col, S32 shader_key) +{ + // always identify as a radiance pass if desaturating irradiance is disabled + static LLCachedControl desaturate_irradiance(gSavedSettings, "RenderDesaturateIrradiance", true); + + LLVector4 vect4(col.mV[0], col.mV[1], col.mV[2]); + + if (desaturate_irradiance && gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass()) + { // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color + auto max_vec = [](LLVector4 col) + { + LLColor3 color(col); + F32 h, s, l; + color.calcHSL(&h, &s, &l); + + col.mV[0] = col.mV[1] = col.mV[2] = l; + return col; + }; + + switch (shader_key) + { + case LLShaderMgr::BLUE_HORIZON: + case LLShaderMgr::BLUE_DENSITY: + vect4 = max_vec(vect4); + break; + } + } + + //_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL; + shader->uniform3fv(shader_key, LLVector3(vect4.mV)); +} + +inline void draw_real(LLShaderUniforms* shader, F32 value, S32 shader_key) +{ + shader->uniform1f(shader_key, value); +} + +void LLSettingsVOSky::applyToUniforms(void* ptarget) +{ + LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY]; + LLSD &settings = getSettings(); + + draw_color(shader, getAmbientColor(), LLShaderMgr::AMBIENT); + draw_color(shader, getBlueDensity(), LLShaderMgr::BLUE_DENSITY); + draw_color(shader, getBlueHorizon(), LLShaderMgr::BLUE_HORIZON); + draw_real(shader, getHazeDensity(), LLShaderMgr::HAZE_DENSITY); + draw_real(shader, getHazeHorizon(), LLShaderMgr::HAZE_HORIZON); + draw_real(shader, getDensityMultiplier(), LLShaderMgr::DENSITY_MULTIPLIER); + draw_real(shader, getDistanceMultiplier(), LLShaderMgr::DISTANCE_MULTIPLIER); + draw_color(shader, getCloudPosDensity2(), LLShaderMgr::CLOUD_POS_DENSITY2); + draw_real(shader, getCloudScale(), LLShaderMgr::CLOUD_SCALE); + draw_real(shader, getCloudShadow(), LLShaderMgr::CLOUD_SHADOW); + draw_real(shader, getCloudVariance(), LLShaderMgr::CLOUD_VARIANCE); + draw_color(shader, getGlow(), LLShaderMgr::GLOW); + draw_real(shader, getMaxY(), LLShaderMgr::MAX_Y); + draw_real(shader, getMoonBrightness(), LLShaderMgr::MOON_BRIGHTNESS); + draw_real(shader, getSkyMoistureLevel(), LLShaderMgr::MOISTURE_LEVEL); + draw_real(shader, getSkyDropletRadius(), LLShaderMgr::DROPLET_RADIUS); + draw_real(shader, getSkyIceLevel(), LLShaderMgr::ICE_LEVEL); + draw_real(shader, getReflectionProbeAmbiance(), LLShaderMgr::REFLECTION_PROBE_AMBIANCE); +} + void LLSettingsVOSky::applySpecial(void *ptarget, bool force) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; @@ -702,7 +764,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction); // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate") - LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]); + LLVector4 vect_c_p_d1(mCloudPosDensity1.mV[0], mCloudPosDensity1.mV[1], mCloudPosDensity1.mV[2]); LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() ); // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll @@ -935,7 +997,7 @@ LLSettingsWater::ptr_t LLSettingsVOWater::buildDefaultWater() return waterp; } -LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() const +LLSettingsWater::ptr_t LLSettingsVOWater::buildClone() { LLSD settings = cloneSettings(); U32 flags = getFlags(); @@ -974,6 +1036,12 @@ LLSD LLSettingsVOWater::convertToLegacy(const LLSettingsWater::ptr_t &pwater) } //------------------------------------------------------------------------- //------------------------------------------------------------------------- + +void LLSettingsVOWater::applyToUniforms(void*) +{ + +} + void LLSettingsVOWater::applySpecial(void *ptarget, bool force) { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; @@ -1373,7 +1441,7 @@ void LLSettingsVODay::combineIntoDayCycle(LLSettingsDay::ptr_t pday, LLSettingsB } -LLSettingsDay::ptr_t LLSettingsVODay::buildClone() const +LLSettingsDay::ptr_t LLSettingsVODay::buildClone() { LLSD settings = cloneSettings(); @@ -1398,10 +1466,10 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildClone() const return dayp; } -LLSettingsDay::ptr_t LLSettingsVODay::buildDeepCloneAndUncompress() const +LLSettingsDay::ptr_t LLSettingsVODay::buildDeepCloneAndUncompress() { // no need for SETTING_TRACKS or SETTING_FRAMES, so take base LLSD - LLSD settings = llsd_clone(mSettings); + LLSD settings = llsd_clone(getSettings()); U32 flags = getFlags(); LLSettingsDay::ptr_t day_clone = std::make_shared(settings); diff --git a/indra/newview/llsettingsvo.h b/indra/newview/llsettingsvo.h index c55b3f82b9..92cb8d0704 100644 --- a/indra/newview/llsettingsvo.h +++ b/indra/newview/llsettingsvo.h @@ -94,7 +94,7 @@ public: static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings, LLSD &messages); static ptr_t buildDefaultSky(); - virtual ptr_t buildClone() const SETTINGS_OVERRIDE; + virtual ptr_t buildClone() SETTINGS_OVERRIDE; static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages); @@ -110,6 +110,7 @@ protected: virtual void updateSettings() override; + virtual void applyToUniforms(void*) override; virtual void applySpecial(void *, bool) override; virtual parammapping_t getParameterMap() const override; @@ -128,7 +129,7 @@ public: static ptr_t buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings, LLSD &messages); static ptr_t buildDefaultWater(); - virtual ptr_t buildClone() const SETTINGS_OVERRIDE; + virtual ptr_t buildClone() SETTINGS_OVERRIDE; static ptr_t buildFromLegacyPresetFile(const std::string &name, const std::string &path, LLSD &messages); @@ -138,6 +139,7 @@ protected: LLSettingsVOWater(); virtual void updateSettings() override; + virtual void applyToUniforms(void*) override; virtual void applySpecial(void *, bool) override; virtual parammapping_t getParameterMap() const override; @@ -167,8 +169,8 @@ public: static ptr_t buildDefaultDayCycle(); static ptr_t buildFromEnvironmentMessage(LLSD settings); static void buildFromOtherSetting(LLSettingsBase::ptr_t settings, asset_built_fn cb); - virtual ptr_t buildClone() const SETTINGS_OVERRIDE; - virtual ptr_t buildDeepCloneAndUncompress() const SETTINGS_OVERRIDE; + virtual ptr_t buildClone() SETTINGS_OVERRIDE; + virtual ptr_t buildDeepCloneAndUncompress() SETTINGS_OVERRIDE; static LLSD convertToLegacy(const ptr_t &); -- cgit v1.2.3 From 0a110ff0833216b167e032987b0d676f29ad0ee5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 11 Sep 2024 18:21:03 +0300 Subject: viewer#2529 Track interpolateSDMap's performance viewer#2529 Fix initialization --- indra/llinventory/llsettingsbase.cpp | 8 ++++---- indra/llinventory/llsettingsbase.h | 4 ++-- indra/llinventory/llsettingsdaycycle.cpp | 2 ++ indra/llinventory/llsettingssky.cpp | 24 +++++++++++++++++++++++- indra/llinventory/llsettingssky.h | 1 + indra/llinventory/llsettingswater.cpp | 3 +++ indra/llinventory/llsettingswater.h | 13 +++++++++++++ 7 files changed, 48 insertions(+), 7 deletions(-) diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index 8575ac6920..f7151403b4 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -69,23 +69,21 @@ const U32 LLSettingsBase::Validator::VALIDATION_PARTIAL(0x01 << 0); LLSettingsBase::LLSettingsBase(): mSettings(LLSD::emptyMap()), mDirty(true), - mLLSDDirty(false), + mLLSDDirty(true), mReplaced(false), mBlendedFactor(0.0), mSettingFlags(0) { - loadValuesFromLLSD(); } LLSettingsBase::LLSettingsBase(const LLSD setting) : mSettings(setting), - mLLSDDirty(false), + mLLSDDirty(true), mDirty(true), mReplaced(false), mBlendedFactor(0.0), mSettingFlags(0) { - loadValuesFromLLSD(); } //virtual @@ -134,6 +132,7 @@ void LLSettingsBase::saveValuesIfNeeded() //========================================================================= void LLSettingsBase::lerpSettings(LLSettingsBase &other, F64 mix) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; saveValuesIfNeeded(); stringset_t skip = getSkipInterpolateKeys(); stringset_t slerps = getSlerpKeys(); @@ -437,6 +436,7 @@ bool LLSettingsBase::validate() saveValuesIfNeeded(); LLSD result = LLSettingsBase::settingValidation(mSettings, validations); + loadValuesFromLLSD(); if (result["errors"].size() > 0) { diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index c2867f32d9..dc2a745fa0 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -125,6 +125,7 @@ public: inline void setName(std::string val) { mSettingName = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -141,6 +142,7 @@ public: inline void setFlags(U32 value) { mSettingFlags = value; + setDirtyFlag(true); setLLSDDirty(); } @@ -183,8 +185,6 @@ public: virtual void setLLSDDirty() { mLLSDDirty = true; - mDirty = true; - clearAssetId(); } //--------------------------------------------------------------------- diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp index 19d1bb1907..2b189e7cca 100644 --- a/indra/llinventory/llsettingsdaycycle.cpp +++ b/indra/llinventory/llsettingsdaycycle.cpp @@ -128,6 +128,7 @@ LLSettingsDay::LLSettingsDay(const LLSD &data) : mDaySettings(LLSD::emptyMap()) { mDayTracks.resize(TRACK_MAX); + loadValuesFromLLSD(); } LLSettingsDay::LLSettingsDay() : @@ -136,6 +137,7 @@ LLSettingsDay::LLSettingsDay() : mDaySettings(LLSD::emptyMap()) { mDayTracks.resize(TRACK_MAX); + replaceSettings(defaults()); } //========================================================================= diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 272219c02d..548c1b30e1 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -407,6 +407,7 @@ LLSettingsSky::LLSettingsSky(const LLSD &data) : mNextRainbowTextureId(), mNextHaloTextureId() { + loadValuesFromLLSD(); } LLSettingsSky::LLSettingsSky(): @@ -418,6 +419,7 @@ LLSettingsSky::LLSettingsSky(): mNextRainbowTextureId(), mNextHaloTextureId() { + replaceSettings(defaults()); } void LLSettingsSky::replaceSettings(LLSD settings) @@ -460,7 +462,6 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) // Special case since SETTING_AMBIENT is both in outer and legacy maps, we prioritize legacy one // see getColor(), we are about to replaceSettings(), so we are free to set it LLColor3 ambient = getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); - setAmbientColor(ambient); settings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = ambient.getValue(); } } @@ -974,6 +975,7 @@ F32 get_float(bool &use_legacy, LLSD& settings, std::string key, F32 default_val { return (F32)settings[key].asReal(); } + use_legacy = true; return default_value; } @@ -989,6 +991,7 @@ LLColor3 get_color(bool& use_legacy, LLSD& settings, const std::string& key, con { return LLColor3(settings[key]); } + use_legacy = true; return default_value; } @@ -1046,6 +1049,7 @@ void LLSettingsSky::loadValuesFromLLSD() mPlanetRadius = (F32)settings[SETTING_PLANET_RADIUS].asReal(); // special case for legacy handling + mHasLegacyHaze = settings.has(LLSettingsSky::SETTING_LEGACY_HAZE); mDistanceMultiplier = get_float(mLegacyDistanceMultiplier, settings, SETTING_DISTANCE_MULTIPLIER, 0.8f); mDensityMultiplier = get_float(mLegacyDensityMultiplier, settings, SETTING_DENSITY_MULTIPLIER, 0.0001f); mHazeHorizon = get_float(mLegacyHazeHorizon, settings, SETTING_HAZE_HORIZON, 0.19f); @@ -1053,6 +1057,14 @@ void LLSettingsSky::loadValuesFromLLSD() mBlueHorizon = get_color(mLegacyBlueHorizon, settings, SETTING_BLUE_HORIZON, LLColor3(0.4954f, 0.4954f, 0.6399f)); mBlueDensity = get_color(mLegacyBlueDensity, settings, SETTING_BLUE_DENSITY, LLColor3(0.2447f, 0.4487f, 0.7599f)); mAmbientColor = get_color(mLegacyAmbientColor, settings, SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); + // one of these values might be true despite not having SETTING_LEGACY_HAZE if defaults were used + mHasLegacyHaze |= mLegacyDistanceMultiplier + || mLegacyDensityMultiplier + || mLegacyHazeHorizon + || mLegacyHazeDensity + || mLegacyBlueHorizon + || mLegacyBlueDensity + || mLegacyAmbientColor; } void LLSettingsSky::saveValuesToLLSD() @@ -1344,6 +1356,7 @@ void LLSettingsSky::setAmbientColor(const LLColor3 &val) mAmbientColor = val; mLegacyAmbientColor = true; setDirtyFlag(true); + setLLSDDirty(); } void LLSettingsSky::setBlueDensity(const LLColor3 &val) @@ -1351,6 +1364,7 @@ void LLSettingsSky::setBlueDensity(const LLColor3 &val) mBlueDensity = val; mLegacyBlueDensity = true; setDirtyFlag(true); + setLLSDDirty(); } void LLSettingsSky::setBlueHorizon(const LLColor3 &val) @@ -1358,6 +1372,7 @@ void LLSettingsSky::setBlueHorizon(const LLColor3 &val) mBlueHorizon = val; mLegacyBlueHorizon = true; setDirtyFlag(true); + setLLSDDirty(); } void LLSettingsSky::setDensityMultiplier(F32 val) @@ -1365,6 +1380,7 @@ void LLSettingsSky::setDensityMultiplier(F32 val) mDensityMultiplier = val; mLegacyDensityMultiplier = true; setDirtyFlag(true); + setLLSDDirty(); } void LLSettingsSky::setDistanceMultiplier(F32 val) @@ -1372,6 +1388,7 @@ void LLSettingsSky::setDistanceMultiplier(F32 val) mDistanceMultiplier = val; mLegacyDistanceMultiplier = true; setDirtyFlag(true); + setLLSDDirty(); } void LLSettingsSky::setHazeDensity(F32 val) @@ -1379,6 +1396,7 @@ void LLSettingsSky::setHazeDensity(F32 val) mHazeDensity = val; mLegacyHazeDensity = true; setDirtyFlag(true); + setLLSDDirty(); } void LLSettingsSky::setHazeHorizon(F32 val) @@ -1386,6 +1404,7 @@ void LLSettingsSky::setHazeHorizon(F32 val) mHazeHorizon = val; mLegacyHazeHorizon = true; setDirtyFlag(true); + setLLSDDirty(); } // Get total from rayleigh and mie density values for normalization @@ -1800,12 +1819,14 @@ void LLSettingsSky::setCloudScrollRate(const LLVector2 &val) void LLSettingsSky::setCloudScrollRateX(F32 val) { mScrollRate.mV[0] = val; + setDirtyFlag(true); setLLSDDirty(); } void LLSettingsSky::setCloudScrollRateY(F32 val) { mScrollRate.mV[1] = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -1851,6 +1872,7 @@ F32 LLSettingsSky::getGamma() const void LLSettingsSky::setGamma(F32 val) { mGamma = val; + setDirtyFlag(true); setLLSDDirty(); } LLColor3 LLSettingsSky::getGlow() const diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index dc8e620f47..535c4722ef 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -402,6 +402,7 @@ protected: LLColor3 mBlueDensity; LLColor3 mAmbientColor; + bool mHasLegacyHaze; bool mLegacyHazeHorizon; bool mLegacyHazeDensity; bool mLegacyDistanceMultiplier; diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index 6127a523ae..cad0b41d67 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -70,12 +70,14 @@ LLSettingsWater::LLSettingsWater(const LLSD &data) : LLSettingsBase(data), mNextNormalMapID() { + loadValuesFromLLSD(); } LLSettingsWater::LLSettingsWater() : LLSettingsBase(), mNextNormalMapID() { + replaceSettings(defaults()); } //========================================================================= @@ -229,6 +231,7 @@ LLSD LLSettingsWater::translateLegacySettings(LLSD legacy) void LLSettingsWater::blend(LLSettingsBase::ptr_t &end, F64 blendf) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast(end); if (other) { diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h index 0f2a62bba2..9d229e6a0b 100644 --- a/indra/llinventory/llsettingswater.h +++ b/indra/llinventory/llsettingswater.h @@ -81,6 +81,7 @@ public: void setBlurMultiplier(F32 val) { mBlurMultiplier = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -92,6 +93,7 @@ public: void setWaterFogColor(LLColor3 val) { mWaterFogColor = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -105,6 +107,7 @@ public: void setWaterFogDensity(F32 val) { mWaterFogDensity = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -116,6 +119,7 @@ public: void setFogMod(F32 val) { mFogMod = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -127,6 +131,7 @@ public: void setFresnelOffset(F32 val) { mFresnelOffset = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -138,6 +143,7 @@ public: void setFresnelScale(F32 val) { mFresnelScale = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -149,6 +155,7 @@ public: void setTransparentTextureID(LLUUID val) { mTransparentTextureID = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -160,6 +167,7 @@ public: void setNormalMapID(LLUUID val) { mNormalMapID = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -171,6 +179,7 @@ public: void setNormalScale(LLVector3 val) { mNormalScale = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -182,6 +191,7 @@ public: void setScaleAbove(F32 val) { mScaleAbove = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -193,6 +203,7 @@ public: void setScaleBelow(F32 val) { mScaleBelow = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -204,6 +215,7 @@ public: void setWave1Dir(LLVector2 val) { mWave1Dir = val; + setDirtyFlag(true); setLLSDDirty(); } @@ -215,6 +227,7 @@ public: void setWave2Dir(LLVector2 val) { mWave2Dir = val; + setDirtyFlag(true); setLLSDDirty(); } -- cgit v1.2.3 From dfff269d83df60de49fe8e5d7fffe9d1913e8036 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 11 Sep 2024 20:05:26 +0300 Subject: viewer#2529 Optimize LLSettingsSky::blend --- indra/llinventory/llsettingsbase.h | 1 + indra/llinventory/llsettingssky.cpp | 246 ++++++++++++++++++++++++++++-------- indra/llinventory/llsettingssky.h | 10 +- 3 files changed, 202 insertions(+), 55 deletions(-) diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index dc2a745fa0..7b59437d6e 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -109,6 +109,7 @@ public: virtual bool isDirty() const { return mDirty; } virtual bool isVeryDirty() const { return mReplaced; } inline void setDirtyFlag(bool dirty) { mDirty = dirty; clearAssetId(); } + inline void setReplaced() { mReplaced = true; } size_t getHash(); // Hash will not include Name, ID or a previously stored Hash diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 548c1b30e1..e574241e9c 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -411,7 +411,7 @@ LLSettingsSky::LLSettingsSky(const LLSD &data) : } LLSettingsSky::LLSettingsSky(): - LLSettingsBase(), + LLSettingsBase(LLSettingsSky::defaults()), mNextSunTextureId(), mNextMoonTextureId(), mNextCloudTextureId(), @@ -445,6 +445,70 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) mNextHaloTextureId = pother->mNextHaloTextureId; } +void lerp_vector2(LLVector2& a, const LLVector2& b, F32 mix) +{ + a.mV[0] = lerp(a.mV[0], b.mV[0], mix); + a.mV[1] = lerp(a.mV[1], b.mV[1], mix); +} + +void lerp_color(LLColor3 &a, const LLColor3 &b, F32 mix) +{ + a.mV[0] = lerp(a.mV[0], b.mV[0], mix); + a.mV[1] = lerp(a.mV[1], b.mV[1], mix); + a.mV[2] = lerp(a.mV[2], b.mV[2], mix); +} + +bool lerp_legacy_color(LLColor3& a, bool& a_has_legacy, const LLColor3& b, bool b_has_legacy, const LLColor3& def, F32 mix) +{ + if (b_has_legacy) + { + if (a_has_legacy) + { + lerp_color(a, b, mix); + } + else + { + a = def; + lerp_color(a, b, mix); + a_has_legacy = true; + } + } + else if (a_has_legacy) + { + lerp_color(a, def, mix); + } + else + { + lerp_color(a, b, mix); + } + return a_has_legacy; +} + +bool lerp_legacy_float(F32& a, bool& a_has_legacy, F32 b, bool b_has_legacy, F32 def, F32 mix) +{ + if (b_has_legacy) + { + if (a_has_legacy) + { + a = lerp(a, b, mix); + } + else + { + a = lerp(def, b, mix); + a_has_legacy = true; + } + } + else if (!a_has_legacy) + { + a = lerp(a, b, mix); + } + else + { + a = lerp(a, def, mix); + } + return a_has_legacy; +} + void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; @@ -453,59 +517,148 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast(end); if (other) { - LLSD& settings = getSettings(); - LLSD& other_settings = other->getSettings(); - if (other_settings.has(SETTING_LEGACY_HAZE)) + if (other->mHasLegacyHaze) { - if (!settings.has(SETTING_LEGACY_HAZE) || !settings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) + if (!mHasLegacyHaze || !mLegacyAmbientColor) { - // Special case since SETTING_AMBIENT is both in outer and legacy maps, we prioritize legacy one - // see getColor(), we are about to replaceSettings(), so we are free to set it - LLColor3 ambient = getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); - settings[SETTING_LEGACY_HAZE][SETTING_AMBIENT] = ambient.getValue(); + // Special case since SETTING_AMBIENT is both in outer and legacy maps, + // we prioritize legacy one + setAmbientColor(other->getAmbientColor()); + mLegacyAmbientColor = true; + mHasLegacyHaze = true; } } else { - if (settings.has(SETTING_LEGACY_HAZE) && settings[SETTING_LEGACY_HAZE].has(SETTING_AMBIENT)) + if (mLegacyAmbientColor) { // Special case due to ambient's duality - // We need to match 'other's' structure for interpolation. - // We are free to change mSettings, since we are about to reset it - LLColor3 ambient = getColor(SETTING_AMBIENT, LLColor3(0.25f, 0.25f, 0.25f)); - settings[SETTING_AMBIENT] = ambient.getValue(); - settings[SETTING_LEGACY_HAZE].erase(SETTING_AMBIENT); + mLegacyAmbientColor = false; } } LLUUID cloud_noise_id = getCloudNoiseTextureId(); LLUUID cloud_noise_id_next = other->getCloudNoiseTextureId(); - F64 cloud_shadow = 0; if (!cloud_noise_id.isNull() && cloud_noise_id_next.isNull()) { // If there is no cloud texture in destination, reduce coverage to imitate disappearance // See LLDrawPoolWLSky::renderSkyClouds... we don't blend present texture with null // Note: Probably can be done by shader - cloud_shadow = lerp((F32)settings[SETTING_CLOUD_SHADOW].asReal(), 0.f, (F32)blendf); + mCloudShadow = lerp(mCloudShadow, 0.f, (F32)blendf); cloud_noise_id_next = cloud_noise_id; } else if (cloud_noise_id.isNull() && !cloud_noise_id_next.isNull()) { // Source has no cloud texture, reduce initial coverage to imitate appearance // use same texture as destination - cloud_shadow = lerp(0.f, (F32)other_settings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf); + mCloudShadow = lerp(0.f, mCloudShadow, (F32)blendf); setCloudNoiseTextureId(cloud_noise_id_next); } else { - cloud_shadow = lerp((F32)settings[SETTING_CLOUD_SHADOW].asReal(), (F32)other_settings[SETTING_CLOUD_SHADOW].asReal(), (F32)blendf); + mCloudShadow = lerp(mCloudShadow, (F32)other->mCloudShadow, (F32)blendf); } + + mSettingFlags |= other->mSettingFlags; + + mCanAutoAdjust = false; // no point? + + mSunRotation = slerp((F32)blendf, mSunRotation, other->mSunRotation); + mMoonRotation = slerp((F32)blendf, mMoonRotation, other->mMoonRotation); + lerp_color(mSunlightColor, other->mSunlightColor, (F32)blendf); + lerp_color(mGlow, other->mGlow, (F32)blendf); + mReflectionProbeAmbiance = lerp(mReflectionProbeAmbiance, other->mReflectionProbeAmbiance, (F32)blendf); + mSunScale = lerp(mSunScale, other->mSunScale, (F32)blendf); + mStarBrightness = lerp(mStarBrightness, other->mStarBrightness, (F32)blendf); + mMoonBrightness = lerp(mMoonBrightness, other->mMoonBrightness, (F32)blendf); + mMoonScale = lerp(mMoonScale, other->mMoonScale, (F32)blendf); + mMaxY = lerp(mMaxY, other->mMaxY, (F32)blendf); + mGamma = lerp(mGamma, other->mGamma, (F32)blendf); + mCloudVariance = lerp(mCloudVariance, other->mCloudVariance, (F32)blendf); + mCloudShadow = lerp(mCloudShadow, other->mCloudShadow, (F32)blendf); + mCloudScale = lerp(mCloudScale, other->mCloudScale, (F32)blendf); + lerp_vector2(mScrollRate, other->mScrollRate, (F32)blendf); + lerp_color(mCloudPosDensity1, other->mCloudPosDensity1, (F32)blendf); + lerp_color(mCloudPosDensity2, other->mCloudPosDensity2, (F32)blendf); + lerp_color(mCloudColor, other->mCloudColor, (F32)blendf); + + parammapping_t defaults = other->getParameterMap(); stringset_t skip = getSkipInterpolateKeys(); stringset_t slerps = getSlerpKeys(); - + mAbsorptionConfigs = interpolateSDMap(mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); + mMieConfigs = interpolateSDMap(mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); + mRayleighConfigs = interpolateSDMap(mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps); + + mSunArcRadians = lerp(mSunArcRadians, other->mSunArcRadians, (F32)blendf); + mSkyTopRadius = lerp(mSkyTopRadius, other->mSkyTopRadius, (F32)blendf); + mSkyBottomRadius = lerp(mSkyBottomRadius, other->mSkyBottomRadius, (F32)blendf); + mSkyMoistureLevel = lerp(mSkyMoistureLevel, other->mSkyMoistureLevel, (F32)blendf); + mSkyDropletRadius = lerp(mSkyDropletRadius, other->mSkyDropletRadius, (F32)blendf); + mSkyIceLevel = lerp(mSkyIceLevel, other->mSkyIceLevel, (F32)blendf); + mPlanetRadius = lerp(mPlanetRadius, other->mPlanetRadius, (F32)blendf); + + mHasLegacyHaze |= lerp_legacy_float(mHazeHorizon, mLegacyHazeHorizon, other->mHazeHorizon, other->mLegacyHazeHorizon, 0.19f, (F32)blendf); + mHasLegacyHaze |= lerp_legacy_float(mHazeDensity, mLegacyHazeDensity, other->mHazeDensity, other->mLegacyHazeDensity, 0.7f, (F32)blendf); + mHasLegacyHaze |= lerp_legacy_float(mDistanceMultiplier, mLegacyDistanceMultiplier, other->mDistanceMultiplier, other->mLegacyDistanceMultiplier, 0.8f, (F32)blendf); + mHasLegacyHaze |= lerp_legacy_float(mDensityMultiplier, mLegacyDensityMultiplier, other->mDensityMultiplier, other->mLegacyDensityMultiplier, 0.0001f, (F32)blendf); + mHasLegacyHaze |= lerp_legacy_color(mBlueHorizon, mLegacyBlueHorizon, other->mBlueHorizon, other->mLegacyBlueHorizon, LLColor3(0.4954f, 0.4954f, 0.6399f), (F32)blendf); + mHasLegacyHaze |= lerp_legacy_color(mBlueDensity, mLegacyBlueDensity, other->mBlueDensity, other->mLegacyBlueDensity, LLColor3(0.2447f, 0.4487f, 0.7599f), (F32)blendf); + + setDirtyFlag(true); + setReplaced(); + setLLSDDirty(); + + /////// validation + /* LLSD blenddata = interpolateSDMap(settings, other_settings, other->getParameterMap(), blendf, skip, slerps); - blenddata[SETTING_CLOUD_SHADOW] = LLSD::Real(cloud_shadow); - replaceSettings(blenddata); + blenddata[SETTING_CLOUD_SHADOW] = LLSD::Real(mCloudShadow); + + LLSettingsSky::ptr_t sky_p = buildClone(); + sky_p->replaceSettings(blenddata); + sky_p->loadValuesFromLLSD(); + llassert(sky_p->getSettingsType() == getSettingsType()); + llassert(sky_p->getSunRotation() == getSunRotation()); + llassert(sky_p->getMoonRotation() == getMoonRotation()); + llassert(sky_p->getSunTextureId() == getSunTextureId()); + llassert(sky_p->getMoonTextureId() == getMoonTextureId()); + llassert(sky_p->getCloudNoiseTextureId() == getCloudNoiseTextureId()); + llassert(sky_p->getBloomTextureId() == getBloomTextureId()); + llassert(sky_p->getRainbowTextureId() == getRainbowTextureId()); + llassert(sky_p->getHaloTextureId() == getHaloTextureId()); + llassert(sky_p->getCloudColor() == getCloudColor()); + llassert(sky_p->getCloudPosDensity1() == getCloudPosDensity1()); + llassert(sky_p->getCloudPosDensity2() == getCloudPosDensity2()); + llassert(sky_p->getCloudScale() == getCloudScale()); + llassert(sky_p->getCloudScrollRate() == getCloudScrollRate()); + llassert(sky_p->getCloudShadow() == getCloudShadow()); + llassert(sky_p->getCloudVariance() == getCloudVariance()); + llassert(sky_p->getDomeOffset() == getDomeOffset()); + llassert(sky_p->getDomeRadius() == getDomeRadius()); + llassert(sky_p->getGamma() == getGamma()); + llassert(sky_p->getStarBrightness() == getStarBrightness()); + llassert(sky_p->getSunlightColor() == getSunlightColor()); + llassert(sky_p->getSunScale() == getSunScale()); + llassert(sky_p->getSunArcRadians() == getSunArcRadians()); + llassert(sky_p->getSunlightColor() == getSunlightColor()); + llassert(sky_p->getGlow() == getGlow()); + llassert(sky_p->getReflectionProbeAmbiance() == getReflectionProbeAmbiance()); + llassert(sky_p->getStarBrightness() == getStarBrightness()); + llassert(sky_p->getMoonBrightness() == getMoonBrightness()); + llassert(sky_p->getMoonScale() == getMoonScale()); + llassert(sky_p->getMaxY() == getMaxY()); + llassert(sky_p->getSkyTopRadius() == getSkyTopRadius()); + llassert(sky_p->getSkyBottomRadius() == getSkyBottomRadius()); + llassert(sky_p->getSkyMoistureLevel() == getSkyMoistureLevel()); + llassert(sky_p->getSkyDropletRadius() == getSkyDropletRadius()); + llassert(sky_p->getSkyIceLevel() == getSkyIceLevel()); + llassert(sky_p->getPlanetRadius() == getPlanetRadius()); + llassert(sky_p->getHazeHorizon() == getHazeHorizon()); + llassert(sky_p->getHazeDensity() == getHazeDensity()); + llassert(sky_p->getDistanceMultiplier() == getDistanceMultiplier()); + llassert(sky_p->getDensityMultiplier() == getDensityMultiplier()); + llassert(sky_p->getBlueHorizon() == getBlueHorizon()); + llassert(sky_p->getBlueDensity() == getBlueDensity());*/ + mNextSunTextureId = other->getSunTextureId(); mNextMoonTextureId = other->getMoonTextureId(); mNextCloudTextureId = cloud_noise_id_next; @@ -1067,6 +1220,19 @@ void LLSettingsSky::loadValuesFromLLSD() || mLegacyAmbientColor; } +void set_legacy(LLSD &settings, LLSD &legacy, const std::string& key, bool has_value, const LLSD & value) +{ + if (has_value) + { + legacy[key] = value; + } + else + { + settings[key] = value; + legacy.erase(key); + } +} + void LLSettingsSky::saveValuesToLLSD() { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; @@ -1117,35 +1283,15 @@ void LLSettingsSky::saveValuesToLLSD() settings[SETTING_SKY_DROPLET_RADIUS] = mSkyDropletRadius; settings[SETTING_SKY_ICE_LEVEL] = mSkyIceLevel; settings[SETTING_PLANET_RADIUS] = mPlanetRadius; + LLSD& legacy = settings[SETTING_LEGACY_HAZE]; - if (mLegacyDistanceMultiplier) - { - legacy[SETTING_DISTANCE_MULTIPLIER] = mDistanceMultiplier; - } - if (mLegacyDensityMultiplier) - { - legacy[SETTING_DENSITY_MULTIPLIER] = mDensityMultiplier; - } - if (mLegacyHazeHorizon) - { - legacy[SETTING_HAZE_HORIZON] = mHazeHorizon; - } - if (mLegacyHazeDensity) - { - legacy[SETTING_HAZE_DENSITY] = mHazeDensity; - } - if (mLegacyBlueHorizon) - { - legacy[SETTING_BLUE_HORIZON] = mBlueHorizon.getValue(); - } - if (mLegacyBlueDensity) - { - legacy[SETTING_BLUE_DENSITY] = mBlueDensity.getValue(); - } - if (mLegacyAmbientColor) - { - legacy[SETTING_AMBIENT] = mAmbientColor.getValue(); - } + set_legacy(settings, legacy, SETTING_DISTANCE_MULTIPLIER, mLegacyDistanceMultiplier, LLSD::Real(mDistanceMultiplier)); + set_legacy(settings, legacy, SETTING_DENSITY_MULTIPLIER, mLegacyDensityMultiplier, LLSD::Real(mDensityMultiplier)); + set_legacy(settings, legacy, SETTING_HAZE_HORIZON, mLegacyHazeHorizon, LLSD::Real(mHazeHorizon)); + set_legacy(settings, legacy, SETTING_HAZE_DENSITY, mLegacyHazeDensity, LLSD::Real(mHazeDensity)); + set_legacy(settings, legacy, SETTING_BLUE_HORIZON, mLegacyBlueHorizon, mBlueHorizon.getValue()); + set_legacy(settings, legacy, SETTING_BLUE_DENSITY, mLegacyBlueDensity, mBlueDensity.getValue()); + set_legacy(settings, legacy, SETTING_AMBIENT, mLegacyAmbientColor, mAmbientColor.getValue()); } F32 LLSettingsSky::getSunMoonGlowFactor() const diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 535c4722ef..b2b042e53f 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -365,21 +365,21 @@ protected: LLUUID mNextHaloTextureId; bool mCanAutoAdjust; - F32 mReflectionProbeAmbiance; - F32 mSunScale; LLQuaternion mSunRotation; + LLQuaternion mMoonRotation; LLColor3 mSunlightColor; + LLColor3 mGlow; + F32 mReflectionProbeAmbiance; + F32 mSunScale; F32 mStarBrightness; F32 mMoonBrightness; F32 mMoonScale; - LLQuaternion mMoonRotation; F32 mMaxY; - LLColor3 mGlow; F32 mGamma; F32 mCloudVariance; F32 mCloudShadow; - LLVector2 mScrollRate; F32 mCloudScale; + LLVector2 mScrollRate; LLColor3 mCloudPosDensity1; LLColor3 mCloudPosDensity2; LLColor3 mCloudColor; -- cgit v1.2.3 From e71215dcfdb960f64a7f10d2fba71790f8e7bcd1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 12 Sep 2024 14:32:43 +0300 Subject: viewer#2529 Optimize LLSettingsWater::blend --- indra/llinventory/llsettingsbase.cpp | 24 +++- indra/llinventory/llsettingsbase.h | 20 +++- indra/llinventory/llsettingssky.cpp | 215 ++++++++++++++++++---------------- indra/llinventory/llsettingssky.h | 3 +- indra/llinventory/llsettingswater.cpp | 57 +++++++-- indra/llinventory/llsettingswater.h | 3 +- indra/newview/llsettingsvo.cpp | 1 - 7 files changed, 207 insertions(+), 116 deletions(-) diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp index f7151403b4..0ee71de3a1 100644 --- a/indra/llinventory/llsettingsbase.cpp +++ b/indra/llinventory/llsettingsbase.cpp @@ -141,6 +141,26 @@ void LLSettingsBase::lerpSettings(LLSettingsBase &other, F64 mix) loadValuesFromLLSD(); } +void LLSettingsBase::lerpVector2(LLVector2& a, const LLVector2& b, F32 mix) +{ + a.mV[0] = lerp(a.mV[0], b.mV[0], mix); + a.mV[1] = lerp(a.mV[1], b.mV[1], mix); +} + +void LLSettingsBase::lerpVector3(LLVector3& a, const LLVector3& b, F32 mix) +{ + a.mV[0] = lerp(a.mV[0], b.mV[0], mix); + a.mV[1] = lerp(a.mV[1], b.mV[1], mix); + a.mV[2] = lerp(a.mV[2], b.mV[2], mix); +} + +void LLSettingsBase::lerpColor(LLColor3& a, const LLColor3& b, F32 mix) +{ + a.mV[0] = lerp(a.mV[0], b.mV[0], mix); + a.mV[1] = lerp(a.mV[1], b.mV[1], mix); + a.mV[2] = lerp(a.mV[2], b.mV[2], mix); +} + LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) { LLSD newSettings; @@ -759,7 +779,7 @@ F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_ if (mTarget) { - mTarget->replaceSettings(mInitial->getSettings()); + mTarget->replaceSettings(mInitial); mTarget->blend(mFinal, blendf); } else @@ -774,7 +794,7 @@ void LLSettingsBlender::triggerComplete() { LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; if (mTarget) - mTarget->replaceSettings(mFinal->getSettings()); + mTarget->replaceSettings(mFinal); LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon mTarget->update(); mOnFinished(shared_from_this()); diff --git a/indra/llinventory/llsettingsbase.h b/indra/llinventory/llsettingsbase.h index 7b59437d6e..816ff3e111 100644 --- a/indra/llinventory/llsettingsbase.h +++ b/indra/llinventory/llsettingsbase.h @@ -173,6 +173,18 @@ public: loadValuesFromLLSD(); } + virtual void replaceSettings(const ptr_t& other) + { + mBlendedFactor = 0.0; + setDirtyFlag(true); + mReplaced = true; + mSettingFlags = other->getFlags(); + mSettingName = other->getName(); + mSettingId = other->getId(); + mAssetId = other->getAssetId(); + setLLSDDirty(); + } + void setSettings(LLSD settings) { setDirtyFlag(true); @@ -327,6 +339,10 @@ public: virtual void updateSettings() { mDirty = false; mReplaced = false; } LLSD cloneSettings(); + static void lerpVector2(LLVector2& a, const LLVector2& b, F32 mix); + static void lerpVector3(LLVector3& a, const LLVector3& b, F32 mix); + static void lerpColor(LLColor3& a, const LLColor3& b, F32 mix); + protected: LLSettingsBase(); @@ -370,9 +386,9 @@ protected: mBlendedFactor = blendfactor; } - virtual void replaceWith(LLSettingsBase::ptr_t other) + virtual void replaceWith(const LLSettingsBase::ptr_t other) { - replaceSettings(other->cloneSettings()); + replaceSettings(other); setBlendFactor(other->getBlendFactor()); } diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index e574241e9c..3685915ffd 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -433,7 +433,80 @@ void LLSettingsSky::replaceSettings(LLSD settings) mNextHaloTextureId.setNull(); } -void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) +void LLSettingsSky::replaceSettings(const LLSettingsBase::ptr_t& other_sky) +{ + LLSettingsBase::replaceSettings(other_sky); + + llassert(getSettingsType() == other_sky->getSettingsType()); + + LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast(other_sky); + + mCanAutoAdjust = other->mCanAutoAdjust; + mReflectionProbeAmbiance = other->mReflectionProbeAmbiance; + + mSunScale = other->mSunScale; + mSunRotation = other->mSunRotation; + mSunlightColor = other->mSunlightColor; + mStarBrightness = other->mStarBrightness; + mMoonBrightness = other->mMoonBrightness; + mMoonScale = other->mMoonScale; + mMoonRotation = other->mMoonRotation; + mMaxY = other->mMaxY; + mGlow = other->mGlow; + mGamma = other->mGamma; + mCloudVariance = other->mCloudVariance; + mCloudShadow = other->mCloudShadow; + mScrollRate = other->mScrollRate; + mCloudScale = other->mCloudScale; + mCloudPosDensity1 = other->mCloudPosDensity1; + mCloudPosDensity2 = other->mCloudPosDensity2; + mCloudColor = other->mCloudColor; + + mAbsorptionConfigs = other->mAbsorptionConfigs; + mMieConfigs = other->mMieConfigs; + mRayleighConfigs = other->mRayleighConfigs; + + mSunArcRadians = other->mSunArcRadians; + mSkyTopRadius = other->mSkyTopRadius; + mSkyBottomRadius = other->mSkyBottomRadius; + mSkyMoistureLevel = other->mSkyMoistureLevel; + mSkyDropletRadius = other->mSkyDropletRadius; + mSkyIceLevel = other->mSkyIceLevel; + mPlanetRadius = other->mPlanetRadius; + + mHasLegacyHaze = other->mHasLegacyHaze; + mDistanceMultiplier = other->mDistanceMultiplier; + mDensityMultiplier = other->mDensityMultiplier; + mHazeHorizon = other->mHazeHorizon; + mHazeDensity = other->mHazeDensity; + mBlueHorizon = other->mBlueHorizon; + mBlueDensity = other->mBlueDensity; + mAmbientColor = other->mAmbientColor; + + mLegacyDistanceMultiplier = other->mLegacyDistanceMultiplier; + mLegacyDensityMultiplier = other->mLegacyDensityMultiplier; + mLegacyHazeHorizon = other->mLegacyHazeHorizon; + mLegacyHazeDensity = other->mLegacyHazeDensity; + mLegacyBlueHorizon = other->mLegacyBlueHorizon; + mLegacyBlueDensity = other->mLegacyBlueDensity; + mLegacyAmbientColor = other->mLegacyAmbientColor; + + mSunTextureId = other->mSunTextureId; + mMoonTextureId = other->mMoonTextureId; + mCloudTextureId = other->mCloudTextureId; + mHaloTextureId = other->mHaloTextureId; + mRainbowTextureId = other->mRainbowTextureId; + mBloomTextureId = other->mBloomTextureId; + + mNextSunTextureId.setNull(); + mNextMoonTextureId.setNull(); + mNextCloudTextureId.setNull(); + mNextBloomTextureId.setNull(); + mNextRainbowTextureId.setNull(); + mNextHaloTextureId.setNull(); +} + +void LLSettingsSky::replaceWithSky(const LLSettingsSky::ptr_t& pother) { replaceWith(pother); @@ -445,41 +518,28 @@ void LLSettingsSky::replaceWithSky(LLSettingsSky::ptr_t pother) mNextHaloTextureId = pother->mNextHaloTextureId; } -void lerp_vector2(LLVector2& a, const LLVector2& b, F32 mix) -{ - a.mV[0] = lerp(a.mV[0], b.mV[0], mix); - a.mV[1] = lerp(a.mV[1], b.mV[1], mix); -} - -void lerp_color(LLColor3 &a, const LLColor3 &b, F32 mix) -{ - a.mV[0] = lerp(a.mV[0], b.mV[0], mix); - a.mV[1] = lerp(a.mV[1], b.mV[1], mix); - a.mV[2] = lerp(a.mV[2], b.mV[2], mix); -} - bool lerp_legacy_color(LLColor3& a, bool& a_has_legacy, const LLColor3& b, bool b_has_legacy, const LLColor3& def, F32 mix) { if (b_has_legacy) { if (a_has_legacy) { - lerp_color(a, b, mix); + LLSettingsBase::lerpColor(a, b, mix); } else { a = def; - lerp_color(a, b, mix); + LLSettingsBase::lerpColor(a, b, mix); a_has_legacy = true; } } else if (a_has_legacy) { - lerp_color(a, def, mix); + LLSettingsBase::lerpColor(a, def, mix); } else { - lerp_color(a, b, mix); + LLSettingsBase::lerpColor(a, b, mix); } return a_has_legacy; } @@ -517,26 +577,6 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) LLSettingsSky::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast(end); if (other) { - if (other->mHasLegacyHaze) - { - if (!mHasLegacyHaze || !mLegacyAmbientColor) - { - // Special case since SETTING_AMBIENT is both in outer and legacy maps, - // we prioritize legacy one - setAmbientColor(other->getAmbientColor()); - mLegacyAmbientColor = true; - mHasLegacyHaze = true; - } - } - else - { - if (mLegacyAmbientColor) - { - // Special case due to ambient's duality - mLegacyAmbientColor = false; - } - } - LLUUID cloud_noise_id = getCloudNoiseTextureId(); LLUUID cloud_noise_id_next = other->getCloudNoiseTextureId(); if (!cloud_noise_id.isNull() && cloud_noise_id_next.isNull()) @@ -565,8 +605,8 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) mSunRotation = slerp((F32)blendf, mSunRotation, other->mSunRotation); mMoonRotation = slerp((F32)blendf, mMoonRotation, other->mMoonRotation); - lerp_color(mSunlightColor, other->mSunlightColor, (F32)blendf); - lerp_color(mGlow, other->mGlow, (F32)blendf); + lerpColor(mSunlightColor, other->mSunlightColor, (F32)blendf); + lerpColor(mGlow, other->mGlow, (F32)blendf); mReflectionProbeAmbiance = lerp(mReflectionProbeAmbiance, other->mReflectionProbeAmbiance, (F32)blendf); mSunScale = lerp(mSunScale, other->mSunScale, (F32)blendf); mStarBrightness = lerp(mStarBrightness, other->mStarBrightness, (F32)blendf); @@ -577,17 +617,10 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) mCloudVariance = lerp(mCloudVariance, other->mCloudVariance, (F32)blendf); mCloudShadow = lerp(mCloudShadow, other->mCloudShadow, (F32)blendf); mCloudScale = lerp(mCloudScale, other->mCloudScale, (F32)blendf); - lerp_vector2(mScrollRate, other->mScrollRate, (F32)blendf); - lerp_color(mCloudPosDensity1, other->mCloudPosDensity1, (F32)blendf); - lerp_color(mCloudPosDensity2, other->mCloudPosDensity2, (F32)blendf); - lerp_color(mCloudColor, other->mCloudColor, (F32)blendf); - - parammapping_t defaults = other->getParameterMap(); - stringset_t skip = getSkipInterpolateKeys(); - stringset_t slerps = getSlerpKeys(); - mAbsorptionConfigs = interpolateSDMap(mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); - mMieConfigs = interpolateSDMap(mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); - mRayleighConfigs = interpolateSDMap(mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps); + lerpVector2(mScrollRate, other->mScrollRate, (F32)blendf); + lerpColor(mCloudPosDensity1, other->mCloudPosDensity1, (F32)blendf); + lerpColor(mCloudPosDensity2, other->mCloudPosDensity2, (F32)blendf); + lerpColor(mCloudColor, other->mCloudColor, (F32)blendf); mSunArcRadians = lerp(mSunArcRadians, other->mSunArcRadians, (F32)blendf); mSkyTopRadius = lerp(mSkyTopRadius, other->mSkyTopRadius, (F32)blendf); @@ -597,6 +630,28 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) mSkyIceLevel = lerp(mSkyIceLevel, other->mSkyIceLevel, (F32)blendf); mPlanetRadius = lerp(mPlanetRadius, other->mPlanetRadius, (F32)blendf); + // Legacy settings + + if (other->mHasLegacyHaze) + { + if (!mHasLegacyHaze || !mLegacyAmbientColor) + { + // Special case since SETTING_AMBIENT is both in outer and legacy maps, + // we prioritize legacy one + setAmbientColor(other->getAmbientColor()); + mLegacyAmbientColor = true; + mHasLegacyHaze = true; + } + } + else + { + if (mLegacyAmbientColor) + { + // Special case due to ambient's duality + mLegacyAmbientColor = false; + } + } + mHasLegacyHaze |= lerp_legacy_float(mHazeHorizon, mLegacyHazeHorizon, other->mHazeHorizon, other->mLegacyHazeHorizon, 0.19f, (F32)blendf); mHasLegacyHaze |= lerp_legacy_float(mHazeDensity, mLegacyHazeDensity, other->mHazeDensity, other->mLegacyHazeDensity, 0.7f, (F32)blendf); mHasLegacyHaze |= lerp_legacy_float(mDistanceMultiplier, mLegacyDistanceMultiplier, other->mDistanceMultiplier, other->mLegacyDistanceMultiplier, 0.8f, (F32)blendf); @@ -604,61 +659,17 @@ void LLSettingsSky::blend(LLSettingsBase::ptr_t &end, F64 blendf) mHasLegacyHaze |= lerp_legacy_color(mBlueHorizon, mLegacyBlueHorizon, other->mBlueHorizon, other->mLegacyBlueHorizon, LLColor3(0.4954f, 0.4954f, 0.6399f), (F32)blendf); mHasLegacyHaze |= lerp_legacy_color(mBlueDensity, mLegacyBlueDensity, other->mBlueDensity, other->mLegacyBlueDensity, LLColor3(0.2447f, 0.4487f, 0.7599f), (F32)blendf); + parammapping_t defaults = other->getParameterMap(); + stringset_t skip = getSkipInterpolateKeys(); + stringset_t slerps = getSlerpKeys(); + mAbsorptionConfigs = interpolateSDMap(mAbsorptionConfigs, other->mAbsorptionConfigs, defaults, blendf, skip, slerps); + mMieConfigs = interpolateSDMap(mMieConfigs, other->mMieConfigs, defaults, blendf, skip, slerps); + mRayleighConfigs = interpolateSDMap(mRayleighConfigs, other->mRayleighConfigs, defaults, blendf, skip, slerps); + setDirtyFlag(true); setReplaced(); setLLSDDirty(); - /////// validation - /* - LLSD blenddata = interpolateSDMap(settings, other_settings, other->getParameterMap(), blendf, skip, slerps); - blenddata[SETTING_CLOUD_SHADOW] = LLSD::Real(mCloudShadow); - - LLSettingsSky::ptr_t sky_p = buildClone(); - sky_p->replaceSettings(blenddata); - sky_p->loadValuesFromLLSD(); - llassert(sky_p->getSettingsType() == getSettingsType()); - llassert(sky_p->getSunRotation() == getSunRotation()); - llassert(sky_p->getMoonRotation() == getMoonRotation()); - llassert(sky_p->getSunTextureId() == getSunTextureId()); - llassert(sky_p->getMoonTextureId() == getMoonTextureId()); - llassert(sky_p->getCloudNoiseTextureId() == getCloudNoiseTextureId()); - llassert(sky_p->getBloomTextureId() == getBloomTextureId()); - llassert(sky_p->getRainbowTextureId() == getRainbowTextureId()); - llassert(sky_p->getHaloTextureId() == getHaloTextureId()); - llassert(sky_p->getCloudColor() == getCloudColor()); - llassert(sky_p->getCloudPosDensity1() == getCloudPosDensity1()); - llassert(sky_p->getCloudPosDensity2() == getCloudPosDensity2()); - llassert(sky_p->getCloudScale() == getCloudScale()); - llassert(sky_p->getCloudScrollRate() == getCloudScrollRate()); - llassert(sky_p->getCloudShadow() == getCloudShadow()); - llassert(sky_p->getCloudVariance() == getCloudVariance()); - llassert(sky_p->getDomeOffset() == getDomeOffset()); - llassert(sky_p->getDomeRadius() == getDomeRadius()); - llassert(sky_p->getGamma() == getGamma()); - llassert(sky_p->getStarBrightness() == getStarBrightness()); - llassert(sky_p->getSunlightColor() == getSunlightColor()); - llassert(sky_p->getSunScale() == getSunScale()); - llassert(sky_p->getSunArcRadians() == getSunArcRadians()); - llassert(sky_p->getSunlightColor() == getSunlightColor()); - llassert(sky_p->getGlow() == getGlow()); - llassert(sky_p->getReflectionProbeAmbiance() == getReflectionProbeAmbiance()); - llassert(sky_p->getStarBrightness() == getStarBrightness()); - llassert(sky_p->getMoonBrightness() == getMoonBrightness()); - llassert(sky_p->getMoonScale() == getMoonScale()); - llassert(sky_p->getMaxY() == getMaxY()); - llassert(sky_p->getSkyTopRadius() == getSkyTopRadius()); - llassert(sky_p->getSkyBottomRadius() == getSkyBottomRadius()); - llassert(sky_p->getSkyMoistureLevel() == getSkyMoistureLevel()); - llassert(sky_p->getSkyDropletRadius() == getSkyDropletRadius()); - llassert(sky_p->getSkyIceLevel() == getSkyIceLevel()); - llassert(sky_p->getPlanetRadius() == getPlanetRadius()); - llassert(sky_p->getHazeHorizon() == getHazeHorizon()); - llassert(sky_p->getHazeDensity() == getHazeDensity()); - llassert(sky_p->getDistanceMultiplier() == getDistanceMultiplier()); - llassert(sky_p->getDensityMultiplier() == getDensityMultiplier()); - llassert(sky_p->getBlueHorizon() == getBlueHorizon()); - llassert(sky_p->getBlueDensity() == getBlueDensity());*/ - mNextSunTextureId = other->getSunTextureId(); mNextMoonTextureId = other->getMoonTextureId(); mNextCloudTextureId = cloud_noise_id_next; diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index b2b042e53f..38c0368423 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -121,8 +121,9 @@ public: virtual void blend(LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE; + virtual void replaceSettings(const LLSettingsBase::ptr_t& other_sky) override; - void replaceWithSky(LLSettingsSky::ptr_t pother); + void replaceWithSky(const LLSettingsSky::ptr_t& pother); static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f); void loadValuesFromLLSD() override; diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp index cad0b41d67..08e18ea26e 100644 --- a/indra/llinventory/llsettingswater.cpp +++ b/indra/llinventory/llsettingswater.cpp @@ -68,14 +68,16 @@ static const LLUUID DEFAULT_OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf8631 //========================================================================= LLSettingsWater::LLSettingsWater(const LLSD &data) : LLSettingsBase(data), - mNextNormalMapID() + mNextNormalMapID(), + mNextTransparentTextureID() { loadValuesFromLLSD(); } LLSettingsWater::LLSettingsWater() : LLSettingsBase(), - mNextNormalMapID() + mNextNormalMapID(), + mNextTransparentTextureID() { replaceSettings(defaults()); } @@ -235,10 +237,24 @@ void LLSettingsWater::blend(LLSettingsBase::ptr_t &end, F64 blendf) LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast(end); if (other) { - stringset_t skip = getSkipInterpolateKeys(); - stringset_t slerps = getSlerpKeys(); - LLSD blenddata = interpolateSDMap(getSettings(), other->getSettings(), other->getParameterMap(), blendf, skip, slerps); - replaceSettings(blenddata); + mSettingFlags |= other->mSettingFlags; + + mBlurMultiplier = lerp((F32)blendf, mBlurMultiplier, other->mBlurMultiplier); + lerpColor(mWaterFogColor, other->mWaterFogColor, (F32)blendf); + mWaterFogDensity = lerp((F32)blendf, mWaterFogDensity, other->mWaterFogDensity); + mFogMod = lerp((F32)blendf, mFogMod, other->mFogMod); + mFresnelOffset = lerp((F32)blendf, mFresnelOffset, other->mFresnelOffset); + mFresnelScale = lerp((F32)blendf, mFresnelScale, other->mFresnelScale); + lerpVector3(mNormalScale, other->mNormalScale, (F32)blendf); + mScaleAbove = lerp((F32)blendf, mScaleAbove, other->mScaleAbove); + mScaleBelow = lerp((F32)blendf, mScaleBelow, other->mScaleBelow); + lerpVector2(mWave1Dir, other->mWave1Dir, (F32)blendf); + lerpVector2(mWave2Dir, other->mWave2Dir, (F32)blendf); + + setDirtyFlag(true); + setReplaced(); + setLLSDDirty(); + mNextNormalMapID = other->getNormalMapID(); mNextTransparentTextureID = other->getTransparentTextureID(); } @@ -256,7 +272,34 @@ void LLSettingsWater::replaceSettings(LLSD settings) mNextTransparentTextureID.setNull(); } -void LLSettingsWater::replaceWithWater(LLSettingsWater::ptr_t other) +void LLSettingsWater::replaceSettings(const LLSettingsBase::ptr_t& other_water) +{ + LLSettingsBase::replaceSettings(other_water); + + llassert(getSettingsType() == other_water->getSettingsType()); + + LLSettingsWater::ptr_t other = PTR_NAMESPACE::dynamic_pointer_cast(other_water); + + mBlurMultiplier = other->mBlurMultiplier; + mWaterFogColor = other->mWaterFogColor; + mWaterFogDensity = other->mWaterFogDensity; + mFogMod = other->mFogMod; + mFresnelOffset = other->mFresnelOffset; + mFresnelScale = other->mFresnelScale; + mNormalScale = other->mNormalScale; + mScaleAbove = other->mScaleAbove; + mScaleBelow = other->mScaleBelow; + mWave1Dir = other->mWave1Dir; + mWave2Dir = other->mWave2Dir; + + mNormalMapID = other->mNormalMapID; + mTransparentTextureID = other->mTransparentTextureID; + + mNextNormalMapID.setNull(); + mNextTransparentTextureID.setNull(); +} + +void LLSettingsWater::replaceWithWater(const LLSettingsWater::ptr_t& other) { replaceWith(other); diff --git a/indra/llinventory/llsettingswater.h b/indra/llinventory/llsettingswater.h index 9d229e6a0b..82fc37cfb3 100644 --- a/indra/llinventory/llsettingswater.h +++ b/indra/llinventory/llsettingswater.h @@ -65,7 +65,8 @@ public: virtual void blend(LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE; virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE; - void replaceWithWater(LLSettingsWater::ptr_t other); + virtual void replaceSettings(const LLSettingsBase::ptr_t& other_water) override; + void replaceWithWater(const LLSettingsWater::ptr_t& other); static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index be891213a7..79691a5ce8 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -724,7 +724,6 @@ inline void draw_real(LLShaderUniforms* shader, F32 value, S32 shader_key) void LLSettingsVOSky::applyToUniforms(void* ptarget) { LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY]; - LLSD &settings = getSettings(); draw_color(shader, getAmbientColor(), LLShaderMgr::AMBIENT); draw_color(shader, getBlueDensity(), LLShaderMgr::BLUE_DENSITY); -- cgit v1.2.3 From 14a3c7573652e669c35dd331214f572da985c2a9 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 12 Sep 2024 11:05:14 -0500 Subject: Mac compatibility pass. --- indra/llrender/llvertexbuffer.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index c1f239fc43..de727eec7b 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1301,6 +1301,9 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst) { #if LL_DARWIN + // on OS X, flush_vbo doesn't actually write to the GL buffer, so be sure to call + // _mapBuffer to tag the buffer for flushing to GL + _mapBuffer(); LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); STOP_GLERROR; // copy into mapped buffer @@ -1591,12 +1594,6 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, U32 in void LLVertexBuffer::setBuffer() { STOP_GLERROR; -#if LL_DARWIN - if (!mGLBuffer) - { // OS X doesn't allocate a buffer until we call unmapBuffer - return; - } -#endif if (mMapped) { -- cgit v1.2.3 From 61990bfd6992ca1c4ee2df2795a469f67b085968 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 12 Sep 2024 11:06:05 -0500 Subject: Fix for tracy not working on mac --- indra/llcommon/llerror.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index ad35bc84f2..90c6ba309b 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -110,7 +110,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { - LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; int syslogPriority = LOG_CRIT; switch (level) { case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break; -- cgit v1.2.3 From bb9a2dd75bce568c5eef596b69a503270994e0ba Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 12 Sep 2024 15:03:44 -0700 Subject: Fix for mac build with tracy enabled. --- indra/llcommon/llerror.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index ad35bc84f2..90c6ba309b 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -110,7 +110,7 @@ namespace { virtual void recordMessage(LLError::ELevel level, const std::string& message) override { - LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING + LL_PROFILE_ZONE_SCOPED_CATEGORY_LOGGING; int syslogPriority = LOG_CRIT; switch (level) { case LLError::LEVEL_DEBUG: syslogPriority = LOG_DEBUG; break; -- cgit v1.2.3 From f4c53518d71180e4ba10b7b7c66bab9d26ec13a4 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 12 Sep 2024 15:04:03 -0700 Subject: Attempted fix for mac crash when showing About Second Life. secondlife/viewer#2553 --- indra/llcommon/llstring.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 505789f9ea..2c40ff3efd 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -1410,6 +1410,14 @@ bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token template<> void LLStringUtil::setLocale(std::string inLocale) { + if(startsWith(inLocale, "MissingString")) + { + // it seems this hasn't been working for some time, and I'm not sure how it is intentded to + // properly discover the correct locale. early out now to avoid failures later in + // formatNumber() + LL_WARNS() << "Failed attempting to set invalid locale: " << inLocale << LL_ENDL; + return; + } sLocale = inLocale; }; -- cgit v1.2.3 From f568fe6655bd52f32fd6987f0bcac8f88a9b6e01 Mon Sep 17 00:00:00 2001 From: Rye Cogtail Date: Thu, 12 Sep 2024 22:40:16 -0400 Subject: Fix macOS locale not being set due to missing locale strings --- indra/newview/skins/default/xui/da/language_settings.xml | 1 + indra/newview/skins/default/xui/de/language_settings.xml | 1 + indra/newview/skins/default/xui/en/language_settings.xml | 1 + indra/newview/skins/default/xui/es/language_settings.xml | 1 + indra/newview/skins/default/xui/fr/language_settings.xml | 1 + indra/newview/skins/default/xui/it/language_settings.xml | 1 + indra/newview/skins/default/xui/ja/language_settings.xml | 3 +++ indra/newview/skins/default/xui/pl/language_settings.xml | 1 + indra/newview/skins/default/xui/pt/language_settings.xml | 1 + 9 files changed, 11 insertions(+) diff --git a/indra/newview/skins/default/xui/da/language_settings.xml b/indra/newview/skins/default/xui/da/language_settings.xml index 0e3cbfd2d2..d31afb320a 100644 --- a/indra/newview/skins/default/xui/da/language_settings.xml +++ b/indra/newview/skins/default/xui/da/language_settings.xml @@ -5,6 +5,7 @@ danish da_DK.UTF-8 + da_DK.UTF-8 da_DK.UTF-8 da_DK.UTF-8 diff --git a/indra/newview/skins/default/xui/de/language_settings.xml b/indra/newview/skins/default/xui/de/language_settings.xml index f9346eef7d..57a327b345 100644 --- a/indra/newview/skins/default/xui/de/language_settings.xml +++ b/indra/newview/skins/default/xui/de/language_settings.xml @@ -5,6 +5,7 @@ german de_DE.UTF-8 + de_DE.UTF-8 de_DE.UTF-8 de_DE.UTF-8 diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml index dd521c09d0..12a1b52a84 100644 --- a/indra/newview/skins/default/xui/en/language_settings.xml +++ b/indra/newview/skins/default/xui/en/language_settings.xml @@ -5,6 +5,7 @@ english C + C C C diff --git a/indra/newview/skins/default/xui/es/language_settings.xml b/indra/newview/skins/default/xui/es/language_settings.xml index 997293a741..7a52f7cdae 100644 --- a/indra/newview/skins/default/xui/es/language_settings.xml +++ b/indra/newview/skins/default/xui/es/language_settings.xml @@ -5,6 +5,7 @@ spanish es_ES.UTF-8 + es_ES.UTF-8 es_ES.UTF-8 es_ES.UTF-8 diff --git a/indra/newview/skins/default/xui/fr/language_settings.xml b/indra/newview/skins/default/xui/fr/language_settings.xml index fdac9d65a7..fdb119ec69 100644 --- a/indra/newview/skins/default/xui/fr/language_settings.xml +++ b/indra/newview/skins/default/xui/fr/language_settings.xml @@ -5,6 +5,7 @@ french fr_FR.UTF-8 + fr_FR.UTF-8 fr_FR.UTF-8 fr_FR.UTF-8 diff --git a/indra/newview/skins/default/xui/it/language_settings.xml b/indra/newview/skins/default/xui/it/language_settings.xml index 5f448fa828..7eb1b560bd 100644 --- a/indra/newview/skins/default/xui/it/language_settings.xml +++ b/indra/newview/skins/default/xui/it/language_settings.xml @@ -5,6 +5,7 @@ italian it_IT.UTF-8 + it_IT.UTF-8 it_IT.UTF-8 it_IT.UTF-8 diff --git a/indra/newview/skins/default/xui/ja/language_settings.xml b/indra/newview/skins/default/xui/ja/language_settings.xml index facae22acf..c94a16cee0 100644 --- a/indra/newview/skins/default/xui/ja/language_settings.xml +++ b/indra/newview/skins/default/xui/ja/language_settings.xml @@ -6,6 +6,9 @@ ja_JP.UTF-8 + + ja_JP.UTF-8 + ja_JP.UTF-8 diff --git a/indra/newview/skins/default/xui/pl/language_settings.xml b/indra/newview/skins/default/xui/pl/language_settings.xml index 0057ca530c..9993062487 100644 --- a/indra/newview/skins/default/xui/pl/language_settings.xml +++ b/indra/newview/skins/default/xui/pl/language_settings.xml @@ -2,6 +2,7 @@ polish pl_PL.UTF-8 + pl_PL.UTF-8 pl_PL.UTF-8 pl_PL.UTF-8 hour,datetime,slt diff --git a/indra/newview/skins/default/xui/pt/language_settings.xml b/indra/newview/skins/default/xui/pt/language_settings.xml index 8799475ace..d5be208eb3 100644 --- a/indra/newview/skins/default/xui/pt/language_settings.xml +++ b/indra/newview/skins/default/xui/pt/language_settings.xml @@ -5,6 +5,7 @@ portuguese pt_PT.UTF-8 + pt_PT.UTF-8 pt_PT.UTF-8 pt_PT.UTF-8 -- cgit v1.2.3 From 74205607b7e106f3b7566ef4a4b9c2fcdfa2f83e Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Fri, 13 Sep 2024 16:28:48 +0200 Subject: Clean up Windows build (#2562) * APR_DECLARE_STATIC and APU_DECLARE_STATIC gets already defined in APR.cmake * Move both _CRT_SECURE_NO_WARNINGS and _WINSOCK_DEPRECATED_NO_WARNINGS definitions to 00-Common.cmake * Always define WIN32_LEAN_AND_MEAN and include subset of Windows API by default * Remove llwin32headerslean.h and remove unnecessary WIN32_LEAN_AND_MEAN definition handling in llwin32headers.h * Clean up includes of Windows API headers * Get rid of workaround to link against IPHLPAPI.lib in lluuid.cpp - this seems to have been an issue in the past that has been fixed --- indra/cmake/00-Common.cmake | 12 +++++------ indra/llcommon/CMakeLists.txt | 1 - indra/llcommon/llapr.h | 2 +- indra/llcommon/llfile.cpp | 2 +- indra/llcommon/llpreprocessor.h | 16 -------------- indra/llcommon/llprocess.h | 3 +-- indra/llcommon/llprocessor.cpp | 2 +- indra/llcommon/llsdutil.cpp | 3 +-- indra/llcommon/llstacktrace.cpp | 2 +- indra/llcommon/llstring.cpp | 3 +-- indra/llcommon/llsys.cpp | 2 +- indra/llcommon/lltimer.cpp | 2 +- indra/llcommon/lluuid.cpp | 3 --- indra/llcommon/llwin32headers.h | 11 ++-------- indra/llcommon/llwin32headerslean.h | 40 ----------------------------------- indra/llmath/llsdutil_math.cpp | 3 +-- indra/llmessage/llhost.cpp | 3 +-- indra/llmessage/lliopipe.h | 2 +- indra/llmessage/lliosocket.h | 2 +- indra/llmessage/llmail.cpp | 1 - indra/llmessage/net.cpp | 2 +- indra/llrender/llglheaders.h | 2 +- indra/llwindow/lldragdropwin32.h | 4 ++-- indra/llwindow/llkeyboardwin32.cpp | 2 +- indra/llwindow/llwindowwin32.h | 2 +- indra/newview/lldirpicker.cpp | 2 +- indra/newview/llsecapi.h | 2 +- indra/newview/llwindebug.h | 2 +- indra/newview/llxmlrpctransaction.cpp | 2 +- 29 files changed, 31 insertions(+), 104 deletions(-) delete mode 100644 indra/llcommon/llwin32headerslean.h diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 5087c308ee..39f26ced5d 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -68,9 +68,12 @@ if (WINDOWS) /NODEFAULTLIB:LIBCMT /IGNORE:4099) - add_definitions( - -DNOMINMAX -# /DDOM_DYNAMIC # For shared library colladadom + add_compile_definitions( + WIN32_LEAN_AND_MEAN + NOMINMAX +# DOM_DYNAMIC # For shared library colladadom + _CRT_SECURE_NO_WARNINGS # Allow use of sprintf etc + _WINSOCK_DEPRECATED_NO_WARNINGS # Disable deprecated WinSock API warnings ) add_compile_options( /Zo @@ -106,9 +109,6 @@ if (WINDOWS) string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") endif() - - # Allow use of sprintf etc - add_compile_definitions(_CRT_SECURE_NO_WARNINGS) endif (WINDOWS) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 437b8d0168..60549d9d11 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -240,7 +240,6 @@ set(llcommon_HEADER_FILES lluriparser.h lluuid.h llwin32headers.h - llwin32headerslean.h llworkerthread.h hbxxh.h lockstatic.h diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 00ff4d60b7..693cd7c01f 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -34,7 +34,7 @@ #endif #include -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "apr_thread_proc.h" #include "apr_getopt.h" #include "apr_signal.h" diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp index ed94ef21ef..d0bc8f7652 100644 --- a/indra/llcommon/llfile.cpp +++ b/indra/llcommon/llfile.cpp @@ -34,7 +34,7 @@ #include "stringize.h" #if LL_WINDOWS -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include // Windows errno #include #else diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index a528cc7fd8..b499a9ce10 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -98,15 +98,6 @@ # define LL_THREAD_LOCAL __thread #endif -// Static linking with apr on windows needs to be declared. -#if LL_WINDOWS && !LL_COMMON_LINK_SHARED -#ifndef APR_DECLARE_STATIC -#define APR_DECLARE_STATIC // For APR on Windows -#endif -#ifndef APU_DECLARE_STATIC -#define APU_DECLARE_STATIC // For APR util on Windows -#endif -#endif #if defined(LL_WINDOWS) #define BOOST_REGEX_NO_LIB 1 @@ -119,13 +110,6 @@ // Deal with VC++ problems #if LL_MSVC -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS // disable warnings for methods considered unsafe -#endif -#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS -#define _WINSOCK_DEPRECATED_NO_WARNINGS // disable deprecated WinSock API warnings -#endif - // level 4 warnings that we need to disable: #pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class #pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index 39ed29c1b4..cc2d6566fc 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -29,7 +29,6 @@ #include "llinitparam.h" #include "llsdparam.h" -#include "llwin32headerslean.h" #include "llexception.h" #include "apr_thread_proc.h" #include @@ -38,7 +37,7 @@ #include // std::ostream #if LL_WINDOWS -#include "llwin32headerslean.h" // for HANDLE +#include "llwin32headers.h" // for HANDLE #elif LL_LINUX #if defined(Status) #undef Status diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index 9d53b9be35..41ff369de2 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -34,7 +34,7 @@ //#include #if LL_WINDOWS -# include "llwin32headerslean.h" +# include "llwin32headers.h" # define _interlockedbittestandset _renamed_interlockedbittestandset # define _interlockedbittestandreset _renamed_interlockedbittestandreset # include diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp index 12f67208c1..dbd89118c9 100644 --- a/indra/llcommon/llsdutil.cpp +++ b/indra/llcommon/llsdutil.cpp @@ -32,8 +32,7 @@ #include #if LL_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include // for htonl +# include "llwin32headers.h" // for htonl #elif LL_LINUX # include #elif LL_DARWIN diff --git a/indra/llcommon/llstacktrace.cpp b/indra/llcommon/llstacktrace.cpp index ca8f4299d9..c223c26bb0 100644 --- a/indra/llcommon/llstacktrace.cpp +++ b/indra/llcommon/llstacktrace.cpp @@ -32,7 +32,7 @@ #include #include -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include typedef USHORT NTAPI RtlCaptureStackBackTrace_Function( diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 2c40ff3efd..07adf71d18 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -33,8 +33,7 @@ #include #if LL_WINDOWS -#include "llwin32headerslean.h" -#include // for WideCharToMultiByte +#include "llwin32headers.h" #endif std::string ll_safe_string(const char* in) diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 79625ad9f8..3f33ad61c5 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -59,7 +59,7 @@ using namespace llsd; #if LL_WINDOWS -# include "llwin32headerslean.h" +# include "llwin32headers.h" # include // GetPerformanceInfo() et al. # include #elif LL_DARWIN diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index 28d6e4e4cc..f36d223100 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -34,7 +34,7 @@ #include #if LL_WINDOWS -# include "llwin32headerslean.h" +# include "llwin32headers.h" #elif LL_LINUX || LL_DARWIN # include # include diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 7aeabc3c4a..b9bd27aa17 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -25,11 +25,8 @@ #include "linden_common.h" - // We can't use WIN32_LEAN_AND_MEAN here, needs lots of includes. #if LL_WINDOWS #include "llwin32headers.h" -// ugh, this is ugly. We need to straighten out our linking for this library -#pragma comment(lib, "IPHLPAPI.lib") #include #include #endif diff --git a/indra/llcommon/llwin32headers.h b/indra/llcommon/llwin32headers.h index f679adc200..df433deb7a 100644 --- a/indra/llcommon/llwin32headers.h +++ b/indra/llcommon/llwin32headers.h @@ -28,15 +28,8 @@ #define LL_LLWINDOWS_H #ifdef LL_WINDOWS -#ifndef NOMINMAX -#define NOMINMAX -#endif -#undef WIN32_LEAN_AND_MEAN -#include -#include -// reset to default, which is lean -#define WIN32_LEAN_AND_MEAN -#undef NOMINMAX +#include // Does not include winsock.h because WIN32_LEAN_AND_MEAN is defined +#include // Requires windows.h #endif #endif diff --git a/indra/llcommon/llwin32headerslean.h b/indra/llcommon/llwin32headerslean.h deleted file mode 100644 index 97c8edb8cf..0000000000 --- a/indra/llcommon/llwin32headerslean.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file llwin32headerslean.h - * @brief sanitized include of windows header files - * - * $LicenseInfo:firstyear=2001&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLWINDOWS_H -#define LL_LLWINDOWS_H - -#ifdef LL_WINDOWS -#ifndef NOMINMAX -#define NOMINMAX -#endif -#define WIN32_LEAN_AND_MEAN -#include -#include -#undef NOMINMAX -#endif - -#endif diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp index 0ea1a9c77a..2d5ec7d510 100644 --- a/indra/llmath/llsdutil_math.cpp +++ b/indra/llmath/llsdutil_math.cpp @@ -38,8 +38,7 @@ #include "v4color.h" #if LL_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include // for htonl +# include "llwin32headers.h" // for htonl #elif LL_LINUX # include #elif LL_DARWIN diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp index ace316512f..e7e3e27f58 100644 --- a/indra/llmessage/llhost.cpp +++ b/indra/llmessage/llhost.cpp @@ -31,8 +31,7 @@ #include "llerror.h" #if LL_WINDOWS - #define WIN32_LEAN_AND_MEAN - #include + #include #else #include #include // ntonl() diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h index 1887b5cd9a..b40539f38c 100644 --- a/indra/llmessage/lliopipe.h +++ b/indra/llmessage/lliopipe.h @@ -30,7 +30,7 @@ #define LL_LLIOPIPE_H #include -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "apr_poll.h" #include "llsd.h" diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h index 0a3f2617e6..4b79c77b56 100644 --- a/indra/llmessage/lliosocket.h +++ b/indra/llmessage/lliosocket.h @@ -38,7 +38,7 @@ */ #include "lliopipe.h" -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "apr_pools.h" #include "apr_network_io.h" #include "llchainio.h" diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp index 9e10a356db..b842aeda62 100644 --- a/indra/llmessage/llmail.cpp +++ b/indra/llmessage/llmail.cpp @@ -28,7 +28,6 @@ #include "llmail.h" -// APR on Windows needs full windows headers #include "llwin32headers.h" #include #include diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index 1c49f9be36..f153c938cf 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -32,7 +32,7 @@ #include #if LL_WINDOWS -#include "llwin32headerslean.h" +#include "llwin32headers.h" #else #include #include diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index c5e1ff3e23..3d4dc5e698 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -46,7 +46,7 @@ // LL_WINDOWS // windows gl headers depend on things like APIENTRY, so include windows. -#include "llwin32headerslean.h" +#include "llwin32headers.h" //---------------------------------------------------------------------------- #include diff --git a/indra/llwindow/lldragdropwin32.h b/indra/llwindow/lldragdropwin32.h index 1b30dced27..16d016677b 100644 --- a/indra/llwindow/lldragdropwin32.h +++ b/indra/llwindow/lldragdropwin32.h @@ -31,7 +31,7 @@ #ifndef LL_LLDRAGDROP32_H #define LL_LLDRAGDROP32_H -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include class LLDragDropWin32 @@ -54,7 +54,7 @@ class LLDragDropWin32 #ifndef LL_LLDRAGDROP32_H #define LL_LLDRAGDROP32_H -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include // impostor class that does nothing diff --git a/indra/llwindow/llkeyboardwin32.cpp b/indra/llwindow/llkeyboardwin32.cpp index ec0055fe60..8d6b8d9b93 100644 --- a/indra/llwindow/llkeyboardwin32.cpp +++ b/indra/llwindow/llkeyboardwin32.cpp @@ -28,7 +28,7 @@ #include "linden_common.h" -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "llkeyboardwin32.h" #include "llwindowcallbacks.h" diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h index 287402faa0..36e89e4586 100644 --- a/indra/llwindow/llwindowwin32.h +++ b/indra/llwindow/llwindowwin32.h @@ -28,7 +28,7 @@ #define LL_LLWINDOWWIN32_H // Limit Windows API to small and manageable set. -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include "llwindow.h" #include "llwindowcallbacks.h" diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 1423ca1b9b..e967ff3df2 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -35,7 +35,7 @@ #include "lltrans.h" #include "llwindow.h" // beforeDialog() #include "llviewercontrol.h" -#include "llwin32headerslean.h" +#include "llwin32headers.h" #if LL_LINUX || LL_DARWIN # include "llfilepicker.h" diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index ceea11cc34..14dda20225 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -28,7 +28,7 @@ #ifndef LLSECAPI_H #define LLSECAPI_H #include -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include #include #include "llpointer.h" diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h index 770584c88d..11b50e3327 100644 --- a/indra/newview/llwindebug.h +++ b/indra/newview/llwindebug.h @@ -28,7 +28,7 @@ #define LL_LLWINDEBUG_H #include "stdtypes.h" -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 48461241a2..07e2b118d3 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -26,7 +26,7 @@ #include "llviewerprecompiledheaders.h" // include this to get winsock2 because openssl attempts to include winsock1 -#include "llwin32headerslean.h" +#include "llwin32headers.h" #include #include #include "llsecapi.h" -- cgit v1.2.3 From da87e8bd370ea079576f8b412a4ddb80c0715bd1 Mon Sep 17 00:00:00 2001 From: leviathan Date: Fri, 13 Sep 2024 10:47:24 -0700 Subject: send AgentUpdate ASAP when control bits change --- indra/newview/llagent.cpp | 54 ++----- indra/newview/llagent.h | 4 - indra/newview/llagentcamera.cpp | 4 - indra/newview/llappviewer.cpp | 38 +---- indra/newview/llappviewer.h | 6 - indra/newview/llviewermessage.cpp | 333 +++++++++++++++++--------------------- 6 files changed, 171 insertions(+), 268 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7c37cc1c00..c8b0adbaf8 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -439,8 +439,6 @@ LLAgent::LLAgent() : mIsDoNotDisturb(false), mControlFlags(0x00000000), - mbFlagsDirty(false), - mbFlagsNeedReset(false), mAutoPilot(false), mAutoPilotFlyOnStop(false), @@ -936,8 +934,6 @@ void LLAgent::setFlying(bool fly, bool fail_sound) // Update Movement Controls according to Fly mode LLFloaterMove::setFlyingMode(fly); - - mbFlagsDirty = true; } @@ -1068,7 +1064,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) { regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback); } - } else { @@ -1556,7 +1551,6 @@ U32 LLAgent::getControlFlags() void LLAgent::setControlFlags(U32 mask) { mControlFlags |= mask; - mbFlagsDirty = true; } @@ -1565,28 +1559,7 @@ void LLAgent::setControlFlags(U32 mask) //----------------------------------------------------------------------------- void LLAgent::clearControlFlags(U32 mask) { - U32 old_flags = mControlFlags; mControlFlags &= ~mask; - if (old_flags != mControlFlags) - { - mbFlagsDirty = true; - } -} - -//----------------------------------------------------------------------------- -// controlFlagsDirty() -//----------------------------------------------------------------------------- -bool LLAgent::controlFlagsDirty() const -{ - return mbFlagsDirty; -} - -//----------------------------------------------------------------------------- -// enableControlFlagReset() -//----------------------------------------------------------------------------- -void LLAgent::enableControlFlagReset() -{ - mbFlagsNeedReset = true; } //----------------------------------------------------------------------------- @@ -1594,14 +1567,9 @@ void LLAgent::enableControlFlagReset() //----------------------------------------------------------------------------- void LLAgent::resetControlFlags() { - if (mbFlagsNeedReset) - { - mbFlagsNeedReset = false; - mbFlagsDirty = false; - // reset all of the ephemeral flags - // some flags are managed elsewhere - mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK; - } + // reset all of the ephemeral flags + // some flags are managed elsewhere + mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK; } //----------------------------------------------------------------------------- @@ -2085,11 +2053,19 @@ void LLAgent::propagate(const F32 dt) } // handle rotation based on keyboard levels - const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second - yaw(YAW_RATE * gAgentCamera.getYawKey() * dt); + constexpr F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second + F32 angle = YAW_RATE * gAgentCamera.getYawKey() * dt; + if (fabs(angle) > 0.0f) + { + yaw(angle); + } - const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second - pitch(PITCH_RATE * gAgentCamera.getPitchKey() * dt); + constexpr F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second + angle = PITCH_RATE * gAgentCamera.getPitchKey() * dt; + if (fabs(angle) > 0.0f) + { + pitch(angle); + } // handle auto-land behavior if (isAgentAvatarValid()) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 7c7f7aa91d..afc34f747f 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -482,21 +482,17 @@ public: void setControlFlags(U32 mask); // Performs bitwise mControlFlags |= mask void clearControlFlags(U32 mask); // Performs bitwise mControlFlags &= ~mask bool controlFlagsDirty() const; - void enableControlFlagReset(); void resetControlFlags(); bool anyControlGrabbed() const; // True iff a script has taken over a control bool isControlGrabbed(S32 control_index) const; // Send message to simulator to force grabbed controls to be // released, in case of a poorly written script. void forceReleaseControls(); - void setFlagsDirty() { mbFlagsDirty = true; } private: S32 mControlsTakenCount[TOTAL_CONTROLS]; S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS]; U32 mControlFlags; // Replacement for the mFooKey's - bool mbFlagsDirty; - bool mbFlagsNeedReset; // ! HACK ! For preventing incorrect flags sent when crossing region boundaries //-------------------------------------------------------------------- // Animations diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index e7531f963b..81e79a2ed9 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2204,10 +2204,6 @@ void LLAgentCamera::changeCameraToMouselook(bool animate) mCameraMode = CAMERA_MODE_MOUSELOOK; const U32 old_flags = gAgent.getControlFlags(); gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != gAgent.getControlFlags()) - { - gAgent.setFlagsDirty(); - } if (animate) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4eb4f5ae20..764e52accb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -642,8 +642,6 @@ LLAppViewer::LLAppViewer() mQuitRequested(false), mClosingFloaters(false), mLogoutRequestSent(false), - mLastAgentControlFlags(0), - mLastAgentForceUpdate(0), mMainloopTimeout(NULL), mAgentRegionLastAlive(false), mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", false)), @@ -4711,30 +4709,13 @@ void LLAppViewer::idle() gAgent.autoPilot(&yaw); } - static LLFrameTimer agent_update_timer; - - // When appropriate, update agent location to the simulator. - F32 agent_update_time = agent_update_timer.getElapsedTimeF32(); - F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time; - bool timed_out = agent_update_time > (1.0f / (F32)AGENT_UPDATES_PER_SECOND); - bool force_send = - // if there is something to send - (gAgent.controlFlagsDirty() && timed_out) - // if something changed - || (mLastAgentControlFlags != gAgent.getControlFlags()) - // keep alive - || (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND)); - // timing out doesn't warranty that an update will be sent, - // just that it will be checked. - if (force_send || timed_out) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - // Send avatar and camera info - mLastAgentControlFlags = gAgent.getControlFlags(); - mLastAgentForceUpdate = force_send ? 0 : agent_force_update_time; - send_agent_update(force_send); - agent_update_timer.reset(); - } + send_agent_update(false); + + // After calling send_agent_update() in the mainloop we always clear + // the agent's ephemeral ControlFlags (whether an AgentUpdate was + // actually sent or not) because these will be recomputed based on + // real-time key/controller input and resubmitted next frame. + gAgent.resetControlFlags(); } ////////////////////////////////////// @@ -5346,11 +5327,6 @@ void LLAppViewer::idleNetwork() } #endif - - - // we want to clear the control after sending out all necessary agent updates - gAgent.resetControlFlags(); - // Decode enqueued messages... S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 7b456cc542..4ce4259ed8 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -322,8 +322,6 @@ private: bool mQuitRequested; // User wants to quit, may have modified documents open. bool mClosingFloaters; bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. - U32 mLastAgentControlFlags; - F32 mLastAgentForceUpdate; struct SettingsFiles* mSettingsLocationList; LLWatchdogTimeout* mMainloopTimeout; @@ -341,10 +339,6 @@ private: bool mIsFirstRun; }; -// consts from viewer.h -const S32 AGENT_UPDATES_PER_SECOND = 125; // Value derived experimentally to avoid Input Delays with latest PBR-Capable Viewers when viewer FPS is highly volatile. -const S32 AGENT_FORCE_UPDATES_PER_SECOND = 1; - // Globals with external linkage. From viewer.h // *NOTE:Mani - These will be removed as the Viewer App Cleanup project continues. // diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 872a9a1581..0861b439eb 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3139,14 +3139,9 @@ void process_crossed_region(LLMessageSystem* msg, void**) } - -// Sends avatar and camera information to simulator. -// Sent roughly once per frame, or 20 times per second, whichever is less often - -const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less than this we need to update head_rot -const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot - // between these values we delay the updates (but no more than one second) - +// sends an AgentUpdate message to the server... or not: +// only when force_send is 'true' OR +// something changed AND the update is not being throttled void send_agent_update(bool force_send, bool send_reliable) { LL_PROFILE_ZONE_SCOPED; @@ -3154,72 +3149,46 @@ void send_agent_update(bool force_send, bool send_reliable) if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { - // We don't care if they want to send an agent update, they're not allowed to until the simulator - // that's the target is ready to receive them (after avatar_init_complete is received) + // We don't care if they want to send an agent update, they're not allowed + // until the target simulator is ready to receive them + // (e.g. after avatar_init_complete is received) return; } - // We have already requested to log out. Don't send agent updates. - if(LLAppViewer::instance()->logoutRequestSent()) + if (LLAppViewer::instance()->logoutRequestSent()) { + // We have already requested to log out. Don't send agent updates. return; } - // no region to send update to - if(gAgent.getRegion() == NULL) + if (gAgent.getRegion() == nullptr || gDisconnected) { + // no region to send update to return; } - const F32 TRANSLATE_THRESHOLD = 0.01f; - - // NOTA BENE: This is (intentionally?) using the small angle sine approximation to test for rotation - // Plus, there is an extra 0.5 in the mix since the perpendicular between last_camera_at and getAtAxis() bisects cam_rot_change - // Thus, we're actually testing against 0.2 degrees - const F32 ROTATION_THRESHOLD = 0.1f * 2.f*F_PI/360.f; // Rotation thresh 0.2 deg, see note above - - const U8 DUP_MSGS = 1; // HACK! number of times to repeat data on motionless agent - - // Store data on last sent update so that if no changes, no send - static LLVector3 last_camera_pos_agent, - last_camera_at, - last_camera_left, - last_camera_up; - - static LLVector3 cam_center_chg, - cam_rot_chg; - - static LLQuaternion last_head_rot; - static U32 last_control_flags = 0; - static U8 last_render_state; - static U8 duplicate_count = 0; - static F32 head_rot_chg = 1.0; - static U8 last_flags; - - LLMessageSystem *msg = gMessageSystem; - LLVector3 camera_pos_agent; // local to avatar's region - U8 render_state; - - LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion(); - LLQuaternion head_rotation = gAgent.getHeadRotation(); - - camera_pos_agent = gAgentCamera.getCameraPositionAgent(); + static F64 last_send_time = 0.0; + static U32 last_control_flags = 0; + static U8 last_render_state = 0; + static U8 last_flags = AU_FLAGS_NONE; + static LLQuaternion last_body_rot, + last_head_rot; + static LLVector3 last_camera_pos_agent, + last_camera_at; - render_state = gAgent.getRenderState(); - - U32 control_flag_change = 0; - U8 flag_change = 0; - - cam_center_chg = last_camera_pos_agent - camera_pos_agent; - cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis(); + // compute sec_since_last_send + constexpr F64 MAX_AGENT_UPDATES_PER_SECOND = 125.0; // Value derived experimentally to avoid Input Delays with latest PBR-Capable Viewers when viewer FPS is highly volatile. + constexpr F64 MIN_AGENT_UPDATES_PER_SECOND = 1.0; // keep-alive rate + constexpr F64 MIN_AGENT_UPDATE_PERIOD = 1.0 / MAX_AGENT_UPDATES_PER_SECOND; + constexpr F64 MAX_AGENT_UPDATE_PERIOD = 1.0 / MIN_AGENT_UPDATES_PER_SECOND; + F64 now = LLFrameTimer::getTotalSeconds(); + F64 sec_since_last_send = now - last_send_time; // If a modifier key is held down, turn off // LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't // trigger a control event. U32 control_flags = gAgent.getControlFlags(); - - MASK key_mask = gKeyboard->currentMask(true); - + MASK key_mask = gKeyboard->currentMask(true); if (key_mask & MASK_ALT || key_mask & MASK_CONTROL) { control_flags &= ~( AGENT_CONTROL_LBUTTON_DOWN | @@ -3228,7 +3197,22 @@ void send_agent_update(bool force_send, bool send_reliable) AGENT_CONTROL_ML_LBUTTON_UP ; } - control_flag_change = last_control_flags ^ control_flags; + // any change in control_flags should be sent ASAP, so we fold that into force_send + force_send = force_send || (control_flags != last_control_flags); + + if (! force_send && sec_since_last_send < MIN_AGENT_UPDATE_PERIOD) + { + // throttle less-important AgentUpdates + return; + } + + bool send_update = force_send || sec_since_last_send > MAX_AGENT_UPDATE_PERIOD; + + LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent(); // local to avatar's region + LLVector3 camera_at = LLViewerCamera::getInstance()->getAtAxis(); + LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion(); + LLQuaternion head_rotation = gAgent.getHeadRotation(); + U8 render_state = gAgent.getRenderState(); U8 flags = AU_FLAGS_NONE; if (gAgent.isGroupTitleHidden()) @@ -3240,159 +3224,140 @@ void send_agent_update(bool force_send, bool send_reliable) flags |= AU_FLAGS_CLIENT_AUTOPILOT; } - flag_change = last_flags ^ flags; - - head_rot_chg = dot(last_head_rot, head_rotation); - - //static S32 msg_number = 0; // Used for diagnostic log messages - - if (force_send || - (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || - (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) || - (last_render_state != render_state) || - (cam_rot_chg.magVec() > ROTATION_THRESHOLD) || - control_flag_change != 0 || - flag_change != 0) + if (!send_update) { - /* Diagnotics to show why we send the AgentUpdate message. Also un-commment the msg_number code above and below this block - msg_number += 1; - if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) - { - //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL; - } - if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) - { - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " << cam_rot_chg.magVec() << LL_ENDL; - } - if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) - { - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL; - } -// if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD) -// { -// LL_INFOS("Messaging") << "drag delta " << drag_delta_chg.magVec() << LL_ENDL; -// } - if (control_flag_change) + // check to see if anything changed + // use a do-while-false to provide easy way to break out as soon as we find something changed + do { - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL; - } -*/ - - duplicate_count = 0; - } - else - { - duplicate_count++; + // start with the easy evaluations and progress to more complicated - if (head_rot_chg < MAX_HEAD_ROT_QDOT && duplicate_count < AGENT_UPDATES_PER_SECOND) - { - // The head_rotation is sent for updating things like attached guns. - // We only trigger a new update when head_rotation deviates beyond - // some threshold from the last update, however this can break fine - // adjustments when trying to aim an attached gun, so what we do here - // (where we would normally skip sending an update when nothing has changed) - // is gradually reduce the threshold to allow a better update to - // eventually get sent... should update to within 0.5 degrees in less - // than a second. - if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT + (MAX_HEAD_ROT_QDOT - THRESHOLD_HEAD_ROT_QDOT) * duplicate_count / AGENT_UPDATES_PER_SECOND) + // check render_state + if (last_render_state != render_state) { - duplicate_count = 0; + send_update = true; + break; } - else + + // check flags + if (last_flags != flags) { - return; + send_update = true; + break; } - } - else - { - return; - } - } - if (duplicate_count < DUP_MSGS && !gDisconnected) - { - /* More diagnostics to count AgentUpdate messages - static S32 update_sec = 0; - static S32 update_count = 0; - static S32 max_update_count = 0; - S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() ); - update_count += 1; - if (cur_sec != update_sec) - { - if (update_sec != 0) + // check translation + constexpr F32 TRANSLATE_THRESHOLD = 0.01f; + if ((last_camera_pos_agent - camera_pos_agent).magVec() > TRANSLATE_THRESHOLD) { - update_sec = cur_sec; - //msg_number = 0; - max_update_count = llmax(max_update_count, update_count); - LL_INFOS() << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << LL_ENDL; + send_update = true; + break; } - update_sec = cur_sec; - update_count = 0; - } - */ - // Build the message - msg->newMessageFast(_PREHASH_AgentUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addQuatFast(_PREHASH_BodyRotation, body_rotation); - msg->addQuatFast(_PREHASH_HeadRotation, head_rotation); - msg->addU8Fast(_PREHASH_State, render_state); - msg->addU8Fast(_PREHASH_Flags, flags); - -// if (camera_pos_agent.mV[VY] > 255.f) -// { -// LL_INFOS("Messaging") << "Sending camera center " << camera_pos_agent << LL_ENDL; -// } - - msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent); - msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis()); - msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); - msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); - msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); + // check camera rotation + // Note: we are using the sine small angle approximation trick here + constexpr F32 RADIANS_PER_DEGREE = F_PI / 360.f; + constexpr F32 CAMERA_AT_THRESHOLD = 0.2f * RADIANS_PER_DEGREE; + if ((last_camera_at - camera_at).magVec() > CAMERA_AT_THRESHOLD) + { + send_update = true; + break; + } - msg->addU32Fast(_PREHASH_ControlFlags, control_flags); + // check head rotation + constexpr F64 MIN_HEAD_ROT_QDOT = 0.9997; // ~= 2.5 degrees -- if its less than this we need to update head_rot + constexpr F64 MAX_HEAD_ROT_QDOT = 0.99999; // ~= 0.5 degrees -- if its greater than this then we consider it close enough - if (gDebugClicks) - { - if (control_flags & AGENT_CONTROL_LBUTTON_DOWN) + if (fabs((F64)(dot(last_body_rot, body_rotation))) < MIN_HEAD_ROT_QDOT) { - LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL; + send_update = true; + break; } - if (control_flags & AGENT_CONTROL_LBUTTON_UP) + F64 head_rot_qdot = fabs((F64)(dot(last_head_rot, head_rotation))); + if (head_rot_qdot > MAX_HEAD_ROT_QDOT) { - LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL; + // close enough + return; + } + else if (head_rot_qdot < MIN_HEAD_ROT_QDOT) + { + // way off + send_update = true; + break; } - } - gAgent.enableControlFlagReset(); + // Finally, if we get here then head_rot_qdot is somewhere between MIN_ and MAX_HEAD_ROT_QDOT - if (!send_reliable) + // The head_rotation is sent for updating things like attached guns. + // We only trigger a new update when head_rotation deviates beyond + // some threshold from the last update, however this can break fine + // adjustments when trying to aim an attached gun, so what we do here + // (where we would normally skip sending an update when nothing has changed) + // is linearly increase the min threshold until an update is sent. + // Min threshold should update to MAX_HEAD_ROT_QDOT within THRESHOLD_GROWTH_PERIOD. + constexpr F64 THRESHOLD_GROWTH_PERIOD = 0.5; + constexpr F64 threshold_growth_per_sec = (MAX_HEAD_ROT_QDOT - MIN_HEAD_ROT_QDOT) / THRESHOLD_GROWTH_PERIOD; + send_update = head_rot_qdot < MIN_HEAD_ROT_QDOT + sec_since_last_send * threshold_growth_per_sec; + } while (false); + } + + if (!send_update) + { + return; + } + + // Build the message + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addQuatFast(_PREHASH_BodyRotation, body_rotation); + msg->addQuatFast(_PREHASH_HeadRotation, head_rotation); + msg->addU8Fast(_PREHASH_State, render_state); + msg->addU8Fast(_PREHASH_Flags, flags); + + msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent); + msg->addVector3Fast(_PREHASH_CameraAtAxis, camera_at); + msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); + msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); + msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); + + msg->addU32Fast(_PREHASH_ControlFlags, control_flags); + + if (gDebugClicks) + { + if (control_flags & AGENT_CONTROL_LBUTTON_DOWN) { - gAgent.sendMessage(); + LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL; } - else + + if (control_flags & AGENT_CONTROL_LBUTTON_UP) { - gAgent.sendReliableMessage(); + LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL; } + } -// LL_DEBUGS("Messaging") << "agent " << avatar_pos_agent << " cam " << camera_pos_agent << LL_ENDL; - - // Copy the old data - last_head_rot = head_rotation; - last_render_state = render_state; - last_camera_pos_agent = camera_pos_agent; - last_camera_at = LLViewerCamera::getInstance()->getAtAxis(); - last_camera_left = LLViewerCamera::getInstance()->getLeftAxis(); - last_camera_up = LLViewerCamera::getInstance()->getUpAxis(); - last_control_flags = control_flags; - last_flags = flags; + if (send_reliable) + { + gAgent.sendReliableMessage(); + } + else + { + gAgent.sendMessage(); } -} + // remember last update data + last_send_time = now; + last_control_flags = control_flags; + last_render_state = render_state; + last_flags = flags; + last_body_rot = body_rotation; + last_head_rot = head_rotation; + last_camera_pos_agent = camera_pos_agent; + last_camera_at = camera_at; +} // sounds can arrive before objects, store them for a short time // Note: this is a workaround for MAINT-4743, real fix would be to make -- cgit v1.2.3 From 85a7020e4903e83701c3f1ccbc9a14bd84c9368b Mon Sep 17 00:00:00 2001 From: Rye Cogtail Date: Fri, 13 Sep 2024 16:26:23 -0400 Subject: Raise resolution of local baked texture preview from 512 to 2048 --- indra/llappearance/llavatarappearancedefines.cpp | 4 +- indra/newview/character/avatar_lad.xml | 46 ++++++++++---------- indra/newview/lldynamictexture.cpp | 54 ++++++++++++++++-------- indra/newview/llgltfmaterialpreviewmgr.cpp | 2 +- indra/newview/pipeline.cpp | 6 ++- indra/newview/pipeline.h | 5 ++- 6 files changed, 72 insertions(+), 45 deletions(-) diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index 580e6433c5..5f98f2c8c1 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -28,8 +28,8 @@ #include "llavatarappearancedefines.h" #include "indra_constants.h" -const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 1024; -const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 1024; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 2048; +const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 2048; using namespace LLAvatarAppearanceDefines; diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index 2cdd86267e..90dc361a5c 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -1,4 +1,4 @@ - + @@ -8923,8 +8923,8 @@ + width="2048" + height="2048"> + width="2048" + height="2048"> + width="2048" + height="2048"> + width="512" + height="512"> = LLPipeline::MAX_BAKE_WIDTH); - llassert(bake_target.getHeight() >= LLPipeline::MAX_BAKE_WIDTH); + llassert(preview_target.getWidth() >= LLPipeline::MAX_PREVIEW_WIDTH); + llassert(preview_target.getHeight() >= LLPipeline::MAX_PREVIEW_WIDTH); + llassert(bake_target.getWidth() >= LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH); + llassert(bake_target.getHeight() >= LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT); - bake_target.bindTarget(); - bake_target.clear(); + preview_target.bindTarget(); + preview_target.clear(); LLGLSLShader::unbind(); LLVertexBuffer::unbind(); bool result = false; bool ret = false ; - for( S32 order = 0; order < ORDER_COUNT; order++ ) - { - for (instance_list_t::iterator iter = LLViewerDynamicTexture::sInstances[order].begin(); - iter != LLViewerDynamicTexture::sInstances[order].end(); ++iter) + auto update_func = [&](LLViewerDynamicTexture* dynamicTexture, LLRenderTarget& renderTarget, S32 width, S32 height) { - LLViewerDynamicTexture *dynamicTexture = *iter; if (dynamicTexture->needsRender()) { - llassert(dynamicTexture->getFullWidth() <= S32(LLPipeline::MAX_BAKE_WIDTH)); - llassert(dynamicTexture->getFullHeight() <= S32(LLPipeline::MAX_BAKE_WIDTH)); + llassert(dynamicTexture->getFullWidth() <= width); + llassert(dynamicTexture->getFullHeight() <= height); glClear(GL_DEPTH_BUFFER_BIT); - gGL.color4f(1,1,1,1); - dynamicTexture->setBoundTarget(&bake_target); + gGL.color4f(1.f, 1.f, 1.f, 1.f); + dynamicTexture->setBoundTarget(&renderTarget); dynamicTexture->preRender(); // Must be called outside of startRender() result = false; if (dynamicTexture->render()) { - ret = true ; + ret = true; result = true; sNumRenders++; } @@ -237,9 +235,31 @@ bool LLViewerDynamicTexture::updateAllInstances() dynamicTexture->setBoundTarget(nullptr); dynamicTexture->postRender(result); } + }; + + // ORDER_FIRST is unused, ORDER_MIDDLE is various ui preview + for(S32 order = 0; order < ORDER_LAST; ++order) + { + for (LLViewerDynamicTexture* dynamicTexture : LLViewerDynamicTexture::sInstances[order]) + { + update_func(dynamicTexture, preview_target, LLPipeline::MAX_PREVIEW_WIDTH, LLPipeline::MAX_PREVIEW_WIDTH); } } + preview_target.flush(); + + // ORDER_LAST is baked skin preview, ORDER_RESET resets appearance parameters and does not render. + bake_target.bindTarget(); + bake_target.clear(); + result = false; + ret = false; + for (S32 order = ORDER_LAST; order < ORDER_COUNT; ++order) + { + for (LLViewerDynamicTexture* dynamicTexture : LLViewerDynamicTexture::sInstances[order]) + { + update_func(dynamicTexture, bake_target, LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH, LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT); + } + } bake_target.flush(); gGL.flush(); diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp index 294b445694..cf6b08797d 100644 --- a/indra/newview/llgltfmaterialpreviewmgr.cpp +++ b/indra/newview/llgltfmaterialpreviewmgr.cpp @@ -193,7 +193,7 @@ LLGLTFPreviewTexture::LLGLTFPreviewTexture(LLPointer mate // static LLPointer LLGLTFPreviewTexture::create(LLPointer material) { - return new LLGLTFPreviewTexture(material, LLPipeline::MAX_BAKE_WIDTH); + return new LLGLTFPreviewTexture(material, LLPipeline::MAX_PREVIEW_WIDTH); } bool LLGLTFPreviewTexture::needsRender() diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 081f4a3564..a48e6815f9 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -219,7 +219,7 @@ S32 LLPipeline::RenderHeroProbeUpdateRate; S32 LLPipeline::RenderHeroProbeConservativeUpdateMultiplier; LLTrace::EventStatHandle LLPipeline::sStatBatchSize("renderbatchsize"); -const U32 LLPipeline::MAX_BAKE_WIDTH = 512; +const U32 LLPipeline::MAX_PREVIEW_WIDTH = 512; const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; @@ -878,6 +878,8 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY) // used to scale down textures // See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown mDownResMap.allocate(4, 4, GL_RGBA); + + mBakeMap.allocate(LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH, LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT, GL_RGBA); } //HACK make screenbuffer allocations start failing after 30 seconds if (gSavedSettings.getBOOL("SimulateFBOFailure")) @@ -1138,6 +1140,8 @@ void LLPipeline::releaseGLBuffers() mDownResMap.release(); + mBakeMap.release(); + for (U32 i = 0; i < 3; i++) { mGlow[i].release(); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index a3ecab3208..5c9b95ef4a 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -737,6 +737,9 @@ public: // downres scratch space for GPU downscaling of textures LLRenderTarget mDownResMap; + // 2k bom scratch target + LLRenderTarget mBakeMap; + LLCullResult mSky; LLCullResult mReflectedObjects; LLCullResult mRefractedObjects; @@ -776,7 +779,7 @@ public: //water distortion texture (refraction) LLRenderTarget mWaterDis; - static const U32 MAX_BAKE_WIDTH; + static const U32 MAX_PREVIEW_WIDTH; //texture for making the glow LLRenderTarget mGlow[3]; -- cgit v1.2.3 From e3c3cc636e66043fa89f402c9f132c208f0217cd Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Mon, 16 Sep 2024 13:14:14 -0700 Subject: Fix for crash in LLPluginProcessParent during early shutdown. fixes secondlife/viewer#2550 --- indra/llplugin/llpluginprocessparent.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index bd1e19c294..908f3c8ff5 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -48,7 +48,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() bool LLPluginProcessParent::sUseReadThread = false; apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; bool LLPluginProcessParent::sPollsetNeedsRebuild = false; -LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex; +LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex = nullptr; LLPluginProcessParent::mapInstances_t LLPluginProcessParent::sInstances; LLThread *LLPluginProcessParent::sReadThread = NULL; @@ -155,6 +155,12 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent /*static*/ void LLPluginProcessParent::shutdown() { + if (!sInstancesMutex) + { + // setup was not complete, skip shutdown + return; + } + LLCoros::LockType lock(*sInstancesMutex); mapInstances_t::iterator it; -- cgit v1.2.3 From eac0c748a2f650a7875e29e9ccc65522f485911b Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Mon, 16 Sep 2024 15:59:34 -0700 Subject: Fix noise post effect due to missing uniform (#2581) --- indra/newview/pipeline.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 081f4a3564..88871f5fb8 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7915,6 +7915,8 @@ void LLPipeline::renderFinalize() gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer); gDeferredPostNoDoFNoiseProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true); + gDeferredPostNoDoFNoiseProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, (GLfloat)finalBuffer->getWidth(), (GLfloat)finalBuffer->getHeight()); + { LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS); mScreenTriangleVB->setBuffer(); -- cgit v1.2.3 From 486613e79bb96b838121f627ef73b1293ee18c12 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 16 Sep 2024 18:49:03 -0500 Subject: Profile guided optimization pass (#2582) - Tune up LLJointRiggingInfoTab - Visualize joint bounding boxes when visualizing joints - Use LLJointRiggingInfo to caclulate desired resolution of a texture - Throttle calls to calcPixelArea - Fetch MeshSkinInfo immediately when header is received --- indra/llmath/llrigginginfo.h | 4 ++ indra/llprimitive/llmodel.cpp | 7 +++ indra/llprimitive/llmodel.h | 5 +- indra/llrender/llrendersphere.cpp | 62 ++++++++++++++++---- indra/llrender/llrendersphere.h | 1 + indra/llrender/llvertexbuffer.cpp | 2 - indra/newview/llface.cpp | 79 ++++++++++++++++++++++--- indra/newview/llface.h | 13 +++++ indra/newview/llmeshrepository.cpp | 88 ++++++++++++++++++++++------ indra/newview/llmeshrepository.h | 19 ++++-- indra/newview/llskinningutil.cpp | 43 ++------------ indra/newview/llviewerobject.cpp | 1 + indra/newview/llvoavatar.cpp | 116 +++++++++++++++++++++++++++++++++---- indra/newview/llvoavatar.h | 2 +- indra/newview/llvovolume.cpp | 6 +- 15 files changed, 345 insertions(+), 103 deletions(-) diff --git a/indra/llmath/llrigginginfo.h b/indra/llmath/llrigginginfo.h index fb550d013f..d761af68b1 100644 --- a/indra/llmath/llrigginginfo.h +++ b/indra/llmath/llrigginginfo.h @@ -66,6 +66,10 @@ public: const LLJointRiggingInfo& operator[](S32 i) const { return mRigInfoPtr[i]; }; bool needsUpdate() { return mNeedsUpdate; } void setNeedsUpdate(bool val) { mNeedsUpdate = val; } + + LLJointRiggingInfo* begin() { return mRigInfoPtr; } + LLJointRiggingInfo* end() { return mRigInfoPtr + mSize; } + private: // Not implemented LLJointRiggingInfoTab& operator=(const LLJointRiggingInfoTab& src); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 15087a7255..9908a155f2 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1547,6 +1547,13 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin) mLockScaleIfJointPosition = false; } + // combine mBindShapeMatrix and mInvBindMatrix into mBindPoseMatrix + mBindPoseMatrix.resize(mInvBindMatrix.size()); + for (U32 i = 0; i < mInvBindMatrix.size(); ++i) + { + matMul(mBindShapeMatrix, mInvBindMatrix[i], mBindPoseMatrix[i]); + } + updateHash(); } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index b0cba2d655..96cfb7151e 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -56,12 +56,15 @@ public: LLUUID mMeshID; std::vector mJointNames; mutable std::vector mJointNums; - typedef std::vector> matrix_list_t; + typedef std::vector matrix_list_t; matrix_list_t mInvBindMatrix; // bones/joints position overrides matrix_list_t mAlternateBindMatrix; + // cached multiply of mBindShapeMatrix and mInvBindMatrix + matrix_list_t mBindPoseMatrix; + LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); float mPelvisOffset; diff --git a/indra/llrender/llrendersphere.cpp b/indra/llrender/llrendersphere.cpp index 9570180554..cd8ef7d68e 100644 --- a/indra/llrender/llrendersphere.cpp +++ b/indra/llrender/llrendersphere.cpp @@ -34,6 +34,8 @@ #include "llerror.h" #include "llglheaders.h" +#include "llvertexbuffer.h" +#include "llglslshader.h" LLRenderSphere gSphere; @@ -53,12 +55,20 @@ inline LLVector3 polar_to_cart(F32 latitude, F32 longitude) void LLRenderSphere::renderGGL() { + LL_PROFILE_ZONE_SCOPED; S32 const LATITUDE_SLICES = 20; S32 const LONGITUDE_SLICES = 30; - if (mSpherePoints.empty()) + if (mVertexBuffer.isNull()) { mSpherePoints.resize(LATITUDE_SLICES + 1); + mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX); + + mVertexBuffer->allocateBuffer((U32)(LATITUDE_SLICES + 1) * (LONGITUDE_SLICES + 1), LATITUDE_SLICES * LONGITUDE_SLICES * 6); + + LLStrider v; + mVertexBuffer->getVertexStrider(v); + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++) { mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1); @@ -68,24 +78,52 @@ void LLRenderSphere::renderGGL() F32 lon = (F32)lon_i / LONGITUDE_SLICES; mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon); + v[lat_i * (LONGITUDE_SLICES + 1) + lon_i] = mSpherePoints[lat_i][lon_i]; } } + + LLStrider i; + mVertexBuffer->getIndexStrider(i); + + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++) + { + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++) + { + i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 0] = lat_i * (LONGITUDE_SLICES + 1) + lon_i; + i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 1] = lat_i * (LONGITUDE_SLICES + 1) + lon_i + 1; + i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 2] = (lat_i + 1) * (LONGITUDE_SLICES + 1) + lon_i; + + i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 3] = (lat_i + 1) * (LONGITUDE_SLICES + 1) + lon_i; + i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 4] = lat_i * (LONGITUDE_SLICES + 1) + lon_i + 1; + i[(lat_i * LONGITUDE_SLICES + lon_i) * 6 + 5] = (lat_i + 1) * (LONGITUDE_SLICES + 1) + lon_i + 1; + } + } + + mVertexBuffer->unmapBuffer(); } - gGL.begin(LLRender::TRIANGLES); - for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++) - { - for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++) + if (LLGLSLShader::sCurBoundShaderPtr->mAttributeMask == LLVertexBuffer::MAP_VERTEX) + { // shader expects only vertex positions in vertex buffer, use fast path + mVertexBuffer->setBuffer(); + mVertexBuffer->drawRange(LLRender::TRIANGLES, 0, mVertexBuffer->getNumVerts(), mVertexBuffer->getNumIndices(), 0); + } + else + { //shader wants colors in the vertex stream, use slow path + gGL.begin(LLRender::TRIANGLES); + for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++) { - gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV); - gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); - gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); + for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++) + { + gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i + 1].mV); + gGL.vertex3fv(mSpherePoints[lat_i + 1][lon_i].mV); - gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV); - gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV); - gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV); + gGL.vertex3fv(mSpherePoints[lat_i + 1][lon_i].mV); + gGL.vertex3fv(mSpherePoints[lat_i][lon_i + 1].mV); + gGL.vertex3fv(mSpherePoints[lat_i + 1][lon_i + 1].mV); + } } + gGL.end(); } - gGL.end(); } diff --git a/indra/llrender/llrendersphere.h b/indra/llrender/llrendersphere.h index e2e886fa06..5b6eabecb8 100644 --- a/indra/llrender/llrendersphere.h +++ b/indra/llrender/llrendersphere.h @@ -45,6 +45,7 @@ public: private: std::vector< std::vector > mSpherePoints; + LLPointer mVertexBuffer; }; extern LLRenderSphere gSphere; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 3a18c28a62..e9fa369b0c 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1341,8 +1341,6 @@ void LLVertexBuffer::unmapBuffer() void LLVertexBuffer::_mapBuffer() { - // must only be called from main thread - llassert(LLCoros::on_main_thread_main_coro()); if (!mMapped) { mMapped = true; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 48fddc32db..ce68474211 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -56,6 +56,7 @@ #include "llvoavatar.h" #include "llsculptidsize.h" #include "llmeshrepository.h" +#include "llskinningutil.h" #if LL_LINUX // Work-around spurious used before init warning on Vector4a @@ -2184,28 +2185,88 @@ F32 LLFace::getTextureVirtualSize() bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) { + constexpr F32 PIXEL_AREA_UPDATE_PERIOD = 0.1f; + // this is an expensive operation and the result is valid (enough) for several frames + // don't update every frame + if (gFrameTimeSeconds - mLastPixelAreaUpdate < PIXEL_AREA_UPDATE_PERIOD) + { + return true; + } + LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; //get area of circle around face - LLVector4a center; LLVector4a size; - if (isState(LLFace::RIGGED)) { - //override with avatar bounding box + LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("calcPixelArea - rigged"); + //override with joint volume face joint bounding boxes LLVOAvatar* avatar = mVObjp->getAvatar(); + bool hasRiggedExtents = false; + if (avatar && avatar->mDrawable) { - center.load3(avatar->getPositionAgent().mV); - const LLVector4a* exts = avatar->mDrawable->getSpatialExtents(); - size.setSub(exts[1], exts[0]); + LLVolume* volume = mVObjp->getVolume(); + if (volume) + { + LLVolumeFace& face = volume->getVolumeFace(mTEOffset); + + auto& rigInfo = face.mJointRiggingInfoTab; + + if (rigInfo.needsUpdate()) + { + LLVOVolume* vo_volume = (LLVOVolume*)mVObjp.get(); + LLVOAvatar* avatar = mVObjp->getAvatar(); + const LLMeshSkinInfo* skin = vo_volume->getSkinInfo(); + LLSkinningUtil::updateRiggingInfo(skin, avatar, face); + } + + // calculate the world space bounding box of the face by combining the bounding boxes of all the joints + LLVector4a& minp = mRiggedExtents[0]; + LLVector4a& maxp = mRiggedExtents[1]; + minp = LLVector4a(FLT_MAX, FLT_MAX, FLT_MAX); + maxp = LLVector4a(-FLT_MAX, -FLT_MAX, -FLT_MAX); + + for (S32 i = 0; i < rigInfo.size(); i++) + { + auto& jointInfo = rigInfo[i]; + if (jointInfo.isRiggedTo()) + { + LLJoint* joint = avatar->getJoint(i); + + if (joint) + { + LLVector4a jointPos; + + LLMatrix4a worldMat; + worldMat.loadu((F32*)&joint->getWorldMatrix().mMatrix[0][0]); + + LLVector4a extents[2]; + + matMulBoundBox(worldMat, jointInfo.getRiggedExtents(), extents); + + minp.setMin(minp, extents[0]); + maxp.setMax(maxp, extents[1]); + hasRiggedExtents = true; + } + } + } + } } - else + + if (!hasRiggedExtents) { + // no rigged extents, zero out bounding box and skip update + mRiggedExtents[0] = mRiggedExtents[1] = LLVector4a(0.f, 0.f, 0.f); + return false; } + + center.setAdd(mRiggedExtents[1], mRiggedExtents[0]); + center.mul(0.5f); + size.setSub(mRiggedExtents[1], mRiggedExtents[0]); } else { @@ -2231,6 +2292,10 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) F32 app_angle = atanf((F32) sqrt(size_squared) / dist); radius = app_angle*LLDrawable::sCurPixelAngle; mPixelArea = radius*radius * 3.14159f; + + // remember last update time, add 10% noise to avoid all faces updating at the same time + mLastPixelAreaUpdate = gFrameTimeSeconds + ll_frand() * PIXEL_AREA_UPDATE_PERIOD * 0.1f; + LLVector4a x_axis; x_axis.load3(camera->getXAxis().mV); cos_angle_to_view_dir = lookAt.dot3(x_axis).getF32(); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 99642016f7..65637fbf85 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -234,8 +234,14 @@ public: // return true if this face is in an alpha draw pool bool isInAlphaPool() const; public: //aligned members + + // bounding box of face in drawable space LLVector4a mExtents[2]; + // cached bounding box of rigged face in world space + // calculated on-demand by LLFace::calcPixelArea and may not be up-to-date + LLVector4a mRiggedExtents[2] = { LLVector4a(0,0,0), LLVector4a(0,0,0) }; + private: friend class LLViewerTextureList; F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); @@ -301,7 +307,14 @@ private: S32 mReferenceIndex; std::vector mRiggedIndex; + // gFrameTimeSeconds when mPixelArea was last updated + F32 mLastPixelAreaUpdate = 0.f; + + // virtual size of face in texture area (mPixelArea adjusted by texture repeats) + // used to determine desired resolution of texture F32 mVSize; + + // pixel area face covers on screen F32 mPixelArea; //importance factor, in the range [0, 1.0]. diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 26e2d8f319..532a87bbd1 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -77,6 +77,8 @@ #include "llinventorypanel.h" #include "lluploaddialog.h" #include "llfloaterreg.h" +#include "llvoavatarself.h" +#include "llskinningutil.h" #include "boost/iostreams/device/array.hpp" #include "boost/iostreams/stream.hpp" @@ -757,7 +759,7 @@ void log_upload_error(LLCore::HttpStatus status, const LLSD& content, << " (" << status.toTerseString() << ")" << LL_ENDL; std::ostringstream details; - typedef std::set mav_errors_set_t; + typedef std::unordered_set mav_errors_set_t; mav_errors_set_t mav_errors; if (content.has("error")) @@ -828,7 +830,8 @@ LLMeshRepoThread::LLMeshRepoThread() mHttpLargeOptions(), mHttpHeaders(), mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), - mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID) + mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID), + mWorkQueue("MeshRepoThread", 1024*1024) { LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp()); @@ -911,6 +914,10 @@ void LLMeshRepoThread::run() break; } + // run mWorkQueue for up to 8ms + static std::chrono::nanoseconds WorkTimeNanoSec{std::chrono::nanoseconds::rep(8 * 1000000) }; + mWorkQueue.runFor(WorkTimeNanoSec); + if (! mHttpRequestSet.empty()) { // Dispatch all HttpHandler notifications @@ -1322,7 +1329,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) { - + LL_PROFILE_ZONE_SCOPED; if (!mHeaderMutex) { return false; @@ -1447,6 +1454,7 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) { + LL_PROFILE_ZONE_SCOPED; if (!mHeaderMutex) { return false; @@ -1554,6 +1562,7 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) { + LL_PROFILE_ZONE_SCOPED; if (!mHeaderMutex) { return false; @@ -1693,6 +1702,7 @@ void LLMeshRepoThread::decActiveHeaderRequests() //return false if failed to get header bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool can_retry) { + LL_PROFILE_ZONE_SCOPED; ++LLMeshRepository::sMeshRequestCount; { @@ -1756,6 +1766,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params, bool c //return false if failed to get mesh lod. bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, bool can_retry) { + LL_PROFILE_ZONE_SCOPED; if (!mHeaderMutex) { return false; @@ -1940,6 +1951,18 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes LLMeshRepository::sCacheBytesHeaders += (U32)header_size; } + // immediately request SkinInfo since we'll need it before we can render any LoD if it is present + { + LLMutexLock lock(gMeshRepo.mMeshMutex); + + if (gMeshRepo.mLoadingSkins.find(mesh_id) == gMeshRepo.mLoadingSkins.end()) + { + gMeshRepo.mLoadingSkins[mesh_id] = {}; // add an empty vector to indicate to main thread that we are loading skin info + } + } + + fetchMeshSkinInfo(mesh_id); + LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests @@ -1971,6 +1994,18 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p { if (volume->getNumFaces() > 0) { + // if we have a valid SkinInfo, cache per-joint bounding boxes for this LOD + LLMeshSkinInfo* skin_info = mSkinMap[mesh_params.getSculptID()]; + if (skin_info && isAgentAvatarValid()) + { + for (S32 i = 0; i < volume->getNumFaces(); ++i) + { + // NOTE: no need to lock gAgentAvatarp as the state being checked is not changed after initialization + LLVolumeFace& face = volume->getVolumeFace(i); + LLSkinningUtil::updateRiggingInfo(skin_info, gAgentAvatarp, face); + } + } + LoadedMesh mesh(volume, mesh_params, lod); { LLMutexLock lock(mMutex); @@ -2014,18 +2049,19 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat } { - LLMeshSkinInfo* info = nullptr; - try - { - info = new LLMeshSkinInfo(mesh_id, skin); - } - catch (const std::bad_alloc& ex) - { - LL_WARNS() << "Failed to allocate skin info with exception: " << ex.what() << LL_ENDL; - return false; + LLPointer info = nullptr; + info = new LLMeshSkinInfo(mesh_id, skin); + + if (isAgentAvatarValid()) + { // joint numbers are consistent inside LLVOAvatar and animations, but inconsistent inside meshes, + // generate a map of mesh joint numbers to LLVOAvatar joint numbers + LLSkinningUtil::initJointNums(info, gAgentAvatarp); } - // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; + // remember the skin info in the background thread so we can use it + // to calculate per-joint bounding boxes when volumes are loaded + mSkinMap[mesh_id] = info; + { LLMutexLock lock(mMutex); mSkinInfoQ.push_back(info); @@ -2265,10 +2301,10 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) S32 mesh_num = 0; S32 texture_num = 0; - std::set textures; - std::map texture_index; + std::unordered_set textures; + std::unordered_map texture_index; - std::map mesh_index; + std::unordered_map mesh_index; std::string model_name; S32 instance_num = 0; @@ -2957,7 +2993,7 @@ void LLMeshRepoThread::notifyLoadedMeshes() { if (mMutex->trylock()) { - std::deque skin_info_q; + std::deque> skin_info_q; std::deque skin_info_unavail_q; std::list decomp_q; @@ -3080,6 +3116,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod) // are cases far off the norm. void LLMeshHandlerBase::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response) { + LL_PROFILE_ZONE_SCOPED; mProcessed = true; unsigned int retries(0U); @@ -3356,6 +3393,7 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status) void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, U8 * data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; if ((!MESH_LOD_PROCESS_FAILED) && ((data != NULL) == (data_size > 0))) // if we have data but no size or have size but no data, something is wrong { @@ -3421,6 +3459,7 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, U8 * data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; if ((!MESH_SKIN_INFO_PROCESS_FAILED) && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong && gMeshRepo.mThread->skinInfoReceived(mMeshID, data, data_size)) @@ -3470,6 +3509,7 @@ void LLMeshDecompositionHandler::processFailure(LLCore::HttpStatus status) void LLMeshDecompositionHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, U8 * data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; if ((!MESH_DECOMP_PROCESS_FAILED) && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong && gMeshRepo.mThread->decompositionReceived(mMeshID, data, data_size)) @@ -3517,6 +3557,7 @@ void LLMeshPhysicsShapeHandler::processFailure(LLCore::HttpStatus status) void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, U8 * data, S32 data_size) { + LL_PROFILE_ZONE_SCOPED; if ((!MESH_PHYS_SHAPE_PROCESS_FAILED) && ((data != NULL) == (data_size > 0)) // if we have data but no size or have size but no data, something is wrong && gMeshRepo.mThread->physicsShapeReceived(mMeshID, data, data_size) == MESH_OK) @@ -3870,6 +3911,13 @@ void LLMeshRepository::notifyLoadedMeshes() { mSkinMap.erase(copy_iter); } + + // erase from background thread + LLUUID id = iter->first; + mThread->mWorkQueue.post([=]() + { + mThread->mSkinMap.erase(id); + }); } //LL_INFOS() << "Skin info cache elements:" << mSkinMap.size() << " Memory: " << U64Kilobytes(skinbytes) << LL_ENDL; } @@ -4206,7 +4254,7 @@ void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - std::set::iterator iter = mLoadingPhysicsShapes.find(mesh_id); + std::unordered_set::iterator iter = mLoadingPhysicsShapes.find(mesh_id); if (iter == mLoadingPhysicsShapes.end()) { //no request pending for this skin info // *FIXME: Nothing ever deletes entries, can't be right @@ -4236,7 +4284,7 @@ LLModel::Decomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh_id { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - std::set::iterator iter = mLoadingDecompositions.find(mesh_id); + std::unordered_set::iterator iter = mLoadingDecompositions.find(mesh_id); if (iter == mLoadingDecompositions.end()) { //no request pending for this skin info mLoadingDecompositions.insert(mesh_id); @@ -4287,6 +4335,8 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id) { + LL_PROFILE_ZONE_SCOPED; + if (mesh_id.isNull()) { return false; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b850ade0bb..b5c2424578 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -28,6 +28,7 @@ #define LL_MESH_REPOSITORY_H #include +#include #include "llassettype.h" #include "llmodel.h" #include "lluuid.h" @@ -341,7 +342,7 @@ public: std::deque mSkinRequests; // list of completed skin info requests - std::deque mSkinInfoQ; + std::deque> mSkinInfoQ; // list of skin info requests that have failed or are unavailaibe std::deque mSkinUnavailableQ; @@ -368,9 +369,17 @@ public: std::deque mLoadedQ; //map of pending header requests and currently desired LODs - typedef boost::unordered_map > pending_lod_map; + typedef std::unordered_map > pending_lod_map; pending_lod_map mPendingLOD; + // map of mesh ID to skin info (mirrors LLMeshRepository::mSkinMap) + /// NOTE: LLMeshRepository::mSkinMap is accessed very frequently, so maintain a copy here to avoid mutex overhead + typedef std::unordered_map> skin_map; + skin_map mSkinMap; + + // workqueue for processing generic requests + LL::WorkQueue mWorkQueue; + // llcorehttp library interface objects. LLCore::HttpStatus mHttpStatus; LLCore::HttpRequest * mHttpRequest; @@ -380,7 +389,7 @@ public: LLCore::HttpRequest::policy_t mHttpPolicyClass; LLCore::HttpRequest::policy_t mHttpLargePolicyClass; - typedef std::set http_request_set; + typedef std::unordered_set http_request_set; http_request_set mHttpRequestSet; // Outstanding HTTP requests std::string mGetMeshCapability; @@ -696,13 +705,13 @@ public: std::queue mPendingSkinRequests; //list of mesh ids awaiting decompositions - std::set mLoadingDecompositions; + std::unordered_set mLoadingDecompositions; //list of mesh ids that need to send decomposition fetch requests std::queue mPendingDecompositionRequests; //list of mesh ids awaiting physics shapes - std::set mLoadingPhysicsShapes; + std::unordered_set mLoadingPhysicsShapes; //list of mesh ids that need to send physics shape fetch requests std::queue mPendingPhysicsShapeRequests; diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp index 1c92e06700..cee43f3cff 100644 --- a/indra/newview/llskinningutil.cpp +++ b/indra/newview/llskinningutil.cpp @@ -317,19 +317,16 @@ void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar) void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; - if (vol_face.mJointRiggingInfoTab.needsUpdate()) { S32 num_verts = vol_face.mNumVertices; S32 num_joints = static_cast(skin->mJointNames.size()); if (num_verts > 0 && vol_face.mWeights && num_joints > 0) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; initJointNums(const_cast(skin), avatar); if (vol_face.mJointRiggingInfoTab.size()==0) { - //std::set active_joints; - //S32 active_verts = 0; vol_face.mJointRiggingInfoTab.resize(LL_CHARACTER_MAX_ANIMATED_JOINTS); LLJointRiggingInfoTab &rig_info_tab = vol_face.mJointRiggingInfoTab; for (S32 i=0; i 0.0f) - { - for (U32 k=0; k<4; ++k) - { - wght[k] /= scale; - } } + for (U32 k=0; k<4; ++k) { S32 joint_index = idx[k]; - if (wght[k] > 0.0f && num_joints > joint_index) + if (wght[k] > 0.2f && num_joints > joint_index) { S32 joint_num = skin->mJointNums[joint_index]; if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS) { rig_info_tab[joint_num].setIsRiggedTo(true); - // FIXME could precompute these matMuls. - const LLMatrix4a& bind_shape = skin->mBindShapeMatrix; - const LLMatrix4a& inv_bind = skin->mInvBindMatrix[joint_index]; - LLMatrix4a mat; + const LLMatrix4a& mat = skin->mBindPoseMatrix[joint_index]; LLVector4a pos_joint_space; - matMul(bind_shape, inv_bind, mat); - mat.affineTransform(pos, pos_joint_space); - pos_joint_space.mul(wght[k]); LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents(); update_min_max(extents[0], extents[1], pos_joint_space); @@ -381,28 +365,9 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a } } } - //LL_DEBUGS("RigSpammish") << "built rigging info for vf " << &vol_face - // << " num_verts " << vol_face.mNumVertices - // << " active joints " << active_joints.size() - // << " active verts " << active_verts - // << LL_ENDL; vol_face.mJointRiggingInfoTab.setNeedsUpdate(false); } } - -#if DEBUG_SKINNING - if (vol_face.mJointRiggingInfoTab.size()!=0) - { - LL_DEBUGS("RigSpammish") << "we have rigging info for vf " << &vol_face - << " num_verts " << vol_face.mNumVertices << LL_ENDL; - } - else - { - LL_DEBUGS("RigSpammish") << "no rigging info for vf " << &vol_face - << " num_verts " << vol_face.mNumVertices << LL_ENDL; - } -#endif - } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index e36a03a749..86440fca48 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7280,6 +7280,7 @@ const std::string& LLViewerObject::getAttachmentItemName() const //virtual LLVOAvatar* LLViewerObject::getAvatar() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (getControlAvatar()) { return getControlAvatar(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 8e8cf7424f..ef0bb3b926 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -1646,6 +1646,9 @@ void LLVOAvatar::renderCollisionVolumes() } } +// defined in llspatialpartition.cpp -- draw a box outline in the current GL context from given center and half-size +void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size); + void LLVOAvatar::renderBones(const std::string &selected_joint) { LLGLEnable blend(GL_BLEND); @@ -1722,6 +1725,88 @@ void LLVOAvatar::renderBones(const std::string &selected_joint) gGL.popMatrix(); } + + + // draw joint space bounding boxes of rigged attachments in yellow + gGL.color3f(1.f, 1.f, 0.f); + for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++) + { + LLJoint* joint = getJoint(joint_num); + LLJointRiggingInfo* rig_info = NULL; + if (joint_num < mJointRiggingInfoTab.size()) + { + rig_info = &mJointRiggingInfoTab[joint_num]; + } + + if (joint && rig_info && rig_info->isRiggedTo()) + { + LLViewerJointAttachment* as_joint_attach = dynamic_cast(joint); + if (as_joint_attach && as_joint_attach->getIsHUDAttachment()) + { + // Ignore bounding box of HUD joints + continue; + } + gGL.pushMatrix(); + gGL.multMatrix(&joint->getXform()->getWorldMatrix().mMatrix[0][0]); + + LLVector4a pos; + LLVector4a size; + + const LLVector4a* extents = rig_info->getRiggedExtents(); + + pos.setAdd(extents[0], extents[1]); + pos.mul(0.5f); + size.setSub(extents[1], extents[0]); + size.mul(0.5f); + + drawBoxOutline(pos, size); + + gGL.popMatrix(); + } + } + + // draw world space attachment rigged bounding boxes in cyan + gGL.color3f(0.f, 1.f, 1.f); + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + if (attachment->getValid()) + { + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = attachment_iter->get(); + if (attached_object && !attached_object->isHUDAttachment()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable && drawable->isState(LLDrawable::RIGGED | LLDrawable::RIGGED_CHILD)) + { + // get face rigged extents + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* facep = drawable->getFace(i); + if (facep && facep->isState(LLFace::RIGGED)) + { + LLVector4a center, size; + + LLVector4a* extents = facep->mRiggedExtents; + + center.setAdd(extents[0], extents[1]); + center.mul(0.5f); + size.setSub(extents[1], extents[0]); + size.mul(0.5f); + drawBoxOutline(center, size); + } + } + } + } + } + } + } } @@ -10662,35 +10747,42 @@ void LLVOAvatar::updateRiggingInfo() LL_DEBUGS("RigSpammish") << getFullname() << " updating rig tab" << LL_ENDL; - std::vector volumes; + // use a local static for scratch space to avoid reallocation here + static std::vector volumes; + volumes.resize(0); getAssociatedVolumes(volumes); - std::map curr_rigging_info_key; - { LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("update rig info - get key") + HBXXH128 hash; // Get current rigging info key for (LLVOVolume* vol : volumes) { - if (vol->isMesh() && vol->getVolume()) + if (vol->isRiggedMesh()) { const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID(); S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD); - curr_rigging_info_key[mesh_id] = max_lod; + + hash.update(mesh_id.mData, sizeof(mesh_id.mData)); + hash.update(&max_lod, sizeof(max_lod)); } } - } - // Check for key change, which indicates some change in volume composition or LOD. - if (curr_rigging_info_key == mLastRiggingInfoKey) - { - return; + LLUUID curr_rigging_info_key = hash.digest(); + + // Check for key change, which indicates some change in volume composition or LOD. + if (curr_rigging_info_key == mLastRiggingInfoKey) + { + return; + } + + + // Something changed. Update. + mLastRiggingInfoKey = curr_rigging_info_key; } - // Something changed. Update. - mLastRiggingInfoKey = curr_rigging_info_key; mJointRiggingInfoTab.clear(); for (LLVOVolume* vol : volumes) { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index a93ccf46bf..ff1cbc34fc 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -226,7 +226,7 @@ public: // virtual void updateRiggingInfo(); // This encodes mesh id and LOD, so we can see whether display is up-to-date. - std::map mLastRiggingInfoKey; + LLUUID mLastRiggingInfoKey; std::set mActiveOverrideMeshes; virtual void onActiveOverrideMeshesChanged(); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 4f48a070e3..2859f8b1c2 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3657,7 +3657,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const // virtual bool LLVOVolume::isRiggedMesh() const { - return isMesh() && getSkinInfo(); + return getSkinInfo() != nullptr; } //---------------------------------------------------------------------------- @@ -3818,7 +3818,6 @@ void LLVOVolume::updateRiggingInfo() LLVolume *volume = getVolume(); if (skin && avatar && volume) { - LL_DEBUGS("RigSpammish") << "starting, vovol " << this << " lod " << getLOD() << " last " << mLastRiggingInfoLOD << LL_ENDL; if (getLOD()>mLastRiggingInfoLOD || getLOD()==3) { // Rigging info may need update @@ -3834,9 +3833,6 @@ void LLVOVolume::updateRiggingInfo() } // Keep the highest LOD info available. mLastRiggingInfoLOD = getLOD(); - LL_DEBUGS("RigSpammish") << "updated rigging info for LLVOVolume " - << this << " lod " << mLastRiggingInfoLOD - << LL_ENDL; } } } -- cgit v1.2.3 From f378d2f95ad751ccf7456f79baba61d6c39f5c36 Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Tue, 17 Sep 2024 02:10:24 +0200 Subject: Fix Visual Studio complaints in LLTrans (#2575) --- indra/llui/lltrans.cpp | 20 ++++++-------------- indra/llui/lltrans.h | 18 ++++++++---------- indra/newview/tests/lldateutil_test.cpp | 4 ++-- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/indra/llui/lltrans.cpp b/indra/llui/lltrans.cpp index 8410031653..0c6c5b64e4 100644 --- a/indra/llui/lltrans.cpp +++ b/indra/llui/lltrans.cpp @@ -28,12 +28,8 @@ #include "lltrans.h" -#include "llfasttimer.h" // for call count statistics #include "llxuiparser.h" #include "llsd.h" -#include "llxmlnode.h" - -#include LLTrans::template_map_t LLTrans::sStringTemplates; LLTrans::template_map_t LLTrans::sDefaultStringTemplates; @@ -59,7 +55,7 @@ struct StringTable : public LLInitParam::Block }; //static -bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set& default_args) +bool LLTrans::parseStrings(LLXMLNodePtr& root, const std::set& default_args) { std::string xml_filename = "(strings file)"; if (!root->hasName("strings")) @@ -107,7 +103,7 @@ bool LLTrans::parseStrings(LLXMLNodePtr &root, const std::set& defa //static -bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root) +bool LLTrans::parseLanguageStrings(LLXMLNodePtr& root) { std::string xml_filename = "(language strings file)"; if (!root->hasName("strings")) @@ -138,10 +134,6 @@ bool LLTrans::parseLanguageStrings(LLXMLNodePtr &root) return true; } - - -static LLTrace::BlockTimerStatHandle FTM_GET_TRANS("Translate string"); - //static std::string LLTrans::getString(std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args, bool def_string) { @@ -235,7 +227,7 @@ std::string LLTrans::getDefString(std::string_view xml_desc, const LLSD& msg_arg } //static -bool LLTrans::findString(std::string &result, std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args) +bool LLTrans::findString(std::string& result, std::string_view xml_desc, const LLStringUtil::format_map_t& msg_args) { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; @@ -257,7 +249,7 @@ bool LLTrans::findString(std::string &result, std::string_view xml_desc, const L } //static -bool LLTrans::findString(std::string &result, std::string_view xml_desc, const LLSD& msg_args) +bool LLTrans::findString(std::string& result, std::string_view xml_desc, const LLSD& msg_args) { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; @@ -277,7 +269,7 @@ bool LLTrans::findString(std::string &result, std::string_view xml_desc, const L } //static -std::string LLTrans::getCountString(const std::string& language, const std::string& xml_desc, S32 count) +std::string LLTrans::getCountString(std::string_view language, std::string_view xml_desc, S32 count) { // Compute which string identifier to use const char* form = ""; @@ -337,7 +329,7 @@ std::string LLTrans::getCountString(const std::string& language, const std::stri args["[COUNT]"] = llformat("%d", count); // Look up "AgeYearsB" or "AgeWeeksC" including the "form" - std::string key = llformat("%s%s", xml_desc.c_str(), form); + std::string key = llformat("%s%s", xml_desc.data(), form); return getString(key, args); } diff --git a/indra/llui/lltrans.h b/indra/llui/lltrans.h index 3492ed0169..c5d01e6f8d 100644 --- a/indra/llui/lltrans.h +++ b/indra/llui/lltrans.h @@ -30,10 +30,8 @@ #include #include -#include "llpointer.h" #include "llstring.h" - -class LLXMLNode; +#include "llxmlnode.h" class LLSD; @@ -58,17 +56,17 @@ public: class LLTrans { public: - LLTrans(); + LLTrans() = default; /** * @brief Parses the xml root that holds the strings. Used once on startup -// *FIXME * @param xml_filename Filename to parse + * @param root xml root node to parse * @param default_args Set of strings (expected to be in the file) to use as default replacement args, e.g. "SECOND_LIFE" * @returns true if the file was parsed successfully, true if something went wrong */ - static bool parseStrings(LLPointer & root, const std::set& default_args); + static bool parseStrings(LLXMLNodePtr& root, const std::set& default_args); - static bool parseLanguageStrings(LLPointer & root); + static bool parseLanguageStrings(LLXMLNodePtr& root); /** * @brief Returns a translated string @@ -80,14 +78,14 @@ public: static std::string getDefString(std::string_view xml_desc, const LLStringUtil::format_map_t& args); static std::string getString(std::string_view xml_desc, const LLSD& args, bool def_string = false); static std::string getDefString(std::string_view xml_desc, const LLSD& args); - static bool findString(std::string &result, std::string_view xml_desc, const LLStringUtil::format_map_t& args); - static bool findString(std::string &result, std::string_view xml_desc, const LLSD& args); + static bool findString(std::string& result, std::string_view xml_desc, const LLStringUtil::format_map_t& args); + static bool findString(std::string& result, std::string_view xml_desc, const LLSD& args); // Returns translated string with [COUNT] replaced with a number, following // special per-language logic for plural nouns. For example, some languages // may have different plurals for 0, 1, 2 and > 2. // See "AgeWeeksA", "AgeWeeksB", etc. in strings.xml for examples. - static std::string getCountString(const std::string& language, const std::string& xml_desc, S32 count); + static std::string getCountString(std::string_view language, std::string_view xml_desc, S32 count); /** * @brief Returns a translated string diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp index 151aadfd4b..acbf019034 100644 --- a/indra/newview/tests/lldateutil_test.cpp +++ b/indra/newview/tests/lldateutil_test.cpp @@ -57,12 +57,12 @@ std::string LLTrans::getString(const std::string_view xml_desc, const LLStringUt return {}; } -std::string LLTrans::getCountString(const std::string& language, const std::string& xml_desc, S32 count) +std::string LLTrans::getCountString(std::string_view language, std::string_view xml_desc, S32 count) { count_string_t key(xml_desc, count); if (gCountString.find(key) == gCountString.end()) { - return std::string("Couldn't find ") + xml_desc; + return std::string("Couldn't find ") + static_cast(xml_desc); } return gCountString[ count_string_t(xml_desc, count) ]; } -- cgit v1.2.3 From 870ffbd55b4ffdfad27edf8824de0c9cbc577a80 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 17 Sep 2024 12:43:47 -0500 Subject: Suppress mapBuffer warnings. (#2584) --- indra/newview/lldynamictexture.cpp | 4 +-- indra/newview/llvoavatar.cpp | 18 ++++-------- indra/newview/llvoavatar.h | 2 +- indra/newview/llvograss.cpp | 1 - indra/newview/llvopartgroup.cpp | 58 -------------------------------------- indra/newview/llvosurfacepatch.cpp | 1 - indra/newview/pipeline.cpp | 1 + 7 files changed, 10 insertions(+), 75 deletions(-) diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 0b9f76e7f6..33325e352f 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -200,8 +200,8 @@ bool LLViewerDynamicTexture::updateAllInstances() } llassert(preview_target.getWidth() >= LLPipeline::MAX_PREVIEW_WIDTH); llassert(preview_target.getHeight() >= LLPipeline::MAX_PREVIEW_WIDTH); - llassert(bake_target.getWidth() >= LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH); - llassert(bake_target.getHeight() >= LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT); + llassert(bake_target.getWidth() >= (U32) LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH); + llassert(bake_target.getHeight() >= (U32) LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT); preview_target.bindTarget(); preview_target.clear(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ef0bb3b926..b6a2dac1e9 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2406,8 +2406,6 @@ void LLVOAvatar::updateMeshData() { if (mDrawable.notNull()) { - stop_glerror(); - S32 f_num = 0 ; const U32 VERTEX_NUMBER_THRESHOLD = 128 ;//small number of this means each part of an avatar has its own vertex buffer. const auto num_parts = mMeshLOD.size(); @@ -2534,7 +2532,6 @@ void LLVOAvatar::updateMeshData() } } - stop_glerror(); buff->unmapBuffer(); if(!f_num) @@ -10754,9 +10751,8 @@ void LLVOAvatar::updateRiggingInfo() getAssociatedVolumes(volumes); { - LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("update rig info - get key") - HBXXH128 hash; - + LL_PROFILE_ZONE_NAMED_CATEGORY_AVATAR("update rig info - get key"); + size_t hash = 0; // Get current rigging info key for (LLVOVolume* vol : volumes) { @@ -10765,22 +10761,20 @@ void LLVOAvatar::updateRiggingInfo() const LLUUID& mesh_id = vol->getVolume()->getParams().getSculptID(); S32 max_lod = llmax(vol->getLOD(), vol->mLastRiggingInfoLOD); - hash.update(mesh_id.mData, sizeof(mesh_id.mData)); - hash.update(&max_lod, sizeof(max_lod)); + boost::hash_combine(hash, mesh_id); + boost::hash_combine(hash, max_lod); } } - LLUUID curr_rigging_info_key = hash.digest(); - // Check for key change, which indicates some change in volume composition or LOD. - if (curr_rigging_info_key == mLastRiggingInfoKey) + if (hash == mLastRiggingInfoKey) { return; } // Something changed. Update. - mLastRiggingInfoKey = curr_rigging_info_key; + mLastRiggingInfoKey = hash; } mJointRiggingInfoTab.clear(); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index ff1cbc34fc..dd1725c322 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -226,7 +226,7 @@ public: // virtual void updateRiggingInfo(); // This encodes mesh id and LOD, so we can see whether display is up-to-date. - LLUUID mLastRiggingInfoKey; + size_t mLastRiggingInfoKey; std::set mActiveOverrideMeshes; virtual void onActiveOverrideMeshesChanged(); diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index 67adcbb244..fdd39a0e30 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -729,7 +729,6 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) } } - buffer->unmapBuffer(); mFaceList.clear(); } diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 8f792c1042..ec32a79829 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -54,63 +54,6 @@ void LLVOPartGroup::initClass() void LLVOPartGroup::restoreGL() { - //TODO: optimize out binormal mask here. Specular and normal coords as well. -#if 0 - sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); - U32 count = LL_MAX_PARTICLE_COUNT; - if (!sVB->allocateBuffer(count*4, count*6)) - { - LL_WARNS() << "Failed to allocate Vertex Buffer to " - << count*4 << " vertices and " - << count * 6 << " indices" << LL_ENDL; - // we are likelly to crash at following getTexCoord0Strider(), so unref and return - sVB = NULL; - return; - } - - //indices and texcoords are always the same, set once - LLStrider indicesp; - - LLStrider verticesp; - - sVB->getIndexStrider(indicesp); - sVB->getVertexStrider(verticesp); - - LLVector4a v; - v.set(0,0,0,0); - - - U16 vert_offset = 0; - - for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++) - { - *indicesp++ = vert_offset + 0; - *indicesp++ = vert_offset + 1; - *indicesp++ = vert_offset + 2; - - *indicesp++ = vert_offset + 1; - *indicesp++ = vert_offset + 3; - *indicesp++ = vert_offset + 2; - - *verticesp++ = v; - - vert_offset += 4; - } - - LLStrider texcoordsp; - sVB->getTexCoord0Strider(texcoordsp); - - for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++) - { - *texcoordsp++ = LLVector2(0.f, 1.f); - *texcoordsp++ = LLVector2(0.f, 0.f); - *texcoordsp++ = LLVector2(1.f, 1.f); - *texcoordsp++ = LLVector2(1.f, 0.f); - } - - sVB->unmapBuffer(); -#endif - } //static @@ -955,7 +898,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) } } - buffer->unmapBuffer(); mFaceList.clear(); } diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index fdccf34e6a..294d36b0a9 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1078,7 +1078,6 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) gen_terrain_tangents(index_offset, indices_index, vertices, normals, tangents, indices, region_width); } - buffer->unmapBuffer(); mFaceList.clear(); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 13dfd48643..33683416a2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3731,6 +3731,7 @@ void LLPipeline::postSort(LLCamera &camera) } } + LLVertexBuffer::flushBuffers(); // LLSpatialGroup::sNoDelete = false; LL_PUSH_CALLSTACKS(); } -- cgit v1.2.3 From fd843d514a4e28f8e4a5d5595bba21ccad195e72 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 17 Sep 2024 13:07:01 -0500 Subject: Mac pass (#2587) --- indra/cmake/Tracy.cmake | 2 +- indra/newview/llmeshrepository.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index d54a32fdc2..ec7178c5a0 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -6,7 +6,7 @@ add_library( ll::tracy INTERFACE IMPORTED ) # default Tracy profiling on for test builds, but off for all others string(TOLOWER ${VIEWER_CHANNEL} channel_lower) -if(WINDOWS AND channel_lower MATCHES "^second life test") +if(channel_lower MATCHES "^second life test") option(USE_TRACY "Use Tracy profiler." ON) else() option(USE_TRACY "Use Tracy profiler." OFF) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 532a87bbd1..1f214344ff 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3900,6 +3900,7 @@ void LLMeshRepository::notifyLoadedMeshes() for (auto iter = mSkinMap.begin(), ender = mSkinMap.end(); iter != ender;) { auto copy_iter = iter++; + LLUUID id = copy_iter->first; //skinbytes += U64Bytes(sizeof(LLMeshSkinInfo)); //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(std::string)); @@ -3913,7 +3914,6 @@ void LLMeshRepository::notifyLoadedMeshes() } // erase from background thread - LLUUID id = iter->first; mThread->mWorkQueue.post([=]() { mThread->mSkinMap.erase(id); -- cgit v1.2.3 From 9241fb80588304f89c035e9811af96172982a8c2 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 17 Sep 2024 15:26:22 -0400 Subject: Increment viewer version to 7.1.11 following promotion of secondlife/viewer #2367: 2024.08 DeltaFPS --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 346a7e3aa1..e0eaaa0bbc 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.10 +7.1.11 -- cgit v1.2.3 From 0a617904f98ab5960379099822e4891a08137e68 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 17 Sep 2024 18:14:22 -0500 Subject: #2590 Fix for horrible FPS on Intel Mac (#2591) * Work around for GHA mac runners not playing nice with Tracy * Delay VBO deletion for a few frames * Enable multithreaded GL driver and multithreaded media textures on Apple silicon --- indra/cmake/Tracy.cmake | 5 + indra/llrender/llgl.cpp | 5 + indra/llrender/llgl.h | 1 + indra/llrender/llvertexbuffer.cpp | 374 +++++++++++++++++++++---------------- indra/newview/featuretable_mac.txt | 14 +- indra/newview/llfeaturemanager.cpp | 8 + 6 files changed, 242 insertions(+), 165 deletions(-) diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index ec7178c5a0..a7eac2711f 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -31,6 +31,11 @@ if (USE_TRACY) target_compile_definitions(ll::tracy INTERFACE -DTRACY_NO_BROADCAST=1 -DTRACY_ONLY_LOCALHOST=1) endif () + # GHA runners don't always provide invariant TSC support, but always build with LL_TESTS enabled + if (DARWIN AND LL_TESTS) + target_compile_definitions(ll::tracy INTERFACE -DTRACY_TIMER_FALLBACK=1) + endif () + # See: indra/llcommon/llprofiler.h add_compile_definitions(LL_PROFILER_CONFIGURATION=3) endif (USE_TRACY) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index c62cacdce6..c5c9d50dee 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -1170,6 +1170,11 @@ bool LLGLManager::initGL() mGLVendorShort = "INTEL"; mIsIntel = true; } + else if (mGLVendor.find("APPLE") != std::string::npos) + { + mGLVendorShort = "APPLE"; + mIsApple = true; + } else { mGLVendorShort = "MISC"; diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 17f825bd71..f5b1e8d786 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -102,6 +102,7 @@ public: bool mIsAMD; bool mIsNVIDIA; bool mIsIntel; + bool mIsApple = false; // hints to the render pipe U32 mDownScaleMethod = 0; // see settings.xml RenderDownScaleMethod diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index e9fa369b0c..0be799db9d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -289,22 +289,58 @@ static GLuint gen_buffer() return ret; } -#define ANALYZE_VBO_POOL 0 +static void delete_buffers(S32 count, GLuint* buffers) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + // wait a few frames before actually deleting the buffers to avoid + // synchronization issues with the GPU + static std::vector sFreeList[4]; + + if (gGLManager.mInited) + { + U32 idx = LLImageGL::sFrameCount % 4; + + for (S32 i = 0; i < count; ++i) + { + sFreeList[idx].push_back(buffers[i]); + } + + idx = (LLImageGL::sFrameCount + 3) % 4; + + if (!sFreeList[idx].empty()) + { + glDeleteBuffers((GLsizei)sFreeList[idx].size(), sFreeList[idx].data()); + sFreeList[idx].resize(0); + } + } +} -#if LL_DARWIN -// experimental -- disable VBO pooling on OS X and use glMapBuffer +#define ANALYZE_VBO_POOL 0 + +// VBO Pool interface class LLVBOPool +{ + public: + virtual ~LLVBOPool() = default; + virtual void allocate(GLenum type, U32 size, GLuint& name, U8*& data) = 0; + virtual void free(GLenum type, U32 size, GLuint name, U8* data) = 0; + virtual U64 getVramBytesUsed() = 0; +}; + +// VBO Pool for Apple GPUs (as in M1/M2 etc, not Intel macs) +// Effectively disables VBO pooling +class LLAppleVBOPool final: public LLVBOPool { public: U64 mAllocated = 0; - U64 getVramBytesUsed() + U64 getVramBytesUsed() override { return mAllocated; } - void allocate(GLenum type, U32 size, GLuint& name, U8*& data) + void allocate(GLenum type, U32 size, GLuint& name, U8*& data) override { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; STOP_GLERROR; @@ -324,7 +360,7 @@ public: } } - void free(GLenum type, U32 size, GLuint name, U8* data) + void free(GLenum type, U32 size, GLuint name, U8* data) override { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); @@ -339,19 +375,17 @@ public: STOP_GLERROR; if (name) { - glDeleteBuffers(1, &name); + delete_buffers(1, &name); } STOP_GLERROR; } }; -#else - -class LLVBOPool +// VBO Pool for GPUs that benefit from VBO pooling +class LLDefaultVBOPool final : public LLVBOPool { public: typedef std::chrono::steady_clock::time_point Time; - struct Entry { U8* mData; @@ -359,7 +393,7 @@ public: Time mAge; }; - ~LLVBOPool() + ~LLDefaultVBOPool() override { clear(); } @@ -377,7 +411,7 @@ public: U32 mMisses = 0; U32 mHits = 0; - U64 getVramBytesUsed() + U64 getVramBytesUsed() override { return mAllocated + mReserved; } @@ -393,7 +427,7 @@ public: size += block_size - (size % block_size); } - void allocate(GLenum type, U32 size, GLuint& name, U8*& data) + void allocate(GLenum type, U32 size, GLuint& name, U8*& data) override { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); @@ -449,7 +483,7 @@ public: clean(); } - void free(GLenum type, U32 size, GLuint name, U8* data) + void free(GLenum type, U32 size, GLuint name, U8* data) override { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); @@ -512,7 +546,7 @@ public: LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vbo cache timeout"); auto& entry = entries.back(); ll_aligned_free_16(entry.mData); - glDeleteBuffers(1, &entry.mGLName); + delete_buffers(1, &entry.mGLName); llassert(mReserved >= iter->first); mReserved -= iter->first; entries.pop_back(); @@ -548,7 +582,7 @@ public: for (auto& entry : entries.second) { ll_aligned_free_16(entry.mData); - glDeleteBuffers(1, &entry.mGLName); + delete_buffers(1, &entry.mGLName); } } @@ -557,7 +591,7 @@ public: for (auto& entry : entries.second) { ll_aligned_free_16(entry.mData); - glDeleteBuffers(1, &entry.mGLName); + delete_buffers(1, &entry.mGLName); } } @@ -567,7 +601,6 @@ public: mVBOPool.clear(); } }; -#endif static LLVBOPool* sVBOPool = nullptr; @@ -896,7 +929,16 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const void LLVertexBuffer::initClass(LLWindow* window) { llassert(sVBOPool == nullptr); - sVBOPool = new LLVBOPool(); + if (gGLManager.mIsApple) + { + LL_INFOS() << "VBO Pooling Disabled" << LL_ENDL; + sVBOPool = new LLAppleVBOPool(); + } + else + { + LL_INFOS() << "VBO Pooling Enabled" << LL_ENDL; + sVBOPool = new LLDefaultVBOPool(); + } #if ENABLE_GL_WORK_QUEUE sQueue = new GLWorkQueue(); @@ -964,7 +1006,6 @@ void LLVertexBuffer::flushBuffers() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; // must only be called from main thread - llassert(LLCoros::on_main_thread_main_coro()); for (auto& buffer : sMappedBuffers) { buffer->_unmapBuffer(); @@ -1231,28 +1272,29 @@ U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 inde count = mNumVerts - index; } -#if !LL_DARWIN - U32 start = mOffsets[type] + sTypeSize[type] * index; - U32 end = start + sTypeSize[type] * count-1; - - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + if (!gGLManager.mIsApple) { - MappedRegion& region = mMappedVertexRegions[i]; - if (expand_region(region, start, end)) + U32 start = mOffsets[type] + sTypeSize[type] * index; + U32 end = start + sTypeSize[type] * count-1; + + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - flagged = true; - break; + MappedRegion& region = mMappedVertexRegions[i]; + if (expand_region(region, start, end)) + { + flagged = true; + break; + } } - } - if (!flagged) - { - //didn't expand an existing region, make a new one - mMappedVertexRegions.push_back({ start, end }); + if (!flagged) + { + //didn't expand an existing region, make a new one + mMappedVertexRegions.push_back({ start, end }); + } } -#endif return mMappedData+mOffsets[type]+sTypeSize[type]*index; } @@ -1267,28 +1309,29 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) count = mNumIndices-index; } -#if !LL_DARWIN - U32 start = sizeof(U16) * index; - U32 end = start + sizeof(U16) * count-1; - - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + if (!gGLManager.mIsApple) { - MappedRegion& region = mMappedIndexRegions[i]; - if (expand_region(region, start, end)) + U32 start = sizeof(U16) * index; + U32 end = start + sizeof(U16) * count-1; + + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - flagged = true; - break; + MappedRegion& region = mMappedIndexRegions[i]; + if (expand_region(region, start, end)) + { + flagged = true; + break; + } } - } - if (!flagged) - { - //didn't expand an existing region, make a new one - mMappedIndexRegions.push_back({ start, end }); + if (!flagged) + { + //didn't expand an existing region, make a new one + mMappedIndexRegions.push_back({ start, end }); + } } -#endif return mMappedIndexData + sizeof(U16)*index; } @@ -1301,37 +1344,40 @@ U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) // dst -- mMappedData or mMappedIndexData void LLVertexBuffer::flush_vbo(GLenum target, U32 start, U32 end, void* data, U8* dst) { -#if LL_DARWIN - // on OS X, flush_vbo doesn't actually write to the GL buffer, so be sure to call - // _mapBuffer to tag the buffer for flushing to GL - _mapBuffer(); - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); - STOP_GLERROR; - // copy into mapped buffer - memcpy(dst+start, data, end-start+1); -#else - llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices); - - // skip mapped data and stream to GPU via glBufferSubData - if (end != 0) + if (gGLManager.mIsApple) { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData"); - LL_PROFILE_ZONE_NUM(start); - LL_PROFILE_ZONE_NUM(end); - LL_PROFILE_ZONE_NUM(end-start); - - constexpr U32 block_size = 65536; + // on OS X, flush_vbo doesn't actually write to the GL buffer, so be sure to call + // _mapBuffer to tag the buffer for flushing to GL + _mapBuffer(); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb memcpy"); + STOP_GLERROR; + // copy into mapped buffer + memcpy(dst+start, data, end-start+1); + } + else + { + llassert(target == GL_ARRAY_BUFFER ? sGLRenderBuffer == mGLBuffer : sGLRenderIndices == mGLIndices); - for (U32 i = start; i <= end; i += block_size) + // skip mapped data and stream to GPU via glBufferSubData + if (end != 0) { - //LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block"); - //LL_PROFILE_GPU_ZONE("glBufferSubData"); - U32 tend = llmin(i + block_size, end); - U32 size = tend - i + 1; - glBufferSubData(target, i, size, (U8*) data + (i-start)); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData"); + LL_PROFILE_ZONE_NUM(start); + LL_PROFILE_ZONE_NUM(end); + LL_PROFILE_ZONE_NUM(end-start); + + constexpr U32 block_size = 65536; + + for (U32 i = start; i <= end; i += block_size) + { + //LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block"); + //LL_PROFILE_GPU_ZONE("glBufferSubData"); + U32 tend = llmin(i + block_size, end); + U32 size = tend - i + 1; + glBufferSubData(target, i, size, (U8*) data + (i-start)); + } } } -#endif } void LLVertexBuffer::unmapBuffer() @@ -1364,114 +1410,116 @@ void LLVertexBuffer::_unmapBuffer() } }; -#if LL_DARWIN - STOP_GLERROR; - if (mMappedData) - { - if (mGLBuffer) - { - glDeleteBuffers(1, &mGLBuffer); - } - mGLBuffer = gen_buffer(); - glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); - sGLRenderBuffer = mGLBuffer; - glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW); - } - else if (mGLBuffer != sGLRenderBuffer) - { - glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); - sGLRenderBuffer = mGLBuffer; - } - STOP_GLERROR; - - if (mMappedIndexData) + if (gGLManager.mIsApple) { - if (mGLIndices) + STOP_GLERROR; + if (mMappedData) { - glDeleteBuffers(1, &mGLIndices); + if (mGLBuffer) + { + delete_buffers(1, &mGLBuffer); + } + mGLBuffer = gen_buffer(); + glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + glBufferData(GL_ARRAY_BUFFER, mSize, mMappedData, GL_STATIC_DRAW); } - - mGLIndices = gen_buffer(); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); - sGLRenderIndices = mGLIndices; - - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW); - } - else if (mGLIndices != sGLRenderIndices) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); - sGLRenderIndices = mGLIndices; - } - STOP_GLERROR; -#else - - if (!mMappedVertexRegions.empty()) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex"); - - if (sGLRenderBuffer != mGLBuffer) + else if (mGLBuffer != sGLRenderBuffer) { glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; } + STOP_GLERROR; - U32 start = 0; - U32 end = 0; - - std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion()); - - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + if (mMappedIndexData) { - const MappedRegion& region = mMappedVertexRegions[i]; - if (region.mStart == end + 1) - { - end = region.mEnd; - } - else + if (mGLIndices) { - flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData); - start = region.mStart; - end = region.mEnd; + delete_buffers(1, &mGLIndices); } - } - - flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData); - mMappedVertexRegions.clear(); - } - if (!mMappedIndexRegions.empty()) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index"); + mGLIndices = gen_buffer(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); + sGLRenderIndices = mGLIndices; - if (mGLIndices != sGLRenderIndices) + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mMappedIndexData, GL_STATIC_DRAW); + } + else if (mGLIndices != sGLRenderIndices) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); sGLRenderIndices = mGLIndices; } - U32 start = 0; - U32 end = 0; + STOP_GLERROR; + } + else + { + if (!mMappedVertexRegions.empty()) + { + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex"); + + if (sGLRenderBuffer != mGLBuffer) + { + glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + } - std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion()); + U32 start = 0; + U32 end = 0; - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion()); + + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + const MappedRegion& region = mMappedVertexRegions[i]; + if (region.mStart == end + 1) + { + end = region.mEnd; + } + else + { + flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData); + start = region.mStart; + end = region.mEnd; + } + } + + flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start, mMappedData); + mMappedVertexRegions.clear(); + } + + if (!mMappedIndexRegions.empty()) { - const MappedRegion& region = mMappedIndexRegions[i]; - if (region.mStart == end + 1) + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index"); + + if (mGLIndices != sGLRenderIndices) { - end = region.mEnd; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); + sGLRenderIndices = mGLIndices; } - else + U32 start = 0; + U32 end = 0; + + std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion()); + + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData); - start = region.mStart; - end = region.mEnd; + const MappedRegion& region = mMappedIndexRegions[i]; + if (region.mStart == end + 1) + { + end = region.mEnd; + } + else + { + flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData); + start = region.mStart; + end = region.mEnd; + } } - } - flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData); - mMappedIndexRegions.clear(); + flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start, mMappedIndexData); + mMappedIndexRegions.clear(); + } } -#endif } //---------------------------------------------------------------------------- diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 2e220d2b1c..06ad730a40 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 60 +version 61 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -68,7 +68,8 @@ RenderFSAASamples 1 3 RenderMaxTextureIndex 1 16 RenderGLContextCoreProfile 1 1 RenderGLMultiThreadedTextures 1 0 -RenderGLMultiThreadedMedia 1 0 +RenderGLMultiThreadedMedia 1 1 +RenderAppleUseMultGL 1 1 RenderReflectionsEnabled 1 1 RenderReflectionProbeDetail 1 2 RenderScreenSpaceReflections 1 1 @@ -381,6 +382,15 @@ list Intel RenderAnisotropic 1 0 RenderFSAASamples 1 0 +// AppleGPU and NonAppleGPU can be thought of as Apple silicon vs Intel Mac +list AppleGPU +RenderGLMultiThreadedMedia 1 1 +RenderAppleUseMultGL 1 1 + +list NonAppleGPU +RenderGLMultiThreadedMedia 1 0 +RenderAppleUseMultGL 1 0 + list GL3 RenderFSAASamples 0 0 RenderReflectionProbeDetail 0 0 diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index aa04221f4b..3259ea249b 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -656,6 +656,14 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("Intel"); } + if (gGLManager.mIsApple) + { + maskFeatures("AppleGPU"); + } + else + { + maskFeatures("NonAppleGPU"); + } if (gGLManager.mGLVersion < 3.f) { maskFeatures("OpenGLPre30"); -- cgit v1.2.3 From 55f2103adc36db0d3f068a31a144e15465226e13 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 13 Sep 2024 20:50:19 +0300 Subject: viewer#2565 Optimize LLFolderViewItem::draw() --- indra/llui/llfolderview.cpp | 2 +- indra/llui/llfolderviewitem.cpp | 116 +++++++++++++++++++---------------- indra/llui/llfolderviewitem.h | 9 ++- indra/newview/llconversationview.cpp | 2 +- 4 files changed, 73 insertions(+), 56 deletions(-) diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index 388dc5b1ac..42a9e267d2 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -1649,7 +1649,7 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr { LLRect local_rect = item->getLocalRect(); S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); - S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); + S32 label_height = getLabelFont()->getLineHeight(); // when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + item->getIconPad()) : local_rect.getHeight(); diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 73803786a6..18bde344a0 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -48,7 +48,6 @@ static LLDefaultChildRegistry::Register r("folder_view_item"); // statics std::map LLFolderViewItem::sFonts; // map of styles to fonts -bool LLFolderViewItem::sColorSetInitialized = false; LLUIColor LLFolderViewItem::sFgColor; LLUIColor LLFolderViewItem::sHighlightBgColor; LLUIColor LLFolderViewItem::sFlashBgColor; @@ -58,6 +57,10 @@ LLUIColor LLFolderViewItem::sFilterBGColor; LLUIColor LLFolderViewItem::sFilterTextColor; LLUIColor LLFolderViewItem::sSuffixColor; LLUIColor LLFolderViewItem::sSearchStatusColor; +S32 LLFolderViewItem::sTopPad = 0; +LLUIImagePtr LLFolderViewItem::sFolderArrowImg; +LLUIImagePtr LLFolderViewItem::sSelectionImg; +LLFontGL* LLFolderViewItem::sSuffixFont = nullptr; // only integers can be initialized in header const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f; @@ -83,15 +86,42 @@ LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style) return rtn; } + +const LLFontGL* LLFolderViewItem::getLabelFont() +{ + if (!pLabelFont) + { + pLabelFont = getLabelFontForStyle(mLabelStyle); + } + return pLabelFont; +} //static void LLFolderViewItem::initClass() { + const Params& default_params = LLUICtrlFactory::getDefaultParams(); + sTopPad = default_params.item_top_pad; + sFolderArrowImg = default_params.folder_arrow_image; + sSelectionImg = default_params.selection_image; + sSuffixFont = getLabelFontForStyle(LLFontGL::NORMAL); + + sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); + sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); + sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE); + sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE); + sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE); + sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); + sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); + sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE); + sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); } //static void LLFolderViewItem::cleanupClass() { sFonts.clear(); + sFolderArrowImg = nullptr; + sSelectionImg = nullptr; + sSuffixFont = nullptr; } @@ -134,6 +164,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mIsItemCut(false), mCutGeneration(0), mLabelStyle( LLFontGL::NORMAL ), + pLabelFont(nullptr), mHasVisibleChildren(false), mLocalIndentation(p.folder_indentation), mIndentation(0), @@ -158,20 +189,6 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p) mMaxFolderItemOverlap(p.max_folder_item_overlap), mDoubleClickOverride(p.double_click_override) { - if (!sColorSetInitialized) - { - sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE); - sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE); - sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE); - sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE); - sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE); - sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE); - sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); - sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE); - sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE); - sColorSetInitialized = true; - } - if (mViewModelItem) { mViewModelItem->setFolderViewItem(this); @@ -320,6 +337,7 @@ void LLFolderViewItem::refresh() // Very Expensive! // Can do a number of expensive checks, like checking active motions, wearables or friend list mLabelStyle = vmi.getLabelStyle(); + pLabelFont = nullptr; // refresh can be called from a coro, don't use getLabelFontForStyle, coro trips font list tread safety mLabelSuffix = utf8str_to_wstring(vmi.getLabelSuffix()); mSuffixFontBuffer.reset(); } @@ -346,6 +364,7 @@ void LLFolderViewItem::refreshSuffix() // Very Expensive! // Can do a number of expensive checks, like checking active motions, wearables or friend list mLabelStyle = vmi->getLabelStyle(); + pLabelFont = nullptr; mLabelSuffix = utf8str_to_wstring(vmi->getLabelSuffix()); } @@ -738,19 +757,17 @@ bool LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, return handled; } -void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color) +void LLFolderViewItem::drawOpenFolderArrow() { //--------------------------------------------------------------------------------// // Draw open folder arrow // - const S32 TOP_PAD = default_params.item_top_pad; if (hasVisibleChildren() || !isFolderComplete()) { - LLUIImage* arrow_image = default_params.folder_arrow_image; gl_draw_scaled_rotated_image( - mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD, - mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), fg_color); + mIndentation, getRect().getHeight() - mArrowSize - mTextPad - sTopPad, + mArrowSize, mArrowSize, mControlLabelRotation, sFolderArrowImg->getImage(), sFgColor); } } @@ -766,7 +783,7 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L /*virtual*/ bool LLFolderViewItem::isFadeItem() { - LLClipboard& clipboard = LLClipboard::instance(); + static const LLClipboard& clipboard = LLClipboard::instance(); // Make it a 'simpleton'? if (mCutGeneration != clipboard.getGeneration()) { mCutGeneration = clipboard.getGeneration(); @@ -902,16 +919,14 @@ void LLFolderViewItem::draw() const bool show_context = (getRoot() ? getRoot()->getShowSelectionContext() : false); const bool filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : false); // If we have keyboard focus, draw selection filled - const Params& default_params = LLUICtrlFactory::getDefaultParams(); - const S32 TOP_PAD = default_params.item_top_pad; - - const LLFontGL* font = getLabelFontForStyle(mLabelStyle); + const LLFontGL* font = getLabelFont(); + S32 line_height = font->getLineHeight(); getViewModelItem()->update(); if (!mSingleFolderMode) { - drawOpenFolderArrow(default_params, sFgColor); + drawOpenFolderArrow(); } drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); @@ -920,18 +935,19 @@ void LLFolderViewItem::draw() // Draw open icon // const S32 icon_x = mIndentation + mArrowSize + mTextPad; + const S32 rect_height = getRect().getHeight(); if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders { - mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1); + mIconOpen->draw(icon_x, rect_height - mIconOpen->getHeight() - sTopPad + 1); } else if (mIcon) { - mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1); + mIcon->draw(icon_x, rect_height - mIcon->getHeight() - sTopPad + 1); } if (mIconOverlay && getRoot()->showItemLinkOverlays()) { - mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1); + mIconOverlay->draw(icon_x, rect_height - mIcon->getHeight() - sTopPad + 1); } //--------------------------------------------------------------------------------// @@ -944,24 +960,22 @@ void LLFolderViewItem::draw() S32 filter_string_length = mViewModelItem->hasFilterStringMatch() ? (S32)mViewModelItem->getFilterStringSize() : 0; F32 right_x = 0; - F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; + F32 y = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad; F32 text_left = (F32)getLabelXPos(); LLWString combined_string = mLabel + mLabelSuffix; - const LLFontGL* suffix_font = getLabelFontForStyle(LLFontGL::NORMAL); S32 filter_offset = static_cast(mViewModelItem->getFilterStringOffset()); if (filter_string_length > 0) { - S32 bottom = getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD; - S32 top = getRect().getHeight() - TOP_PAD; - if(mLabelSuffix.empty() || (font == suffix_font)) + S32 bottom = rect_height - line_height - 3 - sTopPad; + S32 top = rect_height - sTopPad; + if(mLabelSuffix.empty() || (font == sSuffixFont)) { - S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, static_cast(mViewModelItem->getFilterStringOffset())) - 2; - S32 right = left + font->getWidth(combined_string.c_str(), static_cast(mViewModelItem->getFilterStringOffset()), filter_string_length) + 2; + S32 left = ll_round(text_left) + font->getWidth(combined_string.c_str(), 0, filter_offset) - 2; + S32 right = left + font->getWidth(combined_string.c_str(), filter_offset, filter_string_length) + 2; - LLUIImage* box_image = default_params.selection_image; - LLRect box_rect(left, top, right, bottom); - box_image->draw(box_rect, sFilterBGColor); + LLRect box_rect(left, top, right, bottom); + sSelectionImg->draw(box_rect, sFilterBGColor); } else { @@ -970,19 +984,17 @@ void LLFolderViewItem::draw() { S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, llmin(filter_offset, (S32)mLabel.size()))) - 2; S32 right = left + (S32)font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length) + 2; - LLUIImage* box_image = default_params.selection_image; LLRect box_rect(left, top, right, bottom); - box_image->draw(box_rect, sFilterBGColor); + sSelectionImg->draw(box_rect, sFilterBGColor); } S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length; if(suffix_filter_length > 0) { S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size()); - S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2; - S32 right = left + (S32)suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2; - LLUIImage* box_image = default_params.selection_image; + S32 left = (S32)(ll_round(text_left) + font->getWidthF32(mLabel.c_str(), 0, static_cast(mLabel.size())) + sSuffixFont->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset)) - 2; + S32 right = left + (S32)sSuffixFont->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length) + 2; LLRect box_rect(left, top, right, bottom); - box_image->draw(box_rect, sFilterBGColor); + sSelectionImg->draw(box_rect, sFilterBGColor); } } } @@ -1001,7 +1013,7 @@ void LLFolderViewItem::draw() // if (!mLabelSuffix.empty()) { - mSuffixFontBuffer.render(suffix_font, mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(), + mSuffixFontBuffer.render(sSuffixFont, mLabelSuffix, 0, right_x, y, isFadeItem() ? color : sSuffixColor.get(), LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, &right_x); } @@ -1011,10 +1023,10 @@ void LLFolderViewItem::draw() // if (filter_string_length > 0) { - if(mLabelSuffix.empty() || (font == suffix_font)) + if(mLabelSuffix.empty() || (font == sSuffixFont)) { F32 match_string_left = text_left + font->getWidthF32(combined_string.c_str(), 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string.c_str(), filter_offset, filter_string_length); - F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; + F32 yy = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad; font->render(combined_string, filter_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, filter_string_length, S32_MAX, &right_x); @@ -1025,7 +1037,7 @@ void LLFolderViewItem::draw() if(label_filter_length > 0) { F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, filter_offset + label_filter_length) - font->getWidthF32(mLabel.c_str(), filter_offset, label_filter_length); - F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; + F32 yy = (F32)rect_height - line_height - (F32)mTextPad - (F32)sTopPad; font->render(mLabel, filter_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, label_filter_length, S32_MAX, &right_x); @@ -1035,9 +1047,9 @@ void LLFolderViewItem::draw() if(suffix_filter_length > 0) { S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size()); - F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast(mLabel.size())) + suffix_font->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - suffix_font->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length); - F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; - suffix_font->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor, + F32 match_string_left = text_left + font->getWidthF32(mLabel.c_str(), 0, static_cast(mLabel.size())) + sSuffixFont->getWidthF32(mLabelSuffix.c_str(), 0, suffix_offset + suffix_filter_length) - sSuffixFont->getWidthF32(mLabelSuffix.c_str(), suffix_offset, suffix_filter_length); + F32 yy = (F32)rect_height - sSuffixFont->getLineHeight() - (F32)mTextPad - (F32)sTopPad; + sSuffixFont->render(mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, suffix_filter_length, S32_MAX, &right_x); } diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index 7ac28b1a8e..cc8a7d934c 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -135,7 +135,6 @@ protected: LLUIColor mFontHighlightColor; // For now assuming all colors are the same in derived classes. - static bool sColorSetInitialized; static LLUIColor sFgColor; static LLUIColor sFgDisabledColor; static LLUIColor sHighlightBgColor; @@ -158,6 +157,7 @@ protected: virtual void setFlashState(bool) { } static LLFontGL* getLabelFontForStyle(U8 style); + const LLFontGL* getLabelFont(); bool mIsSelected; @@ -297,7 +297,7 @@ public: // virtual void handleDropped(); virtual void draw(); - void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color); + void drawOpenFolderArrow(); void drawHighlight(bool showContent, bool hasKeyboardFocus, const LLUIColor& selectColor, const LLUIColor& flashColor, const LLUIColor& outlineColor, const LLUIColor& mouseOverColor); void drawLabel(const LLFontGL* font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x); virtual bool handleDragAndDrop(S32 x, S32 y, MASK mask, bool drop, @@ -308,9 +308,14 @@ public: private: static std::map sFonts; // map of styles to fonts + static S32 sTopPad; + static LLUIImagePtr sFolderArrowImg; + static LLUIImagePtr sSelectionImg; + static LLFontGL* sSuffixFont; LLFontVertexBuffer mLabelFontBuffer; LLFontVertexBuffer mSuffixFontBuffer; + LLFontGL* pLabelFont{nullptr}; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index b19b6f8dec..a1f627c8cc 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -313,7 +313,7 @@ void LLConversationViewSession::draw() { // update the rotation angle of open folder arrow updateLabelRotation(); - drawOpenFolderArrow(default_params, sFgColor); + drawOpenFolderArrow(); } LLView::draw(); } -- cgit v1.2.3 From 3327ae7938499c4410556bef24662bb9f65274e8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 17 Sep 2024 18:46:44 +0300 Subject: Convert image drawing logic from quads to triangles --- indra/llrender/llrender2dutils.cpp | 284 ++++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 97 deletions(-) diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 428370057e..a63f3c1ef9 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -429,165 +429,247 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex gGL.color4fv(color.mV); - const S32 NUM_VERTICES = 9 * 4; // 9 quads - LLVector2 uv[NUM_VERTICES]; - LLVector3 pos[NUM_VERTICES]; + constexpr S32 NUM_VERTICES = 9 * 2 * 3; // 9 quads, 2 triangles per quad, 3 vertices per triangle + static thread_local LLVector2 uv[NUM_VERTICES]; + static thread_local LLVector3 pos[NUM_VERTICES]; S32 index = 0; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { - // draw bottom left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); + // draw bottom left triangles + // 1 + uv[index].set(uv_outer_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); + // 2 + uv[index].set(uv_outer_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f); index++; - // draw bottom middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); + uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + // draw bottom middle triangles + uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); index++; - // draw bottom right - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); + // 2 + uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - // draw left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); + // draw bottom right triangles + uv[index].set(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_outer_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + uv[index].set(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + // 2 + uv[index].set(uv_center_rect.mRight, uv_outer_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f); index++; - // draw middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + // draw left triangles + uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - // draw right - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); + // 2 + uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); index++; - // draw top left - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + // draw middle triangles + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f); + // 2 + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f); index++; - // draw top middle - uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + // draw right triangles + uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + uv[index].set(uv_outer_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f); index++; - // draw top right - uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + uv[index].set(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + // 2 + uv[index].set(uv_center_rect.mRight, uv_center_rect.mBottom); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f); + index++; + + uv[index].set(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + // draw top left triangles + uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; + + // 2 + uv[index].set(uv_outer_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + uv[index].set(uv_outer_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); + // draw top middle triangles + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); index++; - uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop); - pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + // 2 + uv[index].set(uv_center_rect.mLeft, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mLeft, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f); + index++; + + // draw top right triangles + uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_outer_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_outer_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + // 2 + uv[index].set(uv_center_rect.mRight, uv_center_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_center_rect.mTop, 0.f); + index++; + + uv[index].set(uv_outer_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f); + index++; + + uv[index].set(uv_center_rect.mRight, uv_outer_rect.mTop); + pos[index].set(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f); index++; gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); @@ -629,11 +711,11 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre if (degrees == 0.f) { - const S32 NUM_VERTICES = 4; // 9 quads - LLVector2 uv[NUM_VERTICES]; - LLVector3 pos[NUM_VERTICES]; + constexpr S32 NUM_VERTICES = 2 * 3; + static thread_local LLVector2 uv[NUM_VERTICES]; + static thread_local LLVector3 pos[NUM_VERTICES]; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { LLVector3 ui_scale = gGL.getUIScale(); LLVector3 ui_translation = gGL.getUITranslation(); @@ -644,20 +726,28 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre S32 scaled_width = ll_round(width * ui_scale.mV[VX]); S32 scaled_height = ll_round(height * ui_scale.mV[VY]); - uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); - pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); + uv[index].set(uv_rect.mRight, uv_rect.mTop); + pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); + index++; + + uv[index].set(uv_rect.mLeft, uv_rect.mTop); + pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); + index++; + + uv[index].set(uv_rect.mLeft, uv_rect.mBottom); + pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); index++; - uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); - pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f); + uv[index].set(uv_rect.mRight, uv_rect.mTop); + pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f); index++; - uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); - pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); + uv[index].set(uv_rect.mLeft, uv_rect.mBottom); + pos[index].set(ui_translation.mV[VX], ui_translation.mV[VY], 0.f); index++; - uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); - pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); + uv[index].set(uv_rect.mRight, uv_rect.mBottom); + pos[index].set(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f); index++; gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES); -- cgit v1.2.3 From 689d9e6935421879229909ec11b41a1524e64b33 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 17 Sep 2024 18:57:10 +0300 Subject: More quad to triangle coverage Quads are deprecated --- indra/llrender/llrender2dutils.cpp | 196 +++++++++++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 7 deletions(-) diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index a63f3c1ef9..27da64cce6 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -122,10 +122,13 @@ void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, bool filled ) // Counterclockwise quad will face the viewer if( filled ) { - gGL.begin( LLRender::QUADS ); + gGL.begin( LLRender::TRIANGLES ); gGL.vertex2i(left, top); gGL.vertex2i(left, bottom); gGL.vertex2i(right, bottom); + + gGL.vertex2i(left, top); + gGL.vertex2i(right, bottom); gGL.vertex2i(right, top); gGL.end(); } @@ -777,7 +780,7 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre gGL.color4fv(color.mV); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { LLVector3 v; @@ -793,6 +796,14 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); gGL.vertex2f(v.mV[0], v.mV[1] ); + v = LLVector3(offset_x, offset_y, 0.f) * quat; + gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop); + gGL.vertex2f(v.mV[0], v.mV[1]); + + v = LLVector3(-offset_x, -offset_y, 0.f) * quat; + gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom); + gGL.vertex2f(v.mV[0], v.mV[1]); + v = LLVector3(offset_x, -offset_y, 0.f) * quat; gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom); gGL.vertex2f(v.mV[0], v.mV[1] ); @@ -1038,7 +1049,7 @@ void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, void gl_rect_2d_simple_tex( S32 width, S32 height ) { - gGL.begin( LLRender::QUADS ); + gGL.begin( LLRender::TRIANGLES ); gGL.texCoord2f(1.f, 1.f); gGL.vertex2i(width, height); @@ -1049,6 +1060,12 @@ void gl_rect_2d_simple_tex( S32 width, S32 height ) gGL.texCoord2f(0.f, 0.f); gGL.vertex2i(0, 0); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2i(width, height); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); + gGL.texCoord2f(1.f, 0.f); gGL.vertex2i(width, 0); @@ -1057,10 +1074,13 @@ void gl_rect_2d_simple_tex( S32 width, S32 height ) void gl_rect_2d_simple( S32 width, S32 height ) { - gGL.begin( LLRender::QUADS ); + gGL.begin( LLRender::TRIANGLES ); gGL.vertex2i(width, height); gGL.vertex2i(0, height); gGL.vertex2i(0, 0); + + gGL.vertex2i(width, height); + gGL.vertex2i(0, 0); gGL.vertex2i(width, 0); gGL.end(); } @@ -1101,7 +1121,7 @@ void gl_segmented_rect_2d_tex(const S32 left, LLVector2 width_vec((F32)width, 0.f); LLVector2 height_vec(0.f, (F32)height); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { // draw bottom left gGL.texCoord2f(0.f, 0.f); @@ -1113,6 +1133,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); gGL.vertex2fv((border_width_left + border_height_bottom).mV); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2f(0.f, 0.f); + + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); + gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); gGL.vertex2fv(border_height_bottom.mV); @@ -1126,6 +1152,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(border_width_left.mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); gGL.vertex2fv((border_width_left + border_height_bottom).mV); @@ -1139,6 +1171,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv((width_vec - border_width_right).mV); + + gGL.texCoord2f(1.f, border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + border_height_bottom).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); @@ -1152,6 +1190,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + gGL.texCoord2f(0.f, border_uv_scale.mV[VY]); + gGL.vertex2fv(border_height_bottom.mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((height_vec - border_height_top).mV); @@ -1165,6 +1209,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); @@ -1178,6 +1228,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV); + + gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec + height_vec - border_height_top).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); @@ -1191,6 +1247,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((border_width_left + height_vec).mV); + gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((height_vec - border_height_top).mV); + + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((border_width_left + height_vec).mV); + gGL.texCoord2f(0.f, 1.f); gGL.vertex2fv((height_vec).mV); @@ -1204,6 +1266,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((border_width_left + height_vec).mV); @@ -1217,6 +1285,12 @@ void gl_segmented_rect_2d_tex(const S32 left, gGL.texCoord2f(1.f, 1.f); gGL.vertex2fv((width_vec + height_vec).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f, 1.f); + gGL.vertex2fv((width_vec + height_vec).mV); + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((width_vec - border_width_right + height_vec).mV); } @@ -1271,7 +1345,7 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, LLVector2 x_min; LLVector2 x_max; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { if (start_fragment < middle_start) { @@ -1290,6 +1364,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); gGL.vertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_min, 0.f); + gGL.vertex2fv(x_min.mV); + + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); gGL.vertex2fv((x_min + border_height_bottom).mV); @@ -1303,6 +1383,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((x_min + height_vec - border_height_top).mV); @@ -1316,6 +1402,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, 1.f); gGL.vertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_max, 1.f); + gGL.vertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(u_min, 1.f); gGL.vertex2fv((x_min + height_vec).mV); } @@ -1335,6 +1427,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); gGL.vertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 0.f); + gGL.vertex2fv(x_min.mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); gGL.vertex2fv((x_min + border_height_bottom).mV); @@ -1348,6 +1446,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((x_min + height_vec - border_height_top).mV); @@ -1361,6 +1465,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f); + gGL.vertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(border_uv_scale.mV[VX], 1.f); gGL.vertex2fv((x_min + height_vec).mV); } @@ -1382,6 +1492,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); gGL.vertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_min, 0.f); + gGL.vertex2fv((x_min).mV); + + gGL.texCoord2f(u_max, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + border_height_bottom).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); gGL.vertex2fv((x_min + border_height_bottom).mV); @@ -1395,6 +1511,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + border_height_bottom).mV); + + gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_max + height_vec - border_height_top).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); gGL.vertex2fv((x_min + height_vec - border_height_top).mV); @@ -1408,6 +1530,12 @@ void gl_segmented_rect_2d_fragment_tex(const LLRect& rect, gGL.texCoord2f(u_max, 1.f); gGL.vertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]); + gGL.vertex2fv((x_min + height_vec - border_height_top).mV); + + gGL.texCoord2f(u_max, 1.f); + gGL.vertex2fv((x_max + height_vec).mV); + gGL.texCoord2f(u_min, 1.f); gGL.vertex2fv((x_min + height_vec).mV); } @@ -1422,7 +1550,7 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv { LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { // draw bottom left gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom); @@ -1434,6 +1562,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom); + gGL.vertex3f(0.f, 0.f, 0.f); + + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); @@ -1447,6 +1581,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV); + + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); @@ -1460,6 +1600,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV); + + gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom); + gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV); @@ -1473,6 +1619,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV); + + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV); @@ -1486,6 +1638,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV); + + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV); @@ -1499,6 +1657,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom); + gGL.vertex3fv((center_draw_rect.mRight* width_vec + center_draw_rect.mBottom * height_vec).mV); + + gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop); + gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV); @@ -1512,6 +1676,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); + gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mTop* height_vec).mV); + + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mLeft* width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop); gGL.vertex3fv((height_vec).mV); @@ -1525,6 +1695,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); + gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mLeft* width_vec + center_draw_rect.mTop * height_vec).mV); + + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mRight* width_vec + center_draw_rect.mTop * height_vec).mV); + gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop); gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV); @@ -1538,6 +1714,12 @@ void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop); gGL.vertex3fv((width_vec + height_vec).mV); + gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop); + gGL.vertex3fv((center_draw_rect.mRight* width_vec + center_draw_rect.mTop * height_vec).mV); + + gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop); + gGL.vertex3fv((width_vec + height_vec).mV); + gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop); gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV); } -- cgit v1.2.3 From 83cf25af8d05897986cfbcf27224bf69fe7544c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pantera=20P=C3=B3=C5=82nocy?= Date: Wed, 18 Sep 2024 15:26:32 +0200 Subject: Tiny argument names correction (tittle -> title) (#2594) --- indra/newview/llfloatergltfasseteditor.cpp | 8 ++++---- indra/newview/skins/default/xui/en/floater_gltf_asset_editor.xml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/newview/llfloatergltfasseteditor.cpp b/indra/newview/llfloatergltfasseteditor.cpp index d2cf24f1dd..a127f5d43e 100644 --- a/indra/newview/llfloatergltfasseteditor.cpp +++ b/indra/newview/llfloatergltfasseteditor.cpp @@ -209,7 +209,7 @@ void LLFloaterGLTFAssetEditor::loadFromNode(S32 node_id, LLFolderViewFolder* par std::string name = node.mName; if (node.mName.empty()) { - name = getString("node_tittle"); + name = getString("node_title"); } else { @@ -243,7 +243,7 @@ void LLFloaterGLTFAssetEditor::loadFromNode(S32 node_id, LLFolderViewFolder* par std::string name = mAsset->mMeshes[node.mMesh].mName; if (name.empty()) { - name = getString("mesh_tittle"); + name = getString("mesh_title"); } loadItem(node.mMesh, name, LLGLTFFolderItem::TYPE_MESH, view); } @@ -253,7 +253,7 @@ void LLFloaterGLTFAssetEditor::loadFromNode(S32 node_id, LLFolderViewFolder* par std::string name = mAsset->mSkins[node.mSkin].mName; if (name.empty()) { - name = getString("skin_tittle"); + name = getString("skin_title"); } loadItem(node.mSkin, name, LLGLTFFolderItem::TYPE_SKIN, view); } @@ -306,7 +306,7 @@ void LLFloaterGLTFAssetEditor::loadFromSelection() std::string name = scene.mName; if (scene.mName.empty()) { - name = getString("scene_tittle"); + name = getString("scene_title"); } else { diff --git a/indra/newview/skins/default/xui/en/floater_gltf_asset_editor.xml b/indra/newview/skins/default/xui/en/floater_gltf_asset_editor.xml index b17d0aa5b6..025d537804 100644 --- a/indra/newview/skins/default/xui/en/floater_gltf_asset_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_gltf_asset_editor.xml @@ -11,10 +11,10 @@ name="gltf asset editor" title="[OBJECT_NAME]"> - - - - + + + + Date: Wed, 18 Sep 2024 16:09:51 +0200 Subject: Remove quads rendering mode entirely (#2593) --- indra/llrender/llfontgl.cpp | 43 +++--- indra/llrender/llfontgl.h | 2 +- indra/llrender/llrender.cpp | 212 ++++-------------------------- indra/llrender/llrender.h | 2 - indra/llrender/llrender2dutils.cpp | 62 ++++++--- indra/llrender/llvertexbuffer.cpp | 11 +- indra/llui/llbadge.cpp | 6 +- indra/llui/llfloater.cpp | 24 ++-- indra/llui/llstatbar.cpp | 10 +- indra/newview/llbox.cpp | 25 ++-- indra/newview/llfloaterbvhpreview.cpp | 7 +- indra/newview/llfloaterimagepreview.cpp | 30 +++-- indra/newview/llfloatermodelpreview.cpp | 15 ++- indra/newview/llglsandbox.cpp | 61 ++++----- indra/newview/llhudeffectblob.cpp | 11 +- indra/newview/llhudicon.cpp | 7 +- indra/newview/lljoystickbutton.cpp | 28 ++-- indra/newview/llmanipscale.cpp | 35 +---- indra/newview/llmediactrl.cpp | 14 +- indra/newview/llnetmap.cpp | 18 ++- indra/newview/llsnapshotlivepreview.cpp | 37 +++++- indra/newview/lltoolmorph.cpp | 7 +- indra/newview/llviewerjointattachment.cpp | 8 +- indra/newview/llvoavatar.cpp | 33 +++-- indra/newview/llworldmapview.cpp | 25 +++- indra/newview/pipeline.cpp | 15 ++- 26 files changed, 360 insertions(+), 388 deletions(-) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 9721b020c7..21593b7cb4 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -271,9 +271,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons const LLFontGlyphInfo* next_glyph = NULL; static constexpr S32 GLYPH_BATCH_SIZE = 30; - static thread_local LLVector3 vertices[GLYPH_BATCH_SIZE * 4]; - static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 4]; - static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 4]; + static thread_local LLVector3 vertices[GLYPH_BATCH_SIZE * 6]; + static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6]; + static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 6]; LLColor4U text_color(color); // Preserve the transparency to render fading emojis in fading text (e.g. @@ -305,9 +305,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons // otherwise the queued glyphs will be taken from wrong textures. if (glyph_count > 0) { - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { - gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); + gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 6); } gGL.end(); glyph_count = 0; @@ -338,9 +338,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons if (glyph_count >= GLYPH_BATCH_SIZE) { - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { - gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); + gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 6); } gGL.end(); @@ -376,9 +376,9 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons cur_render_y = cur_y; } - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { - gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 4); + gGL.vertexBatchPreTransformed(vertices, uvs, colors, glyph_count * 6); } gGL.end(); @@ -1227,7 +1227,7 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source) return *this; } -void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const +void LLFontGL::renderTriangle(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const { S32 index = 0; @@ -1246,6 +1246,17 @@ void LLFontGL::renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* c colors_out[index] = color; index++; + + vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f); + uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); + colors_out[index] = color; + index++; + + vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f); + uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); + colors_out[index] = color; + index++; + vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f); uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); colors_out[index] = color; @@ -1265,7 +1276,7 @@ void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_ LLRectf screen_rect_offset = screen_rect; screen_rect_offset.translate((F32)(pass * BOLD_OFFSET), 0.f); - renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, color, slant_offset); + renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect_offset, uv_rect, color, slant_offset); glyph_count++; } } @@ -1296,10 +1307,10 @@ void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_ break; } - renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_offset, uv_rect, shadow_color, slant_offset); + renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect_offset, uv_rect, shadow_color, slant_offset); glyph_count++; } - renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); + renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect, uv_rect, color, slant_offset); glyph_count++; } else if (shadow == DROP_SHADOW) @@ -1308,14 +1319,14 @@ void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_ shadow_color.mV[VALPHA] = U8(color.mV[VALPHA] * drop_shadow_strength); LLRectf screen_rect_shadow = screen_rect; screen_rect_shadow.translate(1.f, -1.f); - renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect_shadow, uv_rect, shadow_color, slant_offset); + renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect_shadow, uv_rect, shadow_color, slant_offset); glyph_count++; - renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); + renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect, uv_rect, color, slant_offset); glyph_count++; } else // normal rendering { - renderQuad(&vertex_out[glyph_count * 4], &uv_out[glyph_count * 4], &colors_out[glyph_count * 4], screen_rect, uv_rect, color, slant_offset); + renderTriangle(&vertex_out[glyph_count * 6], &uv_out[glyph_count * 6], &colors_out[glyph_count * 6], screen_rect, uv_rect, color, slant_offset); glyph_count++; } } diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index de7529a583..f04a77b49c 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -238,7 +238,7 @@ private: LLFontDescriptor mFontDescriptor; LLPointer mFontFreetype; - void renderQuad(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const; + void renderTriangle(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const; void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; // Registry holds all instantiated fonts. diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 16a8309a9a..f432b09107 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -803,7 +803,6 @@ void LLLightState::setSpotDirection(const LLVector3& direction) LLRender::LLRender() : mDirty(false), mCount(0), - mQuadCycle(0), mMode(LLRender::TRIANGLES), mCurrTextureUnitIndex(0) { @@ -1532,13 +1531,7 @@ void LLRender::begin(const GLuint& mode) { if (mode != mMode) { - if (mode == LLRender::QUADS) - { - mQuadCycle = 1; - } - - if (mMode == LLRender::QUADS || - mMode == LLRender::LINES || + if (mMode == LLRender::LINES || mMode == LLRender::TRIANGLES || mMode == LLRender::POINTS) { @@ -1561,8 +1554,7 @@ void LLRender::end() //IMM_ERRS << "GL begin and end called with no vertices specified." << LL_ENDL; } - if ((mMode != LLRender::QUADS && - mMode != LLRender::LINES && + if ((mMode != LLRender::LINES && mMode != LLRender::TRIANGLES && mMode != LLRender::POINTS) || mCount > 2048) @@ -1587,28 +1579,19 @@ void LLRender::flush() //store mCount in a local variable to avoid re-entrance (drawArrays may call flush) U32 count = mCount; - if (mMode == LLRender::QUADS && !sGLCoreProfile) - { - if (mCount%4 != 0) - { - count -= (mCount % 4); - LL_WARNS() << "Incomplete quad requested." << LL_ENDL; - } - } - - if (mMode == LLRender::TRIANGLES) + if (mMode == LLRender::TRIANGLES) + { + if (mCount%3 != 0) { - if (mCount%3 != 0) - { - count -= (mCount % 3); - LL_WARNS() << "Incomplete triangle requested." << LL_ENDL; - } + count -= (mCount % 3); + LL_WARNS() << "Incomplete triangle requested." << LL_ENDL; } + } - if (mMode == LLRender::LINES) + if (mMode == LLRender::LINES) + { + if (mCount%2 != 0) { - if (mCount%2 != 0) - { count -= (mCount % 2); LL_WARNS() << "Incomplete line requested." << LL_ENDL; } @@ -1758,16 +1741,7 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count) void LLRender::drawBuffer(LLVertexBuffer* vb, U32 mode, S32 count) { vb->setBuffer(); - - if (mode == LLRender::QUADS && sGLCoreProfile) - { - vb->drawArrays(LLRender::TRIANGLES, 0, count); - mQuadCycle = 1; - } - else - { - vb->drawArrays(mode, 0, count); - } + vb->drawArrays(mode, 0, count); } void LLRender::resetStriders(S32 count) @@ -1788,7 +1762,6 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) { case LLRender::POINTS: flush(); break; case LLRender::TRIANGLES: if (mCount%3==0) flush(); break; - case LLRender::QUADS: if(mCount%4 == 0) flush(); break; case LLRender::LINES: if (mCount%2 == 0) flush(); break; } } @@ -1809,25 +1782,6 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) mVerticesp[mCount] = vert; } - if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile) - { - mQuadCycle++; - if (mQuadCycle == 4) - { //copy two vertices so fourth quad element will add a triangle - mQuadCycle = 0; - - mCount++; - mVerticesp[mCount] = mVerticesp[mCount-3]; - mColorsp[mCount] = mColorsp[mCount-3]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-3]; - - mCount++; - mVerticesp[mCount] = mVerticesp[mCount-2]; - mColorsp[mCount] = mColorsp[mCount-2]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-2]; - } - } - mCount++; mVerticesp[mCount] = mVerticesp[mCount-1]; mColorsp[mCount] = mColorsp[mCount-1]; @@ -1842,50 +1796,13 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) return; } - if (sGLCoreProfile && mMode == LLRender::QUADS) - { //quads are deprecated, convert to triangle list - S32 i = 0; - - while (i < vert_count) - { - //read first three - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy two - mVerticesp[mCount++] = verts[i-3]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount++] = verts[i-1]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy last one - mVerticesp[mCount++] = verts[i++]; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - } - } - else + for (S32 i = 0; i < vert_count; i++) { - for (S32 i = 0; i < vert_count; i++) - { - mVerticesp[mCount] = verts[i]; + mVerticesp[mCount] = verts[i]; - mCount++; - mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - } + mCount++; + mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; + mColorsp[mCount] = mColorsp[mCount-1]; } if( mCount > 0 ) // ND: Guard against crashes if mCount is zero, yes it can happen @@ -1900,50 +1817,13 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v return; } - if (sGLCoreProfile && mMode == LLRender::QUADS) - { //quads are deprecated, convert to triangle list - S32 i = 0; - - while (i < vert_count) - { - //read first three - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy last two - mVerticesp[mCount] = verts[i-3]; - mTexcoordsp[mCount++] = uvs[i-3]; - mColorsp[mCount] = mColorsp[mCount-1]; - - mVerticesp[mCount] = verts[i-1]; - mTexcoordsp[mCount++] = uvs[i-1]; - mColorsp[mCount] = mColorsp[mCount-1]; - - //copy last one - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount++] = uvs[i++]; - mColorsp[mCount] = mColorsp[mCount-1]; - } - } - else + for (S32 i = 0; i < vert_count; i++) { - for (S32 i = 0; i < vert_count; i++) - { - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; - mCount++; - mColorsp[mCount] = mColorsp[mCount-1]; - } + mCount++; + mColorsp[mCount] = mColorsp[mCount-1]; } if (mCount > 0) @@ -1961,51 +1841,13 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLCol return; } - - if (sGLCoreProfile && mMode == LLRender::QUADS) - { //quads are deprecated, convert to triangle list - S32 i = 0; - - while (i < vert_count) - { - //read first three - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - - //copy last two - mVerticesp[mCount] = verts[i-3]; - mTexcoordsp[mCount] = uvs[i-3]; - mColorsp[mCount++] = colors[i-3]; - - mVerticesp[mCount] = verts[i-1]; - mTexcoordsp[mCount] = uvs[i-1]; - mColorsp[mCount++] = colors[i-1]; - - //copy last one - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount++] = colors[i++]; - } - } - else + for (S32 i = 0; i < vert_count; i++) { - for (S32 i = 0; i < vert_count; i++) - { - mVerticesp[mCount] = verts[i]; - mTexcoordsp[mCount] = uvs[i]; - mColorsp[mCount] = colors[i]; + mVerticesp[mCount] = verts[i]; + mTexcoordsp[mCount] = uvs[i]; + mColorsp[mCount] = colors[i]; - mCount++; - } + mCount++; } if (mCount > 0) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 2645597b1a..2c1417cc26 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -319,7 +319,6 @@ public: POINTS, LINES, LINE_STRIP, - QUADS, LINE_LOOP, NUM_MODES }; @@ -508,7 +507,6 @@ private: LLColor4 mAmbientLightColor; bool mDirty; - U32 mQuadCycle; U32 mCount; U32 mMode; U32 mCurrTextureUnitIndex; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index 27da64cce6..e488082c7e 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -175,50 +175,70 @@ void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &st LLColor4 end_color = start_color; end_color.mV[VALPHA] = 0.f; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); // Right edge, CCW faces screen gGL.color4fv(start_color.mV); - gGL.vertex2i(right, top-lines); - gGL.vertex2i(right, bottom); + gGL.vertex2i(right, top - lines); + gGL.vertex2i(right, bottom); gGL.color4fv(end_color.mV); - gGL.vertex2i(right+lines, bottom); - gGL.vertex2i(right+lines, top-lines); + gGL.vertex2i(right + lines, bottom); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, top - lines); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right + lines, bottom); + gGL.vertex2i(right + lines, top - lines); // Bottom edge, CCW faces screen gGL.color4fv(start_color.mV); - gGL.vertex2i(right, bottom); - gGL.vertex2i(left+lines, bottom); + gGL.vertex2i(right, bottom); + gGL.vertex2i(left + lines, bottom); gGL.color4fv(end_color.mV); - gGL.vertex2i(left+lines, bottom-lines); - gGL.vertex2i(right, bottom-lines); + gGL.vertex2i(left + lines, bottom - lines); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(left + lines, bottom - lines); + gGL.vertex2i(right, bottom - lines); // bottom left Corner gGL.color4fv(start_color.mV); - gGL.vertex2i(left+lines, bottom); + gGL.vertex2i(left + lines, bottom); gGL.color4fv(end_color.mV); - gGL.vertex2i(left, bottom); + gGL.vertex2i(left, bottom); // make the bottom left corner not sharp - gGL.vertex2i(left+1, bottom-lines+1); - gGL.vertex2i(left+lines, bottom-lines); + gGL.vertex2i(left + 1, bottom - lines + 1); + gGL.color4fv(start_color.mV); + gGL.vertex2i(left + lines, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(left + 1, bottom - lines + 1); + gGL.vertex2i(left + lines, bottom - lines); // bottom right corner gGL.color4fv(start_color.mV); - gGL.vertex2i(right, bottom); + gGL.vertex2i(right, bottom); gGL.color4fv(end_color.mV); - gGL.vertex2i(right, bottom-lines); + gGL.vertex2i(right, bottom - lines); // make the rightmost corner not sharp - gGL.vertex2i(right+lines-1, bottom-lines+1); - gGL.vertex2i(right+lines, bottom); + gGL.vertex2i(right + lines - 1, bottom - lines + 1); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, bottom); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right + lines - 1, bottom - lines + 1); + gGL.vertex2i(right + lines, bottom); // top right corner gGL.color4fv(start_color.mV); - gGL.vertex2i( right, top-lines ); + gGL.vertex2i(right, top - lines); gGL.color4fv(end_color.mV); - gGL.vertex2i( right+lines, top-lines ); + gGL.vertex2i(right + lines, top - lines); // make the corner not sharp - gGL.vertex2i( right+lines-1, top-1 ); - gGL.vertex2i( right, top ); + gGL.vertex2i(right + lines - 1, top - 1); + gGL.color4fv(start_color.mV); + gGL.vertex2i(right, top - lines); + gGL.color4fv(end_color.mV); + gGL.vertex2i(right + lines - 1, top - 1); + gGL.vertex2i(right, top); gGL.end(); stop_glerror(); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 0be799db9d..6f4828397a 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -633,15 +633,7 @@ void LLVertexBufferData::draw() gGL.loadMatrix(glm::value_ptr(mTexture0)); mVB->setBuffer(); - - if (mMode == LLRender::QUADS && LLRender::sGLCoreProfile) - { - mVB->drawArrays(LLRender::TRIANGLES, 0, mCount); - } - else - { - mVB->drawArrays(mMode, 0, mCount); - } + mVB->drawArrays(mMode, 0, mCount); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_PROJECTION); @@ -714,7 +706,6 @@ const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = GL_POINTS, GL_LINES, GL_LINE_STRIP, - GL_QUADS, GL_LINE_LOOP, }; diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp index c6654ee0aa..6875e7c0ad 100644 --- a/indra/llui/llbadge.cpp +++ b/indra/llui/llbadge.cpp @@ -205,12 +205,12 @@ void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, cons (F32)ll_round(y) + height); LLVector3 vertices[4]; - vertices[0] = LLVector3(screen_rect.mRight, screen_rect.mTop, 1.0f); - vertices[1] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 1.0f); + vertices[0] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 1.0f); + vertices[1] = LLVector3(screen_rect.mRight, screen_rect.mTop, 1.0f); vertices[2] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 1.0f); vertices[3] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 1.0f); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLE_STRIP); { gGL.vertexBatchPreTransformed(vertices, 4); } diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 92fb4b75bf..4b904f09e0 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2275,36 +2275,28 @@ void LLFloater::drawConeToOwner(F32 &context_cone_opacity, gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLGLEnable(GL_CULL_FACE); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLE_STRIP); { gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); - gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); - gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); - gGL.vertex2i(local_rect.mRight, local_rect.mTop); - gGL.vertex2i(local_rect.mLeft, local_rect.mTop); - gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); gGL.vertex2i(local_rect.mLeft, local_rect.mTop); - gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); - gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); - gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); - + gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); - gGL.vertex2i(local_rect.mRight, local_rect.mBottom); gGL.vertex2i(local_rect.mRight, local_rect.mTop); gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); - gGL.vertex2i(owner_rect.mRight, owner_rect.mTop); gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); - - gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); - gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); gGL.vertex2i(local_rect.mRight, local_rect.mBottom); gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); - gGL.vertex2i(owner_rect.mRight, owner_rect.mBottom); gGL.vertex2i(owner_rect.mLeft, owner_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); + gGL.vertex2i(owner_rect.mLeft, owner_rect.mTop); + gGL.color4f(0.f, 0.f, 0.f, contex_cone_out_alpha * context_cone_opacity); + gGL.vertex2i(local_rect.mLeft, local_rect.mTop); } gGL.end(); } diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 2693243eb1..62c0401869 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -460,7 +460,7 @@ void LLStatBar::draw() max_value = 0.f; gGL.color4f(1.f, 0.f, 0.f, 1.f); - gGL.begin( LLRender::QUADS ); + gGL.begin(LLRender::TRIANGLES); const S32 max_frame = llmin(num_frames, num_values); U32 num_samples = 0; for (S32 i = 1; i <= max_frame; i++) @@ -498,6 +498,9 @@ void LLStatBar::draw() gGL.vertex2f((F32)bar_rect.mRight - offset, max); gGL.vertex2f((F32)bar_rect.mRight - offset, min); gGL.vertex2f((F32)bar_rect.mRight - offset - 1, min); + + gGL.vertex2f((F32)bar_rect.mRight - offset, max); + gGL.vertex2f((F32)bar_rect.mRight - offset - 1, min); gGL.vertex2f((F32)bar_rect.mRight - offset - 1, max); } else @@ -505,7 +508,10 @@ void LLStatBar::draw() gGL.vertex2f(min, (F32)bar_rect.mBottom + offset + 1); gGL.vertex2f(min, (F32)bar_rect.mBottom + offset); gGL.vertex2f(max, (F32)bar_rect.mBottom + offset); - gGL.vertex2f(max, (F32)bar_rect.mBottom + offset + 1 ); + + gGL.vertex2f(min, (F32)bar_rect.mBottom + offset + 1); + gGL.vertex2f(max, (F32)bar_rect.mBottom + offset); + gGL.vertex2f(max, (F32)bar_rect.mBottom + offset + 1); } } gGL.end(); diff --git a/indra/newview/llbox.cpp b/indra/newview/llbox.cpp index dd12a02907..d0787a3902 100644 --- a/indra/newview/llbox.cpp +++ b/indra/newview/llbox.cpp @@ -76,16 +76,23 @@ void LLBox::renderface(S32 which_face) {7, 4, 0, 3} }; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { //gGL.normal3fv(&normals[which_face][0]); - gGL.texCoord2f(1,0); - gGL.vertex3fv(&mVertex[ faces[which_face][0] ][0]); - gGL.texCoord2f(1,1); - gGL.vertex3fv(&mVertex[ faces[which_face][1] ][0]); - gGL.texCoord2f(0,1); - gGL.vertex3fv(&mVertex[ faces[which_face][2] ][0]); - gGL.texCoord2f(0,0); - gGL.vertex3fv(&mVertex[ faces[which_face][3] ][0]); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv(&mVertex[faces[which_face][0]][0]); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv(&mVertex[faces[which_face][1]][0]); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv(&mVertex[faces[which_face][2]][0]); + + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv(&mVertex[faces[which_face][0]][0]); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv(&mVertex[faces[which_face][2]][0]); + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3fv(&mVertex[faces[which_face][3]][0]); + } gGL.end(); } diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 3d81d01e16..b94c31ec04 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -406,7 +406,7 @@ void LLFloaterBvhPreview::draw() gGL.getTexUnit(0)->bind(mAnimPreview); - gGL.begin( LLRender::QUADS ); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(0.f, 1.f); gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); @@ -414,6 +414,11 @@ void LLFloaterBvhPreview::draw() gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); gGL.texCoord2f(1.f, 0.f); gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); gGL.texCoord2f(1.f, 1.f); gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); } diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 711c33e73d..236725bd45 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -285,16 +285,21 @@ void LLFloaterImagePreview::draw() } gGL.color3f(1.f, 1.f, 1.f); - gGL.begin( LLRender::QUADS ); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); + + gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); + gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); + gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop); } gGL.end(); @@ -317,16 +322,21 @@ void LLFloaterImagePreview::draw() gGL.getTexUnit(0)->bind(mAvatarPreview); } - gGL.begin( LLRender::QUADS ); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); + gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop); } gGL.end(); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 5ca727cf66..8332a430e6 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -782,16 +782,21 @@ void LLFloaterModelPreview::draw3dPreview() gGL.getTexUnit(0)->bind(mModelPreview); - gGL.begin( LLRender::QUADS ); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(mPreviewRect.mLeft+1, mPreviewRect.mTop-1); + gGL.vertex2i(mPreviewRect.mLeft + 1, mPreviewRect.mTop - 1); gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(mPreviewRect.mLeft+1, mPreviewRect.mBottom+1); + gGL.vertex2i(mPreviewRect.mLeft + 1, mPreviewRect.mBottom + 1); gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mBottom+1); + gGL.vertex2i(mPreviewRect.mRight - 1, mPreviewRect.mBottom + 1); + + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2i(mPreviewRect.mRight - 1, mPreviewRect.mBottom + 1); gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(mPreviewRect.mRight-1, mPreviewRect.mTop-1); + gGL.vertex2i(mPreviewRect.mRight - 1, mPreviewRect.mTop - 1); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(mPreviewRect.mLeft + 1, mPreviewRect.mTop - 1); } gGL.end(); diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 0248f5710f..731e711cd1 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -338,28 +338,19 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, gGL.end(); gGL.color4f(1.f, 1.f, 0.f, 0.2f); - gGL.begin(LLRender::QUADS); - - gGL.vertex3f(west, north, nw_bottom); - gGL.vertex3f(west, north, nw_top); - gGL.vertex3f(east, north, ne_top); - gGL.vertex3f(east, north, ne_bottom); - - gGL.vertex3f(east, north, ne_bottom); - gGL.vertex3f(east, north, ne_top); - gGL.vertex3f(east, south, se_top); - gGL.vertex3f(east, south, se_bottom); - - gGL.vertex3f(east, south, se_bottom); - gGL.vertex3f(east, south, se_top); - gGL.vertex3f(west, south, sw_top); - gGL.vertex3f(west, south, sw_bottom); - - gGL.vertex3f(west, south, sw_bottom); - gGL.vertex3f(west, south, sw_top); - gGL.vertex3f(west, north, nw_top); - gGL.vertex3f(west, north, nw_bottom); - + gGL.begin(LLRender::TRIANGLE_STRIP); + { + gGL.vertex3f(west, north, nw_bottom); + gGL.vertex3f(west, north, nw_top); + gGL.vertex3f(east, north, ne_bottom); + gGL.vertex3f(east, north, ne_top); + gGL.vertex3f(east, south, se_bottom); + gGL.vertex3f(east, south, se_top); + gGL.vertex3f(west, south, sw_top); + gGL.vertex3f(west, south, sw_bottom); + gGL.vertex3f(west, north, nw_top); + gGL.vertex3f(west, north, nw_bottom); + } gGL.end(); LLUI::setLineWidth(1.f); @@ -493,6 +484,10 @@ void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 hei gGL.vertex3f(x2, y2, z2); + gGL.vertex3f(x1, y1, z); + + gGL.vertex3f(x2, y2, z2); + z = z2+height; gGL.vertex3f(x2, y2, z); } @@ -523,18 +518,24 @@ void LLViewerParcelMgr::renderOneSegment(F32 x1, F32 y1, F32 x2, F32 y2, F32 hei } - gGL.texCoord2f(tex_coord1*0.5f+0.5f, z1*0.5f); + gGL.texCoord2f(tex_coord1 * 0.5f + 0.5f, z1 * 0.5f); gGL.vertex3f(x1, y1, z1); - gGL.texCoord2f(tex_coord2*0.5f+0.5f, z2*0.5f); + gGL.texCoord2f(tex_coord2 * 0.5f + 0.5f, z2 * 0.5f); gGL.vertex3f(x2, y2, z2); // top edge stairsteps - z = llmax(z2+height, z1+height); - gGL.texCoord2f(tex_coord2*0.5f+0.5f, z*0.5f); + z = llmax(z2 + height, z1 + height); + gGL.texCoord2f(tex_coord2 * 0.5f + 0.5f, z * 0.5f); + gGL.vertex3f(x2, y2, z); + + gGL.texCoord2f(tex_coord1 * 0.5f + 0.5f, z1 * 0.5f); + gGL.vertex3f(x1, y1, z1); + + gGL.texCoord2f(tex_coord2 * 0.5f + 0.5f, z * 0.5f); gGL.vertex3f(x2, y2, z); - gGL.texCoord2f(tex_coord1*0.5f+0.5f, z*0.5f); + gGL.texCoord2f(tex_coord1 * 0.5f + 0.5f, z * 0.5f); gGL.vertex3f(x1, y1, z); } } @@ -575,7 +576,7 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi if (!has_segments) { has_segments = true; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); } renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp); } @@ -591,7 +592,7 @@ void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegi if (!has_segments) { has_segments = true; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); } renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp); } @@ -647,7 +648,7 @@ void LLViewerParcelMgr::renderCollisionSegments(U8* segments, bool use_pass, LLV gGL.getTexUnit(0)->bind(mBlockedImage); } - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); for (y = 0; y < STRIDE; y++) { diff --git a/indra/newview/llhudeffectblob.cpp b/indra/newview/llhudeffectblob.cpp index b476226d05..bdb21fd96e 100644 --- a/indra/newview/llhudeffectblob.cpp +++ b/indra/newview/llhudeffectblob.cpp @@ -78,16 +78,23 @@ void LLHUDEffectBlob::render() LLVector3 u_scale = pixel_right * (F32)mPixelSize; LLVector3 v_scale = pixel_up * (F32)mPixelSize; - { gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { gGL.texCoord2f(0.f, 1.f); gGL.vertex3fv((v_scale - u_scale).mV); gGL.texCoord2f(0.f, 0.f); gGL.vertex3fv((-v_scale - u_scale).mV); gGL.texCoord2f(1.f, 0.f); gGL.vertex3fv((-v_scale + u_scale).mV); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv((v_scale - u_scale).mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv((-v_scale + u_scale).mV); gGL.texCoord2f(1.f, 1.f); gGL.vertex3fv((v_scale + u_scale).mV); - } gGL.end(); + } + gGL.end(); } gGL.popMatrix(); } diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp index 8fa4118a40..1a4af470bd 100644 --- a/indra/newview/llhudicon.cpp +++ b/indra/newview/llhudicon.cpp @@ -152,7 +152,7 @@ void LLHUDIcon::render() gGL.getTexUnit(0)->bind(mImagep); } - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(0.f, 1.f); gGL.vertex3fv(upper_left.mV); @@ -160,6 +160,11 @@ void LLHUDIcon::render() gGL.vertex3fv(lower_left.mV); gGL.texCoord2f(1.f, 0.f); gGL.vertex3fv(lower_right.mV); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv(upper_left.mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv(lower_right.mV); gGL.texCoord2f(1.f, 1.f); gGL.vertex3fv(upper_right.mV); } diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 4eaf69c39d..10a1cd6b71 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -637,18 +637,24 @@ void LLJoystickCameraRotate::drawRotatedImage( LLPointer image, S32 r gGL.color4fv(UI_VERTEX_COLOR.mV); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { - gGL.texCoord2fv( uv[ (rotations + 0) % 4]); - gGL.vertex2i(width, height ); + gGL.texCoord2fv(uv[(rotations + 0) % 4]); + gGL.vertex2i(width, height); + + gGL.texCoord2fv(uv[(rotations + 1) % 4]); + gGL.vertex2i(0, height); - gGL.texCoord2fv( uv[ (rotations + 1) % 4]); - gGL.vertex2i(0, height ); + gGL.texCoord2fv(uv[(rotations + 2) % 4]); + gGL.vertex2i(0, 0); + + gGL.texCoord2fv(uv[(rotations + 0) % 4]); + gGL.vertex2i(width, height); - gGL.texCoord2fv( uv[ (rotations + 2) % 4]); + gGL.texCoord2fv(uv[(rotations + 2) % 4]); gGL.vertex2i(0, 0); - gGL.texCoord2fv( uv[ (rotations + 3) % 4]); + gGL.texCoord2fv(uv[(rotations + 3) % 4]); gGL.vertex2i(width, 0); } gGL.end(); @@ -909,7 +915,7 @@ void LLJoystickQuaternion::drawRotatedImage(LLPointer image, S32 rota gGL.color4fv(UI_VERTEX_COLOR.mV); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2fv(uv[(rotations + 0) % 4]); gGL.vertex2i(width, height); @@ -920,6 +926,12 @@ void LLJoystickQuaternion::drawRotatedImage(LLPointer image, S32 rota gGL.texCoord2fv(uv[(rotations + 2) % 4]); gGL.vertex2i(0, 0); + gGL.texCoord2fv(uv[(rotations + 0) % 4]); + gGL.vertex2i(width, height); + + gGL.texCoord2fv(uv[(rotations + 1) % 4]); + gGL.vertex2i(0, height); + gGL.texCoord2fv(uv[(rotations + 3) % 4]); gGL.vertex2i(width, 0); } diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp index 19868f3c3e..9966a8eedb 100644 --- a/indra/newview/llmanipscale.cpp +++ b/indra/newview/llmanipscale.cpp @@ -618,43 +618,22 @@ void LLManipScale::renderFaces( const LLBBox& bbox ) { gGL.color4fv( default_normal_color.mV ); LLGLDepthTest gls_depth(GL_FALSE); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLE_STRIP); { - // Face 0 - gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); - gGL.vertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); - gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); - gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); - - // Face 1 - gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); gGL.vertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); - - // Face 2 gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); - gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); - gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); - - // Face 3 - gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); - gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); gGL.vertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); - - // Face 4 - gGL.vertex3f(min.mV[VX], min.mV[VY], max.mV[VZ]); - gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); - gGL.vertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); gGL.vertex3f(max.mV[VX], min.mV[VY], max.mV[VZ]); - - // Face 5 - gGL.vertex3f(min.mV[VX], min.mV[VY], min.mV[VZ]); - gGL.vertex3f(min.mV[VX], max.mV[VY], min.mV[VZ]); - gGL.vertex3f(max.mV[VX], max.mV[VY], min.mV[VZ]); - gGL.vertex3f(max.mV[VX], min.mV[VY], min.mV[VZ]); + gGL.vertex3f(min.mV[VX], max.mV[VY], max.mV[VZ]); + gGL.vertex3f(max.mV[VX], max.mV[VY], max.mV[VZ]); } gGL.end(); } diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index b39a976ebd..202008f7f9 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -843,7 +843,7 @@ void LLMediaCtrl::draw() calcOffsetsAndSize(&x_offset, &y_offset, &width, &height); // draw the browser - gGL.begin( LLRender::QUADS ); + gGL.begin(LLRender::TRIANGLES); if (! media_plugin->getTextureCoordsOpenGL()) { // render using web browser reported width and height, instead of trying to invert GL scale @@ -856,6 +856,12 @@ void LLMediaCtrl::draw() gGL.texCoord2f( 0.f, max_v ); gGL.vertex2i( x_offset, y_offset ); + gGL.texCoord2f(max_u, 0.f); + gGL.vertex2i(x_offset + width, y_offset + height); + + gGL.texCoord2f(0.f, max_v); + gGL.vertex2i(x_offset, y_offset); + gGL.texCoord2f( max_u, max_v ); gGL.vertex2i( x_offset + width, y_offset ); } @@ -871,6 +877,12 @@ void LLMediaCtrl::draw() gGL.texCoord2f( 0.f, 0.f ); gGL.vertex2i( x_offset, y_offset ); + gGL.texCoord2f(max_u, max_v); + gGL.vertex2i(x_offset + width, y_offset + height); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(x_offset, y_offset); + gGL.texCoord2f( max_u, 0.f ); gGL.vertex2i( x_offset + width, y_offset ); } diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 3f370b1ab5..af472c4259 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -298,15 +298,22 @@ void LLNetMap::draw() // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(left, top); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); + } gGL.end(); gGL.flush(); @@ -347,15 +354,22 @@ void LLNetMap::draw() F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); + } gGL.end(); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 0b73aa493c..e996cc87fc 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -295,13 +295,20 @@ void LLSnapshotLivePreview::draw() gGL.pushMatrix(); { gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom + TOP_PANEL_HEIGHT, 0.f); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(uv_width, uv_height); - gGL.vertex2i(rect.getWidth(), rect.getHeight() ); + gGL.vertex2i(rect.getWidth(), rect.getHeight()); gGL.texCoord2f(0.f, uv_height); - gGL.vertex2i(0, rect.getHeight() ); + gGL.vertex2i(0, rect.getHeight()); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); + + + gGL.texCoord2f(uv_width, uv_height); + gGL.vertex2i(rect.getWidth(), rect.getHeight()); gGL.texCoord2f(0.f, 0.f); gGL.vertex2i(0, 0); @@ -357,13 +364,18 @@ void LLSnapshotLivePreview::draw() S32 y2 = gViewerWindow->getWindowHeightScaled() + TOP_PANEL_HEIGHT; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.color4f(1.f, 1.f, 1.f, 0.f); gGL.vertex2i(x1, y1); gGL.vertex2i(x1 + gViewerWindow->getWindowWidthScaled(), y2); gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY); gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2); + + gGL.color4f(1.f, 1.f, 1.f, 0.f); + gGL.vertex2i(x1, y1); + gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY); + gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2); gGL.vertex2i(x2, y1); gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY); @@ -371,6 +383,11 @@ void LLSnapshotLivePreview::draw() gGL.vertex2i(x2 + gViewerWindow->getWindowWidthScaled(), y2); gGL.color4f(1.f, 1.f, 1.f, 0.f); gGL.vertex2i(x3 + gViewerWindow->getWindowWidthScaled(), y2); + + gGL.color4f(1.f, 1.f, 1.f, SHINE_OPACITY); + gGL.vertex2i(x2, y1); + gGL.color4f(1.f, 1.f, 1.f, 0.f); + gGL.vertex2i(x3 + gViewerWindow->getWindowWidthScaled(), y2); gGL.vertex2i(x3, y1); } gGL.end(); @@ -406,13 +423,19 @@ void LLSnapshotLivePreview::draw() LLRect& rect = mImageRect[old_image_index]; gGL.translatef((F32)rect.mLeft, (F32)rect.mBottom - ll_round(getRect().getHeight() * 2.f * (fall_interp * fall_interp)), 0.f); gGL.rotatef(-45.f * fall_interp, 0.f, 0.f, 1.f); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(uv_width, uv_height); - gGL.vertex2i(rect.getWidth(), rect.getHeight() ); + gGL.vertex2i(rect.getWidth(), rect.getHeight()); gGL.texCoord2f(0.f, uv_height); - gGL.vertex2i(0, rect.getHeight() ); + gGL.vertex2i(0, rect.getHeight()); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex2i(0, 0); + + gGL.texCoord2f(uv_width, uv_height); + gGL.vertex2i(rect.getWidth(), rect.getHeight()); gGL.texCoord2f(0.f, 0.f); gGL.vertex2i(0, 0); diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index 24cfca5eee..8ce9a8b632 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -285,7 +285,7 @@ void LLVisualParamHint::draw(F32 alpha) gGL.color4f(1.f, 1.f, 1.f, alpha); LLGLSUIDefault gls_ui; - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2i(0, 1); gGL.vertex2i(0, mFullHeight); @@ -293,6 +293,11 @@ void LLVisualParamHint::draw(F32 alpha) gGL.vertex2i(0, 0); gGL.texCoord2i(1, 0); gGL.vertex2i(mFullWidth, 0); + + gGL.texCoord2i(0, 1); + gGL.vertex2i(0, mFullHeight); + gGL.texCoord2i(1, 0); + gGL.vertex2i(mFullWidth, 0); gGL.texCoord2i(1, 1); gGL.vertex2i(mFullWidth, mFullHeight); } diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index e733dafcae..511fac9788 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -86,13 +86,17 @@ U32 LLViewerJointAttachment::drawShape( F32 pixelArea, bool first_pass, bool is_ LLGLDisable cull_face(GL_CULL_FACE); gGL.color4f(1.f, 1.f, 1.f, 1.f); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); { gGL.vertex3f(-0.1f, 0.1f, 0.f); gGL.vertex3f(-0.1f, -0.1f, 0.f); gGL.vertex3f(0.1f, -0.1f, 0.f); + + gGL.vertex3f(-0.1f, 0.1f, 0.f); + gGL.vertex3f(0.1f, -0.1f, 0.f); gGL.vertex3f(0.1f, 0.1f, 0.f); - }gGL.end(); + } + gGL.end(); } return 0; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b6a2dac1e9..7bc9d06f9a 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -5424,14 +5424,6 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) gGL.setSceneBlendType(LLRender::BT_ADD); gGL.getTexUnit(diffuse_channel)->unbind(LLTexUnit::TT_TEXTURE); - // gGL.begin(LLRender::QUADS); - // gGL.vertex3fv((pos+left-up).mV); - // gGL.vertex3fv((pos-left-up).mV); - // gGL.vertex3fv((pos-left+up).mV); - // gGL.vertex3fv((pos+left+up).mV); - // gGL.end(); - - gGL.begin(LLRender::LINES); gGL.color4f(1.f,1.f,1.f,1.f); F32 thickness = llmax(F32(5.0f-5.0f*(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)),1.0f); @@ -5452,15 +5444,22 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel) gGL.color4ubv(color.mV); gGL.getTexUnit(diffuse_channel)->bind(&mImpostor); - gGL.begin(LLRender::QUADS); - gGL.texCoord2f(0,0); - gGL.vertex3fv((pos+left-up).mV); - gGL.texCoord2f(1,0); - gGL.vertex3fv((pos-left-up).mV); - gGL.texCoord2f(1,1); - gGL.vertex3fv((pos-left+up).mV); - gGL.texCoord2f(0,1); - gGL.vertex3fv((pos+left+up).mV); + gGL.begin(LLRender::TRIANGLES); + { + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3fv((pos + left - up).mV); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3fv((pos - left - up).mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv((pos - left + up).mV); + + gGL.texCoord2f(0.f, 0.f); + gGL.vertex3fv((pos + left - up).mV); + gGL.texCoord2f(1.f, 1.f); + gGL.vertex3fv((pos - left + up).mV); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3fv((pos + left + up).mV); + } gGL.end(); gGL.flush(); } diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index ca854ac7f7..6b2bd3e6fb 100755 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -462,11 +462,16 @@ void LLWorldMapView::draw() gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { gGL.vertex2f(left, top); gGL.vertex2f(left, bottom); gGL.vertex2f(right, bottom); + + gGL.vertex2f(left, top); + gGL.vertex2f(right, bottom); gGL.vertex2f(right, top); + } gGL.end(); } else if (show_for_sale && (level <= DRAW_LANDFORSALE_THRESHOLD)) @@ -483,15 +488,22 @@ void LLWorldMapView::draw() { gGL.getTexUnit(0)->bind(overlayimage); gGL.color4f(1.f, 1.f, 1.f, 1.f); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { gGL.texCoord2f(0.f, 1.f); gGL.vertex3f(left, top, -0.5f); gGL.texCoord2f(0.f, 0.f); gGL.vertex3f(left, bottom, -0.5f); gGL.texCoord2f(1.f, 0.f); gGL.vertex3f(right, bottom, -0.5f); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3f(left, top, -0.5f); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3f(right, bottom, -0.5f); gGL.texCoord2f(1.f, 1.f); gGL.vertex3f(right, top, -0.5f); + } gGL.end(); } } @@ -737,15 +749,22 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load gGL.color4f(1.f, 1.0f, 1.0f, 1.0f); - gGL.begin(LLRender::QUADS); + gGL.begin(LLRender::TRIANGLES); + { gGL.texCoord2f(0.f, 1.f); gGL.vertex3f(left, top, 0.f); gGL.texCoord2f(0.f, 0.f); gGL.vertex3f(left, bottom, 0.f); gGL.texCoord2f(1.f, 0.f); gGL.vertex3f(right, bottom, 0.f); + + gGL.texCoord2f(0.f, 1.f); + gGL.vertex3f(left, top, 0.f); + gGL.texCoord2f(1.f, 0.f); + gGL.vertex3f(right, bottom, 0.f); gGL.texCoord2f(1.f, 1.f); gGL.vertex3f(right, top, 0.f); + } gGL.end(); #if DEBUG_DRAW_TILE drawTileOutline(level, top, left, bottom, right); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 33683416a2..14a15eb59f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -10897,11 +10897,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool gGL.diffuseColor4fv(LLColor4::pink.mV ); } - gGL.begin(LLRender::QUADS); - gGL.vertex3f(-1, -1, clip_plane); - gGL.vertex3f(1, -1, clip_plane); - gGL.vertex3f(1, 1, clip_plane); - gGL.vertex3f(-1, 1, clip_plane); + gGL.begin(LLRender::TRIANGLES); + { + gGL.vertex3f(-1.f, -1.f, clip_plane); + gGL.vertex3f(1.f, -1.f, clip_plane); + gGL.vertex3f(1.f, 1.f, clip_plane); + + gGL.vertex3f(-1.f, -1.f, clip_plane); + gGL.vertex3f(1.f, 1.f, clip_plane); + gGL.vertex3f(-1.f, 1.f, clip_plane); + } gGL.end(); gGL.flush(); -- cgit v1.2.3 From 27b8e6d576346e3174760087a15811478a90459e Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Wed, 18 Sep 2024 11:44:03 +0200 Subject: #2408 The long covenant with emojis significantly slows down some operations in the viewer --- indra/llui/lltextbase.cpp | 98 +++++++++++++++++++++++++++++++++++ indra/llui/lltextbase.h | 15 ++++++ indra/newview/llchatmsgbox.cpp | 10 ++++ indra/newview/llexpandabletextbox.cpp | 8 +++ indra/newview/llfloaterbuyland.cpp | 25 +++++++++ indra/newview/llfloaterbuyland.h | 2 + indra/newview/llfloaterland.cpp | 10 ++++ indra/newview/llfloaterland.h | 2 + indra/newview/llfloaterregioninfo.cpp | 10 ++++ indra/newview/llfloaterregioninfo.h | 1 + indra/newview/llpanelplaceprofile.cpp | 5 ++ indra/newview/llpanelplaceprofile.h | 2 + indra/newview/llviewermessage.cpp | 36 +++++++++---- indra/newview/llviewertexteditor.cpp | 10 ++++ 14 files changed, 224 insertions(+), 10 deletions(-) diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index e2d31085c4..cbbf83d679 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2368,6 +2368,34 @@ S32 LLTextBase::removeFirstLine() return 0; } +// virtual +void LLTextBase::copyContents(const LLTextBase* source) +{ + llassert(source); + if (!source) + return; + + beforeValueChange(); + deselect(); + + mSegments.clear(); + for (const LLTextSegmentPtr& segp : source->mSegments) + { + mSegments.emplace(segp->clone(*this)); + } + + mLineInfoList.clear(); + for (const line_info& li : mLineInfoList) + { + mLineInfoList.push_back(line_info(li)); + } + + getViewModel()->setDisplay(source->getViewModel()->getDisplay()); + + onValueChange(0, getLength()); + needsReflow(); +} + void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params) { segment_vec_t segments; @@ -3233,6 +3261,24 @@ boost::signals2::connection LLTextBase::setIsObjectBlockedCallback(const is_bloc LLTextSegment::~LLTextSegment() {} +// static +LLStyleSP LLTextSegment::cloneStyle(LLTextBase& target, const LLStyle* source) +{ + // Take most params from target + LLStyle::Params params = target.getStyleParams(); + LLStyle* style = new LLStyle(params); + + // Take some params from source + style->setLinkHREF(source->getLinkHREF()); + if (source->isImage()) + { + style->setImage(source->getImage()->getName()); + } + + return style; +} + + bool LLTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { width = 0; height = 0; return false; } bool LLTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const { @@ -3574,6 +3620,13 @@ void LLNormalTextSegment::setToolTip(const std::string& tooltip) mTooltip = tooltip; } +// virtual +LLTextSegmentPtr LLNormalTextSegment::clone(LLTextBase& target) const +{ + LLStyleConstSP sp(cloneStyle(target, mStyle)); + return new LLNormalTextSegment(sp, mStart, mEnd, target); +} + bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { height = 0; @@ -3701,6 +3754,13 @@ LLLabelTextSegment::LLLabelTextSegment( const LLUIColor& color, S32 start, S32 e { } +// virtual +LLTextSegmentPtr LLLabelTextSegment::clone(LLTextBase& target) const +{ + LLStyleConstSP sp(cloneStyle(target, mStyle)); + return new LLLabelTextSegment(sp, mStart, mEnd, target); +} + /*virtual*/ const LLWString& LLLabelTextSegment::getWText() const { @@ -3725,6 +3785,13 @@ LLEmojiTextSegment::LLEmojiTextSegment(const LLUIColor& color, S32 start, S32 en { } +// virtual +LLTextSegmentPtr LLEmojiTextSegment::clone(LLTextBase& target) const +{ + LLStyleConstSP sp(cloneStyle(target, mStyle)); + return new LLEmojiTextSegment(sp, mStart, mEnd, target); +} + bool LLEmojiTextSegment::handleToolTip(S32 x, S32 y, MASK mask) { if (mTooltip.empty()) @@ -3748,6 +3815,14 @@ LLOnHoverChangeableTextSegment::LLOnHoverChangeableTextSegment( LLStyleConstSP s mHoveredStyle(style), mNormalStyle(normal_style){} +// virtual +LLTextSegmentPtr LLOnHoverChangeableTextSegment::clone(LLTextBase& target) const +{ + LLStyleConstSP hsp(cloneStyle(target, mHoveredStyle)); + LLStyleConstSP nsp(cloneStyle(target, mNormalStyle)); + return new LLOnHoverChangeableTextSegment(hsp, nsp, mStart, mEnd, target); +} + /*virtual*/ F32 LLOnHoverChangeableTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { @@ -3787,6 +3862,13 @@ LLInlineViewSegment::~LLInlineViewSegment() mView->die(); } +// virtual +LLTextSegmentPtr LLInlineViewSegment::clone(LLTextBase& target) const +{ + llassert_always_msg(false, "NOT SUPPORTED"); + return nullptr; +} + bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { if (first_char == 0 && num_chars == 0) @@ -3874,6 +3956,14 @@ LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLT LLLineBreakTextSegment::~LLLineBreakTextSegment() { } + +// virtual +LLTextSegmentPtr LLLineBreakTextSegment::clone(LLTextBase& target) const +{ + LLLineBreakTextSegment* copy = new LLLineBreakTextSegment(mStart); + copy->mFontHeight = mFontHeight; + return copy; +} bool LLLineBreakTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { width = 0; @@ -3901,8 +3991,16 @@ LLImageTextSegment::~LLImageTextSegment() { } +// virtual +LLTextSegmentPtr LLImageTextSegment::clone(LLTextBase& target) const +{ + LLStyleConstSP sp(cloneStyle(target, mStyle)); + return new LLImageTextSegment(sp, mStart, target); +} + static const S32 IMAGE_HPAD = 3; +// virtual bool LLImageTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { width = 0; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index eb4697da15..76d4e160af 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -45,6 +45,7 @@ class LLScrollContainer; class LLContextMenu; class LLUrlMatch; +class LLTextBase; /// /// A text segment is used to specify a subsection of a text string @@ -62,6 +63,9 @@ public: mEnd(end) {} virtual ~LLTextSegment(); + virtual LLTextSegmentPtr clone(LLTextBase& terget) const { return new LLTextSegment(mStart, mEnd); } + static LLStyleSP cloneStyle(LLTextBase& target, const LLStyle* source); + bool getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const; virtual bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; @@ -128,6 +132,7 @@ public: LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor ); LLNormalTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true); virtual ~LLNormalTextSegment(); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; /*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; @@ -180,6 +185,7 @@ class LLLabelTextSegment : public LLNormalTextSegment public: LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor ); LLLabelTextSegment( const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; protected: @@ -194,6 +200,7 @@ class LLEmojiTextSegment : public LLNormalTextSegment public: LLEmojiTextSegment(LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor); LLEmojiTextSegment(const LLUIColor& color, S32 start, S32 end, LLTextBase& editor, bool is_visible = true); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const override; bool canEdit() const override { return false; } bool handleToolTip(S32 x, S32 y, MASK mask) override; @@ -204,6 +211,7 @@ class LLOnHoverChangeableTextSegment : public LLNormalTextSegment { public: LLOnHoverChangeableTextSegment( LLStyleConstSP style, LLStyleConstSP normal_style, S32 start, S32 end, LLTextBase& editor ); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; /*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); protected: @@ -218,6 +226,7 @@ class LLIndexSegment : public LLTextSegment { public: LLIndexSegment() : LLTextSegment(0, 0) {} + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const { return new LLIndexSegment(); } }; class LLInlineViewSegment : public LLTextSegment @@ -235,6 +244,8 @@ public: LLInlineViewSegment(const Params& p, S32 start, S32 end); ~LLInlineViewSegment(); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) 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); @@ -259,6 +270,7 @@ public: LLLineBreakTextSegment(LLStyleConstSP style,S32 pos); LLLineBreakTextSegment(S32 pos); ~LLLineBreakTextSegment(); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars, S32 line_ind) const; F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); @@ -272,6 +284,8 @@ class LLImageTextSegment : public LLTextSegment public: LLImageTextSegment(LLStyleConstSP style,S32 pos,class LLTextBase& editor); ~LLImageTextSegment(); + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const; + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const; S32 getNumChars(S32 num_pixels, S32 segment_offset, S32 char_offset, S32 max_chars, S32 line_ind) const; F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect); @@ -510,6 +524,7 @@ public: const LLFontGL* getFont() const override { return mFont; } + virtual void copyContents(const LLTextBase* source); virtual void appendLineBreakSegment(const LLStyle::Params& style_params); virtual void appendImageSegment(const LLStyle::Params& style_params); virtual void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo); diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp index b70b3eac95..eacbb4366d 100644 --- a/indra/newview/llchatmsgbox.cpp +++ b/indra/newview/llchatmsgbox.cpp @@ -41,6 +41,16 @@ public: mEditor(NULL) {} + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const + { + ChatSeparator* copy = new ChatSeparator(mStart, mEnd); + if (mEditor) + { + copy->mEditor = ⌖ + } + return copy; + } + /*virtual*/ void linkToDocument(class LLTextBase* editor) { mEditor = editor; diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp index 748e10160c..5c46eb9d80 100644 --- a/indra/newview/llexpandabletextbox.cpp +++ b/indra/newview/llexpandabletextbox.cpp @@ -44,6 +44,14 @@ public: mExpanderLabel(utf8str_to_wstring(more_text)) {} + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const + { + LLStyleSP sp(cloneStyle(target, mStyle)); + LLExpanderSegment* copy = new LLExpanderSegment(sp, mStart, mEnd, LLStringUtil::null, target); + copy->mExpanderLabel = mExpanderLabel; + return copy; + } + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { // more label always spans width of text box diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 11505e3047..a38cc94328 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -163,6 +163,7 @@ public: void updateParcelInfo(); void updateCovenantInfo(); static void onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data); + void updateFloaterCovenant(const LLTextBase* source, const LLUUID &asset_id); void updateFloaterCovenantText(const std::string& string, const LLUUID &asset_id); void updateFloaterEstateName(const std::string& name); void updateFloaterLastModified(const std::string& text); @@ -201,6 +202,8 @@ public: void onVisibilityChanged ( const LLSD& new_visibility ); +private: + void onCovenantTextUpdated(const LLUUID& asset_id); }; // static @@ -221,6 +224,15 @@ void LLFloaterBuyLand::buyLand( } } +// static +void LLFloaterBuyLand::updateCovenant(const LLTextBase* source, const LLUUID& asset_id) +{ + if (LLFloaterBuyLandUI* floater = LLFloaterReg::findTypedInstance("buy_land")) + { + floater->updateFloaterCovenant(source, asset_id); + } +} + // static void LLFloaterBuyLand::updateCovenantText(const std::string& string, const LLUUID &asset_id) { @@ -560,11 +572,24 @@ void LLFloaterBuyLandUI::onChangeAgreeCovenant(LLUICtrl* ctrl, void* user_data) } } +void LLFloaterBuyLandUI::updateFloaterCovenant(const LLTextBase* source, const LLUUID& asset_id) +{ + LLViewerTextEditor* editor = getChild("covenant_editor"); + editor->copyContents(source); + + onCovenantTextUpdated(asset_id); +} + void LLFloaterBuyLandUI::updateFloaterCovenantText(const std::string &string, const LLUUID& asset_id) { LLViewerTextEditor* editor = getChild("covenant_editor"); editor->setText(string); + onCovenantTextUpdated(asset_id); +} + +void LLFloaterBuyLandUI::onCovenantTextUpdated(const LLUUID& asset_id) +{ LLCheckBoxCtrl* check = getChild("agree_covenant"); LLTextBox* box = getChild("covenant_text"); if (asset_id.isNull()) diff --git a/indra/newview/llfloaterbuyland.h b/indra/newview/llfloaterbuyland.h index f750a4017a..732312f10f 100644 --- a/indra/newview/llfloaterbuyland.h +++ b/indra/newview/llfloaterbuyland.h @@ -27,6 +27,7 @@ #ifndef LL_LLFLOATERBUYLAND_H #define LL_LLFLOATERBUYLAND_H +class LLTextBase; class LLFloater; class LLViewerRegion; class LLParcelSelection; @@ -37,6 +38,7 @@ public: static void buyLand(LLViewerRegion* region, LLSafeHandle parcel, bool is_for_group); + static void updateCovenant(const LLTextBase* source, const LLUUID& asset_id); static void updateCovenantText(const std::string& string, const LLUUID& asset_id); static void updateEstateName(const std::string& name); static void updateLastModified(const std::string& text); diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index bec76fe5e4..52a3e78d04 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -3123,6 +3123,16 @@ void LLPanelLandCovenant::refresh() } } +// static +void LLPanelLandCovenant::updateCovenant(const LLTextBase* source) +{ + if (LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant()) + { + LLViewerTextEditor* editor = self->getChild("covenant_editor"); + editor->copyContents(source); + } +} + // static void LLPanelLandCovenant::updateCovenantText(const std::string &string) { diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 95f6a44a94..8af0caab33 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -50,6 +50,7 @@ class LLRadioGroup; class LLParcelSelectionObserver; class LLSpinCtrl; class LLTabContainer; +class LLTextBase; class LLTextBox; class LLTextEditor; class LLTextureCtrl; @@ -416,6 +417,7 @@ public: virtual ~LLPanelLandCovenant(); virtual bool postBuild(); void refresh(); + static void updateCovenant(const LLTextBase* source); static void updateCovenantText(const std::string& string); static void updateEstateName(const std::string& name); static void updateLastModified(const std::string& text); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8070284e32..efeee1ad3c 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -2819,6 +2819,16 @@ void LLPanelEstateCovenant::setEstateName(const std::string& name) mEstateNameText->setText(name); } +// static +void LLPanelEstateCovenant::updateCovenant(const LLTextBase* source, const LLUUID& asset_id) +{ + if (LLPanelEstateCovenant* panelp = LLFloaterRegionInfo::getPanelCovenant()) + { + panelp->mEditor->copyContents(source); + panelp->setCovenantID(asset_id); + } +} + // static void LLPanelEstateCovenant::updateCovenantText(const std::string& string, const LLUUID& asset_id) { diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h index b604a28fc3..65c1291728 100644 --- a/indra/newview/llfloaterregioninfo.h +++ b/indra/newview/llfloaterregioninfo.h @@ -382,6 +382,7 @@ public: void* user_data, S32 status, LLExtStat ext_status); // Accessor functions + static void updateCovenant(const LLTextBase* source, const LLUUID& asset_id); static void updateCovenantText(const std::string& string, const LLUUID& asset_id); static void updateEstateName(const std::string& name); static void updateLastModified(const std::string& text); diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index 18588514f8..87f05f2028 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -629,6 +629,11 @@ void LLPanelPlaceProfile::updateCovenantText(const std::string &text) mCovenantText->setText(text); } +void LLPanelPlaceProfile::updateCovenant(const LLTextBase* source) +{ + mCovenantText->copyContents(source); +} + void LLPanelPlaceProfile::onForSaleBannerClick() { LLViewerParcelMgr* mgr = LLViewerParcelMgr::getInstance(); diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h index 45a20fb86a..f562be0f5d 100644 --- a/indra/newview/llpanelplaceprofile.h +++ b/indra/newview/llpanelplaceprofile.h @@ -31,6 +31,7 @@ class LLAccordionCtrl; class LLIconCtrl; +class LLTextBase; class LLTextEditor; class LLPanelPlaceProfile : public LLPanelPlaceInfo @@ -60,6 +61,7 @@ public: void updateEstateName(const std::string& name); void updateEstateOwnerName(const std::string& name); void updateCovenantText(const std::string &text); + void updateCovenant(const LLTextBase* source); private: void onForSaleBannerClick(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 0861b439eb..1d4828fd33 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6739,7 +6739,8 @@ void onCovenantLoadComplete(const LLUUID& asset_uuid, { LL_DEBUGS("Messaging") << "onCovenantLoadComplete()" << LL_ENDL; std::string covenant_text; - if(0 == status) + std::unique_ptr editorp; + if (0 == status) { LLFileSystem file(asset_uuid, type, LLFileSystem::READ); @@ -6760,13 +6761,13 @@ void onCovenantLoadComplete(const LLUUID& asset_uuid, { LL_WARNS("Messaging") << "Problem importing estate covenant." << LL_ENDL; covenant_text = "Problem importing estate covenant."; + delete editor; } else { // Version 0 (just text, doesn't include version number) - covenant_text = editor->getText(); + editorp.reset(editor); // Use covenant from editorp; } - delete editor; } else { @@ -6792,17 +6793,32 @@ void onCovenantLoadComplete(const LLUUID& asset_uuid, LL_WARNS("Messaging") << "Problem loading notecard: " << status << LL_ENDL; } - LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid); - LLPanelLandCovenant::updateCovenantText(covenant_text); - LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid); - LLPanelPlaceProfile* panel = LLFloaterSidePanelContainer::getPanel("places", "panel_place_profile"); - if (panel) + if (editorp) { - panel->updateCovenantText(covenant_text); + LLPanelEstateCovenant::updateCovenant(editorp.get(), asset_uuid); + LLPanelLandCovenant::updateCovenant(editorp.get()); + LLFloaterBuyLand::updateCovenant(editorp.get(), asset_uuid); + } + else + { + LLPanelEstateCovenant::updateCovenantText(covenant_text, asset_uuid); + LLPanelLandCovenant::updateCovenantText(covenant_text); + LLFloaterBuyLand::updateCovenantText(covenant_text, asset_uuid); } -} + if (LLPanelPlaceProfile* panel = LLFloaterSidePanelContainer::getPanel("places", "panel_place_profile")) + { + if (editorp) + { + panel->updateCovenant(editorp.get()); + } + else + { + panel->updateCovenantText(covenant_text); + } + } +} void process_feature_disabled_message(LLMessageSystem* msg, void**) { diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 5793a28b80..210cd62d6f 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -179,6 +179,16 @@ public: mToolTip = inv_item->getName() + '\n' + inv_item->getDescription(); } + /*virtual*/ LLTextSegmentPtr clone(LLTextBase& target) const + { + LLTextEditor* editor = dynamic_cast(&target); + llassert(editor); + if (!editor) + return nullptr; + + return new LLEmbeddedItemSegment(mStart, mImage, mItem, *editor); + } + /*virtual*/ bool getDimensionsF32(S32 first_char, S32 num_chars, F32& width, S32& height) const { if (num_chars == 0) -- cgit v1.2.3 From f037cde7f4d5d55dc0a71eb867f5b2bfcaf5631f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 11 Sep 2024 12:29:18 -0400 Subject: Make Develop->Render Tests->Frame Profile dump JSON to a file too. Make `LLGLSLShader::finishProfile()` accept a string pathname instead of a bool and, in addition to logging statistics to the viewer log, output statistics to that file as JSON. The calls that used to pass `emit_report=false` now pass `report_name=std::string()`. Make llviewerdisplay.cpp's `display()` function synthesize a profile filename in the viewer's logs directory, and pass that filename to `LLGLSLShader::finishProfile()`. (cherry picked from commit d5712689d36a1ee1af32242706901fde7229b08d) --- indra/llrender/llglslshader.cpp | 120 +++++++++++++++++++++++-------------- indra/llrender/llglslshader.h | 5 +- indra/newview/llfeaturemanager.cpp | 2 +- indra/newview/llglsandbox.cpp | 2 +- indra/newview/llviewerdisplay.cpp | 102 +++++++++++++++++++++++-------- 5 files changed, 158 insertions(+), 73 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index a157bfee21..bb734971d5 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -41,6 +41,8 @@ #include "OpenGL/OpenGL.h" #endif +#include + // Print-print list of shader included source files that are linked together via glAttachShader() // i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state. #define DEBUG_SHADER_INCLUDES 0 @@ -101,9 +103,9 @@ void LLGLSLShader::initProfile() sTotalSamplesDrawn = 0; sTotalBinds = 0; - for (std::set::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) + for (auto ptr : sInstances) { - (*iter)->clearStats(); + ptr->clearStats(); } } @@ -117,48 +119,71 @@ struct LLGLSLShaderCompareTimeElapsed }; //static -void LLGLSLShader::finishProfile(bool emit_report) +void LLGLSLShader::finishProfile(const std::string& report_name) { sProfileEnabled = false; - if (emit_report) + if (! report_name.empty()) { - std::vector sorted; - - for (std::set::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter) - { - sorted.push_back(*iter); - } - + std::vector sorted(sInstances.begin(), sInstances.end()); std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + boost::json::object stats; + auto shadersit = stats.emplace("shaders", boost::json::array_kind).first; + auto& shaders = shadersit->value().as_array(); bool unbound = false; - for (std::vector::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) + for (auto ptr : sorted) { - (*iter)->dumpStats(); - if ((*iter)->mBinds == 0) + if (ptr->mBinds == 0) { unbound = true; } + else + { + auto& shaderit = shaders.emplace_back(boost::json::object_kind); + ptr->dumpStats(shaderit.as_object()); + } } + constexpr float mega = 1'000'000.f; + float totalTimeMs = sTotalTimeElapsed / mega; LL_INFOS() << "-----------------------------------" << LL_ENDL; - LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed / 1000000.f) << LL_ENDL; - LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn / 1000000.f) << LL_ENDL; - LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn / 1000000.f) << LL_ENDL; + LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", totalTimeMs) << LL_ENDL; + LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn / mega) << LL_ENDL; + LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn / mega) << LL_ENDL; LL_INFOS() << "-----------------------------------" << LL_ENDL; - + auto totalsit = stats.emplace("totals", boost::json::object_kind).first; + auto& totals = totalsit->value().as_object(); + totals.emplace("time", totalTimeMs / 1000.0); + totals.emplace("binds", sTotalBinds); + totals.emplace("samples", sTotalSamplesDrawn); + totals.emplace("triangles", sTotalTrianglesDrawn); + + auto unusedit = stats.emplace("unused", boost::json::array_kind).first; + auto& unused = unusedit->value().as_array(); if (unbound) { LL_INFOS() << "The following shaders were unused: " << LL_ENDL; - for (std::vector::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) + for (auto ptr : sorted) { - if ((*iter)->mBinds == 0) + if (ptr->mBinds == 0) { - LL_INFOS() << (*iter)->mName << LL_ENDL; + LL_INFOS() << ptr->mName << LL_ENDL; + unused.emplace_back(ptr->mName); } } } + + std::ofstream outf(report_name); + if (! outf) + { + LL_WARNS() << "Couldn't write to " << std::quoted(report_name) << LL_ENDL; + } + else + { + outf << stats; + LL_INFOS() << "(also dumped to " << std::quoted(report_name) << ")" << LL_ENDL; + } } } @@ -170,36 +195,43 @@ void LLGLSLShader::clearStats() mBinds = 0; } -void LLGLSLShader::dumpStats() +void LLGLSLShader::dumpStats(boost::json::object& stats) { - if (mBinds > 0) + stats.emplace("name", mName); + auto filesit = stats.emplace("files", boost::json::array_kind).first; + auto& files = filesit->value().as_array(); + LL_INFOS() << "=============================================" << LL_ENDL; + LL_INFOS() << mName << LL_ENDL; + for (U32 i = 0; i < mShaderFiles.size(); ++i) { - LL_INFOS() << "=============================================" << LL_ENDL; - LL_INFOS() << mName << LL_ENDL; - for (U32 i = 0; i < mShaderFiles.size(); ++i) - { - LL_INFOS() << mShaderFiles[i].first << LL_ENDL; - } - LL_INFOS() << "=============================================" << LL_ENDL; + LL_INFOS() << mShaderFiles[i].first << LL_ENDL; + files.emplace_back(mShaderFiles[i].first); + } + LL_INFOS() << "=============================================" << LL_ENDL; - F32 ms = mTimeElapsed / 1000000.f; - F32 seconds = ms / 1000.f; + constexpr float mega = 1'000'000.f; + constexpr double giga = 1'000'000'000.0; + F32 ms = mTimeElapsed / mega; + F32 seconds = ms / 1000.f; - F32 pct_tris = (F32)mTrianglesDrawn / (F32)sTotalTrianglesDrawn * 100.f; - F32 tris_sec = (F32)(mTrianglesDrawn / 1000000.0); - tris_sec /= seconds; + F32 pct_tris = (F32)mTrianglesDrawn / (F32)sTotalTrianglesDrawn * 100.f; + F32 tris_sec = (F32)(mTrianglesDrawn / mega); + tris_sec /= seconds; - F32 pct_samples = (F32)((F64)mSamplesDrawn / (F64)sTotalSamplesDrawn) * 100.f; - F32 samples_sec = (F32)(mSamplesDrawn / 1000000000.0); - samples_sec /= seconds; + F32 pct_samples = (F32)((F64)mSamplesDrawn / (F64)sTotalSamplesDrawn) * 100.f; + F32 samples_sec = (F32)(mSamplesDrawn / giga); + samples_sec /= seconds; - F32 pct_binds = (F32)mBinds / (F32)sTotalBinds * 100.f; + F32 pct_binds = (F32)mBinds / (F32)sTotalBinds * 100.f; - LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec) << LL_ENDL; - LL_INFOS() << "Binds: " << mBinds << " " << llformat("(%.2f pct of total)", pct_binds) << LL_ENDL; - LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL; - LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32)((F64)mTimeElapsed / (F64)sTotalTimeElapsed) * 100.f, ms) << LL_ENDL; - } + LL_INFOS() << "Triangles Drawn: " << mTrianglesDrawn << " " << llformat("(%.2f pct of total, %.3f million/sec)", pct_tris, tris_sec) << LL_ENDL; + LL_INFOS() << "Binds: " << mBinds << " " << llformat("(%.2f pct of total)", pct_binds) << LL_ENDL; + LL_INFOS() << "SamplesDrawn: " << mSamplesDrawn << " " << llformat("(%.2f pct of total, %.3f billion/sec)", pct_samples, samples_sec) << LL_ENDL; + LL_INFOS() << "Time Elapsed: " << mTimeElapsed << " " << llformat("(%.2f pct of total, %.5f ms)\n", (F32)((F64)mTimeElapsed / (F64)sTotalTimeElapsed) * 100.f, ms) << LL_ENDL; + stats.emplace("time", seconds); + stats.emplace("binds", mBinds); + stats.emplace("samples", mSamplesDrawn); + stats.emplace("triangles", mTrianglesDrawn); } //static diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index 27c8f0b7d0..efcbaf42e8 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -30,6 +30,7 @@ #include "llgl.h" #include "llrender.h" #include "llstaticstringtable.h" +#include #include class LLShaderFeatures @@ -169,14 +170,14 @@ public: static U32 sMaxGLTFNodes; static void initProfile(); - static void finishProfile(bool emit_report = true); + static void finishProfile(const std::string& report_name={}); static void startProfile(); static void stopProfile(); void unload(); void clearStats(); - void dumpStats(); + void dumpStats(boost::json::object& stats); // place query objects for profiling if profiling is enabled // if for_runtime is true, will place timer query only whether or not profiling is enabled diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 3259ea249b..b5d8f70c2e 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -393,7 +393,7 @@ F32 logExceptionBenchmark() __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation())) { // HACK - ensure that profiling is disabled - LLGLSLShader::finishProfile(false); + LLGLSLShader::finishProfile(); // convert to C++ styled exception char integer_string[32]; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 731e711cd1..b0f136fb93 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -924,7 +924,7 @@ struct ShaderProfileHelper } ~ShaderProfileHelper() { - LLGLSLShader::finishProfile(false); + LLGLSLShader::finishProfile(); } }; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 301ea5c5f6..fdfe477a6c 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -28,58 +28,69 @@ #include "llviewerdisplay.h" -#include "llgl.h" -#include "llrender.h" -#include "llglheaders.h" -#include "llgltfmateriallist.h" +#include "fsyspath.h" +#include "hexdump.h" #include "llagent.h" #include "llagentcamera.h" -#include "llviewercontrol.h" +#include "llappviewer.h" #include "llcoord.h" #include "llcriticaldamp.h" +#include "llcubemap.h" #include "lldir.h" -#include "lldynamictexture.h" #include "lldrawpoolalpha.h" +#include "lldrawpoolbump.h" +#include "lldrawpoolwater.h" +#include "lldynamictexture.h" +#include "llenvironment.h" +#include "llfasttimer.h" #include "llfeaturemanager.h" -//#include "llfirstuse.h" +#include "llfloatertools.h" +#include "llfocusmgr.h" +#include "llgl.h" +#include "llglheaders.h" +#include "llgltfmateriallist.h" #include "llhudmanager.h" #include "llimagepng.h" +#include "llmachineid.h" #include "llmemory.h" +#include "llparcel.h" +#include "llperfstats.h" +#include "llpostprocess.h" +#include "llrender.h" +#include "llscenemonitor.h" #include "llselectmgr.h" #include "llsky.h" +#include "llspatialpartition.h" #include "llstartup.h" +#include "llstartup.h" +#include "lltooldraganddrop.h" #include "lltoolfocus.h" #include "lltoolmgr.h" -#include "lltooldraganddrop.h" #include "lltoolpie.h" #include "lltracker.h" #include "lltrans.h" #include "llui.h" +#include "lluuid.h" +#include "llversioninfo.h" #include "llviewercamera.h" +#include "llviewercontrol.h" +#include "llviewernetwork.h" #include "llviewerobjectlist.h" #include "llviewerparcelmgr.h" +#include "llviewerregion.h" +#include "llviewershadermgr.h" +#include "llviewertexturelist.h" #include "llviewerwindow.h" #include "llvoavatarself.h" #include "llvograss.h" #include "llworld.h" #include "pipeline.h" -#include "llspatialpartition.h" -#include "llappviewer.h" -#include "llstartup.h" -#include "llviewershadermgr.h" -#include "llfasttimer.h" -#include "llfloatertools.h" -#include "llviewertexturelist.h" -#include "llfocusmgr.h" -#include "llcubemap.h" -#include "llviewerregion.h" -#include "lldrawpoolwater.h" -#include "lldrawpoolbump.h" -#include "llpostprocess.h" -#include "llscenemonitor.h" -#include "llenvironment.h" -#include "llperfstats.h" +#include + +#include +#include +#include #include #include @@ -127,6 +138,8 @@ void render_ui_3d(); void render_ui_2d(); void render_disconnected_background(); +std::string getProfileStatsFilename(); + void display_startup() { if ( !gViewerWindow @@ -1027,10 +1040,49 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) if (gShaderProfileFrame) { gShaderProfileFrame = false; - LLGLSLShader::finishProfile(); + LLGLSLShader::finishProfile(getProfileStatsFilename()); } } +std::string getProfileStatsFilename() +{ + std::ostringstream basebuff; + // viewer build + basebuff << "profile.v" << LLVersionInfo::instance().getBuild(); + // machine ID: zero-initialize unique_id in case LLMachineID fails + unsigned char unique_id[MAC_ADDRESS_BYTES]{}; + LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); + basebuff << ".m" << LL::hexdump(unique_id, sizeof(unique_id)); + // region ID + LLViewerRegion *region = gAgent.getRegion(); + basebuff << ".r" << (region? region->getRegionID() : LLUUID()); + // local parcel ID + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); + basebuff << ".p" << (parcel? parcel->getLocalID() : 0); + // date/time -- omit seconds for now + auto now = LLDate::now(); + basebuff << ".t" << LLDate::now().toHTTPDateString("%Y-%m-%dT%H-%M-"); + // put this candidate file in our logs directory + auto base = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, basebuff.str()); + S32 sec; + now.split(nullptr, nullptr, nullptr, nullptr, nullptr, &sec); + // Loop over finished filename, incrementing sec until we find one that + // doesn't yet exist. Should rarely loop (only if successive calls within + // same second), may produce (e.g.) sec==61, but avoids collisions and + // preserves chronological filename sort order. + std::string name; + std::error_code ec; + do + { + // base + missing 2-digit seconds, append ".json" + // post-increment sec in case we have to try again + name = stringize(base, std::setw(2), std::setfill('0'), sec++, ".json"); + } while (std::filesystem::exists(fsyspath(name), ec)); + // Ignoring ec means we might potentially return a name that does already + // exist -- but if we can't check its existence, what more can we do? + return name; +} + // WIP simplified copy of display() that does minimal work void display_cube_face() { -- cgit v1.2.3 From a3d6544be07e3cd0bb7e4cb78564a0d6077fd910 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 12 Sep 2024 09:12:33 -0400 Subject: Give `LLGLSLShader::finishProfile()` a static default string param. `finishProfile()` is called at least once within a `__try` block. If we default its `report_name` parameter to a temporary `std::string`, that temporary must be destroyed when the stack is unwound, which `__try` forbids. (cherry picked from commit c6e6f44f50b4de391000c5b9f781a2f0a5024e76) --- indra/llrender/llglslshader.cpp | 1 + indra/llrender/llglslshader.h | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index bb734971d5..56f1533708 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -65,6 +65,7 @@ U64 LLGLSLShader::sTotalTimeElapsed = 0; U32 LLGLSLShader::sTotalTrianglesDrawn = 0; U64 LLGLSLShader::sTotalSamplesDrawn = 0; U32 LLGLSLShader::sTotalBinds = 0; +std::string LLGLSLShader::sDefaultReportName; //UI shader -- declared here so llui_libtest will link properly LLGLSLShader gUIProgram; diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index efcbaf42e8..a9b9bfafa8 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -170,7 +170,7 @@ public: static U32 sMaxGLTFNodes; static void initProfile(); - static void finishProfile(const std::string& report_name={}); + static void finishProfile(const std::string& report_name=sDefaultReportName); static void startProfile(); static void stopProfile(); @@ -364,6 +364,11 @@ public: private: void unloadInternal(); + // This must be static because finishProfile() is called at least once + // within a __try block. If we default its report_name parameter to a + // temporary std::string, that temporary must be destroyed when the stack + // is unwound, which __try forbids. + static std::string sDefaultReportName; }; //UI shader (declared here so llui_libtest will link properly) -- cgit v1.2.3 From 277ee6830f68030ece6f469a86a49009a9c1450a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 12 Sep 2024 12:28:05 -0400 Subject: Add a JSON frame profile stats file pretty-printer script. (cherry picked from commit ab3083819793a30911354670a7929b0d3f7c104c) --- scripts/perf/profile_pretty.py | 54 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 scripts/perf/profile_pretty.py diff --git a/scripts/perf/profile_pretty.py b/scripts/perf/profile_pretty.py new file mode 100644 index 0000000000..ca52fe366a --- /dev/null +++ b/scripts/perf/profile_pretty.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +"""\ +@file profile_pretty.py +@author Nat Goodspeed +@date 2024-09-12 +@brief Pretty-print a JSON file from Develop -> Render Tests -> Frame Profile + +$LicenseInfo:firstyear=2024&license=viewerlgpl$ +Copyright (c) 2024, Linden Research, Inc. +$/LicenseInfo$ +""" + +import logsdir +import json +from pathlib import Path +import sys + +class Error(Exception): + pass + +def pretty(path=None): + if not path: + logs = logsdir.logsdir() + profiles = Path(logs).glob('profile.*.json') + sort = [(p.stat().st_mtime, p) for p in profiles] + sort.sort(reverse=True) + try: + path = sort[0][1] + except IndexError: + raise Error(f'No profile.*.json files in {logs}') + # print path to sys.stderr in case user is redirecting stdout + print(path, file=sys.stderr) + + with open(path) as inf: + data = json.load(inf) + json.dump(data, sys.stdout, indent=4) + +def main(*raw_args): + from argparse import ArgumentParser + parser = ArgumentParser(description=""" +%(prog)s pretty-prints a JSON file from Develop -> Render Tests -> Frame Profile. +The file produced by the viewer is a single dense line of JSON. +""") + parser.add_argument('path', nargs='?', + help="""profile filename to pretty-print (default is most recent)""") + + args = parser.parse_args(raw_args) + pretty(args.path) + +if __name__ == "__main__": + try: + sys.exit(main(*sys.argv[1:])) + except (Error, OSError, json.JSONDecodeError) as err: + sys.exit(str(err)) -- cgit v1.2.3 From ee1b0061c36c36ab019438c2a722696801de04f9 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 12 Sep 2024 13:43:36 -0400 Subject: Add script to convert frame profile JSON file to CSV. Also slightly refactor profile_pretty.py. (cherry picked from commit d60b1f92213ace6a8ab6a4a60cb01a43f45d3955) --- scripts/perf/profile_csv.py | 72 ++++++++++++++++++++++++++++++++++++++++++ scripts/perf/profile_pretty.py | 26 +++++++-------- 2 files changed, 85 insertions(+), 13 deletions(-) create mode 100644 scripts/perf/profile_csv.py diff --git a/scripts/perf/profile_csv.py b/scripts/perf/profile_csv.py new file mode 100644 index 0000000000..273e3b7434 --- /dev/null +++ b/scripts/perf/profile_csv.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +"""\ +@file profile_csv.py +@author Nat Goodspeed +@date 2024-09-12 +@brief Convert a JSON file from Develop -> Render Tests -> Frame Profile to CSV + +$LicenseInfo:firstyear=2024&license=viewerlgpl$ +Copyright (c) 2024, Linden Research, Inc. +$/LicenseInfo$ +""" + +import logsdir +import json +from pathlib import Path +import sys + +class Error(Exception): + pass + +def convert(path, totals=True, unused=True, file=sys.stdout): + with open(path) as inf: + data = json.load(inf) + print('"name", "file1", "file2", "time", "binds", "samples", "triangles"', file=file) + + if totals: + t = data['totals'] + print(f'"totals", "", "", {t["time"]}, {t["binds"]}, {t["samples"]}, {t["triangles"]}', + file=file) + + for sh in data['shaders']: + print(f'"{sh["name"]}", "{sh["files"][0]}", "{sh["files"][1]}", ' + f'{sh["time"]}, {sh["binds"]}, {sh["samples"]}, {sh["triangles"]}', file=file) + + if unused: + for u in data['unused']: + print(f'"{u}", "", "", 0, 0, 0, 0', file=file) + +def main(*raw_args): + from argparse import ArgumentParser + parser = ArgumentParser(description=""" +%(prog)s converts a JSON file from Develop -> Render Tests -> Frame Profile to +a more-or-less equivalent CSV file. It expands the totals stats and unused +shaders list to full shaders lines. +""") + parser.add_argument('-t', '--totals', action='store_false', default=True, + help="""omit totals from CSV file""") + parser.add_argument('-u', '--unused', action='store_false', default=True, + help="""omit unused shaders from CSV file""") + parser.add_argument('path', nargs='?', + help="""profile filename to convert (default is most recent)""") + + args = parser.parse_args(raw_args) + if not args.path: + logs = logsdir.logsdir() + profiles = Path(logs).glob('profile.*.json') + sort = [(p.stat().st_mtime, p) for p in profiles] + sort.sort(reverse=True) + try: + args.path = sort[0][1] + except IndexError: + raise Error(f'No profile.*.json files in {logs}') + # print path to sys.stderr in case user is redirecting stdout + print(args.path, file=sys.stderr) + + convert(args.path, totals=args.totals, unused=args.unused) + +if __name__ == "__main__": + try: + sys.exit(main(*sys.argv[1:])) + except (Error, OSError, json.JSONDecodeError) as err: + sys.exit(str(err)) diff --git a/scripts/perf/profile_pretty.py b/scripts/perf/profile_pretty.py index ca52fe366a..15b6efd94d 100644 --- a/scripts/perf/profile_pretty.py +++ b/scripts/perf/profile_pretty.py @@ -18,19 +18,7 @@ import sys class Error(Exception): pass -def pretty(path=None): - if not path: - logs = logsdir.logsdir() - profiles = Path(logs).glob('profile.*.json') - sort = [(p.stat().st_mtime, p) for p in profiles] - sort.sort(reverse=True) - try: - path = sort[0][1] - except IndexError: - raise Error(f'No profile.*.json files in {logs}') - # print path to sys.stderr in case user is redirecting stdout - print(path, file=sys.stderr) - +def pretty(path): with open(path) as inf: data = json.load(inf) json.dump(data, sys.stdout, indent=4) @@ -45,6 +33,18 @@ The file produced by the viewer is a single dense line of JSON. help="""profile filename to pretty-print (default is most recent)""") args = parser.parse_args(raw_args) + if not args.path: + logs = logsdir.logsdir() + profiles = Path(logs).glob('profile.*.json') + sort = [(p.stat().st_mtime, p) for p in profiles] + sort.sort(reverse=True) + try: + args.path = sort[0][1] + except IndexError: + raise Error(f'No profile.*.json files in {logs}') + # print path to sys.stderr in case user is redirecting stdout + print(args.path, file=sys.stderr) + pretty(args.path) if __name__ == "__main__": -- cgit v1.2.3 From e6d0138a6a1ce6dd285fbfedbcf8532bc6aaa29b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 16 Sep 2024 17:25:48 -0400 Subject: Add LLFloaterAbout info (esp. GPU info) to Frame Profile stats dump With the About info added, `getProfileStatsContext()` need not redundantly add `"channel"`, `"version"` or `"region"`. Slightly improve the efficiency of `LlsdToJson()` and `LlsdFromJson()` by preallocating the known size of the source array or map. (Unfortunately the C++ `LLSD` class offers us no way to preallocate a map.) In `LLAppViewer::getViewerInfo()`, avoid immediate successive calls to `gAgent.getRegion()`. (cherry picked from commit f4b65638879c10c832b3bb8448f82001106ffd11) --- indra/llcommon/llsdjson.cpp | 15 +++++++++++++-- indra/newview/llappviewer.cpp | 4 ++-- indra/newview/llviewerdisplay.cpp | 26 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/indra/llcommon/llsdjson.cpp b/indra/llcommon/llsdjson.cpp index 5d38e55686..1df2a8f9eb 100644 --- a/indra/llcommon/llsdjson.cpp +++ b/indra/llcommon/llsdjson.cpp @@ -61,12 +61,20 @@ LLSD LlsdFromJson(const boost::json::value& val) result = LLSD(val.as_bool()); break; case boost::json::kind::array: + { result = LLSD::emptyArray(); - for (const auto &element : val.as_array()) + auto& array = val.as_array(); + // allocate elements 0 .. (size() - 1) to avoid incremental allocation + if (! array.empty()) + { + result[array.size() - 1] = LLSD(); + } + for (const auto &element : array) { result.append(LlsdFromJson(element)); } break; + } case boost::json::kind::object: result = LLSD::emptyMap(); for (const auto& element : val.as_object()) @@ -106,6 +114,7 @@ boost::json::value LlsdToJson(const LLSD &val) case LLSD::TypeMap: { boost::json::object& obj = result.emplace_object(); + obj.reserve(val.size()); for (const auto& llsd_dat : llsd::inMap(val)) { obj[llsd_dat.first] = LlsdToJson(llsd_dat.second); @@ -115,6 +124,7 @@ boost::json::value LlsdToJson(const LLSD &val) case LLSD::TypeArray: { boost::json::array& json_array = result.emplace_array(); + json_array.reserve(val.size()); for (const auto& llsd_dat : llsd::inArray(val)) { json_array.push_back(LlsdToJson(llsd_dat)); @@ -123,7 +133,8 @@ boost::json::value LlsdToJson(const LLSD &val) } case LLSD::TypeBinary: default: - LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" << val.type() << ")." << LL_ENDL; + LL_ERRS("LlsdToJson") << "Unsupported conversion to JSON from LLSD type (" + << val.type() << ")." << LL_ENDL; break; } diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 764e52accb..093314a9f1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3285,10 +3285,10 @@ LLSD LLAppViewer::getViewerInfo() const LLVector3d pos = gAgent.getPositionGlobal(); info["POSITION"] = ll_sd_from_vector3d(pos); info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos)); - info["REGION"] = gAgent.getRegion()->getName(); + info["REGION"] = region->getName(); boost::regex regex("\\.(secondlife|lindenlab)\\..*"); - info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, ""); + info["HOSTNAME"] = boost::regex_replace(region->getSimHostName(), regex, ""); info["SERVER_VERSION"] = gLastVersionChannel; LLSLURL slurl; LLAgentUI::buildSLURL(slurl); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index fdfe477a6c..ae0579f5f7 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -58,6 +58,7 @@ #include "llpostprocess.h" #include "llrender.h" #include "llscenemonitor.h" +#include "llsdjson.h" #include "llselectmgr.h" #include "llsky.h" #include "llspatialpartition.h" @@ -1044,6 +1045,31 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) } } +void getProfileStatsContext(boost::json::object& stats) +{ + // populate the context with info from LLFloaterAbout + auto contextit = stats.emplace("context", + LlsdToJson(LLAppViewer::instance()->getViewerInfo())).first; + auto& context = contextit->value().as_object(); + + // then add a few more things + unsigned char unique_id[MAC_ADDRESS_BYTES]{}; + LLMachineID::getUniqueID(unique_id, sizeof(unique_id)); + context.emplace("machine", stringize(LL::hexdump(unique_id, sizeof(unique_id)))); + context.emplace("grid", LLGridManager::instance().getGrid()); + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + context.emplace("regionid", stringize(region->getRegionID())); + } + LLParcel* parcel = LLViewerParcelMgr::instance().getAgentParcel(); + if (parcel) + { + context.emplace("parcel", parcel->getName()); + context.emplace("parcelid", parcel->getLocalID()); + } +} + std::string getProfileStatsFilename() { std::ostringstream basebuff; -- cgit v1.2.3 From d6e10ba4b0e08c29b16ea62e0f8b7d1835418903 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 25 Mar 2024 15:50:47 +0200 Subject: viewer#1016 Incorrect behavior of Physics Shapes rendering --- indra/newview/llphysicsshapebuilderutil.cpp | 385 +++++++++++++++------------- indra/newview/llphysicsshapebuilderutil.h | 2 + 2 files changed, 211 insertions(+), 176 deletions(-) diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 37534feadc..a79cc984c1 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llphysicsshapebuilder.cpp * @brief Generic system to convert LL(Physics)VolumeParams to physics shapes * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -28,194 +28,227 @@ #include "llphysicsshapebuilderutil.h" -/* static */ -void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) -{ - const LLProfileParams& profile_params = volume_params.getProfileParams(); - const LLPathParams& path_params = volume_params.getPathParams(); - - specOut.mScale = scale; - - const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f; +#include "llmeshrepository.h" - // count the scale elements that are small - S32 min_size_counts = 0; - for (S32 i = 0; i < 3; ++i) +bool LLPhysicsVolumeParams::hasDecomposition() const + { + if (!isMeshSculpt()) { - if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) - { - ++min_size_counts; - } + return false; } - const bool profile_complete = ( profile_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && - ( profile_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); - - const bool path_complete = ( path_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && - ( path_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); - - const bool simple_params = ( volume_params.getHollow() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW/avgScale ) - && ( fabs(path_params.getShearX()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) - && ( fabs(path_params.getShearY()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) - && ( !volume_params.isMeshSculpt() && !volume_params.isSculpt() ); - - if (simple_params && profile_complete) + LLUUID mesh_id = getSculptID(); + if (mesh_id.isNull()) { - // Try to create an implicit shape or convexified - bool no_taper = ( fabs(path_params.getScaleX() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) - && ( fabs(path_params.getScaleY() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ); - - bool no_twist = ( fabs(path_params.getTwistBegin()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale ) - && ( fabs(path_params.getTwistEnd()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale); - - // Box - if( - ( profile_params.getCurveType() == LL_PCODE_PROFILE_SQUARE ) - && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) - && no_taper - && no_twist - ) - { - specOut.mType = PhysicsShapeSpecification::BOX; - if ( path_complete ) - { - return; - } - else - { - // Side lengths - specOut.mScale[VX] = llmax( scale[VX], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); - specOut.mScale[VY] = llmax( scale[VY], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); - specOut.mScale[VZ] = llmax( scale[VZ] * (path_params.getEnd() - path_params.getBegin()), SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + return false; + } - specOut.mCenter.set( 0.f, 0.f, 0.5f * scale[VZ] * ( path_params.getEnd() + path_params.getBegin() - 1.0f ) ); - return; - } - } + LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id); - // Sphere - if( path_complete - && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF ) - && ( path_params.getCurveType() == LL_PCODE_PATH_CIRCLE ) - && ( fabs(volume_params.getTaper()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) - && no_twist - ) - { - if ( ( scale[VX] == scale[VZ] ) - && ( scale[VY] == scale[VZ] ) ) - { - // perfect sphere - specOut.mType = PhysicsShapeSpecification::SPHERE; - specOut.mScale = scale; - return; - } - else if (min_size_counts > 1) - { - // small or narrow sphere -- we can boxify - for (S32 i=0; i<3; ++i) - { - if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) - { - // reduce each small dimension size to split the approximation errors - specOut.mScale[i] *= 0.75f; - } - } - specOut.mType = PhysicsShapeSpecification::BOX; - return; - } - } + return decomp != NULL; +} - // Cylinder - if( (scale[VX] == scale[VY]) - && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE ) - && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) - && ( volume_params.getBeginS() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) - && ( volume_params.getEndS() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ) - && no_taper +/* static */ +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) +{ + const LLProfileParams& profile_params = volume_params.getProfileParams(); + const LLPathParams& path_params = volume_params.getPathParams(); + + specOut.mScale = scale; + + const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f; + + // count the scale elements that are small + S32 min_size_counts = 0; + for (S32 i = 0; i < 3; ++i) + { + if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + ++min_size_counts; + } + } + + const bool profile_complete = ( profile_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( profile_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool path_complete = ( path_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( path_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool simple_params = ( volume_params.getHollow() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW/avgScale ) + && ( fabs(path_params.getShearX()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( fabs(path_params.getShearY()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( !volume_params.isMeshSculpt() && !volume_params.isSculpt() ); + + if (simple_params && profile_complete) + { + // Try to create an implicit shape or convexified + bool no_taper = ( fabs(path_params.getScaleX() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && ( fabs(path_params.getScaleY() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ); + + bool no_twist = ( fabs(path_params.getTwistBegin()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale ) + && ( fabs(path_params.getTwistEnd()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale); + + // Box + if( + ( profile_params.getCurveType() == LL_PCODE_PROFILE_SQUARE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && no_taper + && no_twist + ) + { + specOut.mType = PhysicsShapeSpecification::BOX; + if ( path_complete ) + { + return; + } + else + { + // Side lengths + specOut.mScale[VX] = llmax( scale[VX], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VY] = llmax( scale[VY], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VZ] = llmax( scale[VZ] * (path_params.getEnd() - path_params.getBegin()), SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + + specOut.mCenter.set( 0.f, 0.f, 0.5f * scale[VZ] * ( path_params.getEnd() + path_params.getBegin() - 1.0f ) ); + return; + } + } + + // Sphere + if( path_complete + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF ) + && ( path_params.getCurveType() == LL_PCODE_PATH_CIRCLE ) + && ( fabs(volume_params.getTaper()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && no_twist + ) + { + if ( ( scale[VX] == scale[VZ] ) + && ( scale[VY] == scale[VZ] ) ) + { + // perfect sphere + specOut.mType = PhysicsShapeSpecification::SPHERE; + specOut.mScale = scale; + return; + } + else if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + specOut.mType = PhysicsShapeSpecification::BOX; + return; + } + } + + // Cylinder + if( (scale[VX] == scale[VY]) + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && ( volume_params.getBeginS() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) + && ( volume_params.getEndS() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ) + && no_taper + ) + { + if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + + specOut.mType = PhysicsShapeSpecification::BOX; + } + else + { + specOut.mType = PhysicsShapeSpecification::CYLINDER; + F32 length = (volume_params.getPathParams().getEnd() - volume_params.getPathParams().getBegin()) * scale[VZ]; + + specOut.mScale[VY] = specOut.mScale[VX]; + specOut.mScale[VZ] = length; + // The minus one below fixes the fact that begin and end range from 0 to 1 not -1 to 1. + specOut.mCenter.set( 0.f, 0.f, 0.5f * (volume_params.getPathParams().getBegin() + volume_params.getPathParams().getEnd() - 1.f) * scale[VZ] ); + } + + return; + } + } + + if ( (min_size_counts == 3 ) + // Possible dead code here--who wants to take it out? + || (path_complete + && profile_complete + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && (min_size_counts > 1 ) ) + ) + { + // it isn't simple but + // we might be able to convexify this shape if the path and profile are complete + // or the path is linear and both path and profile are complete --> we can boxify it + specOut.mType = PhysicsShapeSpecification::BOX; + specOut.mScale = scale; + return; + } + + // Special case for big, very thin objects - bump the small dimensions up to the COLLISION_TOLERANCE + if (min_size_counts == 1 // One dimension is small + && avgScale > 3.f) // ... but others are fairly large + { + for (S32 i = 0; i < 3; ++i) + { + specOut.mScale[i] = llmax( specOut.mScale[i], COLLISION_TOLERANCE ); + } + } + + if ( volume_params.shouldForceConvex() ) + { + // Server distinguishes between convex of a prim vs isSculpt, but we don't care. + specOut.mType = PhysicsShapeSpecification::USER_CONVEX; + } + // Make a simpler convex shape if we can. + else if (volume_params.isConvex() // is convex + || min_size_counts > 1 ) // two or more small dimensions + { + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } + else if (volume_params.isMeshSculpt()) + { + // Check overall dimensions, not individual triangles. + if (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + || scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + || scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE ) { - if (min_size_counts > 1) + if (volume_params.hasDecomposition()) { - // small or narrow sphere -- we can boxify - for (S32 i=0; i<3; ++i) - { - if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) - { - // reduce each small dimension size to split the approximation errors - specOut.mScale[i] *= 0.75f; - } - } - - specOut.mType = PhysicsShapeSpecification::BOX; + specOut.mType = PhysicsShapeSpecification::USER_MESH; } else { - specOut.mType = PhysicsShapeSpecification::CYLINDER; - F32 length = (volume_params.getPathParams().getEnd() - volume_params.getPathParams().getBegin()) * scale[VZ]; - - specOut.mScale[VY] = specOut.mScale[VX]; - specOut.mScale[VZ] = length; - // The minus one below fixes the fact that begin and end range from 0 to 1 not -1 to 1. - specOut.mCenter.set( 0.f, 0.f, 0.5f * (volume_params.getPathParams().getBegin() + volume_params.getPathParams().getEnd() - 1.f) * scale[VZ] ); + // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } - - return; } - } - - if ( (min_size_counts == 3 ) - // Possible dead code here--who wants to take it out? - || (path_complete - && profile_complete - && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) - && (min_size_counts > 1 ) ) - ) - { - // it isn't simple but - // we might be able to convexify this shape if the path and profile are complete - // or the path is linear and both path and profile are complete --> we can boxify it - specOut.mType = PhysicsShapeSpecification::BOX; - specOut.mScale = scale; - return; - } - - // Special case for big, very thin objects - bump the small dimensions up to the COLLISION_TOLERANCE - if (min_size_counts == 1 // One dimension is small - && avgScale > 3.f) // ... but others are fairly large - { - for (S32 i = 0; i < 3; ++i) + else { - specOut.mScale[i] = llmax( specOut.mScale[i], COLLISION_TOLERANCE ); + specOut.mType = PhysicsShapeSpecification::USER_MESH; } } - - if ( volume_params.shouldForceConvex() ) - { - // Server distinguishes between convex of a prim vs isSculpt, but we don't care. - specOut.mType = PhysicsShapeSpecification::USER_CONVEX; - } - // Make a simpler convex shape if we can. - else if (volume_params.isConvex() // is convex - || min_size_counts > 1 ) // two or more small dimensions - { - specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; - } - else if (volume_params.isMeshSculpt() && - // Check overall dimensions, not individual triangles. - (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || - scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || - scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE - ) ) - { - // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. - specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; - } - else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) - { - specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; - } - else // Resort to mesh - { - specOut.mType = PhysicsShapeSpecification::PRIM_MESH; - } + else if ( volume_params.isSculpt() ) + { + specOut.mType = PhysicsShapeSpecification::SCULPT; + } + else // Resort to mesh + { + specOut.mType = PhysicsShapeSpecification::PRIM_MESH; + } } diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index 33c2d0a8b6..01c173523b 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -79,6 +79,8 @@ public: bool shouldForceConvex() const { return mForceConvex; } + bool hasDecomposition() const; + private: bool mForceConvex; }; -- cgit v1.2.3 From 5370a6d323e14d7b4e32a3f41ef78f7744e361c5 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 18 Sep 2024 12:23:14 -0700 Subject: fix whitespace --- indra/newview/llphysicsshapebuilderutil.cpp | 360 ++++++++++++++-------------- 1 file changed, 180 insertions(+), 180 deletions(-) diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index a79cc984c1..eb0df1194e 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llphysicsshapebuilder.cpp * @brief Generic system to convert LL(Physics)VolumeParams to physics shapes * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -51,175 +51,175 @@ bool LLPhysicsVolumeParams::hasDecomposition() const /* static */ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) { - const LLProfileParams& profile_params = volume_params.getProfileParams(); - const LLPathParams& path_params = volume_params.getPathParams(); - - specOut.mScale = scale; - - const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f; - - // count the scale elements that are small - S32 min_size_counts = 0; - for (S32 i = 0; i < 3; ++i) - { - if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) - { - ++min_size_counts; - } - } - - const bool profile_complete = ( profile_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && - ( profile_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); - - const bool path_complete = ( path_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && - ( path_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); - - const bool simple_params = ( volume_params.getHollow() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW/avgScale ) - && ( fabs(path_params.getShearX()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) - && ( fabs(path_params.getShearY()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) - && ( !volume_params.isMeshSculpt() && !volume_params.isSculpt() ); - - if (simple_params && profile_complete) - { - // Try to create an implicit shape or convexified - bool no_taper = ( fabs(path_params.getScaleX() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) - && ( fabs(path_params.getScaleY() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ); - - bool no_twist = ( fabs(path_params.getTwistBegin()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale ) - && ( fabs(path_params.getTwistEnd()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale); - - // Box - if( - ( profile_params.getCurveType() == LL_PCODE_PROFILE_SQUARE ) - && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) - && no_taper - && no_twist - ) - { - specOut.mType = PhysicsShapeSpecification::BOX; - if ( path_complete ) - { - return; - } - else - { - // Side lengths - specOut.mScale[VX] = llmax( scale[VX], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); - specOut.mScale[VY] = llmax( scale[VY], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); - specOut.mScale[VZ] = llmax( scale[VZ] * (path_params.getEnd() - path_params.getBegin()), SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); - - specOut.mCenter.set( 0.f, 0.f, 0.5f * scale[VZ] * ( path_params.getEnd() + path_params.getBegin() - 1.0f ) ); - return; - } - } - - // Sphere - if( path_complete - && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF ) - && ( path_params.getCurveType() == LL_PCODE_PATH_CIRCLE ) - && ( fabs(volume_params.getTaper()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) - && no_twist - ) - { - if ( ( scale[VX] == scale[VZ] ) - && ( scale[VY] == scale[VZ] ) ) - { - // perfect sphere - specOut.mType = PhysicsShapeSpecification::SPHERE; - specOut.mScale = scale; - return; - } - else if (min_size_counts > 1) - { - // small or narrow sphere -- we can boxify - for (S32 i=0; i<3; ++i) - { - if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) - { - // reduce each small dimension size to split the approximation errors - specOut.mScale[i] *= 0.75f; - } - } - specOut.mType = PhysicsShapeSpecification::BOX; - return; - } - } - - // Cylinder - if( (scale[VX] == scale[VY]) - && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE ) - && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) - && ( volume_params.getBeginS() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) - && ( volume_params.getEndS() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ) - && no_taper - ) - { - if (min_size_counts > 1) - { - // small or narrow sphere -- we can boxify - for (S32 i=0; i<3; ++i) - { - if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) - { - // reduce each small dimension size to split the approximation errors - specOut.mScale[i] *= 0.75f; - } - } - - specOut.mType = PhysicsShapeSpecification::BOX; - } - else - { - specOut.mType = PhysicsShapeSpecification::CYLINDER; - F32 length = (volume_params.getPathParams().getEnd() - volume_params.getPathParams().getBegin()) * scale[VZ]; - - specOut.mScale[VY] = specOut.mScale[VX]; - specOut.mScale[VZ] = length; - // The minus one below fixes the fact that begin and end range from 0 to 1 not -1 to 1. - specOut.mCenter.set( 0.f, 0.f, 0.5f * (volume_params.getPathParams().getBegin() + volume_params.getPathParams().getEnd() - 1.f) * scale[VZ] ); - } - - return; - } - } - - if ( (min_size_counts == 3 ) - // Possible dead code here--who wants to take it out? - || (path_complete - && profile_complete - && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) - && (min_size_counts > 1 ) ) - ) - { - // it isn't simple but - // we might be able to convexify this shape if the path and profile are complete - // or the path is linear and both path and profile are complete --> we can boxify it - specOut.mType = PhysicsShapeSpecification::BOX; - specOut.mScale = scale; - return; - } - - // Special case for big, very thin objects - bump the small dimensions up to the COLLISION_TOLERANCE - if (min_size_counts == 1 // One dimension is small - && avgScale > 3.f) // ... but others are fairly large - { - for (S32 i = 0; i < 3; ++i) - { - specOut.mScale[i] = llmax( specOut.mScale[i], COLLISION_TOLERANCE ); - } - } - - if ( volume_params.shouldForceConvex() ) - { + const LLProfileParams& profile_params = volume_params.getProfileParams(); + const LLPathParams& path_params = volume_params.getPathParams(); + + specOut.mScale = scale; + + const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f; + + // count the scale elements that are small + S32 min_size_counts = 0; + for (S32 i = 0; i < 3; ++i) + { + if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + ++min_size_counts; + } + } + + const bool profile_complete = ( profile_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( profile_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool path_complete = ( path_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( path_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool simple_params = ( volume_params.getHollow() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW/avgScale ) + && ( fabs(path_params.getShearX()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( fabs(path_params.getShearY()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( !volume_params.isMeshSculpt() && !volume_params.isSculpt() ); + + if (simple_params && profile_complete) + { + // Try to create an implicit shape or convexified + bool no_taper = ( fabs(path_params.getScaleX() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && ( fabs(path_params.getScaleY() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ); + + bool no_twist = ( fabs(path_params.getTwistBegin()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale ) + && ( fabs(path_params.getTwistEnd()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale); + + // Box + if( + ( profile_params.getCurveType() == LL_PCODE_PROFILE_SQUARE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && no_taper + && no_twist + ) + { + specOut.mType = PhysicsShapeSpecification::BOX; + if ( path_complete ) + { + return; + } + else + { + // Side lengths + specOut.mScale[VX] = llmax( scale[VX], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VY] = llmax( scale[VY], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VZ] = llmax( scale[VZ] * (path_params.getEnd() - path_params.getBegin()), SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + + specOut.mCenter.set( 0.f, 0.f, 0.5f * scale[VZ] * ( path_params.getEnd() + path_params.getBegin() - 1.0f ) ); + return; + } + } + + // Sphere + if( path_complete + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF ) + && ( path_params.getCurveType() == LL_PCODE_PATH_CIRCLE ) + && ( fabs(volume_params.getTaper()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && no_twist + ) + { + if ( ( scale[VX] == scale[VZ] ) + && ( scale[VY] == scale[VZ] ) ) + { + // perfect sphere + specOut.mType = PhysicsShapeSpecification::SPHERE; + specOut.mScale = scale; + return; + } + else if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + specOut.mType = PhysicsShapeSpecification::BOX; + return; + } + } + + // Cylinder + if( (scale[VX] == scale[VY]) + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && ( volume_params.getBeginS() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) + && ( volume_params.getEndS() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ) + && no_taper + ) + { + if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + + specOut.mType = PhysicsShapeSpecification::BOX; + } + else + { + specOut.mType = PhysicsShapeSpecification::CYLINDER; + F32 length = (volume_params.getPathParams().getEnd() - volume_params.getPathParams().getBegin()) * scale[VZ]; + + specOut.mScale[VY] = specOut.mScale[VX]; + specOut.mScale[VZ] = length; + // The minus one below fixes the fact that begin and end range from 0 to 1 not -1 to 1. + specOut.mCenter.set( 0.f, 0.f, 0.5f * (volume_params.getPathParams().getBegin() + volume_params.getPathParams().getEnd() - 1.f) * scale[VZ] ); + } + + return; + } + } + + if ( (min_size_counts == 3 ) + // Possible dead code here--who wants to take it out? + || (path_complete + && profile_complete + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && (min_size_counts > 1 ) ) + ) + { + // it isn't simple but + // we might be able to convexify this shape if the path and profile are complete + // or the path is linear and both path and profile are complete --> we can boxify it + specOut.mType = PhysicsShapeSpecification::BOX; + specOut.mScale = scale; + return; + } + + // Special case for big, very thin objects - bump the small dimensions up to the COLLISION_TOLERANCE + if (min_size_counts == 1 // One dimension is small + && avgScale > 3.f) // ... but others are fairly large + { + for (S32 i = 0; i < 3; ++i) + { + specOut.mScale[i] = llmax( specOut.mScale[i], COLLISION_TOLERANCE ); + } + } + + if ( volume_params.shouldForceConvex() ) + { // Server distinguishes between convex of a prim vs isSculpt, but we don't care. - specOut.mType = PhysicsShapeSpecification::USER_CONVEX; - } - // Make a simpler convex shape if we can. - else if (volume_params.isConvex() // is convex - || min_size_counts > 1 ) // two or more small dimensions - { - specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; - } + specOut.mType = PhysicsShapeSpecification::USER_CONVEX; + } + // Make a simpler convex shape if we can. + else if (volume_params.isConvex() // is convex + || min_size_counts > 1 ) // two or more small dimensions + { + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } else if (volume_params.isMeshSculpt()) { // Check overall dimensions, not individual triangles. @@ -243,12 +243,12 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara specOut.mType = PhysicsShapeSpecification::USER_MESH; } } - else if ( volume_params.isSculpt() ) - { + else if ( volume_params.isSculpt() ) + { specOut.mType = PhysicsShapeSpecification::SCULPT; - } - else // Resort to mesh - { - specOut.mType = PhysicsShapeSpecification::PRIM_MESH; - } + } + else // Resort to mesh + { + specOut.mType = PhysicsShapeSpecification::PRIM_MESH; + } } -- cgit v1.2.3 From 9890b5b2e7f24a8ad52456d80ddfec0e4e505d96 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 18 Sep 2024 12:26:11 -0700 Subject: added .git-blame-ignore for last commit --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 0851d20be0..e06ef89a99 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,3 +9,5 @@ a0b3021bdcf76859054fda8e30abb3ed47749e83 1b67dd855c41f5a0cda7ec2a68d98071986ca703 6cc7dd09d5e69cf57e6de7fb568a0ad2693f9c9a e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 +# multiple problems +5370a6d323e14d7b4e32a3f41ef78f7744e361c5 -- cgit v1.2.3 From 52091a6097cd4e68f3fc1b0972080867ceb09122 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Wed, 18 Sep 2024 13:01:43 -0700 Subject: Mute other / set volume level for other is not working. As part of the boost::json conversion, the json that mutes and sets peer gain was not being formed correctly. Also, tweaked the peer gain default. --- indra/newview/llvoicewebrtc.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 3d684e5a1b..aabf897050 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -87,6 +87,8 @@ namespace { const F32 SPEAKING_AUDIO_LEVEL = 0.30; + const uint32_t PEER_GAIN_CONVERSION_FACTOR = 220; + static const std::string REPORTED_VOICE_SERVER_TYPE = "Secondlife WebRTC Gateway"; // Don't send positional updates more frequently than this: @@ -2443,7 +2445,7 @@ void LLVoiceWebRTCConnection::setSpeakerVolume(F32 volume) void LLVoiceWebRTCConnection::setUserVolume(const LLUUID& id, F32 volume) { - boost::json::object root = {{"ug", {id.asString(), (uint32_t) (volume * 200)}}}; + boost::json::object root = { { "ug", { { id.asString(), (uint32_t)(volume * PEER_GAIN_CONVERSION_FACTOR) } } } }; std::string json_data = boost::json::serialize(root); if (mWebRTCDataInterface) { @@ -2453,7 +2455,7 @@ void LLVoiceWebRTCConnection::setUserVolume(const LLUUID& id, F32 volume) void LLVoiceWebRTCConnection::setUserMute(const LLUUID& id, bool mute) { - boost::json::object root = {{"m", {id.asString(), mute}}}; + boost::json::object root = { { "m", { { id.asString(), mute } } } }; std::string json_data = boost::json::serialize(root); if (mWebRTCDataInterface) { -- cgit v1.2.3 From b31fd167c00a288656ea82d239a9ce379f382c22 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Sep 2024 15:23:20 -0500 Subject: Fix for particles not loading textures (#2598) Also fix assert while prepping GLTF assets --- indra/newview/gltfscenemanager.cpp | 59 ++++++++++++++++++++------------------ indra/newview/llface.cpp | 8 ++++++ 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index ce54fa4c12..ed66753267 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -371,43 +371,46 @@ void GLTFSceneManager::addGLTFObject(LLViewerObject* obj, LLUUID gltf_id) //static void GLTFSceneManager::onGLTFBinLoadComplete(const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) { - LLViewerObject* obj = (LLViewerObject*)user_data; - llassert(asset_type == LLAssetType::AT_GLTF_BIN); - - if (status == LL_ERR_NOERR) - { - if (obj) + LLAppViewer::instance()->postToMainCoro([=]() { - // find the Buffer with the given id in the asset - if (obj->mGLTFAsset) - { - obj->mGLTFAsset->mPendingBuffers--; - + LLViewerObject* obj = (LLViewerObject*)user_data; + llassert(asset_type == LLAssetType::AT_GLTF_BIN); - if (obj->mGLTFAsset->mPendingBuffers == 0) + if (status == LL_ERR_NOERR) + { + if (obj) { - if (obj->mGLTFAsset->prep()) + // find the Buffer with the given id in the asset + if (obj->mGLTFAsset) { - GLTFSceneManager& mgr = GLTFSceneManager::instance(); - if (std::find(mgr.mObjects.begin(), mgr.mObjects.end(), obj) == mgr.mObjects.end()) + obj->mGLTFAsset->mPendingBuffers--; + + + if (obj->mGLTFAsset->mPendingBuffers == 0) { - GLTFSceneManager::instance().mObjects.push_back(obj); + if (obj->mGLTFAsset->prep()) + { + GLTFSceneManager& mgr = GLTFSceneManager::instance(); + if (std::find(mgr.mObjects.begin(), mgr.mObjects.end(), obj) == mgr.mObjects.end()) + { + GLTFSceneManager::instance().mObjects.push_back(obj); + } + } + else + { + LL_WARNS("GLTF") << "Failed to prepare GLTF asset: " << id << LL_ENDL; + obj->mGLTFAsset = nullptr; + } } } - else - { - LL_WARNS("GLTF") << "Failed to prepare GLTF asset: " << id << LL_ENDL; - obj->mGLTFAsset = nullptr; - } } } - } - } - else - { - LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << LL_ENDL; - obj->unref(); - } + else + { + LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << LL_ENDL; + obj->unref(); + } + }); } //static diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index ce68474211..297661effd 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -2268,6 +2268,14 @@ bool LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) center.mul(0.5f); size.setSub(mRiggedExtents[1], mRiggedExtents[0]); } + else if (mDrawablep && mVObjp.notNull() && mVObjp->getPartitionType() == LLViewerRegion::PARTITION_PARTICLE && mDrawablep->getSpatialGroup()) + { // use box of spatial group for particles (over approximates size, but we don't actually have a good size per particle) + LLSpatialGroup* group = mDrawablep->getSpatialGroup(); + const LLVector4a* extents = group->getExtents(); + size.setSub(extents[1], extents[0]); + center.setAdd(extents[1], extents[0]); + center.mul(0.5f); + } else { center.load3(getPositionAgent().mV); -- cgit v1.2.3 From e829828dcd9b989a9efb32f7c69cd8652e9857ec Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 3 Apr 2024 12:31:43 -0400 Subject: Introduce fsyspath subclass of std::filesystem::path. Our std::strings are UTF-8 encoded, so conversion from std::string to std::filesystem::path must use UTF-8 decoding. The native Windows std::filesystem::path constructor and assignment operator accepting std::string use "native narrow encoding," which mangles path strings containing UTF-8 encoded non-ASCII characters. fsyspath's std::string constructor and assignment operator explicitly engage std::filesystem::u8path() to handle encoding. u8path() is deprecated in C++20, but once we adapt fsyspath's conversion to C++20 conventions, consuming code need not be modified. (cherry picked from commit e399b02e3306a249cb161f07cac578d3f2617bab) --- indra/llcommon/CMakeLists.txt | 1 + indra/llcommon/fsyspath.h | 74 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 indra/llcommon/fsyspath.h diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 60549d9d11..a504e71340 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -119,6 +119,7 @@ set(llcommon_HEADER_FILES commoncontrol.h ctype_workaround.h fix_macros.h + fsyspath.h function_types.h indra_constants.h lazyeventapi.h diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h new file mode 100644 index 0000000000..aa4e0132bc --- /dev/null +++ b/indra/llcommon/fsyspath.h @@ -0,0 +1,74 @@ +/** + * @file fsyspath.h + * @author Nat Goodspeed + * @date 2024-04-03 + * @brief Adapt our UTF-8 std::strings for std::filesystem::path + * + * $LicenseInfo:firstyear=2024&license=viewerlgpl$ + * Copyright (c) 2024, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_FSYSPATH_H) +#define LL_FSYSPATH_H + +#include + +// While std::filesystem::path can be directly constructed from std::string on +// both Posix and Windows, that's not what we want on Windows. Per +// https://en.cppreference.com/w/cpp/filesystem/path/path: + +// ... the method of conversion to the native character set depends on the +// character type used by source. +// +// * If the source character type is char, the encoding of the source is +// assumed to be the native narrow encoding (so no conversion takes place on +// POSIX systems). +// * If the source character type is char8_t, conversion from UTF-8 to native +// filesystem encoding is used. (since C++20) +// * If the source character type is wchar_t, the input is assumed to be the +// native wide encoding (so no conversion takes places on Windows). + +// The trouble is that on Windows, from std::string ("source character type is +// char"), the "native narrow encoding" isn't UTF-8, so file paths containing +// non-ASCII characters get mangled. +// +// Once we're building with C++20, we could pass a UTF-8 std::string through a +// vector to engage std::filesystem::path's own UTF-8 conversion. But +// sigh, as of 2024-04-03 we're not yet there. +// +// Anyway, encapsulating the important UTF-8 conversions in our own subclass +// allows us to migrate forward to C++20 conventions without changing +// referencing code. + +class fsyspath: public std::filesystem::path +{ + using super = std::filesystem::path; + +public: + // default + fsyspath() {} + // construct from UTF-8 encoded std::string + fsyspath(const std::string& path): super(std::filesystem::u8path(path)) {} + // construct from UTF-8 encoded const char* + fsyspath(const char* path): super(std::filesystem::u8path(path)) {} + // construct from existing path + fsyspath(const super& path): super(path) {} + + fsyspath& operator=(const super& p) { super::operator=(p); return *this; } + fsyspath& operator=(const std::string& p) + { + super::operator=(std::filesystem::u8path(p)); + return *this; + } + fsyspath& operator=(const char* p) + { + super::operator=(std::filesystem::u8path(p)); + return *this; + } + + // shadow base-class string() method with UTF-8 aware method + std::string string() const { return super::u8string(); } +}; + +#endif /* ! defined(LL_FSYSPATH_H) */ -- cgit v1.2.3 From 837a6e04d85e4f3f301e62aea3329ea61e926566 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 28 Jun 2024 07:54:46 -0400 Subject: Give our fsyspath an operator std::string() conversion method. This is redundant (but harmless) on a Posix system, but it fills a missing puzzle piece on Windows. The point of fsyspath is to be able to interchange freely between fsyspath and std::string. Existing fsyspath could be constructed and assigned from std::string, and we could explicitly call its string() method to get a std::string, but an implicit fsyspath-to-string conversion that worked on Posix would trip us up on Windows. Fix that. (cherry picked from commit fbeff6d8052d4b614a0a2c8ebaf35b45379ab578) --- indra/llcommon/fsyspath.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h index aa4e0132bc..3c749d84de 100644 --- a/indra/llcommon/fsyspath.h +++ b/indra/llcommon/fsyspath.h @@ -69,6 +69,11 @@ public: // shadow base-class string() method with UTF-8 aware method std::string string() const { return super::u8string(); } + // On Posix systems, where value_type is already char, this operator + // std::string() method shadows the base class operator string_type() + // method. But on Windows, where value_type is wchar_t, the base class + // doesn't have operator std::string(). Provide it. + operator std::string() const { return string(); } }; #endif /* ! defined(LL_FSYSPATH_H) */ -- cgit v1.2.3 From 725e1b7d6f8ca31705372f9b391a34969f44577b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 18 Sep 2024 16:56:10 -0400 Subject: Ditch trailing space. --- indra/llcommon/fsyspath.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h index 3c749d84de..5fa4c8ad1b 100644 --- a/indra/llcommon/fsyspath.h +++ b/indra/llcommon/fsyspath.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2024-04-03 * @brief Adapt our UTF-8 std::strings for std::filesystem::path - * + * * $LicenseInfo:firstyear=2024&license=viewerlgpl$ * Copyright (c) 2024, Linden Research, Inc. * $/LicenseInfo$ -- cgit v1.2.3 From 705ec153c5ee3f6d1781647c1bbbfcd7c398c987 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 13 Sep 2024 16:32:04 -0400 Subject: Add script to compare a Frame Profile JSON stats file vs. baseline. Extract `latest_file()` logic replicated in profile_pretty.py and profile_csv.py out to logsdir.py, and use for new profile_cmp.py. (cherry picked from commit 439cfc97a81f221daaf8ba13aa5daa87e8511047) --- scripts/perf/logsdir.py | 46 ++++++++++++++++++ scripts/perf/profile_cmp.py | 104 +++++++++++++++++++++++++++++++++++++++++ scripts/perf/profile_csv.py | 24 +++------- scripts/perf/profile_pretty.py | 22 ++------- 4 files changed, 160 insertions(+), 36 deletions(-) create mode 100644 scripts/perf/logsdir.py create mode 100644 scripts/perf/profile_cmp.py diff --git a/scripts/perf/logsdir.py b/scripts/perf/logsdir.py new file mode 100644 index 0000000000..c8b498cf78 --- /dev/null +++ b/scripts/perf/logsdir.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +"""\ +@file logsdir.py +@author Nat Goodspeed +@date 2024-09-12 +@brief Locate the Second Life logs directory for the current user on the + current platform. + +$LicenseInfo:firstyear=2024&license=viewerlgpl$ +Copyright (c) 2024, Linden Research, Inc. +$/LicenseInfo$ +""" + +import os +from pathlib import Path +import platform + +class Error(Exception): + pass + +# logic used by SLVersionChecker +def logsdir(): + app = 'SecondLife' + system = platform.system() + if (system == 'Darwin'): + base_dir = os.path.join(os.path.expanduser('~'), + 'Library','Application Support',app) + elif (system == 'Linux'): + base_dir = os.path.join(os.path.expanduser('~'), + '.' + app.lower()) + elif (system == 'Windows'): + appdata = os.getenv('APPDATA') + base_dir = os.path.join(appdata, app) + else: + raise ValueError("Unsupported platform '%s'" % system) + + return os.path.join(base_dir, 'logs') + +def latest_file(dirpath, pattern): + files = Path(dirpath).glob(pattern) + sort = [(p.stat().st_mtime, p) for p in files if p.is_file()] + sort.sort(reverse=True) + try: + return sort[0][1] + except IndexError: + raise Error(f'No {pattern} files in {dirpath}') diff --git a/scripts/perf/profile_cmp.py b/scripts/perf/profile_cmp.py new file mode 100644 index 0000000000..9dbfa3145b --- /dev/null +++ b/scripts/perf/profile_cmp.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +"""\ +@file profile_cmp.py +@author Nat Goodspeed +@date 2024-09-13 +@brief Compare a frame profile stats file with a similar baseline file. + +$LicenseInfo:firstyear=2024&license=viewerlgpl$ +Copyright (c) 2024, Linden Research, Inc. +$/LicenseInfo$ +""" + +from datetime import datetime +import json +from logsdir import Error, latest_file, logsdir +from pathlib import Path +import sys + +# variance that's ignorable +DEFAULT_EPSILON = 0.03 # 3% + +def compare(baseline, test, epsilon=DEFAULT_EPSILON): + if Path(baseline).samefile(test): + print(f'{baseline} same as\n{test}\nAnalysis moot.') + return + + with open(baseline) as inf: + bdata = json.load(inf) + with open(test) as inf: + tdata = json.load(inf) + print(f'baseline {baseline}\ntestfile {test}') + + for k, tv in tdata['context'].items(): + bv = bdata['context'].get(k) + if bv != tv: + print(f'baseline {k}={bv} vs.\ntestfile {k}={tv}') + + btime = bdata['context'].get('time') + ttime = tdata['context'].get('time') + if btime and ttime: + print('testfile newer by', + datetime.fromisoformat(ttime) - datetime.fromisoformat(btime)) + + # The following ignores totals and unused shaders, except to the extent + # that some shaders were used in the baseline but not in the recent test + # or vice-versa. While the viewer considers that a shader has been used if + # 'binds' is nonzero, we exclude any whose 'time' is zero to avoid zero + # division. + bshaders = {s['name']: s for s in bdata['shaders'] if s['time'] and s['samples']} + tshaders = {s['name']: s for s in tdata['shaders'] if s['time']} + + bothshaders = set(bshaders).intersection(tshaders) + deltas = [] + for shader in bothshaders: + bshader = bshaders[shader] + tshader = tshaders[shader] + bthruput = bshader['samples']/bshader['time'] + tthruput = tshader['samples']/tshader['time'] + delta = (tthruput - bthruput)/bthruput + if abs(delta) > epsilon: + deltas.append((delta, shader, bthruput, tthruput)) + + # descending order of performance gain + deltas.sort(reverse=True) + print(f'{len(deltas)} shaders showed nontrivial performance differences ' + '(millon samples/sec):') + namelen = max(len(s[1]) for s in deltas) if deltas else 0 + for delta, shader, bthruput, tthruput in deltas: + print(f' {shader.rjust(namelen)} {delta*100:6.1f}% ' + f'{bthruput/1000000:8.2f} -> {tthruput/1000000:8.2f}') + + tunused = set(bshaders).difference(tshaders) + print(f'{len(tunused)} baseline shaders not used in test:') + for s in tunused: + print(f' {s}') + bunused = set(tshaders).difference(bshaders) + print(f'{len(bunused)} shaders newly used in test:') + for s in bunused: + print(f' {s}') + +def main(*raw_args): + from argparse import ArgumentParser + parser = ArgumentParser(description=""" +%(prog)s compares a baseline JSON file from Develop -> Render Tests -> Frame +Profile to another such file from a more recent test. It identifies shaders +that have gained and lost in throughput. +""") + parser.add_argument('-e', '--epsilon', type=float, default=int(DEFAULT_EPSILON*100), + help="""percent variance considered ignorable (default %(default)s%%)""") + parser.add_argument('baseline', + help="""baseline profile filename to compare against""") + parser.add_argument('test', nargs='?', + help="""test profile filename to compare + (default is most recent)""") + args = parser.parse_args(raw_args) + compare(args.baseline, + args.test or latest_file(logsdir(), 'profile.*.json'), + epsilon=(args.epsilon / 100.)) + +if __name__ == "__main__": + try: + sys.exit(main(*sys.argv[1:])) + except (Error, OSError, json.JSONDecodeError) as err: + sys.exit(str(err)) diff --git a/scripts/perf/profile_csv.py b/scripts/perf/profile_csv.py index 273e3b7434..7a6b2b338e 100644 --- a/scripts/perf/profile_csv.py +++ b/scripts/perf/profile_csv.py @@ -10,17 +10,16 @@ Copyright (c) 2024, Linden Research, Inc. $/LicenseInfo$ """ -import logsdir import json -from pathlib import Path +from logsdir import Error, latest_file, logsdir import sys -class Error(Exception): - pass - def convert(path, totals=True, unused=True, file=sys.stdout): with open(path) as inf: data = json.load(inf) + # print path to sys.stderr in case user is redirecting stdout + print(path, file=sys.stderr) + print('"name", "file1", "file2", "time", "binds", "samples", "triangles"', file=file) if totals: @@ -51,19 +50,8 @@ shaders list to full shaders lines. help="""profile filename to convert (default is most recent)""") args = parser.parse_args(raw_args) - if not args.path: - logs = logsdir.logsdir() - profiles = Path(logs).glob('profile.*.json') - sort = [(p.stat().st_mtime, p) for p in profiles] - sort.sort(reverse=True) - try: - args.path = sort[0][1] - except IndexError: - raise Error(f'No profile.*.json files in {logs}') - # print path to sys.stderr in case user is redirecting stdout - print(args.path, file=sys.stderr) - - convert(args.path, totals=args.totals, unused=args.unused) + convert(args.path or latest_file(logsdir(), 'profile.*.json'), + totals=args.totals, unused=args.unused) if __name__ == "__main__": try: diff --git a/scripts/perf/profile_pretty.py b/scripts/perf/profile_pretty.py index 15b6efd94d..405b14b373 100644 --- a/scripts/perf/profile_pretty.py +++ b/scripts/perf/profile_pretty.py @@ -10,17 +10,15 @@ Copyright (c) 2024, Linden Research, Inc. $/LicenseInfo$ """ -import logsdir import json -from pathlib import Path +from logsdir import Error, latest_file, logsdir import sys -class Error(Exception): - pass - def pretty(path): with open(path) as inf: data = json.load(inf) + # print path to sys.stderr in case user is redirecting stdout + print(path, file=sys.stderr) json.dump(data, sys.stdout, indent=4) def main(*raw_args): @@ -33,19 +31,7 @@ The file produced by the viewer is a single dense line of JSON. help="""profile filename to pretty-print (default is most recent)""") args = parser.parse_args(raw_args) - if not args.path: - logs = logsdir.logsdir() - profiles = Path(logs).glob('profile.*.json') - sort = [(p.stat().st_mtime, p) for p in profiles] - sort.sort(reverse=True) - try: - args.path = sort[0][1] - except IndexError: - raise Error(f'No profile.*.json files in {logs}') - # print path to sys.stderr in case user is redirecting stdout - print(args.path, file=sys.stderr) - - pretty(args.path) + pretty(args.path or latest_file(logsdir(), 'profile.*.json')) if __name__ == "__main__": try: -- cgit v1.2.3 From 743a1a6d8eabf069d95777c96e5b657cb8702593 Mon Sep 17 00:00:00 2001 From: Roxie Linden Date: Wed, 18 Sep 2024 14:14:26 -0700 Subject: fix trailing whitespace --- indra/newview/llvoicewebrtc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index aabf897050..ad8f6927ed 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -2445,7 +2445,7 @@ void LLVoiceWebRTCConnection::setSpeakerVolume(F32 volume) void LLVoiceWebRTCConnection::setUserVolume(const LLUUID& id, F32 volume) { - boost::json::object root = { { "ug", { { id.asString(), (uint32_t)(volume * PEER_GAIN_CONVERSION_FACTOR) } } } }; + boost::json::object root = { { "ug", { { id.asString(), (uint32_t)(volume * PEER_GAIN_CONVERSION_FACTOR) } } } }; std::string json_data = boost::json::serialize(root); if (mWebRTCDataInterface) { -- cgit v1.2.3 From f0300cf8b3a96464a921b8df6cd690ac104fba46 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 18 Sep 2024 17:17:59 -0400 Subject: Add hexdump.h with iostream manipulators to dump a byte range as hex or to produce readable text from a mix of printing and nonprinting ASCII characters. (cherry picked from commit 01a59bab1a4b7c4645271a21cfaadc3735b6029c) --- indra/llcommon/hexdump.h | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100755 indra/llcommon/hexdump.h diff --git a/indra/llcommon/hexdump.h b/indra/llcommon/hexdump.h new file mode 100755 index 0000000000..234168cd61 --- /dev/null +++ b/indra/llcommon/hexdump.h @@ -0,0 +1,106 @@ +/** + * @file hexdump.h + * @author Nat Goodspeed + * @date 2023-10-03 + * @brief iostream manipulators to stream hex, or string with nonprinting chars + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Copyright (c) 2023, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_HEXDUMP_H) +#define LL_HEXDUMP_H + +#include +#include +#include +#include + +namespace LL +{ + +// Format a given byte string as 2-digit hex values, no separators +// Usage: std::cout << hexdump(somestring) << ... +class hexdump +{ +public: + hexdump(const std::string_view& data): + hexdump(data.data(), data.length()) + {} + + hexdump(const char* data, size_t len): + hexdump(reinterpret_cast(data), len) + {} + + hexdump(const std::vector& data): + hexdump(data.data(), data.size()) + {} + + hexdump(const unsigned char* data, size_t len): + mData(data, data + len) + {} + + friend std::ostream& operator<<(std::ostream& out, const hexdump& self) + { + auto oldfmt{ out.flags() }; + auto oldfill{ out.fill() }; + out.setf(std::ios_base::hex, std::ios_base::basefield); + out.fill('0'); + for (auto c : self.mData) + { + out << std::setw(2) << unsigned(c); + } + out.setf(oldfmt, std::ios_base::basefield); + out.fill(oldfill); + return out; + } + +private: + std::vector mData; +}; + +// Format a given byte string as a mix of printable characters and, for each +// non-printable character, "\xnn" +// Usage: std::cout << hexmix(somestring) << ... +class hexmix +{ +public: + hexmix(const std::string_view& data): + mData(data) + {} + + hexmix(const char* data, size_t len): + mData(data, len) + {} + + friend std::ostream& operator<<(std::ostream& out, const hexmix& self) + { + auto oldfmt{ out.flags() }; + auto oldfill{ out.fill() }; + out.setf(std::ios_base::hex, std::ios_base::basefield); + out.fill('0'); + for (auto c : self.mData) + { + // std::isprint() must be passed an unsigned char! + if (std::isprint(static_cast(c))) + { + out << c; + } + else + { + out << "\\x" << std::setw(2) << unsigned(c); + } + } + out.setf(oldfmt, std::ios_base::basefield); + out.fill(oldfill); + return out; + } + +private: + std::string mData; +}; + +} // namespace LL + +#endif /* ! defined(LL_HEXDUMP_H) */ -- cgit v1.2.3 From 9fa95dd0b21f323b7d8f60a826bcc128ad4e7ef2 Mon Sep 17 00:00:00 2001 From: Brad Linden <46733234+brad-linden@users.noreply.github.com> Date: Wed, 18 Sep 2024 14:53:36 -0700 Subject: Fix crash in LLImProcessing when message comes in before region is fully init (#2604) secondlife/viewer#2603 --- indra/newview/llimprocessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index c1e68e0288..590cd09a31 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -488,7 +488,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, case IM_NOTHING_SPECIAL: // p2p IM // Don't show dialog, just do IM if (!gAgent.isGodlike() - && gAgent.getRegion()->isPrelude() + && gAgent.inPrelude() && to_id.isNull()) { // do nothing -- don't distract newbies in -- cgit v1.2.3 From 2fd18ee162824e449dc893c66d7dd8c56518ee7c Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Thu, 19 Sep 2024 00:21:22 +0200 Subject: Fix copy&paste error in llfloaterimagepreview.cpp (#2596) --- indra/newview/llfloaterimagepreview.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 236725bd45..989e1d8d04 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -288,18 +288,18 @@ void LLFloaterImagePreview::draw() gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mBottom); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mBottom); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(mPreviewImageRect.mLeft, mPreviewImageRect.mTop); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); gGL.texCoord2f(mPreviewImageRect.mRight, mPreviewImageRect.mTop); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); } gGL.end(); @@ -325,18 +325,18 @@ void LLFloaterImagePreview::draw() gGL.begin(LLRender::TRIANGLES); { gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); gGL.texCoord2f(0.f, 0.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mBottom); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); - gGL.texCoord2f(0.f, 1.f); - gGL.vertex2i(mPreviewRect.mLeft, mPreviewRect.mTop); gGL.texCoord2f(1.f, 0.f); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mBottom); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_HPAD + PREF_BUTTON_HEIGHT + PREVIEW_HPAD); + gGL.texCoord2f(0.f, 1.f); + gGL.vertex2i(PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); gGL.texCoord2f(1.f, 1.f); - gGL.vertex2i(mPreviewRect.mRight, mPreviewRect.mTop); + gGL.vertex2i(r.getWidth() - PREVIEW_HPAD, PREVIEW_TEXTURE_HEIGHT + PREVIEW_VPAD); } gGL.end(); -- cgit v1.2.3 From ee3645ac961aec171cc56ec962723ac5fd28cf38 Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Thu, 19 Sep 2024 00:22:48 +0200 Subject: Fix possible dereferencing of nullptr in llglsandbox.cpp (#2597) --- indra/newview/llglsandbox.cpp | 120 ++++++------------------------------------ 1 file changed, 17 insertions(+), 103 deletions(-) diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 731e711cd1..af025d5879 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -68,7 +68,7 @@ #include // Height of the yellow selection highlight posts for land -const F32 PARCEL_POST_HEIGHT = 0.666f; +constexpr F32 PARCEL_POST_HEIGHT = 0.666f; // Returns true if you got at least one object void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) @@ -178,27 +178,27 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) { std::vector potentials; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + for (LLViewerRegion* region : LLWorld::getInstance()->getRegionList()) { - LLViewerRegion* region = *iter; for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { - LLSpatialPartition* part = region->getSpatialPartition(i); - if (part) + if (LLSpatialPartition* part = region->getSpatialPartition(i)) { part->cull(*LLViewerCamera::getInstance(), &potentials, true); } } } - for (std::vector::iterator iter = potentials.begin(); - iter != potentials.end(); iter++) + for (LLDrawable* drawable : potentials) { - LLDrawable* drawable = *iter; + if (!drawable) + { + continue; + } + LLViewerObject* vobjp = drawable->getVObj(); - if (!drawable || !vobjp || + if (!vobjp || vobjp->getPCode() != LL_PCODE_VOLUME || vobjp->isAttachment() || (deselect && !vobjp->isSelected())) @@ -244,7 +244,7 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask) gViewerWindow->setup3DRender(); } -const F32 WIND_RELATIVE_ALTITUDE = 25.f; +constexpr F32 WIND_RELATIVE_ALTITUDE = 25.f; void LLWind::renderVectors() { @@ -266,14 +266,14 @@ void LLWind::renderVectors() x = mVelX[i + j*mSize] * WIND_SCALE_HACK; y = mVelY[i + j*mSize] * WIND_SCALE_HACK; gGL.pushMatrix(); - gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.0); - gGL.color3f(0,1,0); + gGL.translatef((F32)i * region_width_meters/mSize, (F32)j * region_width_meters/mSize, 0.f); + gGL.color3f(0.f, 1.f, 0.f); gGL.begin(LLRender::POINTS); - gGL.vertex3f(0,0,0); + gGL.vertex3f(0.f, 0.f, 0.f); gGL.end(); - gGL.color3f(1,0,0); + gGL.color3f(1.f, 0.f, 0.f); gGL.begin(LLRender::LINES); - gGL.vertex3f(x * 0.1f, y * 0.1f ,0.f); + gGL.vertex3f(x * 0.1f, y * 0.1f, 0.f); gGL.vertex3f(x, y, 0.f); gGL.end(); gGL.popMatrix(); @@ -287,7 +287,7 @@ void LLWind::renderVectors() // Used by lltoolselectland void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, - const LLVector3d &east_north_top_global ) + const LLVector3d &east_north_top_global) { LLGLSUIDefault gls_ui; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -356,92 +356,6 @@ void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, LLUI::setLineWidth(1.f); } -/* -void LLViewerParcelMgr::renderParcel(LLParcel* parcel ) -{ - S32 i; - S32 count = parcel->getBoxCount(); - for (i = 0; i < count; i++) - { - const LLParcelBox& box = parcel->getBox(i); - - F32 west = box.mMin.mV[VX]; - F32 south = box.mMin.mV[VY]; - - F32 east = box.mMax.mV[VX]; - F32 north = box.mMax.mV[VY]; - - // HACK: At edge of last region of world, we need to make sure the region - // resolves correctly so we can get a height value. - const F32 FUDGE = 0.01f; - - F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) ); - F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) ); - F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) ); - F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) ); - - // little hack to make nearby lines not Z-fight - east -= 0.1f; - north -= 0.1f; - - F32 sw_top = sw_bottom + POST_HEIGHT; - F32 se_top = se_bottom + POST_HEIGHT; - F32 ne_top = ne_bottom + POST_HEIGHT; - F32 nw_top = nw_bottom + POST_HEIGHT; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest gls_depth(GL_TRUE); - - LLUI::setLineWidth(2.f); - gGL.color4f(0.f, 1.f, 1.f, 1.f); - - // Cheat and give this the same pick-name as land - gGL.begin(LLRender::LINES); - - gGL.vertex3f(west, north, nw_bottom); - gGL.vertex3f(west, north, nw_top); - - gGL.vertex3f(east, north, ne_bottom); - gGL.vertex3f(east, north, ne_top); - - gGL.vertex3f(east, south, se_bottom); - gGL.vertex3f(east, south, se_top); - - gGL.vertex3f(west, south, sw_bottom); - gGL.vertex3f(west, south, sw_top); - - gGL.end(); - - gGL.color4f(0.f, 1.f, 1.f, 0.2f); - gGL.begin(LLRender::QUADS); - - gGL.vertex3f(west, north, nw_bottom); - gGL.vertex3f(west, north, nw_top); - gGL.vertex3f(east, north, ne_top); - gGL.vertex3f(east, north, ne_bottom); - - gGL.vertex3f(east, north, ne_bottom); - gGL.vertex3f(east, north, ne_top); - gGL.vertex3f(east, south, se_top); - gGL.vertex3f(east, south, se_bottom); - - gGL.vertex3f(east, south, se_bottom); - gGL.vertex3f(east, south, se_top); - gGL.vertex3f(west, south, sw_top); - gGL.vertex3f(west, south, sw_bottom); - - gGL.vertex3f(west, south, sw_bottom); - gGL.vertex3f(west, south, sw_top); - gGL.vertex3f(west, north, nw_top); - gGL.vertex3f(west, north, nw_bottom); - - gGL.end(); - - LLUI::setLineWidth(1.f); - } -} -*/ - // north = a wall going north/south. Need that info to set up texture // coordinates correctly. -- cgit v1.2.3 From c5a2235e7a249c01999795f45ceb4697150dc3e1 Mon Sep 17 00:00:00 2001 From: Brad Linden <46733234+brad-linden@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:16:24 -0700 Subject: Turn off sLogInSignal to avoid crashing. (#2607) fixes secondlife/viewer#2566 --- indra/llcommon/llapp.cpp | 8 ++++---- indra/llcommon/llapp.h | 8 ++++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 3db03aec7d..08a43983d3 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -88,10 +88,6 @@ LLApp* LLApp::sApplication = NULL; // and disables crashlogger bool LLApp::sDisableCrashlogger = false; -// Local flag for whether or not to do logging in signal handlers. -//static -bool LLApp::sLogInSignal = true; - // static // Keeps track of application status LLScalarCond LLApp::sStatus{LLApp::APP_STATUS_STOPPED}; @@ -596,6 +592,10 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *) // We do the somewhat sketchy operation of blocking in here until the error handler // has gracefully stopped the app. + // FIXME(brad) - we are using this handler for asynchronous signals as well, so sLogInSignal is currently + // disabled for safety. we need to find a way to selectively reenable it when it is safe. + // see issue secondlife/viewer#2566 + if (LLApp::sLogInSignal) { LL_INFOS() << "Signal handler - Got signal " << signum << " - " << apr_signal_description_get(signum) << LL_ENDL; diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index d90ecdf661..3d18864b80 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -339,8 +339,12 @@ private: friend void default_unix_signal_handler(int signum, siginfo_t *info, void *); #endif -public: - static bool sLogInSignal; +private: +#ifdef LL_RELEASE_FOR_DOWNLOAD + static constexpr bool sLogInSignal = false; +#else + static constexpr bool sLogInSignal = true; +#endif }; #endif // LL_LLAPP_H -- cgit v1.2.3 From ecfd66fb094cf46a73c164d8a1b655489d037aec Mon Sep 17 00:00:00 2001 From: Brad Linden <46733234+brad-linden@users.noreply.github.com> Date: Wed, 18 Sep 2024 18:17:02 -0700 Subject: Avoid LL_ERRS when wgl_ARB_pixel_format is not supported (#2606) secondlife/viewer#2599 --- indra/llwindow/llwindowwin32.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 0b6ee541c0..91437b98d1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1630,9 +1630,11 @@ const S32 max_format = (S32)num_formats - 1; } else { - LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr")); - // mWindowHandle is 0, going to crash either way - LL_ERRS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL; + LL_WARNS("Window") << "No wgl_ARB_pixel_format extension!" << LL_ENDL; + // cannot proceed without wgl_ARB_pixel_format extension, shutdown same as any other gGLManager.initGL() failure + OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK); + close(); + return false; } // Verify what pixel format we actually received. -- cgit v1.2.3 From b0597e927a04e622b2434e6fc8327bb5af48ab0f Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 18 Sep 2024 20:04:24 -0700 Subject: add some more whitespace commits to .git-blame-ignore-revs --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index e06ef89a99..c68131402b 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,6 +5,8 @@ a0b3021bdcf76859054fda8e30abb3ed47749e83 8444cd9562a6a7b755fcb075864e205122354192 863c541ce0b2e3e1e566cc88423d3e87aaedb6ca +743a1a6d8eabf069d95777c96e5b657cb8702593 +4a00da1ada89af6f313cee30f5177634b0b180a9 # Wrong line endings 1b67dd855c41f5a0cda7ec2a68d98071986ca703 6cc7dd09d5e69cf57e6de7fb568a0ad2693f9c9a -- cgit v1.2.3 From 6d842ac0af814a088c56f437dc885e4ce58b61a8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 18 Sep 2024 17:11:03 +0300 Subject: Expose LLVector4a in LLRender Avoid using a bunch of allocators. Make sure we use LLVector4a's SSE logic instead of LLVector3's. Some minor optimizations. --- indra/llrender/llfontgl.cpp | 30 +++++++++++++++--------------- indra/llrender/llfontgl.h | 4 ++-- indra/llrender/llrender.cpp | 16 ++++++++-------- indra/llrender/llrender.h | 8 ++++---- indra/llrender/llrender2dutils.cpp | 10 +++------- indra/llui/llbadge.cpp | 10 +++++----- indra/newview/llviewermedia.cpp | 14 ++++++++------ 7 files changed, 45 insertions(+), 47 deletions(-) diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index 21593b7cb4..94daba0817 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -271,7 +271,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons const LLFontGlyphInfo* next_glyph = NULL; static constexpr S32 GLYPH_BATCH_SIZE = 30; - static thread_local LLVector3 vertices[GLYPH_BATCH_SIZE * 6]; + static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6]; static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6]; static thread_local LLColor4U colors[GLYPH_BATCH_SIZE * 6]; @@ -1227,42 +1227,42 @@ LLFontGL &LLFontGL::operator=(const LLFontGL &source) return *this; } -void LLFontGL::renderTriangle(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const +void LLFontGL::renderTriangle(LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const { S32 index = 0; - vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f); - uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); + vertex_out[index].set(screen_rect.mRight, screen_rect.mTop, 0.f); + uv_out[index].set(uv_rect.mRight, uv_rect.mTop); colors_out[index] = color; index++; - vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 0.f); - uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop); + vertex_out[index].set(screen_rect.mLeft, screen_rect.mTop, 0.f); + uv_out[index].set(uv_rect.mLeft, uv_rect.mTop); colors_out[index] = color; index++; - vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f); - uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); + vertex_out[index].set(screen_rect.mLeft, screen_rect.mBottom, 0.f); + uv_out[index].set(uv_rect.mLeft, uv_rect.mBottom); colors_out[index] = color; index++; - vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mTop, 0.f); - uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mTop); + vertex_out[index].set(screen_rect.mRight, screen_rect.mTop, 0.f); + uv_out[index].set(uv_rect.mRight, uv_rect.mTop); colors_out[index] = color; index++; - vertex_out[index] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 0.f); - uv_out[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom); + vertex_out[index].set(screen_rect.mLeft, screen_rect.mBottom, 0.f); + uv_out[index].set(uv_rect.mLeft, uv_rect.mBottom); colors_out[index] = color; index++; - vertex_out[index] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 0.f); - uv_out[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom); + vertex_out[index].set(screen_rect.mRight, screen_rect.mBottom, 0.f); + uv_out[index].set(uv_rect.mRight, uv_rect.mBottom); colors_out[index] = color; } -void LLFontGL::drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const +void LLFontGL::drawGlyph(S32& glyph_count, LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_strength) const { F32 slant_offset; slant_offset = ((style & ITALIC) ? ( -mFontFreetype->getAscenderHeight() * 0.2f) : 0.f); diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h index f04a77b49c..4bb6c55c65 100644 --- a/indra/llrender/llfontgl.h +++ b/indra/llrender/llfontgl.h @@ -238,8 +238,8 @@ private: LLFontDescriptor mFontDescriptor; LLPointer mFontFreetype; - void renderTriangle(LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const; - void drawGlyph(S32& glyph_count, LLVector3* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; + void renderTriangle(LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, F32 slant_amt) const; + void drawGlyph(S32& glyph_count, LLVector4a* vertex_out, LLVector2* uv_out, LLColor4U* colors_out, const LLRectf& screen_rect, const LLRectf& uv_rect, const LLColor4U& color, U8 style, ShadowType shadow, F32 drop_shadow_fade) const; // Registry holds all instantiated fonts. static LLFontRegistry* sFontRegistry; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index f432b09107..c8a9fb4893 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -1298,7 +1298,7 @@ void LLRender::pushUIMatrix() { if (mUIOffset.empty()) { - mUIOffset.push_back(LLVector3(0,0,0)); + mUIOffset.emplace_back(0.f,0.f,0.f); } else { @@ -1307,7 +1307,7 @@ void LLRender::pushUIMatrix() if (mUIScale.empty()) { - mUIScale.push_back(LLVector3(1,1,1)); + mUIScale.emplace_back(1.f,1.f,1.f); } else { @@ -1718,7 +1718,7 @@ LLVertexBuffer* LLRender::genBuffer(U32 attribute_mask, S32 count) vb->setBuffer(); - vb->setPositionData((LLVector4a*)mVerticesp.get()); + vb->setPositionData(mVerticesp.get()); if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0) { @@ -1774,12 +1774,12 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) if (mUIOffset.empty()) { - mVerticesp[mCount] = LLVector3(x,y,z); + mVerticesp[mCount].set(x,y,z); } else { LLVector3 vert = (LLVector3(x,y,z)+mUIOffset.back()).scaledVec(mUIScale.back()); - mVerticesp[mCount] = vert; + mVerticesp[mCount].set(vert.mV[VX], vert.mV[VY], vert.mV[VZ]); } mCount++; @@ -1788,7 +1788,7 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z) mTexcoordsp[mCount] = mTexcoordsp[mCount-1]; } -void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) +void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count) { if (mCount + vert_count > 4094) { @@ -1809,7 +1809,7 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, S32 vert_count) mVerticesp[mCount] = mVerticesp[mCount-1]; } -void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count) +void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count) { if (mCount + vert_count > 4094) { @@ -1833,7 +1833,7 @@ void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 v } } -void LLRender::vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count) +void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count) { if (mCount + vert_count > 4094) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 2c1417cc26..fc7c5ccc18 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -449,9 +449,9 @@ public: void diffuseColor4ubv(const U8* c); void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a); - void vertexBatchPreTransformed(LLVector3* verts, S32 vert_count); - void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, S32 vert_count); - void vertexBatchPreTransformed(LLVector3* verts, LLVector2* uvs, LLColor4U*, S32 vert_count); + void vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count); + void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count); + void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U*, S32 vert_count); void setColorMask(bool writeColor, bool writeAlpha); void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha); @@ -513,7 +513,7 @@ private: bool mCurrColorMask[4]; LLPointer mBuffer; - LLStrider mVerticesp; + LLStrider mVerticesp; LLStrider mTexcoordsp; LLStrider mColorsp; std::array mTexUnits; diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp index e488082c7e..20ad0275bd 100644 --- a/indra/llrender/llrender2dutils.cpp +++ b/indra/llrender/llrender2dutils.cpp @@ -446,15 +446,13 @@ void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTex ui_translation.mV[VX] + width * ui_scale.mV[VX], ui_translation.mV[VY]); - LLGLSUIDefault gls_ui; - gGL.getTexUnit(0)->bind(image, true); gGL.color4fv(color.mV); constexpr S32 NUM_VERTICES = 9 * 2 * 3; // 9 quads, 2 triangles per quad, 3 vertices per triangle static thread_local LLVector2 uv[NUM_VERTICES]; - static thread_local LLVector3 pos[NUM_VERTICES]; + static thread_local LLVector4a pos[NUM_VERTICES]; S32 index = 0; @@ -719,8 +717,6 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre return; } - LLGLSUIDefault gls_ui; - if(image != NULL) { gGL.getTexUnit(0)->bind(image, true); @@ -735,8 +731,8 @@ void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degre if (degrees == 0.f) { constexpr S32 NUM_VERTICES = 2 * 3; - static thread_local LLVector2 uv[NUM_VERTICES]; - static thread_local LLVector3 pos[NUM_VERTICES]; + static thread_local LLVector2 uv[NUM_VERTICES +1]; + static thread_local LLVector4a pos[NUM_VERTICES +1]; gGL.begin(LLRender::TRIANGLES); { diff --git a/indra/llui/llbadge.cpp b/indra/llui/llbadge.cpp index 6875e7c0ad..42b6f1f07b 100644 --- a/indra/llui/llbadge.cpp +++ b/indra/llui/llbadge.cpp @@ -204,11 +204,11 @@ void renderBadgeBackground(F32 centerX, F32 centerY, F32 width, F32 height, cons (F32)ll_round(x) + width, (F32)ll_round(y) + height); - LLVector3 vertices[4]; - vertices[0] = LLVector3(screen_rect.mLeft, screen_rect.mTop, 1.0f); - vertices[1] = LLVector3(screen_rect.mRight, screen_rect.mTop, 1.0f); - vertices[2] = LLVector3(screen_rect.mLeft, screen_rect.mBottom, 1.0f); - vertices[3] = LLVector3(screen_rect.mRight, screen_rect.mBottom, 1.0f); + LLVector4a vertices[4]; + vertices[0].set(screen_rect.mLeft, screen_rect.mTop, 1.0f); + vertices[1].set(screen_rect.mRight, screen_rect.mTop, 1.0f); + vertices[2].set(screen_rect.mLeft, screen_rect.mBottom, 1.0f); + vertices[3].set(screen_rect.mRight, screen_rect.mBottom, 1.0f); gGL.begin(LLRender::TRIANGLE_STRIP); { diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 9739cac311..4e7416bb63 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -688,10 +688,10 @@ void LLViewerMedia::updateMedia(void *dummy_arg) static LLCachedControl inworld_media_enabled(gSavedSettings, "AudioStreamingMedia", true); static LLCachedControl inworld_audio_enabled(gSavedSettings, "AudioStreamingMusic", true); - U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal"); - U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal"); - U32 max_low = gSavedSettings.getU32("PluginInstancesLow"); - F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit"); + static LLCachedControl max_instances(gSavedSettings, "PluginInstancesTotal", 8); + static LLCachedControl max_normal(gSavedSettings, "PluginInstancesNormal", 2); + static LLCachedControl max_low(gSavedSettings, "PluginInstancesLow", 4); + static LLCachedControl max_cpu(gSavedSettings, "PluginInstancesCPULimit", 0.9); // Setting max_cpu to 0.0 disables CPU usage checking. bool check_cpu_usage = (max_cpu != 0.0f); @@ -829,7 +829,8 @@ void LLViewerMedia::updateMedia(void *dummy_arg) } else { - if(gAudiop && LLViewerMedia::hasParcelAudio() && restore_parcel_audio && gSavedSettings.getBOOL("MediaTentativeAutoPlay")) + static LLCachedControl auto_play(gSavedSettings, "MediaTentativeAutoPlay", true); + if(gAudiop && LLViewerMedia::hasParcelAudio() && restore_parcel_audio && auto_play()) { LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLViewerMedia::getParcelAudioURL()); restore_parcel_audio = false; @@ -880,7 +881,8 @@ void LLViewerMedia::updateMedia(void *dummy_arg) } } - if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug")) + static LLCachedControl perf_debug(gSavedSettings, "MediaPerformanceManagerDebug", false); + if(perf_debug()) { // Give impls the same ordering as the priority list // they're already in the right order for this. -- cgit v1.2.3 From 8c40e6f0a9e211ec22331385dc66b5ff5233859c Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 19 Sep 2024 11:46:08 -0400 Subject: Reapply commit f4b6563 -- cherry-picking lost parts of it?! --- indra/llrender/llglslshader.cpp | 21 ++++----------------- indra/llrender/llglslshader.h | 10 +++++----- indra/newview/llviewerdisplay.cpp | 18 +++++++++++++++++- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 56f1533708..6ba5463acd 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -41,8 +41,6 @@ #include "OpenGL/OpenGL.h" #endif -#include - // Print-print list of shader included source files that are linked together via glAttachShader() // i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state. #define DEBUG_SHADER_INCLUDES 0 @@ -65,7 +63,7 @@ U64 LLGLSLShader::sTotalTimeElapsed = 0; U32 LLGLSLShader::sTotalTrianglesDrawn = 0; U64 LLGLSLShader::sTotalSamplesDrawn = 0; U32 LLGLSLShader::sTotalBinds = 0; -std::string LLGLSLShader::sDefaultReportName; +boost::json::value LLGLSLShader::sDefaultStats; //UI shader -- declared here so llui_libtest will link properly LLGLSLShader gUIProgram; @@ -120,16 +118,16 @@ struct LLGLSLShaderCompareTimeElapsed }; //static -void LLGLSLShader::finishProfile(const std::string& report_name) +void LLGLSLShader::finishProfile(boost::json::value& statsv) { sProfileEnabled = false; - if (! report_name.empty()) + if (! statsv.is_null()) { std::vector sorted(sInstances.begin(), sInstances.end()); std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); - boost::json::object stats; + auto& stats = statsv.as_object(); auto shadersit = stats.emplace("shaders", boost::json::array_kind).first; auto& shaders = shadersit->value().as_array(); bool unbound = false; @@ -174,17 +172,6 @@ void LLGLSLShader::finishProfile(const std::string& report_name) } } } - - std::ofstream outf(report_name); - if (! outf) - { - LL_WARNS() << "Couldn't write to " << std::quoted(report_name) << LL_ENDL; - } - else - { - outf << stats; - LL_INFOS() << "(also dumped to " << std::quoted(report_name) << ")" << LL_ENDL; - } } } diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h index a9b9bfafa8..2d669c70a9 100644 --- a/indra/llrender/llglslshader.h +++ b/indra/llrender/llglslshader.h @@ -170,7 +170,7 @@ public: static U32 sMaxGLTFNodes; static void initProfile(); - static void finishProfile(const std::string& report_name=sDefaultReportName); + static void finishProfile(boost::json::value& stats=sDefaultStats); static void startProfile(); static void stopProfile(); @@ -365,10 +365,10 @@ public: private: void unloadInternal(); // This must be static because finishProfile() is called at least once - // within a __try block. If we default its report_name parameter to a - // temporary std::string, that temporary must be destroyed when the stack - // is unwound, which __try forbids. - static std::string sDefaultReportName; + // within a __try block. If we default its stats parameter to a temporary + // json::value, that temporary must be destroyed when the stack is + // unwound, which __try forbids. + static boost::json::value sDefaultStats; }; //UI shader (declared here so llui_libtest will link properly) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index ae0579f5f7..f722d0bd1d 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -139,6 +139,7 @@ void render_ui_3d(); void render_ui_2d(); void render_disconnected_background(); +void getProfileStatsContext(boost::json::object& stats); std::string getProfileStatsFilename(); void display_startup() @@ -1041,7 +1042,21 @@ void display(bool rebuild, F32 zoom_factor, int subfield, bool for_snapshot) if (gShaderProfileFrame) { gShaderProfileFrame = false; - LLGLSLShader::finishProfile(getProfileStatsFilename()); + boost::json::value stats{ boost::json::object_kind }; + getProfileStatsContext(stats.as_object()); + LLGLSLShader::finishProfile(stats); + + auto report_name = getProfileStatsFilename(); + std::ofstream outf(report_name); + if (! outf) + { + LL_WARNS() << "Couldn't write to " << std::quoted(report_name) << LL_ENDL; + } + else + { + outf << stats; + LL_INFOS() << "(also dumped to " << std::quoted(report_name) << ")" << LL_ENDL; + } } } @@ -1068,6 +1083,7 @@ void getProfileStatsContext(boost::json::object& stats) context.emplace("parcel", parcel->getName()); context.emplace("parcelid", parcel->getLocalID()); } + context.emplace("time", LLDate::now().toHTTPDateString("%Y-%m-%dT%H:%M:%S")); } std::string getProfileStatsFilename() -- cgit v1.2.3 From be40936881a747893d03c5c003914efb3867ccd1 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 19 Sep 2024 12:40:56 -0400 Subject: trailing spaces from other branches --- indra/llcommon/fsyspath.h | 2 +- indra/llcommon/hexdump.h | 2 +- scripts/perf/logsdir.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h index 5fa4c8ad1b..1b4aec09b4 100644 --- a/indra/llcommon/fsyspath.h +++ b/indra/llcommon/fsyspath.h @@ -20,7 +20,7 @@ // ... the method of conversion to the native character set depends on the // character type used by source. -// +// // * If the source character type is char, the encoding of the source is // assumed to be the native narrow encoding (so no conversion takes place on // POSIX systems). diff --git a/indra/llcommon/hexdump.h b/indra/llcommon/hexdump.h index 234168cd61..ab5ba2b16d 100755 --- a/indra/llcommon/hexdump.h +++ b/indra/llcommon/hexdump.h @@ -3,7 +3,7 @@ * @author Nat Goodspeed * @date 2023-10-03 * @brief iostream manipulators to stream hex, or string with nonprinting chars - * + * * $LicenseInfo:firstyear=2023&license=viewerlgpl$ * Copyright (c) 2023, Linden Research, Inc. * $/LicenseInfo$ diff --git a/scripts/perf/logsdir.py b/scripts/perf/logsdir.py index c8b498cf78..5ab45a28b6 100644 --- a/scripts/perf/logsdir.py +++ b/scripts/perf/logsdir.py @@ -25,7 +25,7 @@ def logsdir(): if (system == 'Darwin'): base_dir = os.path.join(os.path.expanduser('~'), 'Library','Application Support',app) - elif (system == 'Linux'): + elif (system == 'Linux'): base_dir = os.path.join(os.path.expanduser('~'), '.' + app.lower()) elif (system == 'Windows'): -- cgit v1.2.3 From 7e4cdc30f3af701eb34306c124f1ce32f60c14ef Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 19 Sep 2024 20:34:33 +0300 Subject: Don't keep updating snapshot preview when the floater is closed --- indra/newview/llfloatersnapshot.cpp | 3 ++- indra/newview/llsnapshotlivepreview.cpp | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 1f52f1d180..fb4537f22a 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1297,7 +1297,8 @@ bool LLFloaterSnapshotBase::ImplBase::updatePreviewList(bool initialized) void LLFloaterSnapshotBase::ImplBase::updateLivePreview() { - if (ImplBase::updatePreviewList(true) && mFloater) + // don't update preview for hidden floater + if (mFloater && mFloater->isInVisibleChain() && ImplBase::updatePreviewList(true)) { LL_DEBUGS() << "changed" << LL_ENDL; updateControls(mFloater); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index e996cc87fc..0d0c025db0 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -690,18 +690,25 @@ bool LLSnapshotLivePreview::onIdle( void* snapshot_preview ) return false; } + static LLCachedControl auto_snapshot(gSavedSettings, "AutoSnapshot", false); + static LLCachedControl freeze_time(gSavedSettings, "FreezeTime", false); + static LLCachedControl use_freeze_frame(gSavedSettings, "UseFreezeFrame", false); + static LLCachedControl render_ui(gSavedSettings, "RenderUIInSnapshot", false); + static LLCachedControl render_hud(gSavedSettings, "RenderHUDInSnapshot", false); + static LLCachedControl render_no_post(gSavedSettings, "RenderSnapshotNoPost", false); + // If we're in freeze-frame and/or auto update mode and camera has moved, update snapshot. LLVector3 new_camera_pos = LLViewerCamera::getInstance()->getOrigin(); LLQuaternion new_camera_rot = LLViewerCamera::getInstance()->getQuaternion(); if (previewp->mForceUpdateSnapshot || - (((gSavedSettings.getBOOL("AutoSnapshot") && LLView::isAvailable(previewp->mViewContainer)) || - (gSavedSettings.getBOOL("FreezeTime") && previewp->mAllowFullScreenPreview)) && + (((auto_snapshot && LLView::isAvailable(previewp->mViewContainer)) || + (freeze_time && previewp->mAllowFullScreenPreview)) && (new_camera_pos != previewp->mCameraPos || dot(new_camera_rot, previewp->mCameraRot) < 0.995f))) { previewp->mCameraPos = new_camera_pos; previewp->mCameraRot = new_camera_rot; // request a new snapshot whenever the camera moves, with a time delay - bool new_snapshot = gSavedSettings.getBOOL("AutoSnapshot") || previewp->mForceUpdateSnapshot; + bool new_snapshot = auto_snapshot || previewp->mForceUpdateSnapshot; LL_DEBUGS("Snapshot") << "camera moved, updating thumbnail" << LL_ENDL; previewp->updateSnapshot( new_snapshot, // whether a new snapshot is needed or merely invalidate the existing one @@ -739,10 +746,10 @@ bool LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->getHeight(), previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"), previewp->getSnapshotType() == LLSnapshotModel::SNAPSHOT_TEXTURE, - previewp->mAllowRenderUI && gSavedSettings.getBOOL("RenderUIInSnapshot"), - gSavedSettings.getBOOL("RenderHUDInSnapshot"), + previewp->mAllowRenderUI && render_ui, + render_hud, false, - gSavedSettings.getBOOL("RenderSnapshotNoPost"), + render_no_post, previewp->mSnapshotBufferType, previewp->getMaxImageSize())) { @@ -754,7 +761,7 @@ bool LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->estimateDataSize(); // Full size preview is set: get the decoded image result and save it for animation - if (gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview) + if (use_freeze_frame && previewp->mAllowFullScreenPreview) { previewp->prepareFreezeFrame(); } @@ -767,7 +774,7 @@ bool LLSnapshotLivePreview::onIdle( void* snapshot_preview ) previewp->generateThumbnailImage(true) ; } previewp->getWindow()->decBusyCount(); - previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame") && previewp->mAllowFullScreenPreview); // only show fullscreen preview when in freeze frame mode + previewp->setVisible(use_freeze_frame && previewp->mAllowFullScreenPreview); // only show fullscreen preview when in freeze frame mode previewp->mSnapshotActive = false; LL_DEBUGS("Snapshot") << "done creating snapshot" << LL_ENDL; } -- cgit v1.2.3 From 25969b330e4dc69f6eb39a487b171ccc07a5df14 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 19 Sep 2024 20:11:17 +0300 Subject: viewer#2608 Crash at LLSnapshotLivePreview::getFormattedImage --- indra/llcommon/llmutex.h | 12 ++++++++++++ indra/llimage/llimage.h | 2 +- indra/newview/llsnapshotlivepreview.cpp | 4 +++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 6e8cf9643b..62943845a5 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -194,6 +194,18 @@ public: mSharedMutex->unlock(); } + void lock() + { + if (mSharedMutex) + mSharedMutex->lock(); + } + + void unlock() + { + if (mSharedMutex) + mSharedMutex->unlock(); + } + private: LLSharedMutex* mSharedMutex; }; diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index 8b966b8ea3..6b14b68c78 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -179,7 +179,7 @@ private: public: template - class DataLock : LLSharedMutexLockTemplate + class DataLock : public LLSharedMutexLockTemplate { public: DataLock(const LLImageBase* image) diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 0d0c025db0..ea95d71b27 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -894,7 +894,9 @@ LLPointer LLSnapshotLivePreview::getEncodedImage() else { // Update mFormattedImage if necessary - getFormattedImage(); + lock.unlock(); + getFormattedImage(); // will apply filters to mPreviewImage with a lock + lock.lock(); if (getSnapshotFormat() == LLSnapshotModel::SNAPSHOT_FORMAT_BMP) { // BMP hack : copy instead of decode otherwise decode will crash. -- cgit v1.2.3 From b589d394be3c942c3bcdf1b857ff34a5fde462ab Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 19 Sep 2024 12:02:57 -0700 Subject: remove dead code in build.sh --- build.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/build.sh b/build.sh index dd85fde7d6..eb81ff319a 100755 --- a/build.sh +++ b/build.sh @@ -517,15 +517,6 @@ then fi fi -# Some of the uploads takes a long time to finish in the codeticket backend, -# causing the next codeticket upload attempt to fail. -# Inserting this after each potentially large upload may prevent those errors. -# JJ is making changes to Codeticket that we hope will eliminate this failure, then this can be removed -wait_for_codeticket() -{ - sleep $(( 60 * 6 )) -} - # check status and upload results to S3 if $succeeded then -- cgit v1.2.3 From 71fcf45584d7f418f60047eb212ed2a474b39861 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 19 Sep 2024 12:05:27 -0700 Subject: Incremented viewer version after release/2024.09-ExtraFPS branch creation --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index e0eaaa0bbc..0f9f025fe4 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -7.1.11 +7.1.12 -- cgit v1.2.3 From cae279b6e1019319f9186c2cea1127b9df149a7b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 11 Sep 2024 17:10:48 -0700 Subject: secondlife/viewer#2462: Optimize unloading of prims --- indra/newview/llmeshrepository.cpp | 81 ++++++++++++++++++++++++++++++++++-- indra/newview/llmeshrepository.h | 7 +++- indra/newview/llviewerobjectlist.cpp | 5 +++ indra/newview/llvovolume.cpp | 27 +++++++++++- indra/newview/llvovolume.h | 1 + 5 files changed, 116 insertions(+), 5 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 26e2d8f319..2ca94390e5 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3651,20 +3651,95 @@ S32 LLMeshRepository::update() return static_cast(size); } -void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) +#ifdef SHOW_ASSERT +// Brute-force remove the object from all loading queues. Returns true if +// something was removed. +// This function is used in a debug assert to ensure unregisterMesh and +// unregisterSkinInfo are called as intended. +// *TODO: Consider removing at some point if we feel confident about the code +// working as intended. +bool LLMeshRepository::forceUnregisterMesh(LLVOVolume* vobj) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + + bool found = false; + for (auto& lod : mLoadingMeshes) { for (auto& param : lod) { - vector_replace_with_last(param.second, vobj); + llassert(std::find(param.second.begin(), param.second.end(), vobj) == param.second.end()); + found = found || vector_replace_with_last(param.second, vobj); } } for (auto& skin_pair : mLoadingSkins) { - vector_replace_with_last(skin_pair.second, vobj); + llassert(std::find(skin_pair.second.begin(), skin_pair.second.end(), vobj) == skin_pair.second.end()); + found = found || vector_replace_with_last(skin_pair.second, vobj); + } + + return found; +} +#endif + +void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + + llassert((mesh_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH); + llassert(mesh_params.getSculptID().notNull()); + auto& lod = mLoadingMeshes[detail]; + auto param_iter = lod.find(mesh_params.getSculptID()); + if (param_iter != lod.end()) + { + vector_replace_with_last(param_iter->second, vobj); + llassert(!vector_replace_with_last(param_iter->second, vobj)); + if (param_iter->second.empty()) + { + lod.erase(param_iter); + } + } +} + +void LLMeshRepository::unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + + llassert(mesh_id.notNull()); + auto skin_pair_iter = mLoadingSkins.find(mesh_id); + if (skin_pair_iter != mLoadingSkins.end()) + { + vector_replace_with_last(skin_pair_iter->second, vobj); + llassert(!vector_replace_with_last(skin_pair_iter->second, vobj)); + if (skin_pair_iter->second.empty()) + { + mLoadingSkins.erase(skin_pair_iter); + } + } +} + +// Lots of dead objects make expensive calls to +// LLMeshRepository::unregisterMesh which may delay shutdown. Avoid this by +// preemptively unregistering all meshes. +// We can also do this safely if all objects are confirmed dead for some other +// reason. +void LLMeshRepository::unregisterAllMeshes() +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + + // The size of mLoadingMeshes and mLoadingSkins may be large and thus + // expensive to iterate over in LLVOVolume::~LLVOVolume. + // This is unnecessary during shutdown, so we ignore the referenced objects in the + // least expensive way which is still safe: by clearing these containers. + // Clear now and not in LLMeshRepository::shutdown because + // LLMeshRepository::notifyLoadedMeshes could (depending on invocation + // order) reference a pointer to an object after it has been deleted. + for (auto& lod : mLoadingMeshes) + { + lod.clear(); } + mLoadingSkins.clear(); } S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b850ade0bb..b8bec7f233 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -632,10 +632,15 @@ public: LLMeshRepository(); void init(); + void unregisterAllMeshes(); void shutdown(); S32 update(); - void unregisterMesh(LLVOVolume* volume); +#ifdef SHOW_ASSERT + bool forceUnregisterMesh(LLVOVolume* volume); +#endif + void unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail); + void unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj); //mesh management functions S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 9e1d86faac..6167129077 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -65,6 +65,7 @@ #include "lltoolmgr.h" #include "lltoolpie.h" #include "llkeyboard.h" +#include "llmeshrepository.h" #include "u64.h" #include "llviewertexturelist.h" #include "lldatapacker.h" @@ -1419,6 +1420,10 @@ void LLViewerObjectList::cleanDeadObjects(bool use_timer) // No dead objects, don't need to scan object list. return; } + if ((LLApp::isExiting()) || (mNumDeadObjects == (S32)mObjects.size())) + { + gMeshRepo.unregisterAllMeshes(); + } LL_PROFILE_ZONE_SCOPED; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 7da4358f86..2f2054355a 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -250,10 +250,13 @@ LLVOVolume::~LLVOVolume() delete mVolumeImpl; mVolumeImpl = NULL; - gMeshRepo.unregisterMesh(this); + unregisterOldMeshAndSkin(); + llassert(!gMeshRepo.forceUnregisterMesh(this)); if(!mMediaImplList.empty()) { + LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("delete volume media list"); + for(U32 i = 0 ; i < mMediaImplList.size() ; i++) { if(mMediaImplList[i].notNull()) @@ -998,6 +1001,28 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) return mDrawable; } +// Inverse of gMeshRepo.loadMesh and gMeshRepo.getSkinInfo, combined into one function +// Assume a Collada mesh never changes after being set. +void LLVOVolume::unregisterOldMeshAndSkin() +{ + if (mVolumep) + { + const LLVolumeParams& params = mVolumep->getParams(); + if ((params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) + { + // object is being deleted, so it will no longer need to request + // meshes. + for (S32 lod = 0; lod != LLVolumeLODGroup::NUM_LODS; ++lod) + { + gMeshRepo.unregisterMesh(this, params, lod); + } + // This volume may or may not have a skin + gMeshRepo.unregisterSkinInfo(params.getSculptID(), this); + } + } +} + + bool LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bool unique_volume) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 6241bf42d6..dfd75aa7d0 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -227,6 +227,7 @@ public: void setTexture(const S32 face); S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];} + void unregisterOldMeshAndSkin(); /*virtual*/ bool setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override; void updateSculptTexture(); void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;} -- cgit v1.2.3 From 89106b98a104afc0fb68412cfdf00f8e3e008fd0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 19 Sep 2024 17:34:28 -0700 Subject: secondlife/viewer#2623: Remove assert --- indra/newview/llmeshrepository.cpp | 32 -------------------------------- indra/newview/llmeshrepository.h | 3 --- indra/newview/llvovolume.cpp | 1 - 3 files changed, 36 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 2ca94390e5..61ccd355a1 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3651,38 +3651,6 @@ S32 LLMeshRepository::update() return static_cast(size); } -#ifdef SHOW_ASSERT -// Brute-force remove the object from all loading queues. Returns true if -// something was removed. -// This function is used in a debug assert to ensure unregisterMesh and -// unregisterSkinInfo are called as intended. -// *TODO: Consider removing at some point if we feel confident about the code -// working as intended. -bool LLMeshRepository::forceUnregisterMesh(LLVOVolume* vobj) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - - bool found = false; - - for (auto& lod : mLoadingMeshes) - { - for (auto& param : lod) - { - llassert(std::find(param.second.begin(), param.second.end(), vobj) == param.second.end()); - found = found || vector_replace_with_last(param.second, vobj); - } - } - - for (auto& skin_pair : mLoadingSkins) - { - llassert(std::find(skin_pair.second.begin(), skin_pair.second.end(), vobj) == skin_pair.second.end()); - found = found || vector_replace_with_last(skin_pair.second, vobj); - } - - return found; -} -#endif - void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index b8bec7f233..6e10493e90 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -636,9 +636,6 @@ public: void shutdown(); S32 update(); -#ifdef SHOW_ASSERT - bool forceUnregisterMesh(LLVOVolume* volume); -#endif void unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail); void unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj); //mesh management functions diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2f2054355a..e1eface4e8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -251,7 +251,6 @@ LLVOVolume::~LLVOVolume() mVolumeImpl = NULL; unregisterOldMeshAndSkin(); - llassert(!gMeshRepo.forceUnregisterMesh(this)); if(!mMediaImplList.empty()) { -- cgit v1.2.3 From c3215c1bb07adee2ff6a546e97d4e42165e74b60 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 20 Sep 2024 00:01:25 +0300 Subject: viewer#2576 Crash baning a resident --- indra/newview/llpanelgroupbulk.cpp | 32 +++++++++++--------------------- indra/newview/llpanelgroupbulkban.cpp | 33 ++++++++++++--------------------- indra/newview/llpanelgroupbulkimpl.h | 3 ++- 3 files changed, 25 insertions(+), 43 deletions(-) diff --git a/indra/newview/llpanelgroupbulk.cpp b/indra/newview/llpanelgroupbulk.cpp index 433db74cda..8032e207cd 100644 --- a/indra/newview/llpanelgroupbulk.cpp +++ b/indra/newview/llpanelgroupbulk.cpp @@ -56,6 +56,7 @@ LLPanelGroupBulkImpl::LLPanelGroupBulkImpl(const LLUUID& group_id) : mGroupID(group_id), mBulkAgentList(NULL), mOKButton(NULL), + mAddButton(nullptr), mRemoveButton(NULL), mGroupName(NULL), mLoadingText(), @@ -79,29 +80,18 @@ LLPanelGroupBulkImpl::~LLPanelGroupBulkImpl() } } -// static -void LLPanelGroupBulkImpl::callbackClickAdd(void* userdata) +void LLPanelGroupBulkImpl::callbackClickAdd(LLPanelGroupBulk* panelp) { - if (LLPanelGroupBulk* panelp = (LLPanelGroupBulk*)userdata) - { - // Right now this is hard coded with some knowledge that it is part - // of a floater since the avatar picker needs to be added as a dependent - // floater to the parent floater. - // Soon the avatar picker will be embedded into this panel - // instead of being it's own separate floater. But that is next week. - // This will do for now. -jwolk May 10, 2006 - LLView* button = panelp->findChild("add_button"); - LLFloater* root_floater = gFloaterView->getParentFloater(panelp); - LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( - [&](const uuid_vec_t& agent_ids, const std::vector&) - { - panelp->mImplementation->addUsers(agent_ids); - }, true, false, false, root_floater->getName(), button); - if (picker) + LLFloater* root_floater = gFloaterView->getParentFloater(panelp); + LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show( + [this](const uuid_vec_t& agent_ids, const std::vector&) { - root_floater->addDependentFloater(picker); - LLGroupMgr::getInstance()->sendCapGroupMembersRequest(panelp->mImplementation->mGroupID); - } + addUsers(agent_ids); + }, true, false, false, root_floater->getName(), mAddButton); + if (picker) + { + root_floater->addDependentFloater(picker); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } } diff --git a/indra/newview/llpanelgroupbulkban.cpp b/indra/newview/llpanelgroupbulkban.cpp index 3c764887a6..1d3edad0f3 100644 --- a/indra/newview/llpanelgroupbulkban.cpp +++ b/indra/newview/llpanelgroupbulkban.cpp @@ -68,35 +68,26 @@ bool LLPanelGroupBulkBan::postBuild() mImplementation->mBulkAgentList->setCommitCallback(LLPanelGroupBulkImpl::callbackSelect, mImplementation); } - LLButton* button = getChild("add_button", recurse); - if ( button ) + mImplementation->mAddButton = getChild("add_button", recurse); + // default to opening avatarpicker automatically + mImplementation->mAddButton->setClickedCallback( + [this](LLUICtrl* ctrl, const LLSD& param) { - // default to opening avatarpicker automatically - // (*impl::callbackClickAdd)((void*)this); - button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickAdd, this); - } + mImplementation->callbackClickAdd(this); + }); mImplementation->mRemoveButton = getChild("remove_button", recurse); - if ( mImplementation->mRemoveButton ) - { - mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); - mImplementation->mRemoveButton->setEnabled(false); - } + mImplementation->mRemoveButton->setClickedCallback(LLPanelGroupBulkImpl::callbackClickRemove, mImplementation); + mImplementation->mRemoveButton->setEnabled(false); mImplementation->mOKButton = getChild("ban_button", recurse); - if ( mImplementation->mOKButton ) - { - mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); - mImplementation->mOKButton->setEnabled(false); - } + mImplementation->mOKButton->setClickedCallback(LLPanelGroupBulkBan::callbackClickSubmit, this); + mImplementation->mOKButton->setEnabled(false); - button = getChild("cancel_button", recurse); - if ( button ) - { - button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); - } + LLButton* button = getChild("cancel_button", recurse); + button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation); mImplementation->mTooManySelected = getString("ban_selection_too_large"); mImplementation->mBanNotPermitted = getString("ban_not_permitted"); diff --git a/indra/newview/llpanelgroupbulkimpl.h b/indra/newview/llpanelgroupbulkimpl.h index 5a479f8117..5515bd6d9a 100644 --- a/indra/newview/llpanelgroupbulkimpl.h +++ b/indra/newview/llpanelgroupbulkimpl.h @@ -44,7 +44,7 @@ public: LLPanelGroupBulkImpl(const LLUUID& group_id); ~LLPanelGroupBulkImpl(); - static void callbackClickAdd(void* userdata); + void callbackClickAdd(LLPanelGroupBulk* panelp); static void callbackClickRemove(void* userdata); static void callbackClickCancel(void* userdata); @@ -70,6 +70,7 @@ public: LLNameListCtrl* mBulkAgentList; LLButton* mOKButton; + LLButton* mAddButton; LLButton* mRemoveButton; LLTextBox* mGroupName; -- cgit v1.2.3 From 4f5d58dd036d06c88c552b8d8ac57dbb1e0b45ac Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Thu, 19 Sep 2024 19:30:05 +0200 Subject: #1519 ObjectGrab message includes invalid SurfaceInfo data when in mouselook mode --- indra/newview/lltoolselect.cpp | 9 ++++----- indra/newview/llviewerwindow.cpp | 16 ++++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 5ccda7d4eb..3bd459f5b0 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -55,17 +55,17 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite ) : LLTool( std::string("Select"), composite ), mIgnoreGroup( false ) { - } +} // True if you selected an object. bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask) { // do immediate pick query bool pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); - bool pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects"); - bool pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes"); + static LLCachedControl select_invisible_objects(gSavedSettings, "SelectInvisibleObjects"); + static LLCachedControl select_reflection_probes(gSavedSettings, "SelectReflectionProbes"); - mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, false, true, pick_reflection_probe); + mPick = gViewerWindow->pickImmediate(x, y, select_invisible_objects, pick_rigged, false, true, select_reflection_probes); // Pass mousedown to agent LLTool::handleMouseDown(x, y, mask); @@ -73,7 +73,6 @@ bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask) return mPick.getObject().notNull(); } - // static LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, bool ignore_group, bool temp_select, bool select_root) { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0e7d82fd90..acb2c85ef8 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4255,15 +4255,15 @@ void LLViewerWindow::pickAsync( S32 x, bool pick_unselectable, bool pick_reflection_probes) { + static LLCachedControl select_invisible_objects(gSavedSettings, "SelectInvisibleObjects"); // "Show Debug Alpha" means no object actually transparent bool in_build_mode = LLFloaterReg::instanceVisible("build"); - if (LLDrawPoolAlpha::sShowDebugAlpha - || (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects"))) + if (LLDrawPoolAlpha::sShowDebugAlpha || (in_build_mode && select_invisible_objects)) { pick_transparent = true; } - LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, pick_unselectable, true, callback); + LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, true, pick_unselectable, callback); schedulePick(pick_info); } @@ -4287,7 +4287,6 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info) mWindow->delayInputProcessing(); } - void LLViewerWindow::performPick() { if (!mPicks.empty()) @@ -4321,8 +4320,9 @@ void LLViewerWindow::returnEmptyPicks() // Performs the GL object/land pick. LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transparent, bool pick_rigged, bool pick_particle, bool pick_unselectable, bool pick_reflection_probe) { + static LLCachedControl select_invisible_objects(gSavedSettings, "SelectInvisibleObjects"); bool in_build_mode = LLFloaterReg::instanceVisible("build"); - if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha) + if ((in_build_mode && select_invisible_objects) || LLDrawPoolAlpha::sShowDebugAlpha) { // build mode allows interaction with all transparent objects // "Show Debug Alpha" means no object actually transparent @@ -4330,7 +4330,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transp } // shortcut queueing in mPicks and just update mLastPick in place - MASK key_mask = gKeyboard->currentMask(true); + MASK key_mask = gKeyboard->currentMask(true); mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, true, false, NULL); mLastPick.fetchResults(); @@ -6050,14 +6050,14 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos, bool pick_rigged, bool pick_particle, bool pick_reflection_probe, - bool pick_uv_coords, + bool pick_surface_info, bool pick_unselectable, void (*pick_callback)(const LLPickInfo& pick_info)) : mMousePt(mouse_pos), mKeyMask(keyboard_mask), mPickCallback(pick_callback), mPickType(PICK_INVALID), - mWantSurfaceInfo(pick_uv_coords), + mWantSurfaceInfo(pick_surface_info), mObjectFace(-1), mUVCoords(-1.f, -1.f), mSTCoords(-1.f, -1.f), -- cgit v1.2.3 From fad8b11f480a7e7fc8cae38e0f76de2109a46a99 Mon Sep 17 00:00:00 2001 From: Rye Cogtail Date: Fri, 20 Sep 2024 12:10:06 -0400 Subject: Fix sky settings with reflection probe ambiance of 0 still receiving tonemapping --- indra/newview/pipeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 14a15eb59f..fe02742aac 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7070,7 +7070,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - bool no_post = gSnapshotNoPost || (buildNoPost && gFloaterTools->isAvailable()); + bool no_post = gSnapshotNoPost || psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f || (buildNoPost && gFloaterTools->isAvailable()); LLGLSLShader& shader = no_post ? gNoPostTonemapProgram : gDeferredPostTonemapProgram; shader.bind(); -- cgit v1.2.3 From 0e33882b15e0c970e216d1cca4b93a7702e5113b Mon Sep 17 00:00:00 2001 From: Ansariel Hiller Date: Fri, 20 Sep 2024 19:07:02 +0200 Subject: Restore option to change location of existing pick (#2622) --- indra/newview/llpanelprofilepicks.cpp | 42 ++++++++++++++++++++++ indra/newview/llpanelprofilepicks.h | 10 +++++- .../skins/default/xui/en/panel_profile_pick.xml | 20 +++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp index 08f3d3af5a..11a10ebd2c 100644 --- a/indra/newview/llpanelprofilepicks.cpp +++ b/indra/newview/llpanelprofilepicks.cpp @@ -246,6 +246,8 @@ void LLPanelProfilePicks::onClickNewBtn() select_tab(true). label(pick_panel->getPickName())); updateButtons(); + + pick_panel->addLocationChangedCallbacks(); } void LLPanelProfilePicks::onClickDelete() @@ -571,10 +573,12 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id) { mPickName->setEnabled(true); mPickDescription->setEnabled(true); + mSetCurrentLocationButton->setVisible(true); } else { mSnapshotCtrl->setEnabled(false); + mSetCurrentLocationButton->setVisible(false); } } @@ -585,6 +589,7 @@ bool LLPanelProfilePick::postBuild() mSaveButton = getChild("save_changes_btn"); mCreateButton = getChild("create_changes_btn"); mCancelButton = getChild("cancel_changes_btn"); + mSetCurrentLocationButton = getChild("set_to_curr_location_btn"); mSnapshotCtrl = getChild("pick_snapshot"); mSnapshotCtrl->setCommitCallback(boost::bind(&LLPanelProfilePick::onSnapshotChanged, this)); @@ -597,6 +602,7 @@ bool LLPanelProfilePick::postBuild() mSaveButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); mCreateButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSave, this)); mCancelButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickCancel, this)); + mSetCurrentLocationButton->setCommitCallback(boost::bind(&LLPanelProfilePick::onClickSetLocation, this)); mPickName->setKeystrokeCallback(boost::bind(&LLPanelProfilePick::onPickChanged, this, _1), NULL); mPickName->setEnabled(false); @@ -759,6 +765,32 @@ bool LLPanelProfilePick::isDirty() const return false; } +void LLPanelProfilePick::onClickSetLocation() +{ + // Save location for later use. + setPosGlobal(gAgent.getPositionGlobal()); + + std::string parcel_name, region_name; + + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + if (parcel) + { + mParcelId = parcel->getID(); + parcel_name = parcel->getName(); + } + + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + region_name = region->getName(); + } + + setPickLocation(createLocationText(getLocationNotice(), parcel_name, region_name, getPosGlobal())); + + mLocationChanged = true; + enableSaveButton(true); +} + void LLPanelProfilePick::onClickSave() { if (mRegionCallbackConnection.connected()) @@ -769,6 +801,10 @@ void LLPanelProfilePick::onClickSave() { mParcelCallbackConnection.disconnect(); } + if (mLocationChanged) + { + onClickSetLocation(); + } sendUpdate(); mLocationChanged = false; @@ -816,6 +852,12 @@ void LLPanelProfilePick::processParcelInfo(const LLParcelData& parcel_data) } } +void LLPanelProfilePick::addLocationChangedCallbacks() +{ + mRegionCallbackConnection = gAgent.addRegionChangedCallback([this]() { onClickSetLocation(); }); + mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onClickSetLocation(); }); +} + void LLPanelProfilePick::sendUpdate() { LLPickData pick_data; diff --git a/indra/newview/llpanelprofilepicks.h b/indra/newview/llpanelprofilepicks.h index e3f50f5576..5e5d4ff81e 100644 --- a/indra/newview/llpanelprofilepicks.h +++ b/indra/newview/llpanelprofilepicks.h @@ -138,6 +138,8 @@ public: void setParcelID(const LLUUID& parcel_id) override { mParcelId = parcel_id; } void setErrorStatus(S32 status, const std::string& reason) override {}; + void addLocationChangedCallbacks(); + protected: /** @@ -199,6 +201,11 @@ public: */ void resetDirty() override; + /** + * Callback for "Set Location" button click + */ + void onClickSetLocation(); + /** * Callback for "Save" and "Create" button click */ @@ -221,6 +228,7 @@ protected: LLTextureCtrl* mSnapshotCtrl; LLLineEditor* mPickName; LLTextEditor* mPickDescription; + LLButton* mSetCurrentLocationButton; LLButton* mSaveButton; LLButton* mCreateButton; LLButton* mCancelButton; @@ -236,7 +244,7 @@ protected: bool mLocationChanged; bool mNewPick; - bool mIsEditing; + bool mIsEditing; void onDescriptionFocusReceived(); }; diff --git a/indra/newview/skins/default/xui/en/panel_profile_pick.xml b/indra/newview/skins/default/xui/en/panel_profile_pick.xml index 024120931f..4f441b9b49 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_pick.xml @@ -198,6 +198,26 @@ /> + +