summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2025-03-07 16:44:21 +0800
committerErik Kundiman <erik@megapahit.org>2025-03-07 16:44:21 +0800
commit266e96605781960799dc5388cc1ac168432ff106 (patch)
tree5f46ae7d39a8a954ea9f79dc7216cad6aca2ee6a /indra
parent530ff898b00d1759ab4abb32dcf9767960ce7170 (diff)
parentbf949ce004c25917aabddd1cd24be812713e4602 (diff)
Merge branch '2024.12-ForeverFPS'
Diffstat (limited to 'indra')
-rw-r--r--indra/CMakeLists.txt5
-rw-r--r--indra/llappearance/llavatarappearancedefines.cpp3
-rw-r--r--indra/llappearance/llwearable.cpp4
-rw-r--r--indra/llcommon/CMakeLists.txt4
-rw-r--r--indra/llcommon/fsyspath.h6
-rw-r--r--indra/llcommon/llerror.cpp8
-rw-r--r--indra/llcommon/llerror.h13
-rw-r--r--indra/llcommon/llqueuedthread.cpp4
-rw-r--r--indra/llinventory/llinventory.cpp2
-rw-r--r--indra/llinventory/llsaleinfo.cpp10
-rw-r--r--indra/llinventory/llsettingssky.cpp25
-rw-r--r--indra/llinventory/llsettingssky.h9
-rw-r--r--indra/llmath/llvector4a.h13
-rw-r--r--indra/llmath/v3math.h51
-rw-r--r--indra/llmath/v4math.h51
-rw-r--r--indra/llrender/llcubemaparray.cpp8
-rw-r--r--indra/llrender/llcubemaparray.h2
-rw-r--r--indra/llrender/llfontbitmapcache.cpp6
-rw-r--r--indra/llrender/llfontbitmapcache.h2
-rw-r--r--indra/llrender/llfontfreetype.cpp27
-rw-r--r--indra/llrender/llfontfreetype.h3
-rw-r--r--indra/llrender/llfontgl.cpp23
-rw-r--r--indra/llrender/llfontgl.h2
-rw-r--r--indra/llrender/llfontvertexbuffer.cpp8
-rw-r--r--indra/llrender/llfontvertexbuffer.h5
-rw-r--r--indra/llrender/llglslshader.h1
-rw-r--r--indra/llrender/llimagegl.cpp3
-rw-r--r--indra/llrender/llrender.cpp22
-rw-r--r--indra/llrender/llshadermgr.cpp12
-rw-r--r--indra/llrender/llshadermgr.h3
-rw-r--r--indra/llui/llfolderview.cpp40
-rw-r--r--indra/llui/llfolderview.h2
-rw-r--r--indra/llui/llnotifications.cpp8
-rw-r--r--indra/llui/llstyle.cpp7
-rw-r--r--indra/llui/llstyle.h1
-rw-r--r--indra/llui/lltextbase.cpp10
-rw-r--r--indra/llui/lltextbox.cpp3
-rw-r--r--indra/llui/lltransutil.cpp2
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp5
-rw-r--r--indra/llwindow/llwindowcallbacks.h1
-rw-r--r--indra/llwindow/llwindowmacosx.cpp8
-rw-r--r--indra/llwindow/llwindowwin32.cpp57
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl129
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl180
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/srgbF.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl210
-rw-r--r--indra/newview/featuretable.txt9
-rw-r--r--indra/newview/featuretable_mac.txt9
-rw-r--r--indra/newview/gltfscenemanager.cpp25
-rw-r--r--indra/newview/llagent.cpp27
-rw-r--r--indra/newview/llagentpicksinfo.cpp12
-rw-r--r--indra/newview/llagentpicksinfo.h12
-rw-r--r--indra/newview/llappearancemgr.cpp11
-rw-r--r--indra/newview/llappviewer.cpp181
-rw-r--r--indra/newview/llappviewer.h32
-rw-r--r--indra/newview/llconversationmodel.cpp5
-rw-r--r--indra/newview/lldrawpool.cpp4
-rw-r--r--indra/newview/lldrawpool.h3
-rw-r--r--indra/newview/lldrawpoolwater.cpp245
-rw-r--r--indra/newview/lldrawpoolwater.h2
-rw-r--r--indra/newview/lldrawpoolwaterexclusion.cpp79
-rw-r--r--indra/newview/lldrawpoolwaterexclusion.h61
-rw-r--r--indra/newview/llface.cpp23
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp3
-rw-r--r--indra/newview/llfloatersnapshot.cpp22
-rw-r--r--indra/newview/llgltfmaterialpreviewmgr.cpp4
-rw-r--r--indra/newview/llheroprobemanager.cpp26
-rw-r--r--indra/newview/llheroprobemanager.h3
-rw-r--r--indra/newview/llhudrender.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp52
-rw-r--r--indra/newview/llinventoryfunctions.cpp16
-rw-r--r--indra/newview/llinventoryfunctions.h18
-rw-r--r--indra/newview/llinventorymodel.cpp41
-rw-r--r--indra/newview/llinventorymodel.h3
-rw-r--r--indra/newview/llinventorypanel.cpp4
-rw-r--r--indra/newview/lllogininstance.cpp1
-rw-r--r--indra/newview/lllogininstance.h2
-rw-r--r--indra/newview/llmeshrepository.cpp6
-rw-r--r--indra/newview/llmeshrepository.h4
-rw-r--r--indra/newview/llpanelcontents.cpp68
-rw-r--r--indra/newview/llpanelcontents.h2
-rw-r--r--indra/newview/llpanelemojicomplete.cpp2
-rw-r--r--indra/newview/llpanelface.cpp4
-rw-r--r--indra/newview/llpanelgroupbulk.cpp32
-rw-r--r--indra/newview/llpanelgroupbulkban.cpp33
-rw-r--r--indra/newview/llpanelgroupbulkimpl.h3
-rw-r--r--indra/newview/llpanelmaininventory.cpp10
-rw-r--r--indra/newview/llpanelobjectinventory.h2
-rw-r--r--indra/newview/llpanelprimmediacontrols.cpp4
-rw-r--r--indra/newview/llprogressview.cpp154
-rw-r--r--indra/newview/llprogressview.h26
-rw-r--r--indra/newview/llreflectionmap.cpp29
-rw-r--r--indra/newview/llreflectionmap.h12
-rw-r--r--indra/newview/llreflectionmapmanager.cpp14
-rw-r--r--indra/newview/llsettingsvo.cpp10
-rw-r--r--indra/newview/llspatialpartition.cpp16
-rw-r--r--indra/newview/llstartup.cpp37
-rw-r--r--indra/newview/lltexturefetch.cpp18
-rw-r--r--indra/newview/llviewercamera.cpp4
-rw-r--r--indra/newview/llviewercontrol.cpp10
-rw-r--r--indra/newview/llviewermedia.cpp4
-rw-r--r--indra/newview/llviewermenu.cpp7
-rw-r--r--indra/newview/llviewerobject.h4
-rw-r--r--indra/newview/llviewerobjectlist.cpp84
-rw-r--r--indra/newview/llviewerobjectlist.h5
-rw-r--r--indra/newview/llviewerparcelmgr.cpp10
-rw-r--r--indra/newview/llviewershadermgr.cpp53
-rw-r--r--indra/newview/llviewershadermgr.h2
-rw-r--r--indra/newview/llviewertexture.cpp68
-rw-r--r--indra/newview/llviewertexture.h5
-rw-r--r--indra/newview/llviewertexturelist.cpp16
-rw-r--r--indra/newview/llviewerwindow.cpp11
-rw-r--r--indra/newview/llviewerwindow.h1
-rw-r--r--indra/newview/llvoavatar.cpp10
-rw-r--r--indra/newview/llvoiceclient.cpp1
-rw-r--r--indra/newview/llvoicevivox.cpp2
-rw-r--r--indra/newview/llvoicewebrtc.cpp40
-rw-r--r--indra/newview/llvovolume.cpp43
-rw-r--r--indra/newview/pipeline.cpp111
-rw-r--r--indra/newview/pipeline.h6
-rw-r--r--indra/newview/skins/default/textures/3p_icons/fmod_logo.pngbin14486 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/3p_icons/havok_logo.pngbin41488 -> 0 bytes
-rw-r--r--indra/newview/skins/default/textures/3p_icons/vivox_logo.pngbin2331 -> 0 bytes
-rw-r--r--indra/newview/skins/default/xui/de/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml53
-rw-r--r--indra/newview/skins/default/xui/en/menu_login.xml9
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_progress.xml50
-rw-r--r--indra/newview/skins/default/xui/es/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/fr/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/it/panel_progress.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_preferences_setup.xml2
-rw-r--r--indra/newview/skins/default/xui/ja/panel_progress.xml4
-rw-r--r--indra/newview/skins/default/xui/pl/panel_progress.xml9
-rw-r--r--indra/newview/skins/default/xui/pt/panel_progress.xml2
-rw-r--r--indra/viewer_components/login/lllogin.cpp2
148 files changed, 2084 insertions, 1155 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 25570470db..5bf08f63aa 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -33,6 +33,11 @@ else()
set( USE_AUTOBUILD_3P ON )
endif()
+if (NOT DEFINED CMAKE_CXX_STANDARD)
+ set(CMAKE_CXX_STANDARD 20)
+endif()
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
include(Variables)
include(BuildVersion)
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
index 5f98f2c8c1..47798844bc 100644
--- a/indra/llappearance/llavatarappearancedefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -300,7 +300,8 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::strin
LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) const
{
- return getTexture(index)->mWearableType;
+ auto* tex = getTexture(index);
+ return tex ? tex->mWearableType : LLWearableType::WT_INVALID;
}
// static
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
index a7e5292fed..f30c147b91 100644
--- a/indra/llappearance/llwearable.cpp
+++ b/indra/llappearance/llwearable.cpp
@@ -652,7 +652,7 @@ void LLWearable::setVisualParamWeight(S32 param_index, F32 value)
}
else
{
- LL_ERRS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL;
+ LL_WARNS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL;
}
}
@@ -665,7 +665,7 @@ F32 LLWearable::getVisualParamWeight(S32 param_index) const
}
else
{
- LL_WARNS() << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL;
+ LL_WARNS() << "LLWearable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL;
}
return (F32)-1.0;
}
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 85ab874980..8e56e6a800 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -300,7 +300,9 @@ if (CMAKE_OSX_ARCHITECTURES MATCHES arm64)
file(WRITE ${PREBUILD_TRACKING_DIR}/sse2neon_installed "0")
endif (${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/sse2neon_installed OR NOT ${sse2neon_installed} EQUAL 0)
target_include_directories(llcommon PUBLIC ${LIBS_PREBUILT_DIR}/include/sse2neon)
-endif ()
+elseif (LINUX)
+ target_include_directories(llcommon PUBLIC ${LIBS_PREBUILT_DIR}/include)
+endif (CMAKE_OSX_ARCHITECTURES MATCHES arm64)
if (USE_AUTOBUILD_3P OR USE_CONAN)
add_dependencies(llcommon stage_third_party_libs)
diff --git a/indra/llcommon/fsyspath.h b/indra/llcommon/fsyspath.h
index 1b4aec09b4..e9c96edce3 100644
--- a/indra/llcommon/fsyspath.h
+++ b/indra/llcommon/fsyspath.h
@@ -68,7 +68,11 @@ public:
}
// shadow base-class string() method with UTF-8 aware method
- std::string string() const { return super::u8string(); }
+ std::string string() const
+ {
+ auto u8 = super::u8string();
+ return std::string(u8.begin(), u8.end());
+ }
// 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
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 90c6ba309b..d834098994 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1604,11 +1604,11 @@ namespace LLError
std::string LLUserWarningMsg::sLocalizedOutOfMemoryWarning;
LLUserWarningMsg::Handler LLUserWarningMsg::sHandler;
- void LLUserWarningMsg::show(const std::string& message)
+ void LLUserWarningMsg::show(const std::string& message, S32 error_code)
{
if (sHandler)
{
- sHandler(std::string(), message);
+ sHandler(std::string(), message, error_code);
}
}
@@ -1616,7 +1616,7 @@ namespace LLError
{
if (sHandler && !sLocalizedOutOfMemoryTitle.empty())
{
- sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning);
+ sHandler(sLocalizedOutOfMemoryTitle, sLocalizedOutOfMemoryWarning, ERROR_BAD_ALLOC);
}
}
@@ -1627,7 +1627,7 @@ namespace LLError
"Second Life viewer couldn't access some of the files it needs and will be closed."
"\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
"contact https://support.secondlife.com if issue persists after reinstall.";
- sHandler("Missing Files", error_string);
+ sHandler("Missing Files", error_string, ERROR_MISSING_FILES);
}
void LLUserWarningMsg::setHandler(const LLUserWarningMsg::Handler &handler)
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 8a143ff30a..41893a35e5 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -308,7 +308,16 @@ namespace LLError
class LLUserWarningMsg
{
public:
- typedef std::function<void(const std::string&, const std::string&)> Handler;
+ // error codes, tranlates to last_exec states like LAST_EXEC_OTHER_CRASH
+ typedef enum
+ {
+ ERROR_OTHER = 0,
+ ERROR_BAD_ALLOC = 1,
+ ERROR_MISSING_FILES = 2,
+ } eLastExecEvent;
+
+ // tittle, message and error code to include in error marker file
+ typedef std::function<void(const std::string&, const std::string&, S32 error_code)> Handler;
static void setHandler(const Handler&);
static void setOutOfMemoryStrings(const std::string& title, const std::string& message);
@@ -316,7 +325,7 @@ namespace LLError
static void showOutOfMemory();
static void showMissingFiles();
// Genering error
- static void show(const std::string&);
+ static void show(const std::string&, S32 error_code = -1);
private:
// needs to be preallocated before viewer runs out of memory
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index 1c4ac5a7bf..0196a24b18 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -146,7 +146,7 @@ size_t LLQueuedThread::updateQueue(F32 max_time_ms)
// schedule a call to threadedUpdate for every call to updateQueue
if (!isQuitting())
{
- mRequestQueue.post([=]()
+ mRequestQueue.post([=, this]()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("qt - update");
mIdleThread = false;
@@ -474,7 +474,7 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
#else
using namespace std::chrono_literals;
auto retry_time = LL::WorkQueue::TimePoint::clock::now() + 16ms;
- mRequestQueue.post([=]
+ mRequestQueue.post([=, this]
{
LL_PROFILE_ZONE_NAMED("processRequest - retry");
if (LL::WorkQueue::TimePoint::clock::now() < retry_time)
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 082d8b2f9f..075abf9536 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -918,7 +918,7 @@ void LLInventoryItem::asLLSD( LLSD& sd ) const
}
//sd[INV_FLAGS_LABEL] = (S32)mFlags;
sd[INV_FLAGS_LABEL] = ll_sd_from_U32(mFlags);
- sd[INV_SALE_INFO_LABEL] = mSaleInfo;
+ sd[INV_SALE_INFO_LABEL] = mSaleInfo.asLLSD();
sd[INV_NAME_LABEL] = mName;
sd[INV_DESC_LABEL] = mDescription;
sd[INV_CREATION_DATE_LABEL] = (S32) mCreationDate;
diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp
index 98836b178e..35bbc1dbb1 100644
--- a/indra/llinventory/llsaleinfo.cpp
+++ b/indra/llinventory/llsaleinfo.cpp
@@ -89,8 +89,14 @@ bool LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
LLSD LLSaleInfo::asLLSD() const
{
- LLSD sd = LLSD();
- sd["sale_type"] = lookup(mSaleType);
+ LLSD sd;
+ const char* type = lookup(mSaleType);
+ if (!type)
+ {
+ LL_WARNS_ONCE() << "Unknown sale type: " << mSaleType << LL_ENDL;
+ type = lookup(LLSaleInfo::FS_NOT);
+ }
+ sd["sale_type"] = type;
sd["sale_price"] = mSalePrice;
return sd;
}
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 45396ce9c7..e8ecc94b4b 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -137,7 +137,8 @@ const std::string LLSettingsSky::SETTING_REFLECTION_PROBE_AMBIANCE("reflection_p
const LLUUID LLSettingsSky::DEFAULT_ASSET_ID("651510b8-5f4d-8991-1592-e7eeab2a5a06");
-F32 LLSettingsSky::sAutoAdjustProbeAmbiance = 1.f;
+const F32 LLSettingsSky::DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE = 1.f;
+F32 LLSettingsSky::sAutoAdjustProbeAmbiance = DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE;
static const LLUUID DEFAULT_SUN_ID("32bfbcea-24b1-fb9d-1ef9-48a28a63730f"); // dataserver
static const LLUUID DEFAULT_MOON_ID("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver
@@ -2033,43 +2034,43 @@ F32 LLSettingsSky::getGamma() const
return mGamma;
}
-F32 LLSettingsSky::getHDRMin() const
+F32 LLSettingsSky::getHDRMin(bool auto_adjust) const
{
- if (mCanAutoAdjust)
+ if (mCanAutoAdjust && !auto_adjust)
return 0.f;
return mHDRMin;
}
-F32 LLSettingsSky::getHDRMax() const
+F32 LLSettingsSky::getHDRMax(bool auto_adjust) const
{
- if (mCanAutoAdjust)
+ if (mCanAutoAdjust && !auto_adjust)
return 0.f;
return mHDRMax;
}
-F32 LLSettingsSky::getHDROffset() const
+F32 LLSettingsSky::getHDROffset(bool auto_adjust) const
{
- if (mCanAutoAdjust)
+ if (mCanAutoAdjust && !auto_adjust)
return 1.0f;
return mHDROffset;
}
-F32 LLSettingsSky::getTonemapMix() const
+F32 LLSettingsSky::getTonemapMix(bool auto_adjust) const
{
- if (mCanAutoAdjust)
+ if (mCanAutoAdjust && !auto_adjust)
+ {
+ // legacy settings do not support tonemaping
return 0.0f;
+ }
return mTonemapMix;
}
void LLSettingsSky::setTonemapMix(F32 mix)
{
- if (mCanAutoAdjust)
- return;
-
mTonemapMix = mix;
}
diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h
index 4c635fd946..ff75aea549 100644
--- a/indra/llinventory/llsettingssky.h
+++ b/indra/llinventory/llsettingssky.h
@@ -103,6 +103,7 @@ public:
static const LLUUID DEFAULT_ASSET_ID;
+ static const F32 DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE;
static F32 sAutoAdjustProbeAmbiance;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t;
@@ -209,10 +210,10 @@ public:
F32 getGamma() const;
- F32 getHDRMin() const;
- F32 getHDRMax() const;
- F32 getHDROffset() const;
- F32 getTonemapMix() const;
+ F32 getHDRMin(bool auto_adjust = false) const;
+ F32 getHDRMax(bool auto_adjust = false) const;
+ F32 getHDROffset(bool auto_adjust = false) const;
+ F32 getTonemapMix(bool auto_adjust = false) const;
void setTonemapMix(F32 mix);
void setGamma(F32 val);
diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h
index 8ef560dadf..4004852e06 100644
--- a/indra/llmath/llvector4a.h
+++ b/indra/llmath/llvector4a.h
@@ -33,6 +33,9 @@ class LLRotation;
#include <assert.h>
#include "llpreprocessor.h"
#include "llmemory.h"
+#include "glm/vec3.hpp"
+#include "glm/vec4.hpp"
+#include "glm/gtc/type_ptr.hpp"
///////////////////////////////////
// FIRST TIME USERS PLEASE READ
@@ -364,6 +367,16 @@ public:
inline operator LLQuad() const;
+ explicit inline operator glm::vec3() const
+ {
+ return glm::make_vec3(getF32ptr());
+ };
+
+ explicit inline operator glm::vec4() const
+ {
+ return glm::make_vec4(getF32ptr());
+ };
+
private:
LLQuad mQ{};
};
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index d063b15c74..a3bfa68060 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -31,6 +31,11 @@
#include "llmath.h"
#include "llsd.h"
+
+#include "glm/vec3.hpp"
+#include "glm/vec4.hpp"
+#include "glm/gtc/type_ptr.hpp"
+
class LLVector2;
class LLVector4;
class LLVector4a;
@@ -66,6 +71,11 @@ class LLVector3
explicit LLVector3(const LLVector4a& vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2])
explicit LLVector3(const LLSD& sd);
+ // GLM interop
+ explicit LLVector3(const glm::vec3& vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
+ explicit LLVector3(const glm::vec4& vec); // Initializes LLVector3 to (vec[0]. vec[1], vec[2])
+ explicit inline operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2])
+ explicit inline operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], 1)
LLSD getValue() const;
@@ -92,6 +102,8 @@ class LLVector3
inline void set(const F32 *vec); // Sets LLVector3 to vec
const LLVector3& set(const LLVector4 &vec);
const LLVector3& set(const LLVector3d &vec);// Sets LLVector3 to vec
+ inline void set(const glm::vec4& vec); // Sets LLVector3 to vec
+ inline void set(const glm::vec3& vec); // Sets LLVector3 to vec
inline void setVec(F32 x, F32 y, F32 z); // deprecated
inline void setVec(const LLVector3 &vec); // deprecated
@@ -190,6 +202,20 @@ inline LLVector3::LLVector3(const F32 *vec)
mV[VZ] = vec[VZ];
}
+inline LLVector3::LLVector3(const glm::vec3& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+}
+
+inline LLVector3::LLVector3(const glm::vec4& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+}
+
/*
inline LLVector3::LLVector3(const LLVector3 &copy)
{
@@ -259,6 +285,20 @@ inline void LLVector3::set(const F32 *vec)
mV[2] = vec[2];
}
+inline void LLVector3::set(const glm::vec4& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+}
+
+inline void LLVector3::set(const glm::vec3& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+}
+
// deprecated
inline void LLVector3::setVec(F32 x, F32 y, F32 z)
{
@@ -471,6 +511,17 @@ inline LLVector3 operator-(const LLVector3 &a)
return LLVector3( -a.mV[0], -a.mV[1], -a.mV[2] );
}
+inline LLVector3::operator glm::vec3() const
+{
+ // Do not use glm::make_vec3 it can result in a buffer overrun on some platforms due to glm::vec3 being a simd vector internally
+ return glm::vec3(mV[VX], mV[VY], mV[VZ]);
+}
+
+inline LLVector3::operator glm::vec4() const
+{
+ return glm::vec4(mV[VX], mV[VY], mV[VZ], 1.f);
+}
+
inline F32 dist_vec(const LLVector3 &a, const LLVector3 &b)
{
F32 x = a.mV[0] - b.mV[0];
diff --git a/indra/llmath/v4math.h b/indra/llmath/v4math.h
index a5b6f506d7..a4c9668fdd 100644
--- a/indra/llmath/v4math.h
+++ b/indra/llmath/v4math.h
@@ -32,6 +32,10 @@
#include "v3math.h"
#include "v2math.h"
+#include "glm/vec3.hpp"
+#include "glm/vec4.hpp"
+#include "glm/gtc/type_ptr.hpp"
+
class LLMatrix3;
class LLMatrix4;
class LLQuaternion;
@@ -73,6 +77,11 @@ class LLVector4
mV[3] = (F32)sd[3].asReal();
}
+ // GLM interop
+ explicit LLVector4(const glm::vec3& vec); // Initializes LLVector4 to (vec, 1)
+ explicit LLVector4(const glm::vec4& vec); // Initializes LLVector4 to vec
+ explicit operator glm::vec3() const; // Initializes glm::vec3 to (vec[0]. vec[1], vec[2])
+ explicit operator glm::vec4() const; // Initializes glm::vec4 to (vec[0]. vec[1], vec[2], vec[3])
inline bool isFinite() const; // checks to see if all values of LLVector3 are finite
@@ -85,6 +94,8 @@ class LLVector4
inline void set(const LLVector4 &vec); // Sets LLVector4 to vec
inline void set(const LLVector3 &vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec
inline void set(const F32 *vec); // Sets LLVector4 to vec
+ inline void set(const glm::vec4& vec); // Sets LLVector4 to vec
+ inline void set(const glm::vec3& vec, F32 w = 1.f); // Sets LLVector4 to LLVector3 vec with w defaulted to 1
inline void setVec(F32 x, F32 y, F32 z); // deprecated
inline void setVec(F32 x, F32 y, F32 z, F32 w); // deprecated
@@ -223,6 +234,21 @@ inline LLVector4::LLVector4(const LLSD &sd)
setValue(sd);
}
+inline LLVector4::LLVector4(const glm::vec3& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+ mV[VW] = 1.f;
+}
+
+inline LLVector4::LLVector4(const glm::vec4& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+ mV[VW] = vec.w;
+}
inline bool LLVector4::isFinite() const
{
@@ -297,6 +323,21 @@ inline void LLVector4::set(const F32 *vec)
mV[VW] = vec[VW];
}
+inline void LLVector4::set(const glm::vec4& vec)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+ mV[VW] = vec.w;
+}
+
+inline void LLVector4::set(const glm::vec3& vec, F32 w)
+{
+ mV[VX] = vec.x;
+ mV[VY] = vec.y;
+ mV[VZ] = vec.z;
+ mV[VW] = w;
+}
// deprecated
inline void LLVector4::setVec(F32 x, F32 y, F32 z)
@@ -466,6 +507,16 @@ inline LLVector4 operator-(const LLVector4 &a)
return LLVector4( -a.mV[VX], -a.mV[VY], -a.mV[VZ] );
}
+inline LLVector4::operator glm::vec3() const
+{
+ return glm::vec3(mV[VX], mV[VY], mV[VZ]);
+}
+
+inline LLVector4::operator glm::vec4() const
+{
+ return glm::make_vec4(mV);
+}
+
inline F32 dist_vec(const LLVector4 &a, const LLVector4 &b)
{
LLVector4 vec = a - b;
diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp
index 4e7fa7316e..9c3069e848 100644
--- a/indra/llrender/llcubemaparray.cpp
+++ b/indra/llrender/llcubemaparray.cpp
@@ -109,7 +109,7 @@ LLCubeMapArray::~LLCubeMapArray()
{
}
-void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips)
+void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips, bool hdr)
{
U32 texname = 0;
mWidth = resolution;
@@ -127,7 +127,11 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us
bind(0);
free_cur_tex_image();
- U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F;
+ U32 format = components == 4 ? GL_RGBA16F : GL_R11F_G11F_B10F;
+ if (!hdr)
+ {
+ format = components == 4 ? GL_RGBA8 : GL_RGB8;
+ }
U32 mip = 0;
U32 mip_resolution = resolution;
while (mip_resolution >= 1)
diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h
index 675aaaf07c..bfc72a321d 100644
--- a/indra/llrender/llcubemaparray.h
+++ b/indra/llrender/llcubemaparray.h
@@ -52,7 +52,7 @@ public:
// components - number of components per pixel
// count - number of cube maps in the array
// use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used
- void allocate(U32 res, U32 components, U32 count, bool use_mips = true);
+ void allocate(U32 res, U32 components, U32 count, bool use_mips = true, bool hdr = true);
void bind(S32 stage);
void unbind();
diff --git a/indra/llrender/llfontbitmapcache.cpp b/indra/llrender/llfontbitmapcache.cpp
index ee9cfd0719..6a3af1e608 100644
--- a/indra/llrender/llfontbitmapcache.cpp
+++ b/indra/llrender/llfontbitmapcache.cpp
@@ -107,7 +107,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
mBitmapHeight = image_height;
S32 num_components = getNumComponents(bitmap_type);
- mImageRawVec[bitmap_idx].push_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
+ mImageRawVec[bitmap_idx].emplace_back(new LLImageRaw(mBitmapWidth, mBitmapHeight, num_components));
bitmap_num = static_cast<U32>(mImageRawVec[bitmap_idx].size()) - 1;
LLImageRaw* image_raw = getImageRaw(bitmap_type, bitmap_num);
@@ -117,7 +117,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
}
// Make corresponding GL image.
- mImageGLVec[bitmap_idx].push_back(new LLImageGL(image_raw, false, false));
+ mImageGLVec[bitmap_idx].emplace_back(new LLImageGL(image_raw, false, false));
LLImageGL* image_gl = getImageGL(bitmap_type, bitmap_num);
// Start at beginning of the new image.
@@ -141,6 +141,7 @@ bool LLFontBitmapCache::nextOpenPos(S32 width, S32& pos_x, S32& pos_y, EFontGlyp
bitmap_num = getNumBitmaps(bitmap_type) - 1;
mCurrentOffsetX[bitmap_idx] += width + 1;
+ mGeneration++;
return true;
}
@@ -168,6 +169,7 @@ void LLFontBitmapCache::reset()
mBitmapWidth = 0;
mBitmapHeight = 0;
+ mGeneration++;
}
//static
diff --git a/indra/llrender/llfontbitmapcache.h b/indra/llrender/llfontbitmapcache.h
index f2dfd87877..0ae4e6bed0 100644
--- a/indra/llrender/llfontbitmapcache.h
+++ b/indra/llrender/llfontbitmapcache.h
@@ -63,6 +63,7 @@ public:
U32 getNumBitmaps(EFontGlyphType bitmapType) const { return (bitmapType < EFontGlyphType::Count) ? static_cast<U32>(mImageRawVec[static_cast<U32>(bitmapType)].size()) : 0U; }
S32 getBitmapWidth() const { return mBitmapWidth; }
S32 getBitmapHeight() const { return mBitmapHeight; }
+ S32 getCacheGeneration() const { return mGeneration; }
protected:
static U32 getNumComponents(EFontGlyphType bitmap_type);
@@ -74,6 +75,7 @@ private:
S32 mCurrentOffsetY[static_cast<U32>(EFontGlyphType::Count)] = { 1 };
S32 mMaxCharWidth = 0;
S32 mMaxCharHeight = 0;
+ S32 mGeneration = 0;
std::vector<LLPointer<LLImageRaw>> mImageRawVec[static_cast<U32>(EFontGlyphType::Count)];
std::vector<LLPointer<LLImageGL>> mImageGLVec[static_cast<U32>(EFontGlyphType::Count)];
};
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index fa76669258..723f0d5062 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -148,7 +148,6 @@ LLFontFreetype::LLFontFreetype()
mIsFallback(false),
mFTFace(NULL),
mRenderGlyphCount(0),
- mAddGlyphCount(0),
mStyle(0),
mPointSize(0)
{
@@ -554,7 +553,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l
return NULL;
llassert(!mIsFallback);
- fontp->renderGlyph(requested_glyph_type, glyph_index);
+ fontp->renderGlyph(requested_glyph_type, glyph_index, wch);
EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified;
switch (fontp->mFTFace->glyph->bitmap.pixel_mode)
@@ -576,7 +575,6 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l
S32 pos_x, pos_y;
U32 bitmap_num;
mFontBitmapCachep->nextOpenPos(width, pos_x, pos_y, bitmap_glyph_type, bitmap_num);
- mAddGlyphCount++;
LLFontGlyphInfo* gi = new LLFontGlyphInfo(glyph_index, requested_glyph_type);
gi->mXBitmapOffset = pos_x;
@@ -699,7 +697,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const
}
}
-void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const
+void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const
{
if (mFTFace == NULL)
return;
@@ -714,11 +712,28 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co
FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags);
if (FT_Err_Ok != error)
{
+ if (error == FT_Err_Out_Of_Memory)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Out of memory loading glyph for character " << llformat("U+%xu", U32(wch)) << LL_ENDL;
+ }
+
std::string message = llformat(
- "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d",
- error, FT_Error_String(error), glyph_index, bitmap_type, load_flags);
+ "Error %d (%s) loading wchar %u glyph %u/%u: bitmap_type=%u, load_flags=%d",
+ error, FT_Error_String(error), wch, glyph_index, mFTFace->num_glyphs, bitmap_type, load_flags);
LL_WARNS_ONCE() << message << LL_ENDL;
error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
+ if (FT_Err_Invalid_Outline == error
+ || FT_Err_Invalid_Composite == error
+ || (FT_Err_Ok != error && LLStringOps::isEmoji(wch)))
+ {
+ glyph_index = FT_Get_Char_Index(mFTFace, '?');
+ // if '?' is not present, potentially can use last index, that's supposed to be null glyph
+ if (glyph_index > 0)
+ {
+ error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR);
+ }
+ }
llassert_always_msg(FT_Err_Ok == error, message.c_str());
}
diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h
index eba89f5def..783bf4a4b3 100644
--- a/indra/llrender/llfontfreetype.h
+++ b/indra/llrender/llfontfreetype.h
@@ -156,7 +156,7 @@ private:
bool hasGlyph(llwchar wch) const; // Has a glyph for this character
LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary
LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found)
- void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const;
+ void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const;
void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const;
std::string mName;
@@ -187,7 +187,6 @@ private:
mutable LLFontBitmapCache* mFontBitmapCachep;
mutable S32 mRenderGlyphCount;
- mutable S32 mAddGlyphCount;
};
#endif // LL_FONTFREETYPE_H
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 4c9a062246..16eec1fdd2 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -58,6 +58,7 @@ F32 LLFontGL::sVertDPI = 96.f;
F32 LLFontGL::sHorizDPI = 96.f;
F32 LLFontGL::sScaleX = 1.f;
F32 LLFontGL::sScaleY = 1.f;
+S32 LLFontGL::sResolutionGeneration = 0;
bool LLFontGL::sDisplayFont = true ;
std::string LLFontGL::sAppDir;
@@ -109,6 +110,12 @@ S32 LLFontGL::getNumFaces(const std::string& filename)
return mFontFreetype->getNumFaces(filename);
}
+S32 LLFontGL::getCacheGeneration() const
+{
+ const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+ return font_bitmap_cache->getCacheGeneration();
+}
+
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style,
ShadowType shadow, S32 max_chars, F32* right_x, bool use_ellipses, bool use_color) const
{
@@ -249,6 +256,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const LLFontBitmapCache* font_bitmap_cache = mFontFreetype->getFontBitmapCache();
+ // This looks wrong, value is dynamic.
+ // LLFontBitmapCache::nextOpenPos can alter these values when
+ // new characters get added to cache, which affects whole string.
+ // Todo: Perhaps value should update after symbols were added?
F32 inv_width = 1.f / font_bitmap_cache->getBitmapWidth();
F32 inv_height = 1.f / font_bitmap_cache->getBitmapHeight();
@@ -270,6 +281,10 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
const LLFontGlyphInfo* next_glyph = NULL;
+ // string can have more than one glyph per char (ex: bold or shadow),
+ // make sure that GLYPH_BATCH_SIZE won't end up with half a symbol.
+ // See drawGlyph.
+ // Ex: with shadows it's 6 glyps per char. 30 fits exactly 5 chars.
static constexpr S32 GLYPH_BATCH_SIZE = 30;
static thread_local LLVector4a vertices[GLYPH_BATCH_SIZE * 6];
static thread_local LLVector2 uvs[GLYPH_BATCH_SIZE * 6];
@@ -282,6 +297,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
std::pair<EFontGlyphType, S32> bitmap_entry = std::make_pair(EFontGlyphType::Grayscale, -1);
S32 glyph_count = 0;
+ llwchar last_char = wstr[begin_offset];
for (i = begin_offset; i < begin_offset + length; i++)
{
llwchar wch = wstr[i];
@@ -299,7 +315,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
}
// Per-glyph bitmap texture.
std::pair<EFontGlyphType, S32> next_bitmap_entry = fgi->mBitmapEntry;
- if (next_bitmap_entry != bitmap_entry)
+ if (next_bitmap_entry != bitmap_entry || last_char != wch)
{
// Actually draw the queued glyphs before switching their texture;
// otherwise the queued glyphs will be taken from wrong textures.
@@ -316,6 +332,11 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
bitmap_entry = next_bitmap_entry;
LLImageGL* font_image = font_bitmap_cache->getImageGL(bitmap_entry.first, bitmap_entry.second);
gGL.getTexUnit(0)->bind(font_image);
+
+ // For some reason it's not enough to compare by bitmap_entry.
+ // Issue hits emojis, japenese and chinese glyphs, only on first run.
+ // Todo: figure it out, there might be a bug with raw image data.
+ last_char = wch;
}
if ((start_x + scaled_max_pixels) < (cur_x + fgi->mXBearing + fgi->mWidth))
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 4bb6c55c65..1c8e036f58 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -90,6 +90,7 @@ public:
bool loadFace(const std::string& filename, F32 point_size, const F32 vert_dpi, const F32 horz_dpi, bool is_fallback, S32 face_n);
S32 getNumFaces(const std::string& filename);
+ S32 getCacheGeneration() const;
S32 render(const LLWString &text, S32 begin_offset,
const LLRect& rect,
@@ -224,6 +225,7 @@ public:
static F32 sHorizDPI;
static F32 sScaleX;
static F32 sScaleY;
+ static S32 sResolutionGeneration;
static bool sDisplayFont ;
static std::string sAppDir; // For loading fonts
diff --git a/indra/llrender/llfontvertexbuffer.cpp b/indra/llrender/llfontvertexbuffer.cpp
index 5bd1ca5eed..a223509d30 100644
--- a/indra/llrender/llfontvertexbuffer.cpp
+++ b/indra/llrender/llfontvertexbuffer.cpp
@@ -146,7 +146,9 @@ S32 LLFontVertexBuffer::render(
|| mLastScaleY != LLFontGL::sScaleY
|| mLastVertDPI != LLFontGL::sVertDPI
|| mLastHorizDPI != LLFontGL::sHorizDPI
- || mLastOrigin != LLFontGL::sCurOrigin)
+ || mLastOrigin != LLFontGL::sCurOrigin
+ || mLastResGeneration != LLFontGL::sResolutionGeneration
+ || mLastFontCacheGen != fontp->getCacheGeneration())
{
genBuffers(fontp, text, begin_offset, x, y, color, halign, valign,
style, shadow, max_chars, max_pixels, right_x, use_ellipses, use_color);
@@ -178,6 +180,9 @@ void LLFontVertexBuffer::genBuffers(
{
// todo: add a debug build assert if this triggers too often for to long?
mBufferList.clear();
+ // Save before rendreing, it can change mid-render,
+ // so will need to rerender previous characters
+ mLastFontCacheGen = fontp->getCacheGeneration();
gGL.beginList(&mBufferList);
mChars = fontp->render(text, begin_offset, x, y, color, halign, valign,
@@ -201,6 +206,7 @@ void LLFontVertexBuffer::genBuffers(
mLastVertDPI = LLFontGL::sVertDPI;
mLastHorizDPI = LLFontGL::sHorizDPI;
mLastOrigin = LLFontGL::sCurOrigin;
+ mLastResGeneration = LLFontGL::sResolutionGeneration;
if (right_x)
{
diff --git a/indra/llrender/llfontvertexbuffer.h b/indra/llrender/llfontvertexbuffer.h
index af195dfff9..a9e1e2337c 100644
--- a/indra/llrender/llfontvertexbuffer.h
+++ b/indra/llrender/llfontvertexbuffer.h
@@ -117,8 +117,13 @@ private:
F32 mLastScaleY = 1.f;
F32 mLastVertDPI = 0.f;
F32 mLastHorizDPI = 0.f;
+ S32 mLastResGeneration = 0;
LLCoordGL mLastOrigin;
+ // Adding new characters to bitmap cache can alter value from getBitmapWidth();
+ // which alters whole string. So rerender when new characters were added to cache.
+ S32 mLastFontCacheGen = 0;
+
static bool sEnableBufferCollection;
};
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 58c456f134..873ab0cff5 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -59,6 +59,7 @@ public:
bool attachNothing = false;
bool hasHeroProbes = false;
bool isPBRTerrain = false;
+ bool hasTonemap = false;
};
// ============= Structure for caching shader uniforms ===============
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index e8bba851e1..0146ed3119 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -348,6 +348,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat)
case GL_RGB: return 24;
case GL_SRGB: return 24;
case GL_RGB8: return 24;
+ case GL_R11F_G11F_B10F: return 32;
case GL_RGBA: return 32;
case GL_RGBA8: return 32;
case GL_RGB10_A2: return 32;
@@ -1868,7 +1869,7 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name)
ref();
LL::WorkQueue::postMaybe(
mMainQueue,
- [=]()
+ [=, this]()
{
LL_PROFILE_ZONE_NAMED("cglt - delete callback");
syncTexName(new_tex_name);
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 37e15b96c3..9f3f42d6d5 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -751,9 +751,8 @@ void LLLightState::setPosition(const LLVector4& position)
++gGL.mLightHash;
mPosition = position;
//transform position by current modelview matrix
- glm::vec4 pos(glm::make_vec4(position.mV));
- const glm::mat4& mat = gGL.getModelviewMatrix();
- pos = mat * pos;
+ glm::vec4 pos(position);
+ pos = gGL.getModelviewMatrix() * pos;
mPosition.set(glm::value_ptr(pos));
}
@@ -808,7 +807,7 @@ void LLLightState::setSpotDirection(const LLVector3& direction)
++gGL.mLightHash;
//transform direction by current modelview matrix
- glm::vec3 dir(glm::make_vec3(direction.mV));
+ glm::vec3 dir(direction);
const glm::mat3 mat(gGL.getModelviewMatrix());
dir = mat * dir;
@@ -2106,12 +2105,14 @@ void set_last_projection(const glm::mat4& mat)
glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)
{
- //const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
- //return glm::vec3(
- // (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w,
- // (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w,
- // (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w
- //);
+#if 1 // SIMD path results in strange crashes. Fall back to scalar for now.
+ const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
+ return glm::vec3(
+ (vec[0] * mat[0][0] + vec[1] * mat[1][0] + vec[2] * mat[2][0] + mat[3][0]) / w,
+ (vec[0] * mat[0][1] + vec[1] * mat[1][1] + vec[2] * mat[2][1] + mat[3][1]) / w,
+ (vec[0] * mat[0][2] + vec[1] * mat[1][2] + vec[2] * mat[2][2] + mat[3][2]) / w
+ );
+#else
LLVector4a x, y, z, s, t, p, q;
x.splat(vec.x);
@@ -2141,4 +2142,5 @@ glm::vec3 mul_mat4_vec3(const glm::mat4& mat, const glm::vec3& vec)
res.setAdd(x, z);
res.div(q);
return glm::make_vec3(res.getF32ptr());
+#endif
}
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 0885740934..4807c12226 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -291,6 +291,14 @@ bool LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
}
}
+ if (features->hasTonemap)
+ {
+ if (!shader->attachFragmentObject("deferred/tonemapUtilF.glsl"))
+ {
+ return false;
+ }
+ }
+
// NOTE order of shader object attaching is VERY IMPORTANT!!!
if (features->hasAtmospherics)
{
@@ -466,6 +474,7 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
if (filename.empty())
{
+ LL_WARNS("ShaderLoading") << "tried loading empty filename" << LL_ENDL;
return 0;
}
@@ -923,6 +932,8 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev
}
LL_WARNS("ShaderLoading") << "Failed to load " << filename << LL_ENDL;
}
+
+ LL_DEBUGS("ShaderLoading") << "loadShaderFile() completed, ret: " << U32(ret) << LL_ENDL;
return ret;
}
@@ -1389,6 +1400,7 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("screenTex");
mReservedUniforms.push_back("screenDepth");
mReservedUniforms.push_back("refTex");
+ mReservedUniforms.push_back("exclusionTex");
mReservedUniforms.push_back("eyeVec");
mReservedUniforms.push_back("time");
mReservedUniforms.push_back("waveDir1");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 34bd73a42e..46788841a5 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -36,6 +36,8 @@ public:
LLShaderMgr();
virtual ~LLShaderMgr();
+ // Note: although you can use statically hashed strings to just bind a random uniform, it's generally preferably that you use this.
+ // Always document what the actual shader uniform is next to the shader uniform in this struct.
// clang-format off
typedef enum
{ // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms()
@@ -234,6 +236,7 @@ public:
WATER_SCREENTEX, // "screenTex"
WATER_SCREENDEPTH, // "screenDepth"
WATER_REFTEX, // "refTex"
+ WATER_EXCLUSIONTEX, // "exclusionTex"
WATER_EYEVEC, // "eyeVec"
WATER_TIME, // "time"
WATER_WAVE_DIR1, // "waveDir1"
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 42a9e267d2..b664065532 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -28,6 +28,7 @@
#include "llfolderview.h"
#include "llfolderviewmodel.h"
+#include "llcallbacklist.h"
#include "llclipboard.h" // *TODO: remove this once hack below gone.
#include "llkeyboard.h"
#include "lllineeditor.h"
@@ -274,7 +275,11 @@ LLFolderView::~LLFolderView( void )
mRenamer = NULL;
mStatusTextBox = NULL;
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+ if (mPopupMenuHandle.get())
+ {
+ mPopupMenuHandle.get()->die();
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
mPopupMenuHandle.markDead();
mAutoOpenItems.removeAllNodes();
@@ -1095,7 +1100,10 @@ bool LLFolderView::handleKeyHere( KEY key, MASK mask )
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
- LLMenuGL::sMenuContainer->hideMenus();
+ if (LLMenuGL::sMenuContainer->hideMenus())
+ {
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
}
switch( key )
@@ -1340,7 +1348,10 @@ bool LLFolderView::handleUnicodeCharHere(llwchar uni_char)
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->isOpen())
{
- LLMenuGL::sMenuContainer->hideMenus();
+ if (LLMenuGL::sMenuContainer->hideMenus())
+ {
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
}
//do text search
@@ -1612,7 +1623,11 @@ void LLFolderView::deleteAllChildren()
{
LLUI::getInstance()->removePopup(mRenamer);
}
- if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
+ if (mPopupMenuHandle.get())
+ {
+ mPopupMenuHandle.get()->die();
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, this);
+ }
mPopupMenuHandle.markDead();
mScrollContainer = NULL;
mRenameItem = NULL;
@@ -1979,9 +1994,24 @@ void LLFolderView::updateMenu()
LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
if (menu && menu->getVisible())
{
- updateMenuOptions(menu);
+ // When fetching folders in bulk or in parts, each callback
+ // cause updateMenu individually, so make sure it gets called
+ // only once per frame, after callbacks are done.
+ // gIdleCallbacks has built in dupplicate protection.
+ gIdleCallbacks.addFunction(onIdleUpdateMenu, this);
+ }
+}
+
+void LLFolderView::onIdleUpdateMenu(void* user_data)
+{
+ LLFolderView* self = (LLFolderView*)user_data;
+ LLMenuGL* menu = (LLMenuGL*)self->mPopupMenuHandle.get();
+ if (menu)
+ {
+ self->updateMenuOptions(menu);
menu->needsArrange(); // update menu height if needed
}
+ gIdleCallbacks.deleteFunction(onIdleUpdateMenu, self);
}
bool LLFolderView::isFolderSelected()
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 62ef2a0626..7ed10d9223 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -266,6 +266,7 @@ public:
private:
void updateMenuOptions(LLMenuGL* menu);
void updateRenamerPosition();
+ static void onIdleUpdateMenu(void* user_data);
protected:
LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
@@ -414,6 +415,7 @@ public:
virtual void doItem(LLFolderViewItem* item) {}
void setApply(bool apply);
void clearOpenFolders() { mOpenFolders.clear(); }
+ bool hasOpenFolders() { return !mOpenFolders.empty(); }
protected:
std::set<LLUUID> mOpenFolders;
bool mApply;
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index cd80e7f63f..7405413a3d 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -1555,7 +1555,7 @@ bool LLNotifications::loadTemplates()
gDirUtilp->findSkinnedFilenames(LLDir::XUI, "notifications.xml", LLDir::ALL_SKINS);
if (search_paths.empty())
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem finding notifications.xml" << LL_ENDL;
}
@@ -1565,7 +1565,7 @@ bool LLNotifications::loadTemplates()
if (!success || root.isNull() || !root->hasName( "notifications" ))
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem reading XML from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1576,7 +1576,7 @@ bool LLNotifications::loadTemplates()
if(!params.validateBlock())
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem reading XUI from UI Notifications file: " << base_filename << LL_ENDL;
return false;
}
@@ -1643,7 +1643,7 @@ bool LLNotifications::loadVisibilityRules()
if(!params.validateBlock())
{
- LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"));
+ LLError::LLUserWarningMsg::show(LLTrans::getString("MBMissingFile"), LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
LL_ERRS() << "Problem reading UI Notification Visibility Rules file: " << full_filename << LL_ENDL;
return false;
}
diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp
index df4b0ef6a0..4714665e8b 100644
--- a/indra/llui/llstyle.cpp
+++ b/indra/llui/llstyle.cpp
@@ -39,7 +39,7 @@ LLStyle::Params::Params()
readonly_color("readonly_color", LLColor4::black),
selected_color("selected_color", LLColor4::black),
alpha("alpha", 1.f),
- font("font", LLFontGL::getFontMonospace()),
+ font("font", LLStyle::getDefaultFont()),
image("image"),
link_href("href"),
is_link("is_link")
@@ -70,6 +70,11 @@ const LLFontGL* LLStyle::getFont() const
return mFont;
}
+const LLFontGL* LLStyle::getDefaultFont()
+{
+ return LLFontGL::getFontMonospace();
+}
+
void LLStyle::setLinkHREF(const std::string& href)
{
mLink = href;
diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h
index e506895de5..0c78fe5a9f 100644
--- a/indra/llui/llstyle.h
+++ b/indra/llui/llstyle.h
@@ -72,6 +72,7 @@ public:
void setFont(const LLFontGL* font);
const LLFontGL* getFont() const;
+ static const LLFontGL* getDefaultFont();
const std::string& getLinkHREF() const { return mLink; }
void setLinkHREF(const std::string& href);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index cbbf83d679..fae22fd248 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1438,7 +1438,8 @@ void LLTextBase::onVisibilityChange( bool new_visibility )
//virtual
void LLTextBase::setValue(const LLSD& value )
{
- setText(value.asString());
+ static const LLStyle::Params input_params = LLStyle::Params();
+ setText(value.asString(), input_params);
}
//virtual
@@ -3880,8 +3881,7 @@ bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w
if (mForceNewLine)
{
// Chat, string can't be smaller then font height even if it is empty
- LLStyleSP s(new LLStyle(LLStyle::Params().visible(true)));
- height = s->getFont()->getLineHeight();
+ height = LLStyle::getDefaultFont()->getLineHeight();
return true; // new line
}
@@ -3945,9 +3945,7 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1)
{
- LLStyleSP s( new LLStyle(LLStyle::Params().visible(true)));
-
- mFontHeight = s->getFont()->getLineHeight();
+ mFontHeight = LLStyle::getDefaultFont()->getLineHeight();
}
LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1)
{
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 05af36b71e..9f945d3735 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -159,7 +159,8 @@ LLSD LLTextBox::getValue() const
bool LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text )
{
mText.setArg(key, text);
- LLTextBase::setText(mText.getString());
+ static const LLStyle::Params input_params = LLStyle::Params();
+ LLTextBase::setText(mText.getString(), input_params);
return true;
}
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 4af5376a8b..e82af0b96f 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -48,7 +48,7 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
"Second Life viewer couldn't access some of the files it needs and will be closed."
"\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
"contact https://support.secondlife.com if issue persists after reinstall.";
- LLError::LLUserWarningMsg::show(error_string);
+ LLError::LLUserWarningMsg::show(error_string, LLError::LLUserWarningMsg::ERROR_MISSING_FILES);
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << LL_ENDL;
return false;
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index c160382c17..195f68e08b 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -194,6 +194,11 @@ bool LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor,
return false;
}
+bool LLWindowCallbacks::handleDisplayChanged()
+{
+ return false;
+}
+
bool LLWindowCallbacks::handleWindowDidChangeScreen(LLWindow *window)
{
return false;
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 63b585231f..d812f93524 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -69,6 +69,7 @@ public:
virtual bool handleTimerEvent(LLWindow *window);
virtual bool handleDeviceChange(LLWindow *window);
virtual bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
+ virtual bool handleDisplayChanged();
virtual bool handleWindowDidChangeScreen(LLWindow *window);
enum DragNDropAction {
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index a6ca26236c..7749f03d38 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1061,7 +1061,7 @@ F32 LLWindowMacOSX::getGamma()
&greenGamma,
&blueMin,
&blueMax,
- &blueGamma) == noErr)
+ &blueGamma) == kCGErrorSuccess)
{
// So many choices...
// Let's just return the green channel gamma for now.
@@ -1112,7 +1112,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma)
&greenGamma,
&blueMin,
&blueMax,
- &blueGamma) != noErr)
+ &blueGamma) != kCGErrorSuccess)
{
return false;
}
@@ -1127,7 +1127,7 @@ bool LLWindowMacOSX::setGamma(const F32 gamma)
gamma,
blueMin,
blueMax,
- gamma) != noErr)
+ gamma) != kCGErrorSuccess)
{
return false;
}
@@ -1179,7 +1179,7 @@ bool LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
newPosition.y = screen_pos.mY;
CGSetLocalEventsSuppressionInterval(0.0);
- if(CGWarpMouseCursorPosition(newPosition) == noErr)
+ if(CGWarpMouseCursorPosition(newPosition) == kCGErrorSuccess)
{
result = true;
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index a48bd35765..557af1b158 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -44,6 +44,7 @@
#include "llstring.h"
#include "lldir.h"
#include "llsdutil.h"
+#include "llsys.h"
#include "llglslshader.h"
#include "llthreadsafequeue.h"
#include "stringize.h"
@@ -80,10 +81,6 @@ const S32 BITS_PER_PIXEL = 32;
const S32 MAX_NUM_RESOLUTIONS = 32;
const F32 ICON_FLASH_TIME = 0.5f;
-#ifndef WM_DPICHANGED
-#define WM_DPICHANGED 0x02E0
-#endif
-
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96 // Win7
#endif
@@ -1306,8 +1303,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo
catch (...)
{
LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat");
- OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
- mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1318,8 +1314,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo
if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
&pfd))
{
- OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"),
- mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1357,8 +1352,7 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo
if (!SetPixelFormat(mhDC, pixel_format, &pfd))
{
- OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"),
- mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1366,16 +1360,14 @@ bool LLWindowWin32::switchContext(bool fullscreen, const LLCoordScreen& size, bo
if (!(mhRC = SafeCreateContext(mhDC)))
{
- OSMessageBox(mCallbacks->translateString("MBGLContextErr"),
- mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
if (!wglMakeCurrent(mhDC, mhRC))
{
- OSMessageBox(mCallbacks->translateString("MBGLContextActErr"),
- mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1581,15 +1573,14 @@ const S32 max_format = (S32)num_formats - 1;
if (!mhDC)
{
- OSMessageBox(mCallbacks->translateString("MBDevContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBDevContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
if (!SetPixelFormat(mhDC, pixel_format, &pfd))
{
- OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"),
- mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtSetErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1621,7 +1612,7 @@ const S32 max_format = (S32)num_formats - 1;
{
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);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1630,7 +1621,7 @@ const S32 max_format = (S32)num_formats - 1;
if (!DescribePixelFormat(mhDC, pixel_format, sizeof(PIXELFORMATDESCRIPTOR),
&pfd))
{
- OSMessageBox(mCallbacks->translateString("MBPixelFmtDescErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBPixelFmtDescErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1652,14 +1643,14 @@ const S32 max_format = (S32)num_formats - 1;
if (!wglMakeCurrent(mhDC, mhRC))
{
- OSMessageBox(mCallbacks->translateString("MBGLContextActErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextActErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
if (!gGLManager.initGL())
{
- OSMessageBox(mCallbacks->translateString("MBVideoDrvErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBVideoDrvErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
close();
return false;
}
@@ -1864,7 +1855,7 @@ void* LLWindowWin32::createSharedContext()
if (!rc && !(rc = wglCreateContext(mhDC)))
{
close();
- OSMessageBox(mCallbacks->translateString("MBGLContextErr"), mCallbacks->translateString("MBError"), OSMB_OK);
+ LLError::LLUserWarningMsg::show(mCallbacks->translateString("MBGLContextErr"), 8/*LAST_EXEC_GRAPHICS_INIT*/);
}
return rc;
@@ -2963,6 +2954,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
}
+ case WM_DISPLAYCHANGE:
+ {
+ WINDOW_IMP_POST(window_imp->mCallbacks->handleDisplayChanged());
+ }
+
case WM_SETFOCUS:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS");
@@ -4670,6 +4666,23 @@ void LLWindowWin32::LLWindowWin32Thread::checkDXMem()
// Alternatively use GetDesc from below to get adapter's memory
UINT64 budget_mb = info.Budget / (1024 * 1024);
+ if (gGLManager.mIsIntel)
+ {
+ U32Megabytes phys_mb = gSysMemory.getPhysicalMemoryKB();
+ LL_WARNS() << "Physical memory: " << phys_mb << " MB" << LL_ENDL;
+
+ if (phys_mb > 0)
+ {
+ // Intel uses 'shared' vram, cap it to 25% of total memory
+ // Todo: consider caping all adapters at least to 50% ram
+ budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25));
+ }
+ else
+ {
+ // if no data available, cap to 2Gb
+ budget_mb = llmin(budget_mb, (UINT64)2048);
+ }
+ }
if (gGLManager.mVRAM < (S32)budget_mb)
{
gGLManager.mVRAM = (S32)budget_mb;
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index cfbea419b2..09a3ed029d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -167,6 +167,7 @@ set(viewer_SOURCE_FILES
lldrawpooltree.cpp
lldrawpoolwater.cpp
lldrawpoolwlsky.cpp
+ lldrawpoolwaterexclusion.cpp
lldynamictexture.cpp
llemote.cpp
llenvironment.cpp
@@ -840,6 +841,7 @@ set(viewer_HEADER_FILES
lldrawpooltree.h
lldrawpoolwater.h
lldrawpoolwlsky.h
+ lldrawpoolwaterexclusion.h
lldynamictexture.h
llemote.h
llenvironment.h
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
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4739728bee..1aec56447d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -12783,7 +12783,7 @@
<key>UpdaterWillingToTest</key>
<map>
<key>Comment</key>
- <string>Whether or not the updater should offer test candidate upgrades.</string>
+ <string>Whether or not the updater should offer Beta upgrades.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
index fc6d4d7727..c4610bffac 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredTonemap.glsl
@@ -28,138 +28,11 @@
out vec4 frag_color;
uniform sampler2D diffuseRect;
-uniform sampler2D exposureMap;
-uniform vec2 screen_res;
in vec2 vary_fragcoord;
vec3 linear_to_srgb(vec3 cl);
-
-//===============================================================
-// tone mapping taken from Khronos sample implementation
-//===============================================================
-
-// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
-const mat3 ACESInputMat = mat3
-(
- 0.59719, 0.07600, 0.02840,
- 0.35458, 0.90834, 0.13383,
- 0.04823, 0.01566, 0.83777
-);
-
-
-// ODT_SAT => XYZ => D60_2_D65 => sRGB
-const mat3 ACESOutputMat = mat3
-(
- 1.60475, -0.10208, -0.00327,
- -0.53108, 1.10813, -0.07276,
- -0.07367, -0.00605, 1.07602
-);
-
-// ACES tone map (faster approximation)
-// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
-vec3 toneMapACES_Narkowicz(vec3 color)
-{
- const float A = 2.51;
- const float B = 0.03;
- const float C = 2.43;
- const float D = 0.59;
- const float E = 0.14;
- return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
-}
-
-
-// ACES filmic tone map approximation
-// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
-vec3 RRTAndODTFit(vec3 color)
-{
- vec3 a = color * (color + 0.0245786) - 0.000090537;
- vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
- return a / b;
-}
-
-
-// tone mapping
-vec3 toneMapACES_Hill(vec3 color)
-{
- color = ACESInputMat * color;
-
- // Apply RRT and ODT
- color = RRTAndODTFit(color);
-
- color = ACESOutputMat * color;
-
- // Clamp to [0, 1]
- color = clamp(color, 0.0, 1.0);
-
- return color;
-}
-
-// Khronos Neutral tonemapping
-// https://github.com/KhronosGroup/ToneMapping/tree/main
-// Input color is non-negative and resides in the Linear Rec. 709 color space.
-// Output color is also Linear Rec. 709, but in the [0, 1] range.
-vec3 PBRNeutralToneMapping( vec3 color )
-{
- const float startCompression = 0.8 - 0.04;
- const float desaturation = 0.15;
-
- float x = min(color.r, min(color.g, color.b));
- float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
- color -= offset;
-
- float peak = max(color.r, max(color.g, color.b));
- if (peak < startCompression) return color;
-
- const float d = 1. - startCompression;
- float newPeak = 1. - d * d / (peak + d - startCompression);
- color *= newPeak / peak;
-
- float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
- return mix(color, newPeak * vec3(1, 1, 1), g);
-}
-
-uniform float exposure;
-uniform float tonemap_mix;
-uniform int tonemap_type;
-
-vec3 toneMap(vec3 color)
-{
-#ifndef NO_POST
- float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
-
- color *= exposure * exp_scale;
-
- vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
-
- switch(tonemap_type)
- {
- case 0:
- color = PBRNeutralToneMapping(color);
- break;
- case 1:
- color = toneMapACES_Hill(color);
- break;
- }
-
- // mix tonemapped and linear here to provide adjustment
- color = mix(clamped_color, color, tonemap_mix);
-#endif
-
- return color;
-}
-
-//===============================================================
-
-void debugExposure(inout vec3 color)
-{
- float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
- exp_scale *= 0.5;
- if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
- {
- color = vec3(1,0,0);
- }
-}
+vec3 toneMap(vec3 color);
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl
new file mode 100644
index 0000000000..a63b8d7c2b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/tonemapUtilF.glsl
@@ -0,0 +1,180 @@
+/**
+ * @file postDeferredTonemap.glsl
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, 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$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+uniform sampler2D exposureMap;
+uniform vec2 screen_res;
+in vec2 vary_fragcoord;
+
+//===============================================================
+// tone mapping taken from Khronos sample implementation
+//===============================================================
+
+// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
+const mat3 ACESInputMat = mat3
+(
+ 0.59719, 0.07600, 0.02840,
+ 0.35458, 0.90834, 0.13383,
+ 0.04823, 0.01566, 0.83777
+);
+
+
+// ODT_SAT => XYZ => D60_2_D65 => sRGB
+const mat3 ACESOutputMat = mat3
+(
+ 1.60475, -0.10208, -0.00327,
+ -0.53108, 1.10813, -0.07276,
+ -0.07367, -0.00605, 1.07602
+);
+
+// ACES tone map (faster approximation)
+// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
+vec3 toneMapACES_Narkowicz(vec3 color)
+{
+ const float A = 2.51;
+ const float B = 0.03;
+ const float C = 2.43;
+ const float D = 0.59;
+ const float E = 0.14;
+ return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
+}
+
+
+// ACES filmic tone map approximation
+// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
+vec3 RRTAndODTFit(vec3 color)
+{
+ vec3 a = color * (color + 0.0245786) - 0.000090537;
+ vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
+ return a / b;
+}
+
+
+// tone mapping
+vec3 toneMapACES_Hill(vec3 color)
+{
+ color = ACESInputMat * color;
+
+ // Apply RRT and ODT
+ color = RRTAndODTFit(color);
+
+ color = ACESOutputMat * color;
+
+ // Clamp to [0, 1]
+ color = clamp(color, 0.0, 1.0);
+
+ return color;
+}
+
+// Khronos Neutral tonemapping
+// https://github.com/KhronosGroup/ToneMapping/tree/main
+// Input color is non-negative and resides in the Linear Rec. 709 color space.
+// Output color is also Linear Rec. 709, but in the [0, 1] range.
+vec3 PBRNeutralToneMapping( vec3 color )
+{
+ const float startCompression = 0.8 - 0.04;
+ const float desaturation = 0.15;
+
+ float x = min(color.r, min(color.g, color.b));
+ float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
+ color -= offset;
+
+ float peak = max(color.r, max(color.g, color.b));
+ if (peak < startCompression) return color;
+
+ const float d = 1. - startCompression;
+ float newPeak = 1. - d * d / (peak + d - startCompression);
+ color *= newPeak / peak;
+
+ float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
+ return mix(color, newPeak * vec3(1, 1, 1), g);
+}
+
+uniform float exposure;
+uniform float tonemap_mix;
+uniform int tonemap_type;
+
+vec3 toneMap(vec3 color)
+{
+#ifndef NO_POST
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+
+ color *= exposure * exp_scale;
+
+ vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
+
+ switch(tonemap_type)
+ {
+ case 0:
+ color = PBRNeutralToneMapping(color);
+ break;
+ case 1:
+ color = toneMapACES_Hill(color);
+ break;
+ }
+
+ // mix tonemapped and linear here to provide adjustment
+ color = mix(clamped_color, color, tonemap_mix);
+#endif
+
+ return color;
+}
+
+
+vec3 toneMapNoExposure(vec3 color)
+{
+#ifndef NO_POST
+ vec3 clamped_color = clamp(color.rgb, vec3(0.0), vec3(1.0));
+
+ switch(tonemap_type)
+ {
+ case 0:
+ color = PBRNeutralToneMapping(color);
+ break;
+ case 1:
+ color = toneMapACES_Hill(color);
+ break;
+ }
+
+ // mix tonemapped and linear here to provide adjustment
+ color = mix(clamped_color, color, tonemap_mix);
+#endif
+
+ return color;
+}
+
+
+//===============================================================
+
+void debugExposure(inout vec3 color)
+{
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+ exp_scale *= 0.5;
+ if (abs(vary_fragcoord.y-exp_scale) < 0.01 && vary_fragcoord.x < 0.1)
+ {
+ color = vec3(1,0,0);
+ }
+}
diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
index d7f6d20547..bf8737615f 100644
--- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
@@ -41,6 +41,26 @@ vec3 srgb_to_linear(vec3 cs)
}
+
+vec4 srgb_to_linear4(vec4 cs)
+{
+ vec4 low_range = cs / vec4(12.92);
+ vec4 high_range = pow((cs+vec4(0.055))/vec4(1.055), vec4(2.4));
+ bvec4 lte = lessThanEqual(cs,vec4(0.04045));
+
+#ifdef OLD_SELECT
+ vec4 result;
+ result.r = lte.r ? low_range.r : high_range.r;
+ result.g = lte.g ? low_range.g : high_range.g;
+ result.b = lte.b ? low_range.b : high_range.b;
+ result.a = lte.a ? low_range.a : high_range.a;
+ return result;
+#else
+ return mix(high_range, low_range, lte);
+#endif
+
+}
+
vec3 linear_to_srgb(vec3 cl)
{
cl = clamp(cl, vec3(0), vec3(1));
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index 20b61e9302..44a979e565 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -66,11 +66,11 @@ vec4 getWaterFogViewNoClip(vec3 pos)
float t2 = kd + ks * es;
float t3 = pow(F, t2*l) - 1.0;
- float L = min(t1/t2*t3, 1.0);
+ float L = pow(min(t1/t2*t3, 1.0), 1.0/1.7);
float D = pow(0.98, l*kd);
- return vec4(srgb_to_linear(kc.rgb*L), D);
+ return vec4(srgb_to_linear(kc.rgb)*L, D);
}
vec4 getWaterFogView(vec3 pos)
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl
new file mode 100644
index 0000000000..dea76da5a5
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleColorF.glsl
@@ -0,0 +1,57 @@
+/**
+ * @file simpleColorF.glsl
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+out vec4 frag_color;
+
+in vec4 vertex_color;
+in vec4 vertex_position;
+
+uniform vec4 waterPlane;
+uniform float waterSign;
+
+void waterClip(vec3 pos)
+{
+ // TODO: make this less branchy
+ if (waterSign > 0)
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0)
+ {
+ discard;
+ }
+ }
+ else
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0)
+ {
+ discard;
+ }
+ }
+}
+
+void main()
+{
+
+ frag_color = vertex_color;
+}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl
new file mode 100644
index 0000000000..4564e56313
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoAtmosV.glsl
@@ -0,0 +1,43 @@
+/**
+ * @file simpleNoAtmosV.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, 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$
+ */
+
+uniform mat4 modelview_matrix;
+uniform mat4 modelview_projection_matrix;
+
+uniform vec4 color;
+
+in vec3 position;
+
+out vec4 vertex_color;
+out vec4 vertex_position;
+
+void main()
+{
+ //transform vertex
+ vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+ vertex_position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = vertex_position;
+ vertex_color = color;
+}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index d6569cda33..50b40e9c20 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -150,7 +150,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
float amb_da = 0.0;//ambiance;
if (da > 0.0)
{
- lit = max(da * dist_atten,0.0);
+ lit = clamp(da * dist_atten, 0.0, 1.0);
col = lit * light_col * diffuse;
amb_da += (da*0.5+0.5) * ambiance;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
index a4d3962d12..f8803f1a29 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -140,7 +140,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe
float amb_da = ambiance;
if (da >= 0.0)
{
- lit = max(da * dist_atten, 0.0);
+ lit = clamp(da * dist_atten, 0.0, 1.0);
col = lit * light_col * diffuse;
amb_da += (da*0.5 + 0.5) * ambiance;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 4bae7b6deb..2f577f8459 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -38,6 +38,8 @@ uniform float max_probe_lod;
uniform bool transparent_surface;
+uniform int classic_mode;
+
#define MAX_REFMAP_COUNT 256 // must match LL_MAX_REFLECTION_PROBE_COUNT
layout (std140) uniform ReflectionProbes
@@ -739,7 +741,10 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- ambenv = sampleProbeAmbient(pos, norm, amblit);
+ ambenv = amblit;
+
+ if (classic_mode == 0)
+ ambenv = sampleProbeAmbient(pos, norm, amblit);
float lod = (1.0-glossiness)*reflection_lods;
glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
@@ -784,9 +789,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
probeIndex[probeInfluences++] = 0;
doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit);
-
- // fudge factor to get PBR water at a similar luminance ot legacy water
- glossenv *= 0.4;
}
void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
@@ -845,7 +847,10 @@ void sampleReflectionProbesLegacy(out vec3 ambenv, out vec3 glossenv, out vec3 l
vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- ambenv = sampleProbeAmbient(pos, norm, amblit);
+ ambenv = amblit;
+
+ if (classic_mode == 0)
+ ambenv = sampleProbeAmbient(pos, norm, amblit);
if (glossiness > 0.0)
{
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
index 2bf785e773..091c25d15e 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/waterHazeF.glsl
@@ -35,13 +35,25 @@ vec4 getWaterFogView(vec3 pos);
uniform int above_water;
+uniform sampler2D exclusionTex;
+
void main()
{
vec2 tc = vary_fragcoord.xy/vary_fragcoord.w*0.5+0.5;
float depth = getDepth(tc.xy);
+ float mask = texture(exclusionTex, tc.xy).r;
if (above_water > 0)
{
+ // Just discard if we're in the exclusion mask.
+ // The previous invisiprim hack we're replacing would also crank up water fog desntiy.
+ // But doing that makes exclusion surfaces very slow as we'd need to render even more into the mask.
+ // - Geenz 2025-02-06
+ if (mask < 1)
+ {
+ discard;
+ }
+
// we want to depth test when the camera is above water, but some GPUs have a hard time
// with depth testing against render targets that are bound for sampling in the same shader
// so we do it manually here
@@ -51,11 +63,13 @@ void main()
{
discard;
}
+
}
vec4 pos = getPositionWithDepth(tc, depth);
vec4 fogged = getWaterFogView(pos.xyz);
+ fogged.a = max(pow(fogged.a, 1.7), 0);
frag_color = max(fogged, vec4(0)); //output linear since local lights will be added to this shader's results
diff --git a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 1c02dc764d..fa410e9f11 100644
--- a/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -26,6 +26,7 @@
out vec4 frag_color;
uniform sampler2D bumpMap;
+uniform sampler2D exclusionTex;
#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
@@ -59,6 +60,9 @@ void mirrorClip(vec3 position);
void main()
{
mirrorClip(vary_position);
+ vec2 screen_tc = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+ float water_mask = texture(exclusionTex, screen_tc).r;
+
vec4 color;
//get detail normals
@@ -68,8 +72,8 @@ void main()
vec3 wavef = normalize(wave1+wave2+wave3);
//figure out distortion vector (ripply)
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- distort = distort+wavef.xy*refScale;
+ vec2 distort = screen_tc;
+ distort = mix(distort, distort+wavef.xy*refScale, water_mask);
#ifdef TRANSPARENT_WATER
vec4 fb = texture(screenTex, distort);
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
index 84c287fc50..7320e9ca06 100644
--- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -25,6 +25,8 @@
// class3/environment/waterF.glsl
+#define WATER_MINIMAL 1
+
out vec4 frag_color;
#ifdef HAS_SUN_SHADOW
@@ -86,23 +88,17 @@ uniform sampler2D screenTex;
uniform sampler2D depthMap;
#endif
-uniform sampler2D refTex;
+uniform sampler2D exclusionTex;
-uniform float sunAngle;
-uniform float sunAngle2;
+uniform int classic_mode;
uniform vec3 lightDir;
uniform vec3 specular;
-uniform float lightExp;
+uniform float blurMultiplier;
uniform float refScale;
uniform float kd;
-uniform vec2 screenRes;
uniform vec3 normScale;
uniform float fresnelScale;
uniform float fresnelOffset;
-uniform float blurMultiplier;
-uniform vec4 waterFogColor;
-uniform vec3 waterFogColorLinear;
-
//bigWave is (refCoord.w, view.w);
in vec4 refCoord;
@@ -122,6 +118,10 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2)
vec3 srgb_to_linear(vec3 col);
vec3 linear_to_srgb(vec3 col);
+vec3 atmosLighting(vec3 light);
+vec3 scaleSoftClip(vec3 light);
+vec3 toneMapNoExposure(vec3 color);
+
vec3 vN, vT, vB;
vec3 transform_normal(vec3 vNt)
@@ -132,59 +132,107 @@ vec3 transform_normal(vec3 vNt)
void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear);
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit);
+
+
vec3 getPositionWithNDC(vec3 ndc);
+void generateWaveNormals(out vec3 wave1, out vec3 wave2, out vec3 wave3)
+{
+ // Generate all of our wave normals.
+ // We layer these back and forth.
+
+ vec2 bigwave = vec2(refCoord.w, view.w);
+
+ vec3 wave1_a = texture(bumpMap, bigwave).xyz * 2.0 - 1.0;
+ vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz * 2.0 - 1.0;
+ vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz * 2.0 - 1.0;
+
+ vec3 wave1_b = texture(bumpMap2, bigwave).xyz * 2.0 - 1.0;
+ vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz * 2.0 - 1.0;
+ vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz * 2.0 - 1.0;
+
+ wave1 = BlendNormal(wave1_a, wave1_b);
+ wave2 = BlendNormal(wave2_a, wave2_b);
+ wave3 = BlendNormal(wave3_a, wave3_b);
+}
+
+void calculateFresnelFactors(out vec3 df3, out vec2 df2, vec3 viewVec, vec3 wave1, vec3 wave2, vec3 wave3, vec3 wavef)
+{
+ // We calculate the fresnel here.
+ // We do this by getting the dot product for each sets of waves, and applying scale and offset.
+
+ df3 = max(vec3(0), vec3(
+ dot(viewVec, wave1),
+ dot(viewVec, (wave2 + wave3) * 0.5),
+ dot(viewVec, wave3)
+ ) * fresnelScale + fresnelOffset);
+
+ df3 *= df3;
+
+ df2 = max(vec2(0), vec2(
+ df3.x + df3.y + df3.z,
+ dot(viewVec, wavef) * fresnelScale + fresnelOffset
+ ));
+}
+
void main()
{
mirrorClip(vary_position);
+
vN = vary_normal;
vT = vary_tangent;
vB = cross(vN, vT);
vec3 pos = vary_position.xyz;
+ float linear_depth = 1.0 / -pos.z;
float dist = length(pos.xyz);
//normalize view vector
vec3 viewVec = normalize(pos.xyz);
- //get wave normals
- vec2 bigwave = vec2(refCoord.w, view.w);
- vec3 wave1_a = texture(bumpMap, bigwave, -2.0 ).xyz*2.0-1.0;
- vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1_b = texture(bumpMap2, bigwave ).xyz*2.0-1.0;
- vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+ // Setup our waves.
- //wave1_a = wave2_a = wave3_a = wave1_b = wave2_b = wave3_b = vec3(0,0,1);
+ vec3 wave1 = vec3(0, 0, 1);
+ vec3 wave2 = vec3(0, 0, 1);
+ vec3 wave3 = vec3(0, 0, 1);
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+ generateWaveNormals(wave1, wave2, wave3);
+ float dmod = sqrt(dist);
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- //wave1 = transform_normal(wave1);
- //wave2 = transform_normal(wave2);
- //wave3 = transform_normal(wave3);
-
vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+ vec3 df3 = vec3(0);
+ vec2 df2 = vec2(0);
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+
+ calculateFresnelFactors(df3, df2, normalize(view.xyz), wave1, wave2, wave3, wavef);
+
vec3 waver = wavef*3.0;
vec3 up = transform_normal(vec3(0,0,1));
float vdu = -dot(viewVec, up)*2.0;
- vec3 wave_ibl = wavef;
+ vec3 wave_ibl = wavef * normScale;
wave_ibl.z *= 2.0;
wave_ibl = transform_normal(normalize(wave_ibl));
vec3 norm = transform_normal(normalize(wavef));
vdu = clamp(vdu, 0.0, 1.0);
- wavef.z *= max(vdu*vdu*vdu, 0.1);
+ //wavef.z *= max(vdu*vdu*vdu, 0.1);
wavef = normalize(wavef);
@@ -194,62 +242,66 @@ void main()
float dist2 = dist;
dist = max(dist, 5.0);
- float dmod = sqrt(dist);
-
//figure out distortion vector (ripply)
- vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0);
+ vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0) * 2.0;
distort2 = clamp(distort2, vec2(0), vec2(0.999));
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
float shadow = 1.0f;
+ float water_mask = texture(exclusionTex, distort).r;
+
#ifdef HAS_SUN_SHADOW
shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort);
#endif
- calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+ vec3 sunlit_linear = sunlit;
+ float fade = 1.0;
+#ifdef TRANSPARENT_WATER
+ float depth = texture(depthMap, distort).r;
- vec3 sunlit_linear = srgb_to_linear(sunlit);
+ vec3 refPos = getPositionWithNDC(vec3(distort*2.0-vec2(1.0), depth*2.0-1.0));
-#ifdef TRANSPARENT_WATER
- vec4 fb = texture(screenTex, distort2);
- float depth = texture(depthMap, distort2).r;
- vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
+ // Calculate some distance fade in the water to better assist with refraction blending and reducing the refraction texture's "disconnect".
+ fade = max(0.0,min(1.0, (pos.z - refPos.z) / 10.0)) * water_mask;
+ distort2 = mix(distort, distort2, min(1.0, fade * 10.0));
+ depth = texture(depthMap, distort2).r;
- if (refPos.z > pos.z-0.05)
+ refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
+
+ if (pos.z < refPos.z - 0.05)
{
- //we sampled an above water sample, don't distort
distort2 = distort;
- fb = texture(screenTex, distort2);
- depth = texture(depthMap, distort2).r;
- refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
}
+ vec4 fb = texture(screenTex, distort2);
+
#else
vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0));
-#endif
- // fudge sample on other side of water to be a tad darker
- fb.rgb *= 0.75;
+ if (water_mask < 1.0)
+ discard;
+#endif
- float metallic = 0.0;
- float perceptualRoughness = 0.05;
+ float metallic = 1.0;
+ float perceptualRoughness = blurMultiplier;
float gloss = 1.0 - perceptualRoughness;
vec3 irradiance = vec3(0);
vec3 radiance = vec3(0);
- sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
+ vec3 legacyenv = vec3(0);
- irradiance = vec3(0);
+ // TODO: Make this an option.
+#ifdef WATER_MINIMAL
+ sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
+#elif WATER_MINIMAL_PLUS
+ sampleReflectionProbes(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, false, amblit);
+#endif
vec3 diffuseColor = vec3(0);
vec3 specularColor = vec3(0);
- calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);
+ vec3 specular_linear = srgb_to_linear(specular);
+ calcDiffuseSpecular(specular_linear, metallic, diffuseColor, specularColor);
vec3 v = -normalize(pos.xyz);
@@ -257,46 +309,36 @@ void main()
float ao = 1.0;
vec3 light_dir = transform_normal(lightDir);
- perceptualRoughness = 0.0;
- metallic = 1.0;
-
float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
- float nl = 0;
+ float nl = 0.0;
vec3 diffPunc = vec3(0);
vec3 specPunc = vec3(0);
- pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc);
-
- vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10));
-
- vec3 color = punctual * sunlit_linear * 2.75 * shadow;
- vec3 iblDiff;
- vec3 iblSpec;
- pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0, iblDiff, iblSpec);
-
- color += iblDiff + iblSpec;
+ pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir), nl, diffPunc, specPunc);
- float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
- vec2 brdf = BRDF(clamp(nv, 0.0, 1.0), 1.0);
- float f = 1.0-brdf.y; //1.0 - (brdf.x+brdf.y);
- f *= 0.9;
- f *= f;
+ vec3 punctual = clamp(nl * (diffPunc + specPunc), vec3(0), vec3(10)) * sunlit_linear * shadow * atten;
+ radiance *= df2.y;
+ //radiance = toneMapNoExposure(radiance);
+ vec3 color = vec3(0);
+ color = mix(fb.rgb, radiance, min(1.0, df2.x)) + punctual.rgb;
- // incoming scale is [0, 1] with 0.5 being default
- // shift to 0.5 to 1.5
- f *= (fresnelScale - 0.5)+1.0;
+ float water_haze_scale = 4.0;
- // incoming offset is [0, 1] with 0.5 being default
- // shift from -1 to 1
- f += (fresnelOffset - 0.5) * 2.0;
+ if (classic_mode > 0)
+ water_haze_scale = 1.0;
- f = clamp(f, 0.0, 1.0);
+ // This looks super janky, but we do this to restore water haze in the distance.
+ // These values were finagled in to try and bring back some of the distant brightening on legacy water. Also works reasonably well on PBR skies such as PBR midday.
+ // color = mix(color, additive * water_haze_scale, (1 - atten));
- color = ((1.0 - f) * color) + fb.rgb;
+ // We shorten the fade here at the shoreline so it doesn't appear too soft from a distance.
+ fade *= 60.0;
+ fade = min(1.0, fade);
+ color = mix(fb.rgb, color, fade);
- float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
+ float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.0);
- frag_color = max(vec4(color, spec), vec4(0));
+ frag_color = min(vec4(1),max(vec4(color.rgb, spec * water_mask), vec4(0)));
}
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index d894e1b24e..cb79410d72 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -85,6 +85,7 @@ RenderExposure 1 4
RenderTonemapType 1 1
RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
+RenderMaxTextureResolution 1 2048
//
// Low Graphics Settings
@@ -126,6 +127,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 512
//
// Medium Low Graphics Settings
@@ -167,6 +169,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 1024
//
// Medium Graphics Settings (standard)
@@ -207,6 +210,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Medium High Graphics Settings
@@ -247,6 +251,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Graphics Settings (SSAO + sun shadows)
@@ -287,6 +292,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Ultra Graphics Settings (deferred + SSAO + all shadows)
@@ -327,6 +333,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Ultra graphics (REALLY PURTY!)
@@ -367,6 +374,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Class Unknown Hardware (unknown)
@@ -399,6 +407,7 @@ RenderShadowDetail 0 0
RenderReflectionProbeDetail 0 -1
RenderMirrors 0 0
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 2048
list Intel
RenderAnisotropic 1 0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index eedce61509..f3c3c4fcd9 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -85,6 +85,7 @@ RenderTonemapType 1 1
RenderTonemapMix 1 1
RenderDisableVintageMode 1 1
RenderDownScaleMethod 1 0
+RenderMaxTextureResolution 1 2048
//
// Low Graphics Settings
@@ -126,6 +127,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 512
//
@@ -168,6 +170,7 @@ RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 1024
//
// Medium Graphics Settings (standard)
@@ -208,6 +211,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Medium High Graphics Settings
@@ -248,6 +252,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Graphics Settings (SSAO + sun shadows)
@@ -288,6 +293,7 @@ RenderCASSharpness 1 0
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// High Ultra Graphics Settings (SSAO + all shadows)
@@ -328,6 +334,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Ultra graphics (REALLY PURTY!)
@@ -368,6 +375,7 @@ RenderCASSharpness 1 0.4
RenderExposure 1 1
RenderTonemapType 1 1
RenderTonemapMix 1 0.7
+RenderMaxTextureResolution 1 2048
//
// Class Unknown Hardware (unknown)
@@ -399,6 +407,7 @@ RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
RenderMirrors 0 0
RenderDisableVintageMode 1 0
+RenderMaxTextureResolution 1 2048
list TexUnit8orLess
RenderDeferredSSAO 0 0
diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp
index f362fa51cb..43e8fa3e3c 100644
--- a/indra/newview/gltfscenemanager.cpp
+++ b/indra/newview/gltfscenemanager.cpp
@@ -356,8 +356,9 @@ void GLTFSceneManager::addGLTFObject(LLViewerObject* obj, LLUUID gltf_id)
llassert(obj->getVolume()->getParams().getSculptID() == gltf_id);
llassert(obj->getVolume()->getParams().getSculptType() == LL_SCULPT_TYPE_GLTF);
- if (obj->mGLTFAsset)
- { // object already has a GLTF asset, don't reload it
+ if (obj->mGLTFAsset || obj->mIsGLTFAssetMissing )
+ {
+ // object already has a GLTF asset or load failed, don't reload it
// TODO: below assertion fails on dupliate requests for assets -- possibly need to touch up asset loading state machine
// llassert(std::find(mObjects.begin(), mObjects.end(), obj) != mObjects.end());
@@ -398,16 +399,19 @@ void GLTFSceneManager::onGLTFBinLoadComplete(const LLUUID& id, LLAssetType::ETyp
}
else
{
- LL_WARNS("GLTF") << "Failed to prepare GLTF asset: " << id << LL_ENDL;
+ LL_WARNS("GLTF") << "Failed to prepare GLTF asset: " << id << ". Marking as missing." << LL_ENDL;
+ obj->mIsGLTFAssetMissing = true;
obj->mGLTFAsset = nullptr;
}
}
}
+ obj->unref(); // todo: use LLPointer
}
}
else
{
- LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << LL_ENDL;
+ LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << ". Marking as missing." << LL_ENDL;
+ obj->mIsGLTFAssetMissing = true;
obj->unref();
}
});
@@ -446,7 +450,8 @@ void GLTFSceneManager::onGLTFLoadComplete(const LLUUID& id, LLAssetType::EType a
}
else
{
- LL_WARNS("GLTF") << "Buffer URI is not a valid UUID: " << buffer.mUri << LL_ENDL;
+ LL_WARNS("GLTF") << "Buffer URI is not a valid UUID: " << buffer.mUri << " for asset id: " << id << ". Marking as missing." << LL_ENDL;
+ obj->mIsGLTFAssetMissing = true;
obj->unref();
return;
}
@@ -455,7 +460,8 @@ void GLTFSceneManager::onGLTFLoadComplete(const LLUUID& id, LLAssetType::EType a
}
else
{
- LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << LL_ENDL;
+ LL_WARNS("GLTF") << "Failed to load GLTF asset: " << id << ". Marking as missing." << LL_ENDL;
+ obj->mIsGLTFAssetMissing = true;
obj->unref();
}
}
@@ -500,7 +506,7 @@ void GLTFSceneManager::update()
LLNewBufferedResourceUploadInfo::uploadFinish_f finish = [this, buffer](LLUUID assetId, LLSD response)
{
LLAppViewer::instance()->postToMainCoro(
- [=]()
+ [=, this]()
{
if (mUploadingAsset)
{
@@ -517,6 +523,7 @@ void GLTFSceneManager::update()
if (mUploadingObject)
{
mUploadingObject->mGLTFAsset = nullptr;
+ mUploadingObject->mIsGLTFAssetMissing = false;
mUploadingObject->setGLTFAsset(assetId);
mUploadingObject->markForUpdate();
mUploadingObject = nullptr;
@@ -975,9 +982,9 @@ void renderAssetDebug(LLViewerObject* obj, Asset* asset)
LLVector4a t;
agent_to_asset.affineTransform(gDebugRaycastStart, t);
- start = glm::make_vec4(t.getF32ptr());
+ start = vec4(t);
agent_to_asset.affineTransform(gDebugRaycastEnd, t);
- end = glm::make_vec4(t.getF32ptr());
+ end = vec4(t);
start.w = end.w = 1.0;
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 26c080bf89..dde4555770 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -56,6 +56,7 @@
#include "llgroupmgr.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
+#include "lllandmarkactions.h"
#include "llmorphview.h"
#include "llmoveview.h"
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
@@ -4317,8 +4318,17 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id)
{
- LLViewerRegion *regionp = getRegion();
- if(regionp && teleportCore())
+ bool is_local(false);
+ LLViewerRegion* regionp = getRegion();
+
+ if (LLLandmark* landmark = gLandmarkList.getAsset(landmark_asset_id, NULL))
+ {
+ LLVector3d pos_global;
+ landmark->getGlobalPos(pos_global);
+ is_local = (regionp->getHandle() == to_region_handle_global((F32)pos_global.mdV[VX], (F32)pos_global.mdV[VY]));
+ }
+
+ if(regionp && teleportCore(is_local))
{
LL_INFOS("Teleport") << "Sending TeleportLandmarkRequest. Current region handle " << regionp->getHandle()
<< " region id " << regionp->getRegionID()
@@ -4879,10 +4889,19 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)
LLXMLNodePtr root;
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
- if (!success || !root || !root->hasName( "teleport_messages" ))
+ if (!success)
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Problem reading teleport string XML file: "
- << xml_filename << LL_ENDL;
+ << xml_filename << LL_ENDL;
+ return;
+ }
+
+ if (!root || !root->hasName("teleport_messages"))
+ {
+ LLError::LLUserWarningMsg::showMissingFiles();
+ LL_ERRS() << "Invalid teleport string XML file: "
+ << xml_filename << LL_ENDL;
return;
}
diff --git a/indra/newview/llagentpicksinfo.cpp b/indra/newview/llagentpicksinfo.cpp
index e2a2d2d8a9..265e4060ff 100644
--- a/indra/newview/llagentpicksinfo.cpp
+++ b/indra/newview/llagentpicksinfo.cpp
@@ -28,6 +28,7 @@
#include "llagentpicksinfo.h"
#include "llagent.h"
+#include "llagentbenefits.h"
#include "llavatarpropertiesprocessor.h"
const S32 MAX_AVATAR_PICKS = 10;
@@ -85,10 +86,9 @@ private:
LLAgentPicksInfo::LLAgentPicksInfo()
: mAgentPicksObserver(NULL)
- , mMaxNumberOfPicks(MAX_AVATAR_PICKS)
// Disable Pick creation until we get number of Picks from server - in case
// avatar has maximum number of Picks.
- , mNumberOfPicks(mMaxNumberOfPicks)
+ , mNumberOfPicks(S32_MAX)
{
}
@@ -110,7 +110,13 @@ void LLAgentPicksInfo::requestNumberOfPicks()
mAgentPicksObserver->sendAgentPicksRequest();
}
-bool LLAgentPicksInfo::isPickLimitReached()
+// static
+S32 LLAgentPicksInfo::getMaxNumberOfPicks()
+{
+ return LLAgentBenefitsMgr::current().getPicksLimit();
+}
+
+bool LLAgentPicksInfo::isPickLimitReached() const
{
return getNumberOfPicks() >= getMaxNumberOfPicks();
}
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index 9bc105a655..3514ade65d 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -52,17 +52,17 @@ public:
/**
* Returns number of Picks.
*/
- S32 getNumberOfPicks() { return mNumberOfPicks; }
+ S32 getNumberOfPicks() const { return mNumberOfPicks; }
/**
* Returns maximum number of Picks.
*/
- S32 getMaxNumberOfPicks() { return mMaxNumberOfPicks; }
+ static S32 getMaxNumberOfPicks();
/**
* Returns true if Agent has maximum allowed number of Picks.
*/
- bool isPickLimitReached();
+ bool isPickLimitReached() const;
/**
* After creating or deleting a Pick we can assume operation on server will be
@@ -83,15 +83,9 @@ private:
*/
void setNumberOfPicks(S32 number) { mNumberOfPicks = number; }
- /**
- * Sets maximum number of Picks.
- */
- void setMaxNumberOfPicks(S32 max_picks) { mMaxNumberOfPicks = max_picks; }
-
private:
LLAgentPicksObserver* mAgentPicksObserver;
- S32 mMaxNumberOfPicks;
S32 mNumberOfPicks;
};
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 946d674e8b..4e0c5d7df0 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -537,9 +537,14 @@ LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
selfStopPhase("update_appearance_on_destroy");
- LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions,
- mEnforceOrdering,
- mPostUpdateFunc);
+ //avoid calling an update inside coroutine
+ bool force_restrictions(mEnforceItemRestrictions);
+ bool enforce_ordering(mEnforceOrdering);
+ nullary_func_t post_update_func(mPostUpdateFunc);
+ doOnIdleOneTime([force_restrictions,enforce_ordering,post_update_func]()
+ {
+ LLAppearanceMgr::instance().updateAppearanceFromCOF(force_restrictions, enforce_ordering, post_update_func);
+ });
}
}
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7c040a3ca1..2c203869c7 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -305,6 +305,7 @@ bool gUseQuickTime = true;
eLastExecEvent gLastExecEvent = LAST_EXEC_NORMAL;
S32 gLastExecDuration = -1; // (<0 indicates unknown)
+LLUUID gLastAgentSessionId;
#if LL_WINDOWS
# define LL_PLATFORM_KEY "win"
@@ -381,7 +382,6 @@ const int MAX_MARKER_LENGTH = 1024;
const std::string MARKER_FILE_NAME("SecondLife.exec_marker");
const std::string START_MARKER_FILE_NAME("SecondLife.start_marker");
const std::string ERROR_MARKER_FILE_NAME("SecondLife.error_marker");
-const std::string LLERROR_MARKER_FILE_NAME("SecondLife.llerror_marker");
const std::string LOGOUT_MARKER_FILE_NAME("SecondLife.logout_marker");
static bool gDoDisconnect = false;
static std::string gLaunchFileOnQuit;
@@ -2262,6 +2262,7 @@ bool LLAppViewer::initThreads()
return true;
}
+// Callback for all LL_ERROR calls
void errorCallback(LLError::ELevel level, const std::string &error_string)
{
if (level == LLError::LEVEL_ERROR)
@@ -2277,15 +2278,38 @@ void errorCallback(LLError::ELevel level, const std::string &error_string)
// haven't actually trashed anything yet, we can afford to write the whole
// static info file.
LLAppViewer::instance()->writeDebugInfo();
+
+ std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+ if (!LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
+ {
+ // If marker doesn't exist, create a marker with llerror code for next launch
+ // otherwise don't override existing file
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_LLERROR_CRASH);
+ }
}
}
-void errorMSG(const std::string& title_string, const std::string& message_string)
+// Callback for LLError::LLUserWarningMsg
+void errorHandler(const std::string& title_string, const std::string& message_string, S32 code)
{
if (!message_string.empty())
{
OSMessageBox(message_string, title_string.empty() ? LLTrans::getString("MBFatalError") : title_string, OSMB_OK);
}
+ switch (code)
+ {
+ case LLError::LLUserWarningMsg::ERROR_OTHER:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_OTHER_CRASH);
+ break;
+ case LLError::LLUserWarningMsg::ERROR_BAD_ALLOC:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_BAD_ALLOC);
+ break;
+ case LLError::LLUserWarningMsg::ERROR_MISSING_FILES:
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
+ break;
+ default:
+ break;
+ }
}
void LLAppViewer::initLoggingAndGetLastDuration()
@@ -2299,7 +2323,7 @@ void LLAppViewer::initLoggingAndGetLastDuration()
LLError::addGenericRecorder(&errorCallback);
//LLError::setTimeFunction(getRuntime);
- LLError::LLUserWarningMsg::setHandler(errorMSG);
+ LLError::LLUserWarningMsg::setHandler(errorHandler);
if (mSecondInstance)
@@ -2591,6 +2615,7 @@ bool LLAppViewer::initConfiguration()
OSMessageBox(
"Unable to load default settings file. The installation may be corrupted.",
LLStringUtil::null,OSMB_OK);
+ LLAppViewer::instance()->createErrorMarker(LAST_EXEC_MISSING_FILES);
return false;
}
@@ -3755,16 +3780,21 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
bool sameVersion = false;
std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
- char marker_version[MAX_MARKER_LENGTH];
+ char marker_data[MAX_MARKER_LENGTH];
S32 marker_version_length;
LLAPRFile marker_file;
marker_file.open(marker_name, LL_APR_RB);
if (marker_file.getFileHandle())
{
- marker_version_length = marker_file.read(marker_version, sizeof(marker_version));
- std::string marker_string(marker_version, marker_version_length);
- if ( 0 == my_version.compare( 0, my_version.length(), marker_version, 0, marker_version_length ) )
+ marker_version_length = marker_file.read(marker_data, sizeof(marker_data));
+ std::string marker_string(marker_data, marker_version_length);
+ size_t pos = marker_string.find('\n');
+ if (pos != std::string::npos)
+ {
+ marker_string = marker_string.substr(0, pos);
+ }
+ if ( 0 == my_version.compare( 0, my_version.length(), marker_string, 0, marker_string.length()) )
{
sameVersion = true;
}
@@ -3778,6 +3808,88 @@ bool LLAppViewer::markerIsSameVersion(const std::string& marker_name) const
return sameVersion;
}
+void LLAppViewer::recordSessionToMarker()
+{
+ std::string marker_version(LLVersionInfo::instance().getChannelAndVersion());
+ std::string uuid_str = "\n" + gAgentSessionID.asString();
+ if (marker_version.length() + uuid_str.length() > MAX_MARKER_LENGTH)
+ {
+ LL_WARNS_ONCE("MarkerFile") << "Version length (" << marker_version.length() << ")"
+ << " greater than maximum (" << MAX_MARKER_LENGTH << ")"
+ << ": marker matching may be incorrect"
+ << LL_ENDL;
+ }
+
+ mMarkerFile.seek(APR_SET, (S32)marker_version.length());
+ mMarkerFile.write(uuid_str.data(), (S32)uuid_str.length());
+}
+
+LLUUID LLAppViewer::getMarkerSessionId(const std::string& marker_name) const
+{
+ std::string data;
+ if (getMarkerData(marker_name, data))
+ {
+ return LLUUID(data);
+ }
+ return LLUUID();
+}
+
+S32 LLAppViewer::getMarkerErrorCode(const std::string& marker_name) const
+{
+ std::string data;
+ if (getMarkerData(marker_name, data))
+ {
+ if (data.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ return std::stoi(data);
+ }
+ }
+ return -1;
+}
+
+bool LLAppViewer::getMarkerData(const std::string& marker_name, std::string& data) const
+{
+ bool sameVersion = false;
+
+ std::string my_version(LLVersionInfo::instance().getChannelAndVersion());
+ char marker_data[MAX_MARKER_LENGTH];
+ S32 marker_version_length;
+
+ LLAPRFile marker_file;
+ marker_file.open(marker_name, LL_APR_RB);
+ if (marker_file.getFileHandle())
+ {
+ marker_version_length = marker_file.read(marker_data, sizeof(marker_data));
+ marker_file.close();
+ std::string marker_string(marker_data, marker_version_length);
+ size_t pos = marker_string.find('\n');
+ if (pos != std::string::npos)
+ {
+ data = marker_string.substr(pos + 1, marker_version_length - pos - 1);
+ marker_string = marker_string.substr(0, pos);
+ }
+ if (0 == my_version.compare(0, my_version.length(), marker_string, 0, marker_string.length()))
+ {
+ sameVersion = true;
+ }
+ else
+ {
+ return false;
+ }
+ LL_DEBUGS("MarkerFile") << "Compare markers for '" << marker_name << "': "
+ << "\n mine '" << my_version << "'"
+ << "\n marker '" << marker_string << "'"
+ << "\n " << (sameVersion ? "same" : "different") << " version"
+ << LL_ENDL;
+ return true;
+ }
+ return false;
+}
+
void LLAppViewer::processMarkerFiles()
{
//We've got 4 things to test for here
@@ -3796,6 +3908,10 @@ void LLAppViewer::processMarkerFiles()
// File exists...
// first, read it to see if it was created by the same version (we need this later)
marker_is_same_version = markerIsSameVersion(mMarkerFileName);
+ if (marker_is_same_version)
+ {
+ gLastAgentSessionId = getMarkerSessionId(mMarkerFileName);
+ }
// now test to see if this file is locked by a running process (try to open for write)
marker_log_stream << "Checking exec marker file for lock...";
@@ -3885,44 +4001,27 @@ void LLAppViewer::processMarkerFiles()
}
LLAPRFile::remove(logout_marker_file);
}
- // further refine based on whether or not a marker created during an llerr crash is found
- std::string llerror_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, LLERROR_MARKER_FILE_NAME);
- if(LLAPRFile::isExist(llerror_marker_file, NULL, LL_APR_RB))
- {
- if (markerIsSameVersion(llerror_marker_file))
- {
- if ( gLastExecEvent == LAST_EXEC_LOGOUT_FROZE )
- {
- gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
- }
- else
- {
- gLastExecEvent = LAST_EXEC_LLERROR_CRASH;
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL;
- }
- }
- else
- {
- LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' found, but versions did not match" << LL_ENDL;
- }
- LLAPRFile::remove(llerror_marker_file);
- }
// and last refine based on whether or not a marker created during a non-llerr crash is found
std::string error_marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB))
{
- if (markerIsSameVersion(error_marker_file))
+ S32 marker_code = getMarkerErrorCode(error_marker_file);
+ if (marker_code >= 0)
{
if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE)
{
gLastExecEvent = LAST_EXEC_LOGOUT_CRASH;
LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL;
}
+ else if (marker_code > 0 && marker_code < (S32)LAST_EXEC_COUNT)
+ {
+ gLastExecEvent = (eLastExecEvent)marker_code;
+ LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ }
else
{
gLastExecEvent = LAST_EXEC_OTHER_CRASH;
- LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
+ LL_INFOS("MarkerFile") << "Error marker '" << error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL;
}
}
else
@@ -5212,6 +5311,24 @@ void LLAppViewer::postToMainCoro(const LL::WorkQueue::Work& work)
gMainloopWork.post(work);
}
+void LLAppViewer::createErrorMarker(eLastExecEvent error_code) const
+{
+ if (!mSecondInstance)
+ {
+ std::string error_marker = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ERROR_MARKER_FILE_NAME);
+
+ LLAPRFile file;
+ file.open(error_marker, LL_APR_WB);
+ if (file.getFileHandle())
+ {
+ recordMarkerVersion(file);
+ std::string data = "\n" + std::to_string((S32)error_code);
+ file.write(data.data(), static_cast<S32>(data.length()));
+ file.close();
+ }
+ }
+}
+
void LLAppViewer::outOfMemorySoftQuit()
{
if (!mQuitRequested)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 4ce4259ed8..b4756eecd6 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -66,6 +66,20 @@ class LLViewerRegion;
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
+typedef enum
+{
+ LAST_EXEC_NORMAL = 0,
+ LAST_EXEC_FROZE,
+ LAST_EXEC_LLERROR_CRASH,
+ LAST_EXEC_OTHER_CRASH,
+ LAST_EXEC_LOGOUT_FROZE,
+ LAST_EXEC_LOGOUT_CRASH,
+ LAST_EXEC_BAD_ALLOC,
+ LAST_EXEC_MISSING_FILES,
+ LAST_EXEC_GRAPHICS_INIT,
+ LAST_EXEC_COUNT
+} eLastExecEvent;
+
class LLAppViewer : public LLApp
{
public:
@@ -147,6 +161,7 @@ public:
void saveExperienceCache();
void removeMarkerFiles();
+ void recordSessionToMarker();
void removeDumpDir();
// LLAppViewer testing helpers.
@@ -227,6 +242,9 @@ public:
// post given work to the "mainloop" work queue for handling on the main thread
void postToMainCoro(const LL::WorkQueue::Work& work);
+ // Writes an error code into the error_marker file for use on next startup.
+ void createErrorMarker(eLastExecEvent error_code) const;
+
// Attempt a 'soft' quit with disconnect and saving of settings/cache.
// Intended to be thread safe.
// Good chance of viewer crashing either way, but better than alternatives.
@@ -272,6 +290,9 @@ private:
void processMarkerFiles();
static void recordMarkerVersion(LLAPRFile& marker_file);
bool markerIsSameVersion(const std::string& marker_name) const;
+ LLUUID getMarkerSessionId(const std::string& marker_name) const;
+ S32 getMarkerErrorCode(const std::string& marker_name) const;
+ bool getMarkerData(const std::string& marker_name, std::string &data) const;
void idle();
void idleShutdown();
@@ -347,18 +368,9 @@ private:
extern LLSD gDebugInfo;
extern bool gShowObjectUpdates;
-typedef enum
-{
- LAST_EXEC_NORMAL = 0,
- LAST_EXEC_FROZE,
- LAST_EXEC_LLERROR_CRASH,
- LAST_EXEC_OTHER_CRASH,
- LAST_EXEC_LOGOUT_FROZE,
- LAST_EXEC_LOGOUT_CRASH
-} eLastExecEvent;
-
extern eLastExecEvent gLastExecEvent; // llstartup
extern S32 gLastExecDuration; ///< the duration of the previous run in seconds (<0 indicates unknown)
+extern LLUUID gLastAgentSessionId; // will be set if agent logged in
extern const char* gPlatform;
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 0c939add95..af5a46742c 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -357,8 +357,9 @@ void LLConversationItemSession::clearParticipants()
void LLConversationItemSession::clearAndDeparentModels()
{
- for (LLFolderViewModelItem* child : mChildren)
+ for (child_list_t::iterator it = mChildren.begin(); it != mChildren.end();)
{
+ LLFolderViewModelItem* child = *it;
if (child->getNumRefs() == 0)
{
// LLConversationItemParticipant can be created but not assigned to any view,
@@ -370,8 +371,8 @@ void LLConversationItemSession::clearAndDeparentModels()
// Model is still assigned to some view/widget
child->setParent(NULL);
}
+ it = mChildren.erase(it);
}
- mChildren.clear();
}
LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 74d7997a8d..325c3f9b94 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -42,6 +42,7 @@
#include "lldrawpooltree.h"
#include "lldrawpoolterrain.h"
#include "lldrawpoolwater.h"
+#include "lldrawpoolwaterexclusion.h"
#include "llface.h"
#include "llviewerobjectlist.h" // For debug listing.
#include "pipeline.h"
@@ -119,6 +120,9 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_GLTF_PBR_ALPHA_MASK:
poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
break;
+ case POOL_WATEREXCLUSION:
+ poolp = new LLDrawPoolWaterExclusion();
+ break;
default:
LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
return NULL;
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index bc412214c7..1c8864a9df 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -55,6 +55,7 @@ public:
// based on fill rate and likelihood to occlude future passes (faster, large occluders first).
//
POOL_SKY = 1,
+ POOL_WATEREXCLUSION,
POOL_WL_SKY,
POOL_SIMPLE,
POOL_FULLBRIGHT,
@@ -140,7 +141,7 @@ public:
PASS_GRASS,
PASS_FULLBRIGHT,
PASS_FULLBRIGHT_RIGGED,
- PASS_INVISIBLE,
+ PASS_INVISIBLE, // Formerly, invisiprims. Now, water exclusion surfaces.
PASS_INVISIBLE_RIGGED,
PASS_INVISI_SHINY,
PASS_INVISI_SHINY_RIGGED,
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 53d6e528b6..7d58511d41 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -176,173 +176,156 @@ void LLDrawPoolWater::renderPostDeferred(S32 pass)
light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
- // set up normal maps filtering
- for (auto norm_map : mWaterNormp)
- {
- if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
- }
+ LLTexUnit::eTextureFilterOptions filter_mode = has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT;
LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
LLGLSLShader *shader = nullptr;
- // two passes, first with standard water shader bound, second with edge water shader bound
- for (int edge = 0; edge < 2; edge++)
+ // One pass, one of two shaders. Void water and region water share state.
+ // There isn't a good reason anymore to really have void water run in a separate pass.
+ // It also just introduced a bunch of weird state consistency stuff that we really don't need.
+ // Not to mention, re-binding the the same shader and state for that shader is kind of wasteful.
+ // - Geenz 2025-02-11
+ // select shader
+ if (underwater)
{
- // select shader
- if (underwater)
- {
- shader = &gUnderWaterProgram;
- }
- else
- {
- if (edge)
- {
- shader = &gWaterEdgeProgram;
- }
- else
- {
- shader = &gWaterProgram;
- }
- }
+ shader = &gUnderWaterProgram;
+ }
+ else
+ {
+ shader = &gWaterProgram;
+ }
- gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
+ gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
- //bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
- LLViewerTexture* tex_a = mWaterNormp[0];
- LLViewerTexture* tex_b = mWaterNormp[1];
+ F32 blend_factor = (F32)pwater->getBlendFactor();
- F32 blend_factor = (F32)pwater->getBlendFactor();
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ tex_a->setFilteringOption(filter_mode);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b && !tex_a)
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_b);
+ tex_b->setFilteringOption(filter_mode);
+ blend_factor = 0; // only one tex provided, no blending
+ }
+ else if (tex_b != tex_a)
+ {
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP, tex_a);
+ tex_a->setFilteringOption(filter_mode);
+ shader->bindTexture(LLViewerShaderMgr::BUMP_MAP2, tex_b);
+ tex_b->setFilteringOption(filter_mode);
+ }
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ shader->bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &gPipeline.mWaterExclusionMask);
- if (tex_a && (!tex_b || (tex_a == tex_b)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b && !tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b != tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
- }
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- // bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
- F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
+ shader->bindTexture(LLShaderMgr::WATER_SCREENTEX, &gPipeline.mWaterDis);
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2));
+ }
- F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
+ F32 water_height = environment.getWaterHeight();
+ F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
+ shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
+ shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- if (screentex > -1)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- if (mShaderLevel == 1)
- {
- fog_color.mV[VALPHA] = (F32)(log(fog_density) / log(2));
- }
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
- F32 water_height = environment.getWaterHeight();
- F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
- shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
- shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
- shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
- shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
+ shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, fmaxf(0, pwater->getBlurMultiplier()) * 2);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ static LLStaticHashedString s_exposure("exposure");
+ static LLStaticHashedString tonemap_mix("tonemap_mix");
+ static LLStaticHashedString tonemap_type("tonemap_type");
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
- shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", false);
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ shader->uniform1f(s_exposure, e);
+ static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);
+ shader->uniform1i(tonemap_type, tonemap_type_setting);
+ shader->uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust()));
- shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
- shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
- // SL-15861 This was changed from getRotatedLightNorm() as it was causing
- // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
- LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
- shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ // SL-15861 This was changed from getRotatedLightNorm() as it was causing
+ // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- LLGLDisable cullface(GL_CULL_FACE);
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
- LLVOWater* water = nullptr;
- for (LLFace* const& face : mDrawFace)
- {
- if (!face) continue;
- water = static_cast<LLVOWater*>(face->getViewerObject());
- if (!water) continue;
-
- if ((bool)edge == (bool)water->getIsEdgePatch())
- {
- face->renderIndexed();
-
- // Note non-void water being drawn, updates required
- if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
- {
- sNeedsReflectionUpdate = true;
- sNeedsDistortionUpdate = true;
- }
- }
- }
+ LLGLDisable cullface(GL_CULL_FACE);
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+ // Only push the water planes once.
+ // Previously we did this twice: once for void water and one for region water.
+ // However, the void water and region water shaders are the same exact shader.
+ // They also had the same exact state with the sole exception setting an edge water flag.
+ // That flag was not actually used anywhere in the shaders.
+ // - Geenz 2025-02-11
+ pushWaterPlanes(0);
- // clean up
- gPipeline.unbindDeferredShader(*shader);
+ // clean up
+ gPipeline.unbindDeferredShader(*shader);
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ gGL.setColorMask(true, false);
+}
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+void LLDrawPoolWater::pushWaterPlanes(int pass)
+{
+ LLVOWater* water = nullptr;
+ for (LLFace* const& face : mDrawFace)
+ {
+ water = static_cast<LLVOWater*>(face->getViewerObject());
- gGL.setColorMask(true, false);
+ face->renderIndexed();
+
+ // Note non-void water being drawn, updates required
+ // Previously we had some logic to determine if this pass was also our water edge pass.
+ // Now we only have one pass. Check if we're doing a region water plane or void water plane.
+ // - Geenz 2025-02-11
+ if (!water->getIsEdgePatch())
+ {
+ sNeedsReflectionUpdate = true;
+ sNeedsDistortionUpdate = true;
+ }
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index f64477a059..7fc9b68bcf 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -74,6 +74,8 @@ public:
void setOpaqueTexture(const LLUUID& opaqueTextureId);
void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId);
+ void pushWaterPlanes(int pass);
+
protected:
void renderOpaqueLegacyWater();
};
diff --git a/indra/newview/lldrawpoolwaterexclusion.cpp b/indra/newview/lldrawpoolwaterexclusion.cpp
new file mode 100644
index 0000000000..d796bf39bf
--- /dev/null
+++ b/indra/newview/lldrawpoolwaterexclusion.cpp
@@ -0,0 +1,79 @@
+/**
+ * @file lldrawpool.cpp
+ * @brief LLDrawPoolMaterials class implementation
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldrawpoolwaterexclusion.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+#include "llglcommonfunc.h"
+#include "llvoavatar.h"
+#include "lldrawpoolwater.h"
+
+LLDrawPoolWaterExclusion::LLDrawPoolWaterExclusion() : LLRenderPass(LLDrawPool::POOL_WATEREXCLUSION)
+{
+ LL_INFOS("DPInvisible") << "Creating water exclusion draw pool" << LL_ENDL;
+}
+
+
+void LLDrawPoolWaterExclusion::render(S32 pass)
+{ // render invisiprims
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; // LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
+
+ if (gPipeline.shadersLoaded())
+ {
+ gDrawColorProgram.bind();
+ }
+
+
+ LLGLDepthTest depth(GL_TRUE);
+ gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 1, 1, 1, 1);
+
+ LLDrawPoolWater* pwaterpool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
+ if (pwaterpool)
+ {
+ // Just treat our water planes as double sided for the purposes of generating the exclusion mask.
+ LLGLDisable cullface(GL_CULL_FACE);
+ pwaterpool->pushWaterPlanes(0);
+
+ // Take care of the edge water tiles.
+ pwaterpool->pushWaterPlanes(1);
+ }
+
+ gDrawColorProgram.uniform4f(LLShaderMgr::DIFFUSE_COLOR, 0, 0, 0, 1);
+
+ static LLStaticHashedString waterSign("waterSign");
+ gDrawColorProgram.uniform1f(waterSign, 1.f);
+
+ pushBatches(LLRenderPass::PASS_INVISIBLE, false, false);
+
+
+ if (gPipeline.shadersLoaded())
+ {
+ gDrawColorProgram.unbind();
+ }
+}
diff --git a/indra/newview/lldrawpoolwaterexclusion.h b/indra/newview/lldrawpoolwaterexclusion.h
new file mode 100644
index 0000000000..e95721a443
--- /dev/null
+++ b/indra/newview/lldrawpoolwaterexclusion.h
@@ -0,0 +1,61 @@
+/**
+ * @file lldrawpoolwaterexclusion.h
+ * @brief LLDrawPoolWaterExclusion class definition
+ * @author Jonathan "Geenz" Goodman
+ *
+ * $LicenseInfo:firstyear=2025&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2013, 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_LLDRAWPOOLWATEREXCLUSION_H
+#define LL_LLDRAWPOOLWATEREXCLUSION_H
+
+#include "v4coloru.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "llvertexbuffer.h"
+#include "lldrawpool.h"
+
+class LLViewerTexture;
+class LLDrawInfo;
+class LLGLSLShader;
+
+class LLDrawPoolWaterExclusion : public LLRenderPass
+{
+public:
+ LLDrawPoolWaterExclusion();
+
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX
+ };
+
+ virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+
+ virtual void prerender() {}
+
+ virtual void render(S32 pass = 0);
+ virtual void beginRenderPass(S32 pass) {}
+ virtual void endRenderPass(S32 pass) {}
+ virtual S32 getNumPasses() { return 1; }
+};
+
+#endif // LL_LLDRAWPOOLWATEREXCLUSION_H
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index e06127c1c8..85f902db8d 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -896,7 +896,7 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, const LLVector4a& po
//VECTORIZE THIS
// see if we have a non-default mapping
- U8 texgen = getTextureEntry()->getTexGen();
+ U8 texgen = tep->getTexGen();
if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{
LLVector4a& center = *(mDrawablep->getVOVolume()->getVolume()->getVolumeFace(mTEOffset).mCenter);
@@ -986,8 +986,17 @@ bool LLFace::calcAlignedPlanarTE(const LLFace* align_to, LLVector2* res_st_offs
return false;
}
const LLTextureEntry *orig_tep = align_to->getTextureEntry();
+ if (!orig_tep)
+ {
+ return false;
+ }
+ const LLTextureEntry* tep = getTextureEntry();
+ if (!tep)
+ {
+ return false;
+ }
if ((orig_tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR) ||
- (getTextureEntry()->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
+ (tep->getTexGen() != LLTextureEntry::TEX_GEN_PLANAR))
{
return false;
}
@@ -1566,7 +1575,8 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
bump_t_primary_light_ray.load3((offset_multiple * t_scale * primary_light_ray).mV);
}
- U8 texgen = getTextureEntry()->getTexGen();
+ const LLTextureEntry* tep = getTextureEntry();
+ U8 texgen = tep ? tep->getTexGen() : LLTextureEntry::TEX_GEN_DEFAULT;
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
mVObjp->getVolume()->genTangents(face_index);
@@ -2054,7 +2064,12 @@ bool LLFace::getGeometryVolume(const LLVolume& volume,
LLStrider<LLColor4U> emissive;
mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount);
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
+ const LLTextureEntry* tep = getTextureEntry();
+ U8 glow = 0;
+ if (tep)
+ {
+ glow = (U8)llclamp((S32)(tep->getGlow() * 255), 0, 255);
+ }
LLVector4a src;
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 7b1c0ba5d4..335aba2cc9 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -634,7 +634,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD& args)
chat_args["show_names_for_p2p_conv"] = !mIsP2PChat ||
gSavedSettings.getBOOL("IMShowNamesForP2PConv");
- mChatHistory->appendMessage(chat, chat_args);
+ static const LLStyle::Params input_append_params = LLStyle::Params();
+ mChatHistory->appendMessage(chat, chat_args, input_append_params);
}
void LLFloaterIMSessionTab::updateUsedEmojis(LLWStringView text)
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index fb4537f22a..68b9e758a1 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -60,6 +60,10 @@ LLPanelSnapshot* LLFloaterSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase*
{
LLSideTrayPanelContainer* panel_container = floater->getChild<LLSideTrayPanelContainer>("panel_container");
LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel_container->getCurrentPanel());
+ if (!active_panel)
+ {
+ LL_WARNS() << "No snapshot active panel, current panel index: " << panel_container->getCurrentPanelIndex() << LL_ENDL;
+ }
if (!ok_if_not_found)
{
llassert_always(active_panel != NULL);
@@ -643,20 +647,18 @@ void LLFloaterSnapshotBase::ImplBase::setWorking(bool working)
working_lbl->setVisible(working);
mFloater->getChild<LLUICtrl>("working_indicator")->setVisible(working);
- if (working)
- {
- const std::string panel_name = getActivePanel(mFloater, false)->getName();
- const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size());
- std::string progress_text = mFloater->getString(prefix + "_" + "progress_str");
- working_lbl->setValue(progress_text);
- }
-
// All controls should be disabled while posting.
mFloater->setCtrlsEnabled(!working);
- LLPanelSnapshot* active_panel = getActivePanel(mFloater);
- if (active_panel)
+ if (LLPanelSnapshot* active_panel = getActivePanel(mFloater))
{
active_panel->enableControls(!working);
+ if (working)
+ {
+ const std::string panel_name = active_panel->getName();
+ const std::string prefix = panel_name.substr(getSnapshotPanelPrefix().size());
+ std::string progress_text = mFloater->getString(prefix + "_" + "progress_str");
+ working_lbl->setValue(progress_text);
+ }
}
}
diff --git a/indra/newview/llgltfmaterialpreviewmgr.cpp b/indra/newview/llgltfmaterialpreviewmgr.cpp
index cf6b08797d..da1f1a466f 100644
--- a/indra/newview/llgltfmaterialpreviewmgr.cpp
+++ b/indra/newview/llgltfmaterialpreviewmgr.cpp
@@ -472,9 +472,9 @@ bool LLGLTFPreviewTexture::render()
gPipeline.setupHWLights();
glm::mat4 mat = get_current_modelview();
- glm::vec4 transformed_light_dir = glm::make_vec4(light_dir.mV);
+ glm::vec4 transformed_light_dir(light_dir);
transformed_light_dir = mat * transformed_light_dir;
- SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(glm::value_ptr(transformed_light_dir)));
+ SetTemporarily<LLVector4> force_sun_direction_high_graphics(&gPipeline.mTransformedSunDir, LLVector4(transformed_light_dir));
// Override lights to ensure the sun is always shining from a certain direction (low graphics)
// See also force_sun_direction_high_graphics and fixup_shader_constants
{
diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp
index 368306ded8..343bb01072 100644
--- a/indra/newview/llheroprobemanager.cpp
+++ b/indra/newview/llheroprobemanager.cpp
@@ -80,6 +80,17 @@ void LLHeroProbeManager::update()
return;
}
+ // Part of a hacky workaround to fix #3331.
+ // For some reason clearing shaders will cause mirrors to actually work.
+ // There's likely some deeper state issue that needs to be resolved.
+ // - Geenz 2025-02-25
+ if (!mInitialized && LLStartUp::getStartupState() > STATE_PRECACHE)
+ {
+ LLViewerShaderMgr::instance()->clearShaderCache();
+ LLViewerShaderMgr::instance()->setShaders();
+ mInitialized = true;
+ }
+
LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
llassert(!gCubeSnapshot); // assert a snapshot is not in progress
if (LLAppViewer::instance()->logoutRequestSent())
@@ -89,9 +100,11 @@ void LLHeroProbeManager::update()
initReflectionMaps();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
if (!mRenderTarget.isComplete())
{
- U32 color_fmt = GL_RGBA16F;
+ U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8;
mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true);
}
@@ -103,7 +116,7 @@ void LLHeroProbeManager::update()
mMipChain.resize(count);
for (U32 i = 0; i < count; ++i)
{
- mMipChain[i].allocate(res, res, GL_RGBA16F);
+ mMipChain[i].allocate(res, res, render_hdr ? GL_RGBA16F : GL_RGBA8);
res /= 2;
}
}
@@ -220,7 +233,7 @@ void LLHeroProbeManager::renderProbes()
static LLCachedControl<S32> sUpdateRate(gSavedSettings, "RenderHeroProbeUpdateRate", 0);
F32 near_clip = 0.01f;
- if (mNearestHero != nullptr &&
+ if (mNearestHero != nullptr && !mNearestHero->isDead() &&
!gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime");
@@ -249,12 +262,13 @@ void LLHeroProbeManager::renderProbes()
LL_PROFILE_ZONE_NUM(gFrameCount % rate);
LL_PROFILE_ZONE_NUM(rate);
+ bool dynamic = mNearestHero->getReflectionProbeIsDynamic() && sDetail() > 0;
for (U32 i = 0; i < 6; ++i)
{
if ((gFrameCount % rate) == (i % rate))
{ // update 6/rate faces per frame
LL_PROFILE_ZONE_NUM(i);
- updateProbeFace(mProbes[0], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip);
+ updateProbeFace(mProbes[0], i, dynamic, near_clip);
}
}
generateRadiance(mProbes[0]);
@@ -539,8 +553,10 @@ void LLHeroProbeManager::initReflectionMaps()
mTexture = new LLCubeMapArray();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
// store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
- mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr);
if (mDefaultProbe.isNull())
{
diff --git a/indra/newview/llheroprobemanager.h b/indra/newview/llheroprobemanager.h
index 58a94a3de8..2737ec5ddf 100644
--- a/indra/newview/llheroprobemanager.h
+++ b/indra/newview/llheroprobemanager.h
@@ -144,6 +144,7 @@ private:
std::vector<LLPointer<LLVOVolume>> mHeroVOList;
LLPointer<LLVOVolume> mNearestHero;
-
+ // Part of a hacky workaround to fix #3331.
+ bool mInitialized = false;
};
diff --git a/indra/newview/llhudrender.cpp b/indra/newview/llhudrender.cpp
index 135fba7897..6850e57b94 100644
--- a/indra/newview/llhudrender.cpp
+++ b/indra/newview/llhudrender.cpp
@@ -106,7 +106,7 @@ void hud_render_text(const LLWString &wstr, const LLVector3 &pos_agent,
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight());
- glm::vec3 win_coord = glm::project(glm::make_vec3(render_pos.mV), get_current_modelview(), get_current_projection(), viewport);
+ glm::vec3 win_coord = glm::project(glm::vec3(render_pos), get_current_modelview(), get_current_projection(), viewport);
//fonts all render orthographically, set up projection``
gGL.matrixMode(LLRender::MM_PROJECTION);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d511171679..c103d40a38 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4231,14 +4231,9 @@ void LLFolderBridge::staticFolderOptionsMenu()
bool LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& is_type)
{
- LLInventoryModel::cat_array_t cat_array;
- LLInventoryModel::item_array_t item_array;
- model->collectDescendentsIf(mUUID,
- cat_array,
- item_array,
+ return model->hasMatchingDescendents(mUUID,
LLInventoryModel::EXCLUDE_TRASH,
is_type);
- return !item_array.empty();
}
void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items, menuentry_vec_t& disabled_items)
@@ -4415,21 +4410,26 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
//Added by aura to force inventory pull on right-click to display folder options correctly. 07-17-06
mCallingCards = mWearables = false;
- LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
- if (checkFolderForContentsOfType(model, is_callingcard))
+ if (gInventory.getRootFolderID() != mUUID)
{
- mCallingCards=true;
- }
+ LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
+ if (checkFolderForContentsOfType(model, is_callingcard))
+ {
+ mCallingCards = true;
+ }
- LLFindWearables is_wearable;
- LLIsType is_object( LLAssetType::AT_OBJECT );
- LLIsType is_gesture( LLAssetType::AT_GESTURE );
+ const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE };
+ LLIsOneOfTypes is_wearable(types);
- if (checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture) )
+ if (checkFolderForContentsOfType(model, is_wearable))
+ {
+ mWearables = true;
+ }
+ }
+ else
{
- mWearables=true;
+ // Assume that there are wearables in the root folder
+ mWearables = true;
}
items.push_back(std::string("Set favorite folder"));
@@ -4444,13 +4444,10 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
LLFolderType::EType type = category->getPreferredType();
const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
- LLFindWearables is_wearable;
- LLIsType is_object(LLAssetType::AT_OBJECT);
- LLIsType is_gesture(LLAssetType::AT_GESTURE);
+ const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE };
+ LLIsOneOfTypes is_wearable(types);
- if (checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture))
+ if (checkFolderForContentsOfType(model, is_wearable))
{
mWearables = true;
}
@@ -4573,14 +4570,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t&
// wearables related functionality for folders.
//is_wearable
- LLFindWearables is_wearable;
- LLIsType is_object( LLAssetType::AT_OBJECT );
- LLIsType is_gesture( LLAssetType::AT_GESTURE );
+ const std::vector<LLAssetType::EType> types = { LLAssetType::AT_CLOTHING, LLAssetType::AT_BODYPART, LLAssetType::AT_OBJECT, LLAssetType::AT_GESTURE };
+ LLIsOneOfTypes is_wearable(types);
if (mWearables ||
- checkFolderForContentsOfType(model, is_wearable) ||
- checkFolderForContentsOfType(model, is_object) ||
- checkFolderForContentsOfType(model, is_gesture) )
+ checkFolderForContentsOfType(model, is_wearable))
{
// Only enable add/replace outfit for non-system folders.
if (!is_system_folder)
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index dadd0590a9..1ccefa3212 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -2634,6 +2634,22 @@ bool LLIsType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
return false;
}
+bool LLIsOneOfTypes::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
+{
+ for (LLAssetType::EType &type : mTypes)
+ {
+ if (type == LLAssetType::AT_CATEGORY)
+ {
+ if (cat) return true;
+ }
+ if (item)
+ {
+ if (item->getType() == type) return true;
+ }
+ }
+ return false;
+}
+
bool LLIsNotType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(mType == LLAssetType::AT_CATEGORY)
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index a25c0d5ad6..13a64f21dc 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -246,6 +246,24 @@ protected:
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLIsOneOfTypes
+//
+// Implementation of a LLInventoryCollectFunctor which returns true if
+// the type is one of the types passed in during construction.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLIsOneOfTypes : public LLInventoryCollectFunctor
+{
+public:
+ LLIsOneOfTypes(const std::vector<LLAssetType::EType> &types) : mTypes(types) {}
+ virtual ~LLIsOneOfTypes() {}
+ virtual bool operator()(LLInventoryCategory* cat,
+ LLInventoryItem* item);
+protected:
+ std::vector <LLAssetType::EType> mTypes;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLIsNotType
//
// Implementation of a LLInventoryCollectFunctor which returns false if the
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 53ea02983a..b6ff31a7ed 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1305,6 +1305,47 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
}
}
+bool LLInventoryModel::hasMatchingDescendents(const LLUUID& id,
+ bool include_trash,
+ LLInventoryCollectFunctor& matches)
+{
+ if (!include_trash)
+ {
+ const LLUUID trash_id = findCategoryUUIDForType(LLFolderType::FT_TRASH);
+ if (trash_id.notNull() && (trash_id == id))
+ return false;
+ }
+ cat_array_t* cat_array = get_ptr_in_map(mParentChildCategoryTree, id);
+ if (cat_array)
+ {
+ for (auto& cat : *cat_array)
+ {
+ if (matches(cat, NULL))
+ {
+ return true;
+ }
+ if (hasMatchingDescendents(cat->getUUID(), include_trash, matches))
+ {
+ return true;
+ }
+ }
+ }
+
+ item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, id);
+
+ if (item_array)
+ {
+ for (auto& item : *item_array)
+ {
+ if (matches(NULL, item))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask)
{
const LLInventoryObject *obj = getObject(object_id);
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 1472b705e4..d28743357e 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -287,6 +287,9 @@ public:
item_array_t& items,
bool include_trash,
LLInventoryCollectFunctor& add);
+ bool hasMatchingDescendents(const LLUUID& id,
+ bool include_trash,
+ LLInventoryCollectFunctor& add);
// Collect all items in inventory that are linked to item_id.
// Assumes item_id is itself not a linked item.
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index bf12e6a7e0..1795de727d 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -580,7 +580,7 @@ void LLInventoryPanel::itemChanged(const LLUUID& item_id, U32 mask, const LLInve
{
if (model_item && view_item && viewmodel_item)
{
- const LLUUID& idp = viewmodel_item->getUUID();
+ const LLUUID idp = viewmodel_item->getUUID();
removeItemID(idp);
view_item->destroyView();
}
@@ -1335,6 +1335,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
if (fchild
&& fchild->getViewModelItem()
+ // Is this right? Name might be localized,
+ // use FT_ROOT_INVENTORY or gInventory.getRootFolderID()?
&& fchild->getViewModelItem()->getName() == "My Inventory")
{
fchild->setOpen(true);
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index ad04c11cc6..cbc3744aa3 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -212,6 +212,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
request_params["read_critical"] = false; // handleTOSResponse
request_params["last_exec_event"] = mLastExecEvent;
request_params["last_exec_duration"] = mLastExecDuration;
+ request_params["last_exec_session_id"] = mLastAgentSessionId.asString();
request_params["mac"] = (char*)hashed_unique_id_string;
request_params["version"] = LLVersionInfo::instance().getVersion();
request_params["channel"] = LLVersionInfo::instance().getChannel();
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index 624408d46d..748909c069 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -64,6 +64,7 @@ public:
void setSerialNumber(const std::string& sn) { mSerialNumber = sn; }
void setLastExecEvent(int lee) { mLastExecEvent = lee; }
void setLastExecDuration(S32 duration) { mLastExecDuration = duration; }
+ void setLastAgentSessionId(const LLUUID& id) { mLastAgentSessionId = id; }
void setPlatformInfo(const std::string platform, const std::string platform_version, const std::string platform_name);
void setNotificationsInterface(LLNotificationsInterface* ni) { mNotifications = ni; }
@@ -101,6 +102,7 @@ private:
std::string mSerialNumber;
int mLastExecEvent;
S32 mLastExecDuration;
+ LLUUID mLastAgentSessionId;
std::string mPlatform;
std::string mPlatformVersion;
std::string mPlatformVersionName;
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index a5bed1dbe6..93453f507c 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -548,8 +548,8 @@ LLViewerFetchedTexture* LLMeshUploadThread::FindViewerTexture(const LLImportMate
return ppTex ? (*ppTex).get() : NULL;
}
-volatile S32 LLMeshRepoThread::sActiveHeaderRequests = 0;
-volatile S32 LLMeshRepoThread::sActiveLODRequests = 0;
+std::atomic<S32> LLMeshRepoThread::sActiveHeaderRequests = 0;
+std::atomic<S32> LLMeshRepoThread::sActiveLODRequests = 0;
U32 LLMeshRepoThread::sMaxConcurrentRequests = 1;
S32 LLMeshRepoThread::sRequestLowWater = REQUEST2_LOW_WATER_MIN;
S32 LLMeshRepoThread::sRequestHighWater = REQUEST2_HIGH_WATER_MIN;
@@ -3916,7 +3916,7 @@ void LLMeshRepository::notifyLoadedMeshes()
}
// erase from background thread
- mThread->mWorkQueue.post([=]()
+ mThread->mWorkQueue.post([=, this]()
{
mThread->mSkinMap.erase(id);
});
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index b5c2424578..3d25a4dd78 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -256,8 +256,8 @@ class LLMeshRepoThread : public LLThread
{
public:
- volatile static S32 sActiveHeaderRequests;
- volatile static S32 sActiveLODRequests;
+ static std::atomic<S32> sActiveHeaderRequests;
+ static std::atomic<S32> sActiveLODRequests;
static U32 sMaxConcurrentRequests;
static S32 sRequestLowWater;
static S32 sRequestHighWater;
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index dbf56c2b6d..7910bcb41d 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -139,32 +139,60 @@ void LLPanelContents::getState(LLViewerObject *objectp )
void LLPanelContents::onFilterEdit()
{
const std::string& filter_substring = mFilterEditor->getText();
- if (filter_substring.empty())
+ if (!mPanelInventoryObject->hasInventory())
{
- if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
- {
- // The current filter and the new filter are empty, nothing to do
- return;
- }
-
- mSavedFolderState.setApply(true);
- mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
-
- // Add a folder with the current item to the list of previously opened folders
- LLOpenFoldersWithSelection opener;
- mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener);
- mPanelInventoryObject->getRootFolder()->scrollToShowSelection();
+ mDirtyFilter = true;
}
- else if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
+ else
{
- // The first letter in search term, save existing folder open state
- if (!mPanelInventoryObject->getFilter().isNotDefault())
+ LLFolderView* root_folder = mPanelInventoryObject->getRootFolder();
+ if (filter_substring.empty())
{
- mSavedFolderState.setApply(false);
- mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
+ if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
+ {
+ // The current filter and the new filter are empty, nothing to do
+ return;
+ }
+
+ if (mDirtyFilter && !mSavedFolderState.hasOpenFolders())
+ {
+ if (root_folder)
+ {
+ root_folder->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN);
+ }
+ }
+ else
+ {
+ mSavedFolderState.setApply(true);
+ if (root_folder)
+ {
+ root_folder->applyFunctorRecursively(mSavedFolderState);
+ }
+ }
+ mDirtyFilter = false;
+
+ // Add a folder with the current item to the list of previously opened folders
+ if (root_folder)
+ {
+ LLOpenFoldersWithSelection opener;
+ root_folder->applyFunctorRecursively(opener);
+ root_folder->scrollToShowSelection();
+ }
+ }
+ else if (mPanelInventoryObject->getFilter().getFilterSubString().empty())
+ {
+ // The first letter in search term, save existing folder open state
+ if (!mPanelInventoryObject->getFilter().isNotDefault())
+ {
+ mSavedFolderState.setApply(false);
+ if (root_folder)
+ {
+ root_folder->applyFunctorRecursively(mSavedFolderState);
+ }
+ mDirtyFilter = false;
+ }
}
}
-
mPanelInventoryObject->getFilter().setFilterSubString(filter_substring);
}
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index bb6308e8b8..6e02b17bab 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -70,6 +70,8 @@ protected:
void getState(LLViewerObject *object);
void onFilterEdit();
+ bool mDirtyFilter { false };
+
public:
class LLFilterEditor* mFilterEditor;
LLSaveFolderState mSavedFolderState;
diff --git a/indra/newview/llpanelemojicomplete.cpp b/indra/newview/llpanelemojicomplete.cpp
index 9def7b8b03..4f1fd5dfca 100644
--- a/indra/newview/llpanelemojicomplete.cpp
+++ b/indra/newview/llpanelemojicomplete.cpp
@@ -441,7 +441,7 @@ void LLPanelEmojiComplete::updateConstraints()
{
mRenderRect = getLocalRect();
- mEmojiWidth = (U16)(mIconFont->getWidthF32(u8"\U0001F431") + mPadding * 2);
+ mEmojiWidth = (U16)(mIconFont->getWidthF32(LLWString(1, 0x1F431).c_str()) + mPadding * 2);
if (mVertical)
{
mEmojiHeight = mIconFont->getLineHeight() + mPadding * 2;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index b07946dd5d..74fb2f0f93 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -898,6 +898,10 @@ struct LLPanelFaceGetIsAlignedTEFunctor : public LLSelectedTEFunctor
if (facep->calcAlignedPlanarTE(mCenterFace, &aligned_st_offset, &aligned_st_scale, &aligned_st_rot))
{
const LLTextureEntry* tep = facep->getTextureEntry();
+ if (!tep)
+ {
+ return false;
+ }
LLVector2 st_offset, st_scale;
tep->getOffset(&st_offset.mV[VX], &st_offset.mV[VY]);
tep->getScale(&st_scale.mV[VX], &st_scale.mV[VY]);
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<LLButton>("add_button");
- LLFloater* root_floater = gFloaterView->getParentFloater(panelp);
- LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
- [&](const uuid_vec_t& agent_ids, const std::vector<LLAvatarName>&)
- {
- 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<LLAvatarName>&)
{
- 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<LLButton>("add_button", recurse);
- if ( button )
+ mImplementation->mAddButton = getChild<LLButton>("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<LLButton>("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<LLButton>("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<LLButton>("cancel_button", recurse);
- if ( button )
- {
- button->setClickedCallback(LLPanelGroupBulkImpl::callbackClickCancel, mImplementation);
- }
+ LLButton* button = getChild<LLButton>("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;
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 377af4384a..a5b4db0580 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -2425,10 +2425,14 @@ void LLPanelMainInventory::updateCombinationVisibility()
mCombinationGalleryLayoutPanel->setVisible(!is_gallery_empty);
mCombinationListLayoutPanel->setVisible(show_inv_pane);
- mCombinationInventoryPanel->getRootFolder()->setForceArrange(!show_inv_pane);
- if(mCombinationInventoryPanel->hasVisibleItems())
+ LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder();
+ if (root_folder)
{
- mForceShowInvLayout = false;
+ root_folder->setForceArrange(!show_inv_pane);
+ if (mCombinationInventoryPanel->hasVisibleItems())
+ {
+ mForceShowInvLayout = false;
+ }
}
if(is_gallery_empty)
{
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index abb48dbeed..154639e4bb 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -85,6 +85,8 @@ public:
static void idle(void* user_data);
+ bool hasInventory(){ return mHaveInventory; };
+
protected:
void reset();
/*virtual*/ void inventoryChanged(LLViewerObject* object,
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 4db0a5b59d..b8c12ce0b9 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -660,11 +660,11 @@ void LLPanelPrimMediaControls::updateShape()
for(; vert_it != vert_end; ++vert_it)
{
// project silhouette vertices into screen space
- glm::vec3 screen_vert(glm::make_vec3(vert_it->mV));
+ glm::vec3 screen_vert(*vert_it);
screen_vert = mul_mat4_vec3(mat, screen_vert);
// add to screenspace bounding box
- update_min_max(min, max, LLVector3(glm::value_ptr(screen_vert)));
+ update_min_max(min, max, LLVector3(screen_vert));
}
// convert screenspace bbox to pixels (in screen coords)
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index 3add43a3c0..2c09943b83 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -81,10 +81,9 @@ bool LLProgressView::postBuild()
{
mProgressBar = getChild<LLProgressBar>("login_progress_bar");
- mLogosLabel = getChild<LLTextBox>("logos_lbl");
-
mProgressText = getChild<LLTextBox>("progress_text");
mMessageText = getChild<LLTextBox>("message_text");
+ mMessageTextRectInitial = mMessageText->getRect(); // auto resizes, save initial size
// media control that is used to play intro video
mMediaCtrl = getChild<LLMediaCtrl>("login_media_panel");
@@ -96,6 +95,12 @@ bool LLProgressView::postBuild()
mCancelBtn = getChild<LLButton>("cancel_btn");
mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL );
+ mLayoutPanel4 = getChild<LLView>("panel4");
+ mLayoutPanel4RectInitial = mLayoutPanel4->getRect();
+
+ mLayoutMOTD = getChild<LLView>("panel_motd");
+ mLayoutMOTDRectInitial = mLayoutMOTD->getRect();
+
getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);
@@ -234,33 +239,6 @@ void LLProgressView::drawStartTexture(F32 alpha)
gGL.popMatrix();
}
-void LLProgressView::drawLogos(F32 alpha)
-{
- if (mLogosList.empty())
- {
- return;
- }
-
- // logos are tied to label,
- // due to potential resizes we have to figure offsets out on draw or resize
- S32 offset_x, offset_y;
- mLogosLabel->localPointToScreen(0, 0, &offset_x, &offset_y);
- std::vector<TextureData>::const_iterator iter = mLogosList.begin();
- std::vector<TextureData>::const_iterator end = mLogosList.end();
- for (; iter != end; iter++)
- {
- gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x,
- iter->mDrawRect.mBottom + offset_y,
- iter->mDrawRect.getWidth(),
- iter->mDrawRect.getHeight(),
- iter->mTexturep.get(),
- UI_VERTEX_COLOR % alpha,
- false,
- iter->mClipRect,
- iter->mOffsetRect);
- }
-}
-
void LLProgressView::draw()
{
static LLTimer timer;
@@ -276,7 +254,6 @@ void LLProgressView::draw()
}
LLPanel::draw();
- drawLogos(alpha);
return;
}
@@ -289,7 +266,6 @@ void LLProgressView::draw()
drawStartTexture(alpha);
LLPanel::draw();
- drawLogos(alpha);
// faded out completely - remove panel and reveal world
if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME )
@@ -324,7 +300,6 @@ void LLProgressView::draw()
drawStartTexture(1.0f);
// draw children
LLPanel::draw();
- drawLogos(1.0f);
}
void LLProgressView::setText(const std::string& text)
@@ -341,109 +316,18 @@ void LLProgressView::setMessage(const std::string& msg)
{
mMessage = msg;
mMessageText->setValue(mMessage);
-}
-
-void LLProgressView::loadLogo(const std::string &path,
- const U8 image_codec,
- const LLRect &pos_rect,
- const LLRectf &clip_rect,
- const LLRectf &offset_rect)
-{
- // We need these images very early, so we have to force-load them, otherwise they might not load in time.
- if (!gDirUtilp->fileExists(path))
+ S32 height = mMessageText->getTextPixelHeight();
+ S32 delta = height - mMessageTextRectInitial.getHeight();
+ if (delta > 0)
{
- return;
+ mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight() + delta);
+ mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight() + delta);
}
-
- LLPointer<LLImageFormatted> start_image_frmted = LLImageFormatted::createFromType(image_codec);
- if (!start_image_frmted->load(path))
- {
- LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL;
- return;
- }
-
- LLPointer<LLImageRaw> raw = new LLImageRaw;
- if (!start_image_frmted->decode(raw, 0.0f))
+ else
{
- LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL;
- return;
+ mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight());
+ mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight());
}
- // HACK: getLocalTexture allows only power of two dimentions
- raw->expandToPowerOfTwo();
-
- TextureData data;
- data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false);
- data.mDrawRect = pos_rect;
- data.mClipRect = clip_rect;
- data.mOffsetRect = offset_rect;
- mLogosList.push_back(data);
-}
-
-void LLProgressView::initLogos()
-{
- mLogosList.clear();
-
-#if LL_FMODSTUDIO || LL_HAVOK
- const U8 image_codec = IMG_CODEC_PNG;
- const LLRectf default_clip(0.f, 1.f, 1.f, 0.f);
- //const S32 default_height = 28;
- const S32 default_pad = 15;
-
- S32 icon_width, icon_height;
-
- // We don't know final screen rect yet, so we can't precalculate position fully
- S32 texture_start_x = (S32)mLogosLabel->getFont()->getWidthF32(mLogosLabel->getWText().c_str()) + default_pad;
- S32 texture_start_y = -7;
-#endif //LL_FMODSTUDIO || LL_HAVOK
-
- // Normally we would just preload these textures from textures.xml,
- // and display them via icon control, but they are only needed on
- // startup and preloaded/UI ones stay forever
- // (and this code was done already so simply reused it)
- std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons");
-
- temp_str += gDirUtilp->getDirDelimiter();
-
-#ifdef LL_FMODSTUDIO
- // original image size is 264x96, it is on longer side but
- // with no internal paddings so it gets additional padding
- icon_width = 77;
- icon_height = 21;
- S32 pad_fmod_y = 4;
- texture_start_x++;
- loadLogo(temp_str + "fmod_logo.png",
- image_codec,
- LLRect(texture_start_x, texture_start_y + pad_fmod_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_fmod_y),
- default_clip,
- default_clip);
-
- texture_start_x += icon_width + default_pad + 1;
-#endif //LL_FMODSTUDIO
-#ifdef LL_HAVOK
- // original image size is 342x113, central element is on a larger side
- // plus internal padding, so it gets slightly more height than desired 32
- icon_width = 88;
- icon_height = 29;
- S32 pad_havok_y = -1;
- loadLogo(temp_str + "havok_logo.png",
- image_codec,
- LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y),
- default_clip,
- default_clip);
-
- texture_start_x += icon_width + default_pad;
-#endif //LL_HAVOK
-
-/*
- // 108x41
- icon_width = 74;
- icon_height = default_height;
- loadLogo(temp_str + "vivox_logo.png",
- image_codec,
- LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y),
- default_clip,
- default_clip);
-*/
}
void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)
@@ -524,19 +408,11 @@ void LLProgressView::initStartTexture(S32 location_id, bool is_in_production)
void LLProgressView::initTextures(S32 location_id, bool is_in_production)
{
initStartTexture(location_id, is_in_production);
- initLogos();
-
- childSetVisible("panel_icons", !mLogosList.empty());
- childSetVisible("panel_top_spacer", mLogosList.empty());
}
void LLProgressView::releaseTextures()
{
gStartTexture = NULL;
- mLogosList.clear();
-
- childSetVisible("panel_top_spacer", true);
- childSetVisible("panel_icons", false);
}
void LLProgressView::setCancelButtonVisible(bool b, const std::string& label)
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index 15b04a8eb9..250ee511d7 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -53,7 +53,6 @@ public:
/*virtual*/ void draw();
void drawStartTexture(F32 alpha);
- void drawLogos(F32 alpha);
/*virtual*/ bool handleHover(S32 x, S32 y, MASK mask);
/*virtual*/ bool handleKeyHere(KEY key, MASK mask);
@@ -86,7 +85,6 @@ public:
protected:
LLProgressBar* mProgressBar;
LLMediaCtrl* mMediaCtrl;
- LLTextBox* mLogosLabel = nullptr;
LLTextBox* mProgressText = nullptr;
LLTextBox* mMessageText = nullptr;
F32 mPercentDone;
@@ -95,6 +93,13 @@ protected:
LLFrameTimer mFadeToWorldTimer;
LLFrameTimer mFadeFromLoginTimer;
LLRect mOutlineRect;
+ LLView* mLayoutPanel4 = nullptr;
+ LLView* mLayoutMOTD = nullptr;
+ // Rects for resizing purposes
+ LLRect mMessageTextRectInitial;
+ LLRect mLayoutPanel4RectInitial;
+ LLRect mLayoutMOTDRectInitial;
+
bool mMouseDownInActiveArea;
bool mStartupComplete;
@@ -105,25 +110,8 @@ protected:
bool handleUpdate(const LLSD& event_data);
static void onIdle(void* user_data);
- void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect);
- // logos have unusual location and need to be preloaded to not appear grey, then deleted
- void initLogos();
// Loads a bitmap to display during load
void initStartTexture(S32 location_id, bool is_in_production);
-
-private:
- // We need to draw textures on login, but only once.
- // So this vector gets filled up for textures to render and gets cleaned later
- // Some textures have unusual requirements, so we are rendering directly
- class TextureData
- {
- public:
- LLPointer<LLViewerTexture> mTexturep;
- LLRect mDrawRect;
- LLRectf mClipRect;
- LLRectf mOffsetRect;
- };
- std::vector<TextureData> mLogosList;
};
#endif // LL_LLPROGRESSVIEW_H
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index f77d37f821..f3adb52d5e 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -65,8 +65,9 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 n
}
F32 clip = (near_clip > 0) ? near_clip : getNearClip();
+ bool dynamic = force_dynamic || getIsDynamic();
- gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane);
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, dynamic, useClipPlane, clipPlane);
}
void LLReflectionMap::autoAdjustOrigin()
@@ -185,7 +186,7 @@ void LLReflectionMap::autoAdjustOrigin()
}
}
-bool LLReflectionMap::intersects(LLReflectionMap* other)
+bool LLReflectionMap::intersects(LLReflectionMap* other) const
{
LLVector4a delta;
delta.setSub(other->mOrigin, mOrigin);
@@ -201,24 +202,24 @@ bool LLReflectionMap::intersects(LLReflectionMap* other)
extern LLControlGroup gSavedSettings;
-F32 LLReflectionMap::getAmbiance()
+F32 LLReflectionMap::getAmbiance() const
{
F32 ret = 0.f;
- if (mViewerObject && mViewerObject->getVolume())
+ if (mViewerObject && mViewerObject->getVolumeConst())
{
- ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
+ ret = mViewerObject->getReflectionProbeAmbiance();
}
return ret;
}
-F32 LLReflectionMap::getNearClip()
+F32 LLReflectionMap::getNearClip() const
{
const F32 MINIMUM_NEAR_CLIP = 0.1f;
F32 ret = 0.f;
- if (mViewerObject && mViewerObject->getVolume())
+ if (mViewerObject && mViewerObject->getVolumeConst())
{
ret = mViewerObject->getReflectionProbeNearClip();
}
@@ -234,11 +235,13 @@ F32 LLReflectionMap::getNearClip()
return llmax(ret, MINIMUM_NEAR_CLIP);
}
-bool LLReflectionMap::getIsDynamic()
+bool LLReflectionMap::getIsDynamic() const
{
- if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
+ static LLCachedControl<S32> detail(gSavedSettings, "RenderReflectionProbeDetail", 1);
+ if (detail() > (S32)LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
mViewerObject &&
- mViewerObject->getVolume())
+ !mViewerObject->isDead() &&
+ mViewerObject->getVolumeConst())
{
return mViewerObject->getReflectionProbeIsDynamic();
}
@@ -256,7 +259,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
glm::mat4 mv(get_current_modelview());
LLVector3 s = mViewerObject->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
mRadius = s.magVec();
- glm::mat4 scale = glm::scale(glm::make_vec3(s.mV));
+ glm::mat4 scale = glm::scale(glm::vec3(s));
if (mViewerObject->mDrawable != nullptr)
{
// object to agent space (no scale)
@@ -278,12 +281,12 @@ bool LLReflectionMap::getBox(LLMatrix4& box)
return false;
}
-bool LLReflectionMap::isActive()
+bool LLReflectionMap::isActive() const
{
return mCubeIndex != -1;
}
-bool LLReflectionMap::isRelevant()
+bool LLReflectionMap::isRelevant() const
{
static LLCachedControl<S32> RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
index 117ea4cfa6..d20bba7059 100644
--- a/indra/newview/llreflectionmap.h
+++ b/indra/newview/llreflectionmap.h
@@ -58,16 +58,16 @@ public:
void autoAdjustOrigin();
// return true if given Reflection Map's influence volume intersect's with this one's
- bool intersects(LLReflectionMap* other);
+ bool intersects(LLReflectionMap* other) const;
// Get the ambiance value to use for this probe
- F32 getAmbiance();
+ F32 getAmbiance() const;
// Get the near clip plane distance to use for this probe
- F32 getNearClip();
+ F32 getNearClip() const;
// Return true if this probe should include avatars in its reflection map
- bool getIsDynamic();
+ bool getIsDynamic() const;
// get the encoded bounding box of this probe's influence volume
// will only return a box if this probe is associated with a VOVolume
@@ -76,13 +76,13 @@ public:
bool getBox(LLMatrix4& box);
// return true if this probe is active for rendering
- bool isActive();
+ bool isActive() const;
// perform occlusion query/readback
void doOcclusion(const LLVector4a& eye);
// return false if this probe isn't currently relevant (for example, disabled due to graphics preferences)
- bool isRelevant();
+ bool isRelevant() const;
// point at which environment map was last generated from (in agent space)
LLVector4a mOrigin;
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 69ade8d796..2708d5edf0 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -223,9 +223,11 @@ void LLReflectionMapManager::update()
initReflectionMaps();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
if (!mRenderTarget.isComplete())
{
- U32 color_fmt = GL_RGB16F;
+ U32 color_fmt = render_hdr ? GL_R11F_G11F_B10F : GL_RGB8;
U32 targetRes = mProbeResolution * 4; // super sample
mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
}
@@ -238,7 +240,7 @@ void LLReflectionMapManager::update()
mMipChain.resize(count);
for (U32 i = 0; i < count; ++i)
{
- mMipChain[i].allocate(res, res, GL_RGB16F);
+ mMipChain[i].allocate(res, res, render_hdr ? GL_R11F_G11F_B10F : GL_RGB8);
res /= 2;
}
}
@@ -306,7 +308,7 @@ void LLReflectionMapManager::update()
LLReflectionMap* probe = mProbes[i];
llassert(probe != nullptr);
- if (probe->mCubeIndex != -1 && mUpdatingProbe != probe)
+ if (probe && probe->mCubeIndex != -1 && mUpdatingProbe != probe)
{ // free this index
mCubeFree.push_back(probe->mCubeIndex);
@@ -1425,11 +1427,13 @@ void LLReflectionMapManager::initReflectionMaps()
{
mTexture = new LLCubeMapArray();
+ static LLCachedControl<bool> render_hdr(gSavedSettings, "RenderHDREnabled", true);
+
// store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
- mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr);
mIrradianceMaps = new LLCubeMapArray();
- mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false);
+ mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr);
}
// reset probe state
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index cf96072ae2..6023f6885d 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -807,7 +807,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
static LLCachedControl<F32> tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f);
// sky is a "classic" sky following pre SL 7.0 shading
- bool classic_mode = psky->canAutoAdjust();
+ bool classic_mode = psky->canAutoAdjust() && !should_auto_adjust();
if (!classic_mode)
{
@@ -832,6 +832,10 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
{
shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, sqrtf(g)*2.0f); // use a modifier here so 1.0 maps to the "most desirable" default and the maximum value doesn't go off the rails
+
+ // Low quality setting
+ if (!LLPipeline::sReflectionProbesEnabled)
+ probe_ambiance = DEFAULT_AUTO_ADJUST_PROBE_AMBIANCE;
}
else if (psky->canAutoAdjust() && should_auto_adjust)
{ // auto-adjust legacy sky to take advantage of probe ambiance
@@ -1093,8 +1097,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.x, enorm.y, enorm.z, -glm::dot(ep, enorm));
- norm = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorNormal.mV);
- p = glm::make_vec3(gPipeline.mHeroProbeManager.mMirrorPosition.mV);
+ norm = glm::vec3(gPipeline.mHeroProbeManager.mMirrorNormal);
+ p = glm::vec3(gPipeline.mHeroProbeManager.mMirrorPosition);
enorm = mul_mat4_vec3(invtrans, norm);
enorm = glm::normalize(enorm);
ep = mul_mat4_vec3(mat, p);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index c56900d986..a90ff73578 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2615,12 +2615,8 @@ void renderTexturePriority(LLDrawable* drawable)
LLGLDisable blend(GL_BLEND);
- //LLViewerTexture* imagep = facep->getTexture();
- //if (imagep)
if (facep)
{
-
- //F32 vsize = imagep->mMaxVirtualSize;
F32 vsize = facep->getPixelArea();
if (vsize > sCurMaxTexPriority)
@@ -2646,18 +2642,6 @@ void renderTexturePriority(LLDrawable* drawable)
size.mul(0.5f);
size.add(LLVector4a(0.01f));
drawBox(center, size);
-
- /*S32 boost = imagep->getBoostLevel();
- if (boost>LLGLTexture::BOOST_NONE)
- {
- F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
- LLVector4 col = lerp(boost_cold, boost_hot, t);
- LLGLEnable blend_on(GL_BLEND);
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
- gGL.diffuseColor4fv(col.mV);
- drawBox(center, size);
- gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }*/
}
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9b715be26e..6bf203c140 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1072,6 +1072,7 @@ bool idle_startup()
login->setSerialNumber(LLAppViewer::instance()->getSerialNumber());
login->setLastExecEvent(gLastExecEvent);
login->setLastExecDuration(gLastExecDuration);
+ login->setLastAgentSessionId(gLastAgentSessionId);
// This call to LLLoginInstance::connect() starts the
// authentication process.
@@ -1420,7 +1421,7 @@ bool idle_startup()
}
else if (regionp->capabilitiesError())
{
- LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL;
if (gRememberPassword)
{
LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
@@ -1429,6 +1430,15 @@ bool idle_startup()
{
LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
}
+
+ // Session was created, don't just hang up on server, send a logout request
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
reset_login();
}
else
@@ -1436,7 +1446,7 @@ bool idle_startup()
U32 num_retries = regionp->getNumSeedCapRetries();
if (num_retries > MAX_SEED_CAP_ATTEMPTS_BEFORE_ABORT)
{
- LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Failed to get capabilities. Logging out and backing up to login screen!" << LL_ENDL;
if (gRememberPassword)
{
LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
@@ -1445,6 +1455,15 @@ bool idle_startup()
{
LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
}
+
+ // Session was created, don't just hang up on server, send a logout request
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
reset_login();
}
else if (num_retries > 0)
@@ -1534,7 +1553,7 @@ bool idle_startup()
// create a container's instance for start a controlling conversation windows
// by the voice's events
LLFloaterIMContainer *im_inst = LLFloaterIMContainer::getInstance();
- if(gAgent.isFirstLogin())
+ if(gAgent.isFirstLogin() && im_inst)
{
im_inst->openFloater(im_inst->getKey());
}
@@ -1747,7 +1766,7 @@ bool idle_startup()
if (!gAgentMovementCompleted && timeout.getElapsedTimeF32() > STATE_AGENT_WAIT_TIMEOUT)
{
- LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
+ LL_WARNS("AppInit") << "Timeout on agent movement. Sending logout and backing up to login screen!" << LL_ENDL;
if (gRememberPassword)
{
LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
@@ -1756,6 +1775,15 @@ bool idle_startup()
{
LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
}
+
+ // Session was created, don't just hang up on server, send a logout request
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessageFast(_PREHASH_LogoutRequest);
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ gAgent.sendReliableMessage();
+
reset_login();
}
return false;
@@ -3564,6 +3592,7 @@ bool process_login_success_response()
text = response["session_id"].asString();
if(!text.empty()) gAgentSessionID.set(text);
gDebugInfo["SessionID"] = text;
+ LLAppViewer::instance()->recordSessionToMarker();
// Session id needed for parcel info request in LLUrlEntryParcel
// to resolve parcel name.
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index bac0c736b1..087761cbd0 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -29,6 +29,7 @@
#include <iostream>
#include <map>
#include <algorithm>
+#include <atomic>
#include "lltexturefetch.h"
@@ -2843,7 +2844,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, S3
bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
{
LL_PROFILE_ZONE_SCOPED;
- mRequestQueue.tryPost([=]()
+ mRequestQueue.tryPost([=, this]()
{
LLTextureFetchWorker* worker = getWorker(id);
if (worker)
@@ -3571,29 +3572,30 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
//if (! gViewerAssetStatsThread1)
// return true;
- static volatile bool reporting_started(false);
- static volatile S32 report_sequence(0);
+ static std::atomic<bool> reporting_started(false);
+ static std::atomic<S32> report_sequence(0);
// In mStatsSD, we have a copy we own of the LLSD representation
// of the asset stats. Add some additional fields and ship it off.
static const S32 metrics_data_version = 2;
- bool initial_report = !reporting_started;
+ bool initial_report = !reporting_started.load();
mStatsSD["session_id"] = mSessionID;
mStatsSD["agent_id"] = mAgentID;
mStatsSD["message"] = "ViewerAssetMetrics";
- mStatsSD["sequence"] = report_sequence;
+ mStatsSD["sequence"] = report_sequence.load();
mStatsSD["initial"] = initial_report;
mStatsSD["version"] = metrics_data_version;
mStatsSD["break"] = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);
// Update sequence number
- if (S32_MAX == ++report_sequence)
+ if (S32_MAX == report_sequence.fetch_add(1))
{
- report_sequence = 0;
+ report_sequence.store(0);
}
- reporting_started = true;
+
+ reporting_started.store(true);
// Limit the size of the stats report if necessary.
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index f5acc840be..6cf99b68b2 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -420,7 +420,7 @@ bool LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoord
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight());
- glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport);
+ glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport);
{
// convert screen coordinates to virtual UI coordinates
@@ -515,7 +515,7 @@ bool LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
LLRect world_view_rect = gViewerWindow->getWorldViewRectRaw();
glm::ivec4 viewport(world_view_rect.mLeft, world_view_rect.mBottom, world_view_rect.getWidth(), world_view_rect.getHeight());
- glm::vec3 win_coord = glm::project(glm::make_vec3(pos_agent.mV), get_current_modelview(), get_current_projection(), viewport);
+ glm::vec3 win_coord = glm::project(glm::vec3(pos_agent), get_current_modelview(), get_current_projection(), viewport);
{
win_coord.x /= gViewerWindow->getDisplayScale().mV[VX];
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 18746e76fc..598ad89907 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -261,6 +261,8 @@ static bool handleDisableVintageMode(const LLSD& newvalue)
static bool handleEnableHDR(const LLSD& newvalue)
{
+ gPipeline.mReflectionMapManager.reset();
+ gPipeline.mHeroProbeManager.reset();
return handleReleaseGLBufferChanged(newvalue) && handleSetShaderChanged(newvalue);
}
@@ -448,11 +450,11 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
if (gPipeline.isInit())
{
LLPipeline::refreshCachedSettings();
+ gPipeline.mReflectionMapManager.reset();
+ gPipeline.mHeroProbeManager.reset();
gPipeline.releaseGLBuffers();
gPipeline.createGLBuffers();
LLViewerShaderMgr::instance()->setShaders();
- gPipeline.mReflectionMapManager.reset();
- gPipeline.mHeroProbeManager.reset();
}
return true;
}
@@ -762,9 +764,9 @@ LLPointer<LLControlVariable> setting_get_control(LLControlGroup& group, const st
LLPointer<LLControlVariable> cntrl_ptr = group.getControl(setting);
if (cntrl_ptr.isNull())
{
+ LLError::LLUserWarningMsg::showMissingFiles();
LL_ERRS() << "Unable to set up setting listener for " << setting
- << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall."
- << LL_ENDL;
+ << "." << LL_ENDL;
}
return cntrl_ptr;
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 1dfa3a81bf..569924298f 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -2918,14 +2918,14 @@ void LLViewerMediaImpl::update()
media_tex->ref();
main_queue->postTo(
mTexUpdateQueue, // Worker thread queue
- [=]() // work done on update worker thread
+ [=, this]() // work done on update worker thread
{
#if LL_IMAGEGL_THREAD_CHECK
media_tex->getGLTexture()->mActiveThread = LLThread::currentID();
#endif
doMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height, true);
},
- [=]() // callback to main thread
+ [=, this]() // callback to main thread
{
#if LL_IMAGEGL_THREAD_CHECK
media_tex->getGLTexture()->mActiveThread = LLThread::currentID();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index cbc615b01a..bdae400f1d 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -5211,15 +5211,16 @@ void handle_take(bool take_separate)
// MAINT-290
// Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
// Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
- params.functor.function([take_separate](const LLSD &notification, const LLSD &response)
+ LLObjectSelectionHandle obj_selection = LLSelectMgr::instance().getSelection();
+ params.functor.function([take_separate, obj_selection](const LLSD &notification, const LLSD &response)
{
if (take_separate)
{
- confirm_take_separate(notification, response, LLSelectMgr::instance().getSelection());
+ confirm_take_separate(notification, response, obj_selection);
}
else
{
- confirm_take(notification, response, LLSelectMgr::instance().getSelection());
+ confirm_take(notification, response, obj_selection);
}
});
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 09f813accc..63458e60ea 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -728,6 +728,9 @@ public:
// index into LLViewerObjectList::mActiveObjects or -1 if not in list
S32 mListIndex;
+ // last index data for mIndexAndLocalIDToUUID
+ U32 mRegionIndex;
+
LLPointer<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
@@ -756,6 +759,7 @@ public:
// Associated GLTF Asset
std::shared_ptr<LL::GLTF::Asset> mGLTFAsset;
+ bool mIsGLTFAssetMissing = false;
// Pipeline classes
LLPointer<LLDrawable> mDrawable;
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index d667fdbea8..d72d428c08 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -164,21 +164,14 @@ U64 LLViewerObjectList::getIndex(const U32 local_id,
return (((U64)index) << 32) | (U64)local_id;
}
-bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
+bool LLViewerObjectList::removeFromLocalIDTable(LLViewerObject* objectp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
- if(objectp && objectp->getRegion())
+ if(objectp && objectp->mRegionIndex != 0)
{
U32 local_id = objectp->mLocalID;
- U32 ip = objectp->getRegion()->getHost().getAddress();
- U32 port = objectp->getRegion()->getHost().getPort();
- U64 ipport = (((U64)ip) << 32) | (U64)port;
- U32 index = mIPAndPortToIndex[ipport];
-
- // LL_INFOS() << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << LL_ENDL;
-
- U64 indexid = (((U64)index) << 32) | (U64)local_id;
+ U64 indexid = (((U64)objectp->mRegionIndex) << 32) | (U64)local_id;
std::map<U64, LLUUID>::iterator iter = mIndexAndLocalIDToUUID.find(indexid);
if (iter == mIndexAndLocalIDToUUID.end())
@@ -190,6 +183,7 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
if (iter->second == objectp->getID())
{ // Full UUIDs match, so remove the entry
mIndexAndLocalIDToUUID.erase(iter);
+ objectp->mRegionIndex = 0;
return true;
}
// UUIDs did not match - this would zap a valid entry, so don't erase it
@@ -203,7 +197,8 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp)
void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
const U32 local_id,
const U32 ip,
- const U32 port)
+ const U32 port,
+ LLViewerObject* objectp)
{
U64 ipport = (((U64)ip) << 32) | (U64)port;
@@ -215,6 +210,7 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
mIPAndPortToIndex[ipport] = index;
}
+ objectp->mRegionIndex = index; // should never be zero, sSimulatorMachineIndex starts from 1
U64 indexid = (((U64)index) << 32) | (U64)local_id;
mIndexAndLocalIDToUUID[indexid] = id;
@@ -335,7 +331,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*
removeFromLocalIDTable(objectp);
setUUIDAndLocal(fullid, entry->getLocalID(),
regionp->getHost().getAddress(),
- regionp->getHost().getPort());
+ regionp->getHost().getPort(),
+ objectp);
if (objectp->mLocalID != entry->getLocalID())
{ // Update local ID in object with the one sent from the region
@@ -582,7 +579,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
setUUIDAndLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
+ gMessageSystem->getSenderPort(),
+ objectp);
if (objectp->mLocalID != local_id)
{ // Update local ID in object with the one sent from the region
@@ -1381,11 +1379,20 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
void LLViewerObjectList::killAllObjects()
{
// Used only on global destruction.
- LLViewerObject *objectp;
+ // Mass cleanup to not clear lists one item at a time
+ mIndexAndLocalIDToUUID.clear();
+ mActiveObjects.clear();
+ mMapObjects.clear();
+
+ LLViewerObject *objectp;
for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
{
objectp = *iter;
+ objectp->setOnActiveList(false);
+ objectp->setListIndex(-1);
+ objectp->mRegionIndex = 0;
+ objectp->mOnMap = false;
killObject(objectp);
// Object must be dead, or it's the LLVOAvatarSelf which never dies.
llassert((objectp == gAgentAvatarp) || objectp->isDead());
@@ -1398,18 +1405,6 @@ void LLViewerObjectList::killAllObjects()
LL_WARNS() << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << LL_ENDL;
mObjects.clear();
}
-
- if (!mActiveObjects.empty())
- {
- LL_WARNS() << "Some objects still on active object list!" << LL_ENDL;
- mActiveObjects.clear();
- }
-
- if (!mMapObjects.empty())
- {
- LL_WARNS() << "Some objects still on map object list!" << LL_ENDL;
- mMapObjects.clear();
- }
}
void LLViewerObjectList::cleanDeadObjects(bool use_timer)
@@ -1471,20 +1466,25 @@ void LLViewerObjectList::removeFromActiveList(LLViewerObject* objectp)
{
S32 idx = objectp->getListIndex();
if (idx != -1)
- { //remove by moving last element to this object's position
- llassert(mActiveObjects[idx] == objectp);
-
+ {
objectp->setListIndex(-1);
- S32 last_index = static_cast<S32>(mActiveObjects.size()) - 1;
-
- if (idx != last_index)
+ S32 size = (S32)mActiveObjects.size();
+ if (size > 0) // mActiveObjects could have been cleaned already
{
- mActiveObjects[idx] = mActiveObjects[last_index];
- mActiveObjects[idx]->setListIndex(idx);
- }
+ // Remove by moving last element to this object's position
- mActiveObjects.pop_back();
+ llassert(idx < size); // idx should be always within mActiveObjects, unless killAllObjects was called
+ llassert(mActiveObjects[idx] == objectp); // object should be there
+
+ S32 last_index = size - 1;
+ if (idx < last_index)
+ {
+ mActiveObjects[idx] = mActiveObjects[last_index];
+ mActiveObjects[idx]->setListIndex(idx);
+ } // else assume it's the last element, no need to swap
+ mActiveObjects.pop_back();
+ }
}
}
@@ -1509,9 +1509,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp)
mActiveObjects.push_back(objectp);
objectp->setListIndex(static_cast<S32>(mActiveObjects.size()) - 1);
objectp->setOnActiveList(true);
- }
- else
- {
+ }
+ else
+ {
llassert(idx < mActiveObjects.size());
llassert(mActiveObjects[idx] == objectp);
@@ -1863,7 +1863,8 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L
setUUIDAndLocal(uuid,
local_id,
regionp->getHost().getAddress(),
- regionp->getHost().getPort());
+ regionp->getHost().getPort(),
+ objectp);
mObjects.push_back(objectp);
updateActive(objectp);
@@ -1901,7 +1902,8 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe
setUUIDAndLocal(fullid,
local_id,
gMessageSystem->getSenderIP(),
- gMessageSystem->getSenderPort());
+ gMessageSystem->getSenderPort(),
+ objectp);
mObjects.push_back(objectp);
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index dc31995eb1..547ef9fb2d 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -179,9 +179,10 @@ public:
void setUUIDAndLocal(const LLUUID &id,
const U32 local_id,
const U32 ip,
- const U32 port); // Requires knowledge of message system info!
+ const U32 port,
+ LLViewerObject* objectp); // Requires knowledge of message system info!
- bool removeFromLocalIDTable(const LLViewerObject* objectp);
+ bool removeFromLocalIDTable(LLViewerObject* objectp);
// Used ONLY by the orphaned object code.
U64 getIndex(const U32 local_id, const U32 ip, const U32 port);
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 8c24b2438b..8e6657b4b9 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1824,6 +1824,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
S32 bitmap_size = parcel_mgr.mParcelsPerEdge
* parcel_mgr.mParcelsPerEdge
/ 8;
+ S32 size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Bitmap);
+ if (size != bitmap_size)
+ {
+ // Might be better to ignore bitmap and drop highlights
+ LL_WARNS("ParcelMgr") << "Parcel Bitmap size expected: " << bitmap_size
+ << " actual " << size
+ << ". Bitmap might be corrupted!" << LL_ENDL;
+ bitmap_size = size;
+ }
+
U8* bitmap = new U8[ bitmap_size ];
msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index c54e54237e..7ef13c3a35 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -101,6 +101,7 @@ LLGLSLShader gReflectionProbeDisplayProgram;
LLGLSLShader gCopyProgram;
LLGLSLShader gCopyDepthProgram;
LLGLSLShader gPBRTerrainBakeProgram;
+LLGLSLShader gDrawColorProgram;
//object shaders
LLGLSLShader gObjectPreviewProgram;
@@ -113,7 +114,6 @@ LLGLSLShader gObjectAlphaMaskNoColorProgram;
//environment shaders
LLGLSLShader gWaterProgram;
-LLGLSLShader gWaterEdgeProgram;
LLGLSLShader gUnderWaterProgram;
//interface shaders
@@ -409,7 +409,6 @@ void LLViewerShaderMgr::finalizeShaderList()
//ONLY shaders that need WL Param management should be added here
mShaderList.push_back(&gAvatarProgram);
mShaderList.push_back(&gWaterProgram);
- mShaderList.push_back(&gWaterEdgeProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectBumpProgram);
@@ -623,6 +622,8 @@ void LLViewerShaderMgr::setShaders()
else
{
// "ShaderLoading" and "Shader" need to be logged
+ LL_WARNS("Shader") << "Failed loading basic shaders. Retrying with increased log level..." << LL_ENDL;
+
LLError::ELevel lvl = LLError::getDefaultLevel();
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
loadBasicShaders();
@@ -843,7 +844,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
// Note usage of GL_VERTEX_SHADER
if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
{
- LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
+ LL_WARNS("Shader") << "Failed to load basic vertex shader " << i << ": " << shaders[i].first << LL_ENDL;
return shaders[i].first;
}
}
@@ -874,6 +875,7 @@ std::string LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/pbrterrainUtilF.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/tonemapUtilF.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
@@ -906,7 +908,6 @@ bool LLViewerShaderMgr::loadShadersWater()
if (mShaderLevel[SHADER_WATER] == 0)
{
gWaterProgram.unload();
- gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
return true;
}
@@ -920,6 +921,7 @@ bool LLViewerShaderMgr::loadShadersWater()
gWaterProgram.mFeatures.hasGamma = true;
gWaterProgram.mFeatures.hasSrgb = true;
gWaterProgram.mFeatures.hasReflectionProbes = true;
+ gWaterProgram.mFeatures.hasTonemap = true;
gWaterProgram.mFeatures.hasShadows = use_sun_shadow;
gWaterProgram.mShaderFiles.clear();
gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
@@ -943,36 +945,6 @@ bool LLViewerShaderMgr::loadShadersWater()
if (success)
{
- // load water shader
- gWaterEdgeProgram.mName = "Water Edge Shader";
- gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
- gWaterEdgeProgram.mFeatures.hasGamma = true;
- gWaterEdgeProgram.mFeatures.hasSrgb = true;
- gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
- gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow;
- gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
- gWaterEdgeProgram.clearPermutations();
- gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
- if (LLPipeline::sRenderTransparentWater)
- {
- gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
- }
-
- if (use_sun_shadow)
- {
- gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1");
- }
- gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
- success = gWaterEdgeProgram.createShader();
- llassert(success);
- }
-
- if (success)
- {
//load under water vertex shader
gUnderWaterProgram.mName = "Underwater Shader";
gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
@@ -2481,6 +2453,7 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostTonemapProgram.mName = "Deferred Tonemap Post Process";
gDeferredPostTonemapProgram.mFeatures.hasSrgb = true;
gDeferredPostTonemapProgram.mFeatures.isDeferred = true;
+ gDeferredPostTonemapProgram.mFeatures.hasTonemap = true;
gDeferredPostTonemapProgram.mShaderFiles.clear();
gDeferredPostTonemapProgram.clearPermutations();
gDeferredPostTonemapProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
@@ -2495,6 +2468,7 @@ bool LLViewerShaderMgr::loadShadersDeferred()
gNoPostTonemapProgram.mName = "No Post Tonemap Post Process";
gNoPostTonemapProgram.mFeatures.hasSrgb = true;
gNoPostTonemapProgram.mFeatures.isDeferred = true;
+ gNoPostTonemapProgram.mFeatures.hasTonemap = true;
gNoPostTonemapProgram.mShaderFiles.clear();
gNoPostTonemapProgram.clearPermutations();
gNoPostTonemapProgram.addPermutation("NO_POST", "1");
@@ -3353,6 +3327,17 @@ bool LLViewerShaderMgr::loadShadersInterface()
success = gCopyDepthProgram.createShader();
}
+ if (success)
+ {
+ gDrawColorProgram.mName = "Draw Color Shader";
+ gDrawColorProgram.mShaderFiles.clear();
+ gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoAtmosV.glsl", GL_VERTEX_SHADER));
+ gDrawColorProgram.mShaderFiles.push_back(make_pair("objects/simpleColorF.glsl", GL_FRAGMENT_SHADER));
+ gDrawColorProgram.clearPermutations();
+ gDrawColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = gDrawColorProgram.createShader();
+ }
+
if (gSavedSettings.getBOOL("LocalTerrainPaintEnabled"))
{
if (success)
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index b08796025a..7ad2da9464 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -175,6 +175,7 @@ extern LLGLSLShader gReflectionProbeDisplayProgram;
extern LLGLSLShader gCopyProgram;
extern LLGLSLShader gCopyDepthProgram;
extern LLGLSLShader gPBRTerrainBakeProgram;
+extern LLGLSLShader gDrawColorProgram;
//output tex0[tc0] - tex1[tc1]
extern LLGLSLShader gTwoTextureCompareProgram;
@@ -191,7 +192,6 @@ extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
//environment shaders
extern LLGLSLShader gWaterProgram;
-extern LLGLSLShader gWaterEdgeProgram;
extern LLGLSLShader gUnderWaterProgram;
extern LLGLSLShader gGlowProgram;
extern LLGLSLShader gGlowExtractProgram;
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 36b6787ace..609ad38e96 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -87,6 +87,7 @@ S32 LLViewerTexture::sRawCount = 0;
S32 LLViewerTexture::sAuxCount = 0;
LLFrameTimer LLViewerTexture::sEvaluationTimer;
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
+U32 LLViewerTexture::sBiasTexturesUpdated = 0;
S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
@@ -107,12 +108,6 @@ LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTextur
const F64 log_2 = log(2.0);
-#if ADDRESS_SIZE == 32
-const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT / 2;
-#else
-const U32 DESIRED_NORMAL_TEXTURE_SIZE = (U32)LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT;
-#endif
-
//----------------------------------------------------------------------------------------------
//namespace: LLViewerTextureAccess
//----------------------------------------------------------------------------------------------
@@ -518,6 +513,7 @@ void LLViewerTexture::updateClass()
bool is_sys_low = isSystemMemoryLow();
bool is_low = is_sys_low || over_pct > 0.f;
+ F32 discard_bias = sDesiredDiscardBias;
static bool was_low = false;
static bool was_sys_low = false;
@@ -556,12 +552,13 @@ void LLViewerTexture::updateClass()
// don't execute above until the slam to 1.5 has a chance to take effect
sEvaluationTimer.reset();
- // lower discard bias over time when free memory is available
- if (sDesiredDiscardBias > 1.f && over_pct < 0.f)
+ // lower discard bias over time when at least 10% of budget is free
+ const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f;
+ if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD)
{
static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f);
- F32 decrement = high_mem_discard_decrement - llmin(over_pct, 0.f);
+ F32 decrement = high_mem_discard_decrement - llmin(over_pct - FREE_PERCENTAGE_TRESHOLD, 0.f);
sDesiredDiscardBias -= decrement * gFrameIntervalSeconds;
}
}
@@ -603,6 +600,12 @@ void LLViewerTexture::updateClass()
}
sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f);
+ if (discard_bias != sDesiredDiscardBias)
+ {
+ // bias changed, reset texture update counter to
+ // let updates happen at an increased rate.
+ sBiasTexturesUpdated = 0;
+ }
LLViewerTexture::sFreezeImageUpdates = false;
}
@@ -1685,6 +1688,16 @@ void LLViewerFetchedTexture::processTextureStats()
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
+ U32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT;
+ if (mBoostLevel < LLGLTexture::BOOST_HIGH)
+ {
+ // restrict texture resolution to download based on RenderMaxTextureResolution
+ static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
+ // sanity clamp debug setting to avoid settings hack shenanigans
+ max_tex_res = (U32)llclamp((U32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT);
+ mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)(max_tex_res * max_tex_res));
+ }
+
if (textures_fullres)
{
mDesiredDiscardLevel = 0;
@@ -1706,10 +1719,9 @@ void LLViewerFetchedTexture::processTextureStats()
}
else
{
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
if(!mKnownDrawWidth || !mKnownDrawHeight || (S32)mFullWidth <= mKnownDrawWidth || (S32)mFullHeight <= mKnownDrawHeight)
{
- if (mFullWidth > desired_size || mFullHeight > desired_size)
+ if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
{
mDesiredDiscardLevel = 1;
}
@@ -2913,8 +2925,6 @@ LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, co
void LLViewerLODTexture::init(bool firstinit)
{
mTexelsPerImage = 64*64;
- mDiscardVirtualSize = 0.f;
- mCalculatedDiscardLevel = -1.f;
}
//virtual
@@ -2939,12 +2949,14 @@ void LLViewerLODTexture::processTextureStats()
static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes", false);
- { // restrict texture resolution to download based on RenderMaxTextureResolution
+ F32 max_tex_res = MAX_IMAGE_SIZE_DEFAULT;
+ if (mBoostLevel < LLGLTexture::BOOST_HIGH)
+ {
+ // restrict texture resolution to download based on RenderMaxTextureResolution
static LLCachedControl<U32> max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048);
// sanity clamp debug setting to avoid settings hack shenanigans
- F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048);
- tex_res *= tex_res;
- mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res);
+ max_tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT);
+ mMaxVirtualSize = llmin(mMaxVirtualSize, max_tex_res * max_tex_res);
}
if (textures_fullres)
@@ -2993,19 +3005,12 @@ void LLViewerLODTexture::processTextureStats()
{
// Calculate the required scale factor of the image using pixels per texel
discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4);
- mDiscardVirtualSize = mMaxVirtualSize;
- mCalculatedDiscardLevel = discard_level;
}
discard_level = floorf(discard_level);
F32 min_discard = 0.f;
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 2048 and max size ever is 4096
- if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED)
- {
- desired_size = DESIRED_NORMAL_TEXTURE_SIZE;
- }
- if (mFullWidth > desired_size || mFullHeight > desired_size)
+ if (mFullWidth > max_tex_res || mFullHeight > max_tex_res)
min_discard = 1.f;
discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
@@ -3543,18 +3548,7 @@ void LLViewerMediaTexture::setPlaying(bool playing)
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
LLFace* facep = *iter;
- const LLTextureEntry* te = facep->getTextureEntry();
- if (te->getGLTFMaterial())
- {
- // PBR material, switch emissive and basecolor
- switchTexture(LLRender::EMISSIVE_MAP, *iter);
- switchTexture(LLRender::BASECOLOR_MAP, *iter);
- }
- else
- {
- // blinn-phong material, switch diffuse map only
- switchTexture(LLRender::DIFFUSE_MAP, *iter);
- }
+ switchTexture(LLRender::DIFFUSE_MAP, facep);
}
}
else //stop playing this media
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 4241ef958f..e1582c74bd 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -220,6 +220,7 @@ public:
static S32 sAuxCount;
static LLFrameTimer sEvaluationTimer;
static F32 sDesiredDiscardBias;
+ static U32 sBiasTexturesUpdated;
static S32 sMaxSculptRez ;
static U32 sMinLargeImageSize ;
static U32 sMaxSmallImageSize ;
@@ -540,10 +541,6 @@ public:
private:
void init(bool firstinit) ;
-
-private:
- F32 mDiscardVirtualSize; // Virtual size used to calculate desired discard
- F32 mCalculatedDiscardLevel; // Last calculated discard level
};
//
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index c2eb8ddd25..a4a001eceb 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -276,7 +276,7 @@ void LLViewerTextureList::doPrefetchImages()
S32 pixel_area = imagesd["area"];
S32 texture_type = imagesd["type"];
- if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)
+ if((LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type))
{
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);
if (image)
@@ -1091,7 +1091,8 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
imagep->mCreatePending = false;
mCreateTextureList.pop();
- if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel())
+ if (imagep->hasGLTexture() && imagep->getDiscardLevel() < imagep->getDesiredDiscardLevel() &&
+ (imagep->getDesiredDiscardLevel() <= MAX_DISCARD_LEVEL))
{
// NOTE: this may happen if the desired discard reduces while a decode is in progress and does not
// necessarily indicate a problem, but if log occurrences excede that of dsiplay_stats: FPS,
@@ -1208,10 +1209,17 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
//update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater
update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20);
- if (LLViewerTexture::sDesiredDiscardBias > 1.f)
+ if (LLViewerTexture::sDesiredDiscardBias > 1.f
+ && LLViewerTexture::sBiasTexturesUpdated < (U32)mUUIDMap.size())
{
- // we are over memory target, update more agresively
+ // We are over memory target. Bias affects discard rates, so update
+ // existing textures agresively to free memory faster.
update_count = (S32)(update_count * LLViewerTexture::sDesiredDiscardBias);
+
+ // This isn't particularly precise and can overshoot, but it doesn't need
+ // to be, just making sure it did a full circle and doesn't get stuck updating
+ // at bias = 4 with 4 times the rate permanently.
+ LLViewerTexture::sBiasTexturesUpdated += update_count;
}
update_count = llmin(update_count, (U32) mUUIDMap.size());
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d399cc6469..82a67d50dc 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1331,7 +1331,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
// Check the whitelist, if there's media (otherwise just show it)
if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
{
- if ( obj != mDragHoveredObject)
+ if ( obj != mDragHoveredObject.get())
{
// Highlight the dragged object
LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
@@ -1746,6 +1746,7 @@ bool LLViewerWindow::handleDeviceChange(LLWindow *window)
bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
{
+ LLFontGL::sResolutionGeneration++;
if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE)
{
LLViewerWindow::reshape(window_width, window_height);
@@ -1759,6 +1760,12 @@ bool LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32
}
}
+bool LLViewerWindow::handleDisplayChanged()
+{
+ LLFontGL::sResolutionGeneration++;
+ return false;
+}
+
bool LLViewerWindow::handleWindowDidChangeScreen(LLWindow *window)
{
LLCoordScreen window_rect;
@@ -1927,6 +1934,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
mDisplayScale *= ui_scale_factor;
LLUI::setScaleFactor(mDisplayScale);
+ LLFontGL::sResolutionGeneration++;
{
LLCoordWindow size;
@@ -2496,6 +2504,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
bool display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
LLUI::setScaleFactor(mDisplayScale);
+ LLFontGL::sResolutionGeneration++;
// update our window rectangle
mWindowRectScaled.mRight = mWindowRectScaled.mLeft + ll_round((F32)width / mDisplayScale.mV[VX]);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 1b995ea650..fbc2c58fbf 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -225,6 +225,7 @@ public:
/*virtual*/ bool handleTimerEvent(LLWindow *window);
/*virtual*/ bool handleDeviceChange(LLWindow *window);
/*virtual*/ bool handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
+ /*virtual*/ bool handleDisplayChanged();
/*virtual*/ bool handleWindowDidChangeScreen(LLWindow *window);
/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 2ef45442ee..f5dfcca873 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1944,8 +1944,8 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
glm::mat4 inverse = glm::inverse(mat);
glm::mat4 norm_mat = glm::transpose(inverse);
- glm::vec3 p1(glm::make_vec3(start.getF32ptr()));
- glm::vec3 p2(glm::make_vec3(end.getF32ptr()));
+ glm::vec3 p1(start);
+ glm::vec3 p2(end);
p1 = mul_mat4_vec3(inverse, p1);
p2 = mul_mat4_vec3(inverse, p2);
@@ -1953,12 +1953,12 @@ bool LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
LLVector3 position;
LLVector3 norm;
- if (linesegment_sphere(LLVector3(glm::value_ptr(p1)), LLVector3(glm::value_ptr(p2)), LLVector3(0,0,0), 1.f, position, norm))
+ if (linesegment_sphere(LLVector3(p1), LLVector3(p2), LLVector3(0,0,0), 1.f, position, norm))
{
- glm::vec3 res_pos(glm::make_vec3(position.mV));
+ glm::vec3 res_pos(position);
res_pos = mul_mat4_vec3(mat, res_pos);
- glm::vec3 res_norm(glm::make_vec3(norm.mV));
+ glm::vec3 res_norm(norm);
res_norm = glm::normalize(res_norm);
res_norm = glm::mat3(norm_mat) * res_norm;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 3d8ffc35e7..e5eb2f8008 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -293,6 +293,7 @@ void LLVoiceClient::setNonSpatialVoiceModule(const std::string &voice_server_typ
void LLVoiceClient::setHidden(bool hidden)
{
+ LL_INFOS("Voice") << "( " << (hidden ? "true" : "false") << " )" << LL_ENDL;
#if !__FreeBSD__
LLWebRTCVoiceClient::getInstance()->setHidden(hidden);
#endif
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index d64c25d312..7faef8cc41 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -2014,7 +2014,7 @@ bool LLVivoxVoiceClient::waitForChannel()
{
recordingAndPlaybackMode();
}
- else if (mProcessChannels && (mNextAudioSession == NULL) && checkParcelChanged())
+ else if (mProcessChannels && ((mNextAudioSession == NULL) || checkParcelChanged()))
{
// the parcel is changed, or we have no pending audio sessions,
// so try to request the parcel voice info
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index b2e5de5371..93c217a7ba 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -345,6 +345,8 @@ void LLWebRTCVoiceClient::updateSettings()
static LLCachedControl<std::string> sOutputDevice(gSavedSettings, "VoiceOutputAudioDevice");
setRenderDevice(sOutputDevice);
+ LL_INFOS("Voice") << "Input device: " << std::quoted(sInputDevice()) << ", output device: " << std::quoted(sOutputDevice()) << LL_ENDL;
+
static LLCachedControl<F32> sMicLevel(gSavedSettings, "AudioLevelMic");
setMicGain(sMicLevel);
@@ -554,7 +556,7 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
}
}
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (sShuttingDown)
{
return;
@@ -672,7 +674,7 @@ void LLWebRTCVoiceClient::OnDevicesChanged(const llwebrtc::LLWebRTCVoiceDeviceLi
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=]
+ [=, this]
{
OnDevicesChangedImpl(render_devices, capture_devices);
});
@@ -896,7 +898,7 @@ void LLWebRTCVoiceClient::OnConnectionShutDown(const std::string &channelID, con
{
if (mSession && mSession->mChannelID == channelID)
{
- LL_DEBUGS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
+ LL_INFOS("Voice") << "Main WebRTC Connection Shut Down." << LL_ENDL;
}
}
mSession->removeAllParticipants(regionID);
@@ -1504,6 +1506,11 @@ bool LLWebRTCVoiceClient::compareChannels(const LLSD &channelInfo1, const LLSD &
// we're muting the mic, so tell each session such
void LLWebRTCVoiceClient::setMuteMic(bool muted)
{
+ if (mMuteMic != muted)
+ {
+ LL_INFOS("Voice") << "( " << (muted ? "true" : "false") << " )" << LL_ENDL;
+ }
+
mMuteMic = muted;
// when you're hidden, your mic is always muted.
if (!mHidden)
@@ -1552,14 +1559,10 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- LL_DEBUGS("Voice")
- << "( " << (enabled ? "enabled" : "disabled") << " )"
- << " was "<< (mVoiceEnabled ? "enabled" : "disabled")
- << " coro "<< (mIsCoroutineActive ? "active" : "inactive")
- << LL_ENDL;
-
if (enabled != mVoiceEnabled)
{
+ LL_INFOS("Voice") << "( " << (enabled ? "enabled" : "disabled") << " )"
+ << ", coro: " << (mIsCoroutineActive ? "active" : "inactive") << LL_ENDL;
// TODO: Refactor this so we don't call into LLVoiceChannel, but simply
// use the status observer
mVoiceEnabled = enabled;
@@ -2208,7 +2211,7 @@ LLVoiceWebRTCConnection::~LLVoiceWebRTCConnection()
void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObserver::EIceGatheringState state)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
LL_DEBUGS("Voice") << "Ice Gathering voice account. " << state << LL_ENDL;
switch (state)
@@ -2231,7 +2234,7 @@ void LLVoiceWebRTCConnection::OnIceGatheringState(llwebrtc::LLWebRTCSignalingObs
// callback from llwebrtc
void LLVoiceWebRTCConnection::OnIceCandidate(const llwebrtc::LLWebRTCIceCandidate& candidate)
{
- LL::WorkQueue::postMaybe(mMainQueue, [=] { mIceCandidates.push_back(candidate); });
+ LL::WorkQueue::postMaybe(mMainQueue, [=, this] { mIceCandidates.push_back(candidate); });
}
void LLVoiceWebRTCConnection::processIceUpdates()
@@ -2349,7 +2352,7 @@ void LLVoiceWebRTCConnection::processIceUpdatesCoro(connectionPtr_t connection)
void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
@@ -2376,7 +2379,7 @@ void LLVoiceWebRTCConnection::OnOfferAvailable(const std::string &sdp)
void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterface* audio_interface)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
@@ -2398,7 +2401,7 @@ void LLVoiceWebRTCConnection::OnAudioEstablished(llwebrtc::LLWebRTCAudioInterfac
void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL;
if (!mShutDown)
{
@@ -2412,7 +2415,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
void LLVoiceWebRTCConnection::OnPeerConnectionClosed()
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
LL_DEBUGS("Voice") << "Peer connection has closed." << LL_ENDL;
if (mVoiceConnectionState == VOICE_STATE_WAIT_FOR_CLOSE)
{
@@ -2483,7 +2486,7 @@ void LLVoiceWebRTCConnection::breakVoiceConnectionCoro(connectionPtr_t connectio
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
- LL_DEBUGS("Voice") << "Disconnecting voice." << LL_ENDL;
+ LL_INFOS("Voice") << "Disconnecting voice." << LL_ENDL;
if (connection->mWebRTCDataInterface)
{
connection->mWebRTCDataInterface->unsetDataObserver(connection.get());
@@ -2591,6 +2594,7 @@ void LLVoiceWebRTCSpatialConnection::requestVoiceConnection()
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+ LL_INFOS("Voice") << "Voice connection request: " << (status ? "Success" : status.toString()) << LL_ENDL;
if (status)
{
OnVoiceConnectionRequestSuccess(result);
@@ -2884,7 +2888,7 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
// llwebrtc callback
void LLVoiceWebRTCConnection::OnDataReceived(const std::string& data, bool binary)
{
- LL::WorkQueue::postMaybe(mMainQueue, [=] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); });
+ LL::WorkQueue::postMaybe(mMainQueue, [=, this] { LLVoiceWebRTCConnection::OnDataReceivedImpl(data, binary); });
}
//
@@ -3040,7 +3044,7 @@ void LLVoiceWebRTCConnection::OnDataReceivedImpl(const std::string &data, bool b
void LLVoiceWebRTCConnection::OnDataChannelReady(llwebrtc::LLWebRTCDataInterface *data_interface)
{
LL::WorkQueue::postMaybe(mMainQueue,
- [=] {
+ [=, this] {
if (mShutDown)
{
return;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7740376d5c..3fb7a3c156 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -645,8 +645,12 @@ void LLVOVolume::animateTextures()
// LLVOVolume::updateTextureVirtualSize when the
// mTextureMatrix is not yet present
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
- mDrawable->getSpatialGroup()->dirtyGeom();
- gPipeline.markRebuild(mDrawable->getSpatialGroup());
+ LLSpatialGroup* group = mDrawable->getSpatialGroup();
+ if (group)
+ {
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
}
}
@@ -5735,13 +5739,23 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
- LLFetchedGLTFMaterial *gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
+ LLFetchedGLTFMaterial* gltf_mat = nullptr;
+ const LLTextureEntry* te = facep->getTextureEntry();
+ if (te)
+ {
+ gltf_mat = (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial();
+ } // if not te, continue?
bool is_pbr = gltf_mat != nullptr;
if (is_pbr)
{
// tell texture streaming system to ignore blinn-phong textures
- facep->setTexture(LLRender::DIFFUSE_MAP, nullptr);
+ // except the special case of the diffuse map containing a
+ // media texture that will be reused for swapping on to the pbr face
+ if (!facep->hasMedia())
+ {
+ facep->setTexture(LLRender::DIFFUSE_MAP, nullptr);
+ }
facep->setTexture(LLRender::NORMAL_MAP, nullptr);
facep->setTexture(LLRender::SPECULAR_MAP, nullptr);
@@ -5797,10 +5811,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
cur_total += facep->getGeomCount();
- const LLTextureEntry* te = facep->getTextureEntry();
LLViewerTexture* tex = facep->getTexture();
- if (te->getGlow() > 0.f)
+ if (te && te->getGlow() > 0.f)
{
emissive = true;
}
@@ -5894,6 +5907,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
facep->mLastUpdateTime = gFrameTimeSeconds;
}
+ if (te)
{
LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
@@ -5958,6 +5972,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
add_face(sFullbrightFaces, fullbright_count, facep);
}
}
+ else // no texture entry
+ {
+ facep->setState(LLFace::FULLBRIGHT);
+ add_face(sFullbrightFaces, fullbright_count, facep);
+ }
}
}
else
@@ -6712,8 +6731,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ //shiny
if (tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim+shiny
- registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
- registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh())
+ {
+ registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
+ registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ }
}
else if (!hud_group)
{ //deferred rendering
@@ -6749,7 +6771,10 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ //not alpha and not shiny
if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
{ //invisiprim
- registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ if (!facep->getViewerObject()->isAttachment() && !facep->getViewerObject()->isRiggedMesh())
+ {
+ registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
+ }
}
else if (fullbright || bake_sunlight)
{ //fullbright
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3240e2a663..e441e189ad 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -431,6 +431,7 @@ void LLPipeline::init()
stop_glerror();
//create render pass pools
+ getPool(LLDrawPool::POOL_WATEREXCLUSION);
getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
getPool(LLDrawPool::POOL_SIMPLE);
@@ -673,6 +674,8 @@ void LLPipeline::cleanup()
// don't delete wl sky pool it was handled above in the for loop
//delete mWLSkyPool;
mWLSkyPool = NULL;
+ delete mWaterExclusionPool;
+ mWaterExclusionPool = nullptr;
releaseGLBuffers();
@@ -907,6 +910,15 @@ bool LLPipeline::allocateScreenBufferInternal(U32 resX, U32 resY)
mPostMap.allocate(resX, resY, screenFormat);
+ // The water exclusion mask needs its own depth buffer so we can take care of the problem of multiple water planes.
+ // Should we ever make water not just a plane, it also aids with that as well as the water planes will be rendered into the mask.
+ // Why do we do this? Because it saves us some janky logic in the exclusion shader when we generate the mask.
+ // Regardless, this should always only be an R8 texture unless we choose to start having multiple kinds of exclusion that 8 bits can't handle.
+ // - Geenz 2025-02-06
+ bool success = mWaterExclusionMask.allocate(resX, resY, GL_R8, true);
+
+ assert(success);
+
// used to scale down textures
// See LLViwerTextureList::updateImagesCreateTextures and LLImageGL::scaleDown
mDownResMap.allocate(1024, 1024, GL_RGBA);
@@ -1166,6 +1178,8 @@ void LLPipeline::releaseGLBuffers()
mSceneMap.release();
+ mWaterExclusionMask.release();
+
mPostMap.release();
mFXAAMap.release();
@@ -1676,6 +1690,10 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mPBRAlphaMaskPool;
break;
+ case LLDrawPool::POOL_WATEREXCLUSION:
+ poolp = mWaterExclusionPool;
+ break;
+
default:
llassert(0);
LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
@@ -3855,7 +3873,12 @@ void LLPipeline::renderSelectedFaces(const LLColor4& color)
for (auto facep : mSelectedFaces)
{
- if (!facep || facep->getDrawable()->isDead())
+ if (!facep || !facep->getViewerObject())
+ {
+ LLSelectMgr::getInstance()->clearSelections();
+ return;
+ }
+ if (!facep->getDrawable() || facep->getDrawable()->isDead())
{
LL_ERRS() << "Bad face on selection" << LL_ENDL;
return;
@@ -4067,6 +4090,8 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
#endif
}
+// Render all of our geometry that's required after our deferred pass.
+// This is gonna be stuff like alpha, water, etc.
void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -4085,6 +4110,10 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
bool done_atmospherics = LLPipeline::sRenderingHUDs; //skip atmospherics on huds
bool done_water_haze = done_atmospherics;
+ bool done_water_exclusion = false;
+
+ // do water exclusion just before water pass.
+ U32 water_exclusion_pass = LLDrawPool::POOL_WATEREXCLUSION;
// do atmospheric haze just before post water alpha
U32 atmospherics_pass = LLDrawPool::POOL_ALPHA_POST_WATER;
@@ -4123,6 +4152,12 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
cur_type = poolp->getType();
+ if (cur_type >= water_exclusion_pass && !done_water_exclusion)
+ { // do water exclusion against depth buffer before rendering alpha
+ doWaterExclusionMask();
+ done_water_exclusion = true;
+ }
+
if (cur_type >= atmospherics_pass && !done_atmospherics)
{ // do atmospherics against depth buffer before rendering alpha
doAtmospherics();
@@ -5238,6 +5273,17 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_WATEREXCLUSION:
+ if (mWaterExclusionPool)
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water Exclusion Pool" << LL_ENDL;
+ }
+ else
+ {
+ mWaterExclusionPool = new_poolp;
+ }
+ break;
default:
llassert(0);
@@ -5360,6 +5406,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mPBRAlphaMaskPool = NULL;
break;
+ case LLDrawPool::POOL_WATEREXCLUSION:
+ llassert(poolp == mWaterExclusionPool);
+ mWaterExclusionPool = nullptr;
+ break;
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
@@ -7118,7 +7169,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
- F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
+ F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust());
F32 exp_min = 1.f;
F32 exp_max = 1.f;
@@ -7129,13 +7180,13 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
{
if (dynamic_exposure_enabled)
{
- exp_min = sky->getHDROffset() - sky->getHDRMin();
- exp_max = sky->getHDROffset() + sky->getHDRMax();
+ exp_min = sky->getHDROffset(should_auto_adjust()) - sky->getHDRMin(should_auto_adjust());
+ exp_max = sky->getHDROffset(should_auto_adjust()) + sky->getHDRMax(should_auto_adjust());
}
else
{
- exp_min = sky->getHDROffset();
- exp_max = sky->getHDROffset();
+ exp_min = sky->getHDROffset(should_auto_adjust());
+ exp_max = sky->getHDROffset(should_auto_adjust());
}
}
else if (dynamic_exposure_enabled)
@@ -7155,7 +7206,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool
shader->uniform1f(dt, gFrameIntervalSeconds);
shader->uniform2f(noiseVec, ll_frand() * 2.0f - 1.0f, ll_frand() * 2.0f - 1.0f);
shader->uniform4f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max, dynamic_exposure_speed_error);
- shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(), exp_min, exp_max, dynamic_exposure_speed_target);
+ shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(should_auto_adjust()), exp_min, exp_max, dynamic_exposure_speed_target);
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -7213,7 +7264,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst)
static LLCachedControl<U32> tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U);
shader.uniform1i(tonemap_type, tonemap_type_setting);
- shader.uniform1f(tonemap_mix, psky->getTonemapMix());
+ shader.uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust()));
mScreenTriangleVB->setBuffer();
mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -8433,13 +8484,13 @@ void LLPipeline::renderDeferredLighting()
setupHWLights(); // to set mSun/MoonDir;
- glm::vec4 tc(glm::make_vec4(mSunDir.mV));
+ glm::vec4 tc(mSunDir);
tc = mat * tc;
- mTransformedSunDir.set(glm::value_ptr(tc));
+ mTransformedSunDir.set(tc);
- glm::vec4 tc_moon(glm::make_vec4(mMoonDir.mV));
+ glm::vec4 tc_moon(mMoonDir);
tc_moon = mat * tc_moon;
- mTransformedMoonDir.set(glm::value_ptr(tc_moon));
+ mTransformedMoonDir.set(tc_moon);
if ((RenderDeferredSSAO && !gCubeSnapshot) || RenderShadowDetail > 0)
{
@@ -8692,7 +8743,7 @@ void LLPipeline::renderDeferredLighting()
continue;
}
- glm::vec3 tc(glm::make_vec3(c));
+ glm::vec3 tc(center);
tc = mul_mat4_vec3(mat, tc);
fullscreen_lights.push_back(LLVector4(tc.x, tc.y, tc.z, s));
@@ -8799,13 +8850,12 @@ void LLPipeline::renderDeferredLighting()
LLDrawable* drawablep = *iter;
LLVOVolume* volume = drawablep->getVOVolume();
LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
F32 light_size_final = volume->getLightRadius() * 1.5f;
F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF);
sVisibleLightCount++;
- glm::vec3 tc(glm::make_vec3(c));
+ glm::vec3 tc(center);
tc = mul_mat4_vec3(mat, tc);
setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
@@ -8862,6 +8912,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_WATEREXCLUSION,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
@@ -9000,6 +9051,8 @@ void LLPipeline::doWaterHaze()
static LLStaticHashedString above_water_str("above_water");
haze_shader.uniform1i(above_water_str, sUnderWaterRender ? -1 : 1);
+ haze_shader.bindTexture(LLShaderMgr::WATER_EXCLUSIONTEX, &mWaterExclusionMask);
+
if (LLPipeline::sUnderWaterRender)
{
LLGLDepthTest depth(GL_FALSE);
@@ -9030,6 +9083,17 @@ void LLPipeline::doWaterHaze()
}
}
+void LLPipeline::doWaterExclusionMask()
+{
+ mWaterExclusionMask.bindTarget();
+ glClearColor(1, 1, 1, 1);
+ mWaterExclusionMask.clear();
+ mWaterExclusionPool->render();
+
+ mWaterExclusionMask.flush();
+ glClearColor(0, 0, 0, 0);
+}
+
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -9946,10 +10010,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLVector3 lightDir = -caster_dir;
lightDir.normVec();
- glm::vec3 light_dir(glm::make_vec3(lightDir.mV));
-
//create light space camera matrix
-
LLVector3 at = lightDir;
LLVector3 up = camera.getAtAxis();
@@ -10001,9 +10062,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//get good split distances for frustum
for (U32 i = 0; i < fp.size(); ++i)
{
- glm::vec3 v(glm::make_vec3(fp[i].mV));
+ glm::vec3 v(fp[i]);
v = mul_mat4_vec3(saved_view, v);
- fp[i].setVec(glm::value_ptr(v));
+ fp[i] = LLVector3(v);
}
min = fp[0];
@@ -10152,9 +10213,9 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
for (U32 i = 0; i < fp.size(); i++)
{
- glm::vec3 p = glm::make_vec3(fp[i].mV);
+ glm::vec3 p(fp[i]);
p = mul_mat4_vec3(view[j], p);
- wpf.push_back(LLVector3(glm::value_ptr(p)));
+ wpf.push_back(LLVector3(p));
}
min = wpf[0];
@@ -10355,19 +10416,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
view[j] = glm::inverse(view[j]);
//llassert(origin.isFinite());
- glm::vec3 origin_agent(glm::make_vec3(origin.mV));
+ glm::vec3 origin_agent(origin);
//translate view to origin
origin_agent = mul_mat4_vec3(view[j], origin_agent);
- eye = LLVector3(glm::value_ptr(origin_agent));
+ eye = LLVector3(origin_agent);
//llassert(eye.isFinite());
if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowFrustOrigin[j] = eye;
}
- view[j] = look(LLVector3(glm::value_ptr(origin_agent)), lightDir, -up);
+ view[j] = look(LLVector3(origin_agent), lightDir, -up);
F32 fx = 1.f/tanf(fovx);
F32 fz = 1.f/tanf(fovz);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 5c9b95ef4a..315e38ed8c 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -337,6 +337,9 @@ public:
// should be called just before rendering pre-water alpha objects
void doWaterHaze();
+ // Generate the water exclusion surface mask.
+ void doWaterExclusionMask();
+
void postDeferredGammaCorrect(LLRenderTarget* screen_target);
void generateSunShadow(LLCamera& camera);
@@ -500,6 +503,7 @@ public:
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
+ RENDER_TYPE_WATEREXCLUSION = LLDrawPool::POOL_WATEREXCLUSION,
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
RENDER_TYPE_GLTF_PBR = LLDrawPool::POOL_GLTF_PBR,
@@ -714,6 +718,7 @@ public:
LLRenderTarget mSpotShadow[2];
LLRenderTarget mPbrBrdfLut;
+ LLRenderTarget mWaterExclusionMask;
// copy of the color/depth buffer just before gamma correction
// for use by SSR
@@ -953,6 +958,7 @@ protected:
LLDrawPool* mWLSkyPool = nullptr;
LLDrawPool* mPBROpaquePool = nullptr;
LLDrawPool* mPBRAlphaMaskPool = nullptr;
+ LLDrawPool* mWaterExclusionPool = nullptr;
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png
deleted file mode 100644
index 5a50e0ad34..0000000000
--- a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png
deleted file mode 100644
index ff1ea3a72e..0000000000
--- a/indra/newview/skins/default/textures/3p_icons/havok_logo.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png
deleted file mode 100644
index 6f20e87b7a..0000000000
--- a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png
+++ /dev/null
Binary files differ
diff --git a/indra/newview/skins/default/xui/de/panel_progress.xml b/indra/newview/skins/default/xui/de/panel_progress.xml
index 8d1abdcac1..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/de/panel_progress.xml
+++ b/indra/newview/skins/default/xui/de/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Second Life verwendet</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 0fdc1596c4..9db5502387 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
- height="430"
+ height="452"
layout="topleft"
name="prefs_graphics_advanced"
help_topic="Preferences_Graphics_Advanced"
@@ -118,6 +118,41 @@
name="MaxLights"
top_delta="16"
width="336" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ top_delta="16"
+ left="30"
+ width="160"
+ name="MaxTextureResolutionLabel"
+ text_readonly_color="LabelDisabledColor">
+ Maximum LOD resolution:
+ </text>
+ <combo_box
+ control_name="RenderMaxTextureResolution"
+ height="19"
+ layout="topleft"
+ left_pad="10"
+ top_delta="0"
+ name="MaxTextureResolution"
+ tool_tip="Maximum resolution for 'level of detail' textures"
+ width="90">
+ <combo_box.item
+ label="512"
+ name="512"
+ value="512"/>
+ <combo_box.item
+ label="1024"
+ name="1024"
+ value="1024"/>
+ <combo_box.item
+ label="2048"
+ name="2048"
+ value="2048"/>
+ </combo_box>
<check_box
control_name="RenderVSyncEnable"
@@ -152,7 +187,7 @@
layout="topleft"
left="30"
top_delta="16"
- width="128"
+ width="130"
name="AvatarComplexityModeLabel"
text_readonly_color="LabelDisabledColor">
Avatar display:
@@ -160,10 +195,10 @@
<combo_box
control_name="RenderAvatarComplexityMode"
- height="18"
+ height="19"
layout="topleft"
- left_delta="130"
- top_delta="0"
+ left_pad="40"
+ top_delta="-1"
name="AvatarComplexityMode"
width="150">
<combo_box.item
@@ -195,7 +230,7 @@
max_val="101"
name="IndirectMaxComplexity"
show_text="false"
- top_delta="16"
+ top_delta="19"
width="300">
<slider.commit_callback
function="Pref.UpdateIndirectMaxComplexity"
@@ -368,7 +403,7 @@
left="30"
name="antialiasing label"
top_delta="20"
- width="120">
+ width="130">
Antialiasing:
</text>
<combo_box
@@ -403,7 +438,7 @@
left="30"
name="antialiasing quality label"
top_delta="20"
- width="120">
+ width="130">
Antialiasing Quality:
</text>
<combo_box
@@ -1015,7 +1050,7 @@
layout="topleft"
left="13"
name="horiz_border"
- top="393"
+ top="415"
top_delta="5"
width="774"/>
<button
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 1d1b81e31a..5fff9b7bc0 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -95,18 +95,11 @@
</menu_item_call>
<menu_item_separator/>
<menu_item_call
- label="[SECOND_LIFE] News"
- name="Second Life News">
- <menu_item_call.on_click
- function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>
- </menu_item_call>
- <menu_item_call
label="[SECOND_LIFE] Blogs"
name="Second Life Blogs">
<menu_item_call.on_click
function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+ parameter="https://community.secondlife.com/news/"/>
</menu_item_call>
<menu_item_separator/>
<menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 977b225960..607c7698c3 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1796,18 +1796,11 @@ function="World.EnvPreset"
</menu_item_call>
<menu_item_separator/>
<menu_item_call
- label="[SECOND_LIFE] News"
- name="Second Life News">
- <menu_item_call.on_click
- function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>
- </menu_item_call>
- <menu_item_call
label="[SECOND_LIFE] Blogs"
name="Second Life Blogs">
<menu_item_call.on_click
function="Advanced.ShowURL"
- parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+ parameter="https://community.secondlife.com/news/"/>
</menu_item_call>
<menu_item_separator/>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 28c2d2af6e..258c49785e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -202,7 +202,7 @@
follows="left|top"
height="14"
control_name="UpdaterWillingToTest"
- label="Willing to update to release candidates"
+ label="Willing to update to Beta"
left_delta="0"
mouse_opaque="true"
name="update_willing_to_test"
diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml
index 0742cef7c7..6b19907372 100644
--- a/indra/newview/skins/default/xui/en/panel_progress.xml
+++ b/indra/newview/skins/default/xui/en/panel_progress.xml
@@ -33,7 +33,7 @@
layout="topleft"
left="0"
orientation="vertical"
- name="vertical_centering"
+ name="vertical_centering1"
top="0"
width="670">
<layout_panel
@@ -44,40 +44,32 @@
width="670" />
<layout_panel
auto_resize="false"
- height="275"
+ height="220"
layout="topleft"
- min_height="275"
+ min_height="220"
name="panel4"
width="670">
<icon
color="LoginProgressBoxCenterColor"
follows="left|right|bottom|top"
- height="275"
image_name="Rounded_Square"
layout="topleft"
left="0"
top="0"
+ height="220"
width="670" />
<layout_stack
follows="left|right|top|bottom"
- height="275"
+ height="220"
layout="topleft"
left="0"
orientation="vertical"
- name="vertical_centering"
+ name="vertical_centering2"
animate="false"
top="0"
width="670">
<layout_panel
auto_resize="false"
- height="30"
- layout="topleft"
- min_height="30"
- name="panel_top_spacer"
- width="670">
- </layout_panel>
- <layout_panel
- auto_resize="false"
height="100"
layout="topleft"
min_height="100"
@@ -121,9 +113,9 @@
</layout_panel>
<layout_panel
auto_resize="false"
- height="110"
+ height="90"
layout="topleft"
- min_height="110"
+ min_height="90"
name="panel_motd"
width="670">
<text
@@ -132,7 +124,7 @@
font_shadow="none"
halign="left"
valign="center"
- height="100"
+ height="80"
layout="topleft"
left="45"
line_spacing.pixels="2"
@@ -142,30 +134,6 @@
right="-90"
word_wrap="true"/>
</layout_panel>
- <layout_panel
- auto_resize="false"
- height="40"
- layout="topleft"
- min_height="40"
- name="panel_icons"
- width="670">
- <!--Logos are tied to following label from code-->
- <text
- follows="left|right|top"
- layout="topleft"
- font="SansSerifLarge"
- font_shadow="none"
- halign="left"
- height="16"
- width="240"
- left="47"
- top="6"
- line_spacing.pixels="2"
- name="logos_lbl"
- text_color="LoginProgressBoxTextColor">
- Megapahit uses
- </text>
- </layout_panel>
</layout_stack>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/es/panel_progress.xml b/indra/newview/skins/default/xui/es/panel_progress.xml
index 64aaf246f8..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/es/panel_progress.xml
+++ b/indra/newview/skins/default/xui/es/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Usos de Second Life</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_progress.xml b/indra/newview/skins/default/xui/fr/panel_progress.xml
index 673ec63642..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/fr/panel_progress.xml
+++ b/indra/newview/skins/default/xui/fr/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Second Life utilise</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/it/panel_progress.xml b/indra/newview/skins/default/xui/it/panel_progress.xml
index fd2892a88f..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/it/panel_progress.xml
+++ b/indra/newview/skins/default/xui/it/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Utilizzi di Second Life</text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
index f487bc32a9..959f827a61 100644
--- a/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/ja/panel_preferences_setup.xml
@@ -30,7 +30,7 @@
<combo_box.item label="オプションのアップデートのインストール準備ができたら通知する" name="Install_ask"/>
<combo_box.item label="必須アップデートのみインストールする" name="Install_manual"/>
</combo_box>
- <check_box label="release candidate にアップグレードします" name="update_willing_to_test"/>
+ <check_box label="Beta にアップグレードします" name="update_willing_to_test"/>
<check_box label="更新後にリリースノートを表示する" name="update_show_release_notes"/>
<text name="Proxy Settings:">
プロキシ設定:
diff --git a/indra/newview/skins/default/xui/ja/panel_progress.xml b/indra/newview/skins/default/xui/ja/panel_progress.xml
index 7fd7d5ab5c..1edada6098 100644
--- a/indra/newview/skins/default/xui/ja/panel_progress.xml
+++ b/indra/newview/skins/default/xui/ja/panel_progress.xml
@@ -1,12 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">
- セカンドライフ使用
- </text>
</layout_stack>
</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_progress.xml b/indra/newview/skins/default/xui/pl/panel_progress.xml
index 22b6a8fcf5..8da982cc3f 100644
--- a/indra/newview/skins/default/xui/pl/panel_progress.xml
+++ b/indra/newview/skins/default/xui/pl/panel_progress.xml
@@ -2,14 +2,9 @@
<panel name="login_progress_panel">
<layout_stack name="horizontal_centering">
<layout_panel name="center">
- <layout_stack name="vertical_centering">
+ <layout_stack name="vertical_centering1">
<layout_panel name="panel4">
- <layout_stack name="vertical_centering">
- <layout_panel name="panel_icons">
- <text name="logos_lbl">
- Second Life używa
- </text>
- </layout_panel>
+ <layout_stack name="vertical_centering2">
</layout_stack>
</layout_panel>
</layout_stack>
diff --git a/indra/newview/skins/default/xui/pt/panel_progress.xml b/indra/newview/skins/default/xui/pt/panel_progress.xml
index 63bb663cfc..c9bed9fd9b 100644
--- a/indra/newview/skins/default/xui/pt/panel_progress.xml
+++ b/indra/newview/skins/default/xui/pt/panel_progress.xml
@@ -1,10 +1,8 @@
<?xml version="1.0" ?>
<panel name="login_progress_panel">
- <layout_panel name="panel_icons"/>
<layout_stack name="vertical_centering"/>
<layout_panel name="panel4"/>
<layout_panel name="center"/>
<layout_stack name="horizontal_centering">
- <text name="logos_lbl">Usos do Second Life</text>
</layout_stack>
</panel>
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index feebecf4cb..425df0e0f9 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -128,7 +128,7 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)
// Launch a coroutine with our login_() method. Run the coroutine until
// its first wait; at that point, return here.
std::string coroname =
- LLCoros::instance().launch("LLLogin::Impl::login_", [=]() { loginCoro(uri, login_params); });
+ LLCoros::instance().launch("LLLogin::Impl::login_", [=, this]() { loginCoro(uri, login_params); });
LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL;
}