summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/cmake/FMODSTUDIO.cmake2
-rw-r--r--indra/cmake/LLAddBuildTest.cmake14
-rw-r--r--indra/cmake/Variables.cmake18
-rw-r--r--indra/llcommon/llcallstack.h12
-rw-r--r--indra/llcommon/llerror.cpp14
-rw-r--r--indra/llcommon/llerror.h24
-rw-r--r--indra/llcommon/llmutex.h5
-rw-r--r--indra/llcommon/llsdutil.h69
-rw-r--r--indra/llcommon/tests/lleventdispatcher_test.cpp182
-rw-r--r--indra/llcommon/tests/llsdserialize_test.cpp8
-rw-r--r--indra/llcommon/workqueue.h68
-rw-r--r--indra/llimage/llimageworker.cpp23
-rw-r--r--indra/llinventory/llsettingsdaycycle.cpp4
-rw-r--r--indra/llinventory/llsettingssky.cpp121
-rw-r--r--indra/llinventory/llsettingswater.cpp36
-rw-r--r--indra/llmath/llvolume.cpp5
-rw-r--r--indra/llprimitive/llgltfmaterial.h1
-rw-r--r--indra/llrender/llglslshader.cpp72
-rw-r--r--indra/llrender/llglslshader.h16
-rw-r--r--indra/llwindow/llwindowwin32.cpp136
-rw-r--r--indra/newview/groupchatlistener.cpp10
-rw-r--r--indra/newview/llappviewer.cpp15
-rw-r--r--indra/newview/llappviewerwin32.cpp36
-rw-r--r--indra/newview/lldrawable.cpp6
-rw-r--r--indra/newview/lldrawpool.cpp70
-rw-r--r--indra/newview/lldrawpoolalpha.cpp44
-rw-r--r--indra/newview/lldrawpoolavatar.cpp5
-rw-r--r--indra/newview/lldrawpoolbump.cpp36
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp14
-rw-r--r--indra/newview/llfloatereditsky.cpp2
-rw-r--r--indra/newview/llfloatereditwater.cpp2
-rw-r--r--indra/newview/llfloaterperformance.cpp248
-rw-r--r--indra/newview/llfloaterperformance.h4
-rw-r--r--indra/newview/llgltfmateriallist.cpp133
-rw-r--r--indra/newview/llgltfmateriallist.h7
-rw-r--r--indra/newview/llmeshrepository.cpp142
-rw-r--r--indra/newview/llmeshrepository.h71
-rw-r--r--indra/newview/llperfstats.cpp13
-rw-r--r--indra/newview/llperfstats.h73
-rw-r--r--indra/newview/llselectmgr.cpp36
-rw-r--r--indra/newview/llselectmgr.h3
-rw-r--r--indra/newview/llsettingsvo.cpp32
-rw-r--r--indra/newview/llspatialpartition.cpp115
-rw-r--r--indra/newview/lltooldraganddrop.cpp5
-rw-r--r--indra/newview/llviewerjointmesh.cpp10
-rw-r--r--indra/newview/llviewerobject.cpp10
-rw-r--r--indra/newview/llviewerobject.h7
-rw-r--r--indra/newview/llviewerstats.cpp11
-rw-r--r--indra/newview/llvoavatar.cpp343
-rw-r--r--indra/newview/llvoavatar.h33
-rw-r--r--indra/newview/llvoavatarself.cpp1
-rw-r--r--indra/newview/llvovolume.cpp331
-rw-r--r--indra/newview/llvovolume.h26
-rw-r--r--indra/newview/llworld.cpp8
-rw-r--r--indra/newview/llworld.h4
-rw-r--r--indra/newview/pipeline.cpp148
-rw-r--r--indra/newview/pipeline.h13
-rw-r--r--indra/newview/skins/default/xui/en/panel_performance_preferences.xml79
-rw-r--r--indra/test/llsdutil_tut.cpp16
59 files changed, 1390 insertions, 1602 deletions
diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake
index c5b21ac4e5..9a1cdff6cb 100644
--- a/indra/cmake/FMODSTUDIO.cmake
+++ b/indra/cmake/FMODSTUDIO.cmake
@@ -2,7 +2,7 @@
include_guard()
-# FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON
+# FMODSTUDIO can be set when launching the make using the argument -DUSE_FMODSTUDIO:BOOL=ON
# When building using proprietary binaries though (i.e. having access to LL private servers),
# we always build with FMODSTUDIO.
if (INSTALL_PROPRIETARY)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index bf569e5d99..2172b56da2 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -126,6 +126,13 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
endif()
+ if (DARWIN)
+ # test binaries always need to be signed for local development
+ set_target_properties(PROJECT_${project}_TEST_${name}
+ PROPERTIES
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
+ endif ()
+
#
# Setup test targets
#
@@ -221,6 +228,13 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
)
endif ()
+ if (DARWIN)
+ # test binaries always need to be signed for local development
+ set_target_properties(INTEGRATION_TEST_${testname}
+ PROPERTIES
+ XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
+ endif ()
+
# Add link deps to the executable
if(TEST_DEBUG)
message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 79de3a9055..469fb3d330 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -173,13 +173,17 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "${CMAKE_MATCH_1}")
message(STATUS "CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL = '${CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL}'")
- string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}")
- list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx)
- if ("${sysroot_idx}" LESS 0)
- message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'")
- endif ()
- math(EXPR sysroot_idx "${sysroot_idx} + 1")
- list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT)
+ # allow disabling this check by setting LL_SKIP_REQUIRE_SYSROOT either ON as cmake cache var or non-empty as environment var
+ set(LL_SKIP_REQUIRE_SYSROOT OFF CACHE BOOL "Skip requirement to set toolchain sysroot ahead of time. Not skipped by default for consistency, but skipping can be useful for selecting alternative xcode versions side by side")
+ if("$ENV{LL_SKIP_REQUIRE_SYSROOT}" STREQUAL "" AND NOT ${LL_SKIP_REQUIRE_SYSROOT})
+ string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}")
+ list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx)
+ if ("${sysroot_idx}" LESS 0)
+ message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'")
+ endif ()
+ math(EXPR sysroot_idx "${sysroot_idx} + 1")
+ list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT)
+ endif()
message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'")
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
diff --git a/indra/llcommon/llcallstack.h b/indra/llcommon/llcallstack.h
index 5acf04a49f..d5a2b7b157 100644
--- a/indra/llcommon/llcallstack.h
+++ b/indra/llcommon/llcallstack.h
@@ -79,9 +79,9 @@ struct LLContextStatus
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLContextStatus& context_status);
-#define dumpStack(tag) \
- if (debugLoggingEnabled(tag)) \
- { \
- LLCallStack cs; \
- LL_DEBUGS(tag) << "STACK:\n" << "====================\n" << cs << "====================" << LL_ENDL; \
- }
+#define dumpStack(tag) \
+ LL_DEBUGS(tag) << "STACK:\n" \
+ << "====================\n" \
+ << LLCallStack() \
+ << "====================" \
+ << LL_ENDL;
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 56fb7c21ca..5aa8558878 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -1609,19 +1609,5 @@ namespace LLError
}
}
-bool debugLoggingEnabled(const std::string& tag)
-{
- LLMutexTrylock lock(getMutex<LOG_MUTEX>(), 5);
- if (!lock.isLocked())
- {
- return false;
- }
-
- SettingsConfigPtr s = Globals::getInstance()->getSettingsConfig();
- LLError::ELevel level = LLError::LEVEL_DEBUG;
- bool res = checkLevelMap(s->mTagLevelMap, tag, level);
- return res;
-}
-
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index b7dec3cb7f..08eb323c4a 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -467,7 +467,29 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
LLError::CallSite& _site(_sites[which]); \
lllog_test_()
-// Check at run-time whether logging is enabled, without generating output
+/*
+// Check at run-time whether logging is enabled, without generating output.
+Resist the temptation to add a function like this because it incurs the
+expense of locking and map-searching every time control reaches it.
bool debugLoggingEnabled(const std::string& tag);
+Instead of:
+
+if debugLoggingEnabled("SomeTag")
+{
+ // ... presumably expensive operation ...
+ LL_DEBUGS("SomeTag") << ... << LL_ENDL;
+}
+
+Use this:
+
+LL_DEBUGS("SomeTag");
+// ... presumably expensive operation ...
+LL_CONT << ...;
+LL_ENDL;
+
+LL_DEBUGS("SomeTag") performs the locking and map-searching ONCE, then caches
+the result in a static variable.
+*/
+
#endif // LL_LLERROR_H
diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h
index 838d7d34c0..0d70da6178 100644
--- a/indra/llcommon/llmutex.h
+++ b/indra/llcommon/llmutex.h
@@ -36,7 +36,8 @@
//============================================================================
-#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
+//#define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO)
+#define MUTEX_DEBUG 0 //disable mutex debugging as it's interfering with profiles
#if MUTEX_DEBUG
#include <map>
@@ -61,7 +62,7 @@ protected:
mutable LLThread::id_t mLockingThread;
#if MUTEX_DEBUG
- std::map<LLThread::id_t, BOOL> mIsLocked;
+ std::unordered_map<LLThread::id_t, BOOL> mIsLocked;
#endif
};
diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h
index 1321615805..372278c51a 100644
--- a/indra/llcommon/llsdutil.h
+++ b/indra/llcommon/llsdutil.h
@@ -191,75 +191,6 @@ LLSD& drill_ref( LLSD& blob, const LLSD& path);
}
-/*****************************************************************************
-* LLSDArray
-*****************************************************************************/
-/**
- * Construct an LLSD::Array inline, with implicit conversion to LLSD. Usage:
- *
- * @code
- * void somefunc(const LLSD&);
- * ...
- * somefunc(LLSDArray("text")(17)(3.14));
- * @endcode
- *
- * For completeness, LLSDArray() with no args constructs an empty array, so
- * <tt>LLSDArray()("text")(17)(3.14)</tt> produces an array equivalent to the
- * above. But for most purposes, LLSD() is already equivalent to an empty
- * array, and if you explicitly want an empty isArray(), there's
- * LLSD::emptyArray(). However, supporting a no-args LLSDArray() constructor
- * follows the principle of least astonishment.
- */
-class LLSDArray
-{
-public:
- LLSDArray():
- _data(LLSD::emptyArray())
- {}
-
- /**
- * Need an explicit copy constructor. Consider the following:
- *
- * @code
- * LLSD array_of_arrays(LLSDArray(LLSDArray(17)(34))
- * (LLSDArray("x")("y")));
- * @endcode
- *
- * The coder intends to construct [[17, 34], ["x", "y"]].
- *
- * With the compiler's implicit copy constructor, s/he gets instead
- * [17, 34, ["x", "y"]].
- *
- * The expression LLSDArray(17)(34) constructs an LLSDArray with those two
- * values. The reader assumes it should be converted to LLSD, as we always
- * want with LLSDArray, before passing it to the @em outer LLSDArray
- * constructor! This copy constructor makes that happen.
- */
- LLSDArray(const LLSDArray& inner):
- _data(LLSD::emptyArray())
- {
- _data.append(inner);
- }
-
- LLSDArray(const LLSD& value):
- _data(LLSD::emptyArray())
- {
- _data.append(value);
- }
-
- LLSDArray& operator()(const LLSD& value)
- {
- _data.append(value);
- return *this;
- }
-
- operator LLSD() const { return _data; }
- LLSD get() const { return _data; }
-
-private:
- LLSD _data;
-};
-
namespace llsd
{
diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp
index 9da1ecfd67..991ec4819f 100644
--- a/indra/llcommon/tests/lleventdispatcher_test.cpp
+++ b/indra/llcommon/tests/lleventdispatcher_test.cpp
@@ -345,7 +345,7 @@ namespace tut
lleventdispatcher_data():
work("test dispatcher", "op"),
// map {d=double, array=[3 elements]}
- required(LLSDMap("d", LLSD::Real(0))("array", LLSDArray(LLSD())(LLSD())(LLSD()))),
+ required(LLSDMap("d", LLSD::Real(0))("array", llsd::array(LLSD(), LLSD(), LLSD()))),
// first several params are required, last couple optional
partial_offset(3)
{
@@ -434,8 +434,8 @@ namespace tut
// freena(), methodna(), cmethodna(), smethodna() all take same param list.
// Same for freenb() et al.
- params = LLSDMap("a", LLSDArray("b")("i")("f")("d")("cp"))
- ("b", LLSDArray("s")("uuid")("date")("uri")("bin"));
+ params = LLSDMap("a", llsd::array("b", "i", "f", "d", "cp"))
+ ("b", llsd::array("s", "uuid", "date", "uri", "bin"));
debug("params:\n",
params, "\n"
"params[\"a\"]:\n",
@@ -452,12 +452,12 @@ namespace tut
// LLDate values are, as long as they're different from the
// LLUUID() and LLDate() default values so inspect() will report
// them.
- dft_array_full = LLSDMap("a", LLSDArray(true)(17)(3.14)(123456.78)("classic"))
- ("b", LLSDArray("string")
- (LLUUID::generateNewID())
- (LLDate::now())
- (LLURI("http://www.ietf.org/rfc/rfc3986.txt"))
- (binary));
+ dft_array_full = LLSDMap("a", llsd::array(true, 17, 3.14, 123456.78, "classic"))
+ ("b", llsd::array("string",
+ LLUUID::generateNewID(),
+ LLDate::now(),
+ LLURI("http://www.ietf.org/rfc/rfc3986.txt"),
+ binary));
debug("dft_array_full:\n",
dft_array_full);
// Partial defaults arrays.
@@ -723,7 +723,7 @@ namespace tut
{
set_test_name("map-style registration with non-array params");
// Pass "param names" as scalar or as map
- LLSD attempts(LLSDArray(17)(LLSDMap("pi", 3.14)("two", 2)));
+ LLSD attempts(llsd::array(17, LLSDMap("pi", 3.14)("two", 2)));
foreach(LLSD ae, inArray(attempts))
{
std::string threw = catch_what<std::exception>([this, &ae](){
@@ -738,7 +738,7 @@ namespace tut
{
set_test_name("map-style registration with badly-formed defaults");
std::string threw = catch_what<std::exception>([this](){
- work.add("freena_err", "freena", freena, LLSDArray("a")("b"), 17);
+ work.add("freena_err", "freena", freena, llsd::array("a", "b"), 17);
});
ensure_has(threw, "must be a map or an array");
}
@@ -749,8 +749,8 @@ namespace tut
set_test_name("map-style registration with too many array defaults");
std::string threw = catch_what<std::exception>([this](){
work.add("freena_err", "freena", freena,
- LLSDArray("a")("b"),
- LLSDArray(17)(0.9)("gack"));
+ llsd::array("a", "b"),
+ llsd::array(17, 0.9, "gack"));
});
ensure_has(threw, "shorter than");
}
@@ -761,7 +761,7 @@ namespace tut
set_test_name("map-style registration with too many map defaults");
std::string threw = catch_what<std::exception>([this](){
work.add("freena_err", "freena", freena,
- LLSDArray("a")("b"),
+ llsd::array("a", "b"),
LLSDMap("b", 17)("foo", 3.14)("bar", "sinister"));
});
ensure_has(threw, "nonexistent params");
@@ -798,7 +798,7 @@ namespace tut
void object::test<8>()
{
set_test_name("query Callables with/out required params");
- LLSD names(LLSDArray("free1")("Dmethod1")("Dcmethod1")("method1"));
+ LLSD names(llsd::array("free1", "Dmethod1", "Dcmethod1", "method1"));
foreach(LLSD nm, inArray(names))
{
LLSD metadata(getMetadata(nm));
@@ -821,13 +821,13 @@ namespace tut
{
set_test_name("query array-style functions/methods");
// Associate each registered name with expected arity.
- LLSD expected(LLSDArray
- (LLSDArray
- (0)(LLSDArray("free0_array")("smethod0_array")("method0_array")))
- (LLSDArray
- (5)(LLSDArray("freena_array")("smethodna_array")("methodna_array")))
- (LLSDArray
- (5)(LLSDArray("freenb_array")("smethodnb_array")("methodnb_array"))));
+ LLSD expected(llsd::array
+ (llsd::array
+ (0, llsd::array("free0_array", "smethod0_array", "method0_array")),
+ llsd::array
+ (5, llsd::array("freena_array", "smethodna_array", "methodna_array")),
+ llsd::array
+ (5, llsd::array("freenb_array", "smethodnb_array", "methodnb_array"))));
foreach(LLSD ae, inArray(expected))
{
LLSD::Integer arity(ae[0].asInteger());
@@ -853,7 +853,7 @@ namespace tut
set_test_name("query map-style no-params functions/methods");
// - (Free function | non-static method), map style, no params (ergo
// no defaults)
- LLSD names(LLSDArray("free0_map")("smethod0_map")("method0_map"));
+ LLSD names(llsd::array("free0_map", "smethod0_map", "method0_map"));
foreach(LLSD nm, inArray(names))
{
LLSD metadata(getMetadata(nm));
@@ -877,13 +877,13 @@ namespace tut
// there should (!) be no difference beween array defaults and map
// defaults. Verify, so we can ignore the distinction for all other
// tests.
- LLSD equivalences(LLSDArray
- (LLSDArray("freena_map_adft")("freena_map_mdft"))
- (LLSDArray("freenb_map_adft")("freenb_map_mdft"))
- (LLSDArray("smethodna_map_adft")("smethodna_map_mdft"))
- (LLSDArray("smethodnb_map_adft")("smethodnb_map_mdft"))
- (LLSDArray("methodna_map_adft")("methodna_map_mdft"))
- (LLSDArray("methodnb_map_adft")("methodnb_map_mdft")));
+ LLSD equivalences(llsd::array
+ (llsd::array("freena_map_adft", "freena_map_mdft"),
+ llsd::array("freenb_map_adft", "freenb_map_mdft"),
+ llsd::array("smethodna_map_adft", "smethodna_map_mdft"),
+ llsd::array("smethodnb_map_adft", "smethodnb_map_mdft"),
+ llsd::array("methodna_map_adft", "methodna_map_mdft"),
+ llsd::array("methodnb_map_adft", "methodnb_map_mdft")));
foreach(LLSD eq, inArray(equivalences))
{
LLSD adft(eq[0]);
@@ -953,42 +953,42 @@ namespace tut
debug("skipreq:\n",
skipreq);
- LLSD groups(LLSDArray // array of groups
+ LLSD groups(llsd::array // array of groups
- (LLSDArray // group
- (LLSDArray("freena_map_allreq")("smethodna_map_allreq")("methodna_map_allreq"))
- (LLSDArray(allreq["a"])(LLSD()))) // required, optional
+ (llsd::array // group
+ (llsd::array("freena_map_allreq", "smethodna_map_allreq", "methodna_map_allreq"),
+ llsd::array(allreq["a"], LLSD())), // required, optional
- (LLSDArray // group
- (LLSDArray("freenb_map_allreq")("smethodnb_map_allreq")("methodnb_map_allreq"))
- (LLSDArray(allreq["b"])(LLSD()))) // required, optional
+ llsd::array // group
+ (llsd::array("freenb_map_allreq", "smethodnb_map_allreq", "methodnb_map_allreq"),
+ llsd::array(allreq["b"], LLSD())), // required, optional
- (LLSDArray // group
- (LLSDArray("freena_map_leftreq")("smethodna_map_leftreq")("methodna_map_leftreq"))
- (LLSDArray(leftreq["a"])(rightdft["a"]))) // required, optional
+ llsd::array // group
+ (llsd::array("freena_map_leftreq", "smethodna_map_leftreq", "methodna_map_leftreq"),
+ llsd::array(leftreq["a"], rightdft["a"])), // required, optional
- (LLSDArray // group
- (LLSDArray("freenb_map_leftreq")("smethodnb_map_leftreq")("methodnb_map_leftreq"))
- (LLSDArray(leftreq["b"])(rightdft["b"]))) // required, optional
+ llsd::array // group
+ (llsd::array("freenb_map_leftreq", "smethodnb_map_leftreq", "methodnb_map_leftreq"),
+ llsd::array(leftreq["b"], rightdft["b"])), // required, optional
- (LLSDArray // group
- (LLSDArray("freena_map_skipreq")("smethodna_map_skipreq")("methodna_map_skipreq"))
- (LLSDArray(skipreq["a"])(dft_map_partial["a"]))) // required, optional
+ llsd::array // group
+ (llsd::array("freena_map_skipreq", "smethodna_map_skipreq", "methodna_map_skipreq"),
+ llsd::array(skipreq["a"], dft_map_partial["a"])), // required, optional
- (LLSDArray // group
- (LLSDArray("freenb_map_skipreq")("smethodnb_map_skipreq")("methodnb_map_skipreq"))
- (LLSDArray(skipreq["b"])(dft_map_partial["b"]))) // required, optional
+ llsd::array // group
+ (llsd::array("freenb_map_skipreq", "smethodnb_map_skipreq", "methodnb_map_skipreq"),
+ llsd::array(skipreq["b"], dft_map_partial["b"])), // required, optional
- // We only need mention the full-map-defaults ("_mdft" suffix)
- // registrations, having established their equivalence with the
- // full-array-defaults ("_adft" suffix) registrations in another test.
- (LLSDArray // group
- (LLSDArray("freena_map_mdft")("smethodna_map_mdft")("methodna_map_mdft"))
- (LLSDArray(LLSD::emptyMap())(dft_map_full["a"]))) // required, optional
+ // We only need mention the full-map-defaults ("_mdft" suffix)
+ // registrations, having established their equivalence with the
+ // full-array-defaults ("_adft" suffix) registrations in another test.
+ llsd::array // group
+ (llsd::array("freena_map_mdft", "smethodna_map_mdft", "methodna_map_mdft"),
+ llsd::array(LLSD::emptyMap(), dft_map_full["a"])), // required, optional
- (LLSDArray // group
- (LLSDArray("freenb_map_mdft")("smethodnb_map_mdft")("methodnb_map_mdft"))
- (LLSDArray(LLSD::emptyMap())(dft_map_full["b"])))); // required, optional
+ llsd::array // group
+ (llsd::array("freenb_map_mdft", "smethodnb_map_mdft", "methodnb_map_mdft"),
+ llsd::array(LLSD::emptyMap(), dft_map_full["b"])))); // required, optional
foreach(LLSD grp, inArray(groups))
{
@@ -1077,7 +1077,7 @@ namespace tut
// with 'required'.
LLSD answer(42);
// LLSD value matching 'required' according to llsd_matches() rules.
- LLSD matching(LLSDMap("d", 3.14)("array", LLSDArray("answer")(true)(answer)));
+ LLSD matching(LLSDMap("d", 3.14)("array", llsd::array("answer", true, answer)));
// Okay, walk through 'tests'.
foreach(const CallablesTriple& tr, tests)
{
@@ -1114,17 +1114,17 @@ namespace tut
call_exc("free0_map", 17, map_exc);
// Passing an array to a map-style function works now! No longer an
// error case!
-// call_exc("free0_map", LLSDArray("a")("b"), map_exc);
+// call_exc("free0_map", llsd::array("a", "b"), map_exc);
}
template<> template<>
void object::test<18>()
{
set_test_name("call no-args functions");
- LLSD names(LLSDArray
- ("free0_array")("free0_map")
- ("smethod0_array")("smethod0_map")
- ("method0_array")("method0_map"));
+ LLSD names(llsd::array
+ ("free0_array", "free0_map",
+ "smethod0_array", "smethod0_map",
+ "method0_array", "method0_map"));
foreach(LLSD name, inArray(names))
{
// Look up the Vars instance for this function.
@@ -1142,10 +1142,10 @@ namespace tut
}
// Break out this data because we use it in a couple different tests.
- LLSD array_funcs(LLSDArray
- (LLSDMap("a", "freena_array") ("b", "freenb_array"))
- (LLSDMap("a", "smethodna_array")("b", "smethodnb_array"))
- (LLSDMap("a", "methodna_array") ("b", "methodnb_array")));
+ LLSD array_funcs(llsd::array
+ (LLSDMap("a", "freena_array") ("b", "freenb_array"),
+ LLSDMap("a", "smethodna_array")("b", "smethodnb_array"),
+ LLSDMap("a", "methodna_array") ("b", "methodnb_array")));
template<> template<>
void object::test<19>()
@@ -1153,7 +1153,7 @@ namespace tut
set_test_name("call array-style functions with too-short arrays");
// Could have two different too-short arrays, one for *na and one for
// *nb, but since they both take 5 params...
- LLSD tooshort(LLSDArray("this")("array")("too")("short"));
+ LLSD tooshort(llsd::array("this", "array", "too", "short"));
foreach(const LLSD& funcsab, inArray(array_funcs))
{
foreach(const llsd::MapEntry& e, inMap(funcsab))
@@ -1172,12 +1172,12 @@ namespace tut
{
binary.push_back((U8)h);
}
- LLSD args(LLSDMap("a", LLSDArray(true)(17)(3.14)(123.456)("char*"))
- ("b", LLSDArray("string")
- (LLUUID("01234567-89ab-cdef-0123-456789abcdef"))
- (LLDate("2011-02-03T15:07:00Z"))
- (LLURI("http://secondlife.com"))
- (binary)));
+ LLSD args(LLSDMap("a", llsd::array(true, 17, 3.14, 123.456, "char*"))
+ ("b", llsd::array("string",
+ LLUUID("01234567-89ab-cdef-0123-456789abcdef"),
+ LLDate("2011-02-03T15:07:00Z"),
+ LLURI("http://secondlife.com"),
+ binary)));
LLSD argsplus(args);
argsplus["a"].append("bogus");
argsplus["b"].append("bogus");
@@ -1191,7 +1191,7 @@ namespace tut
debug("expect: ", expect);
// Use substantially the same logic for args and argsplus
- LLSD argsarrays(LLSDArray(args)(argsplus));
+ LLSD argsarrays(llsd::array(args, argsplus));
// So i==0 selects 'args', i==1 selects argsplus
for (LLSD::Integer i(0), iend(argsarrays.size()); i < iend; ++i)
{
@@ -1236,8 +1236,8 @@ namespace tut
set_test_name("call map-style functions with (full | oversized) (arrays | maps)");
const char binary[] = "\x99\x88\x77\x66\x55";
LLSD array_full(LLSDMap
- ("a", LLSDArray(false)(255)(98.6)(1024.5)("pointer"))
- ("b", LLSDArray("object")(LLUUID::generateNewID())(LLDate::now())(LLURI("http://wiki.lindenlab.com/wiki"))(LLSD::Binary(boost::begin(binary), boost::end(binary)))));
+ ("a", llsd::array(false, 255, 98.6, 1024.5, "pointer"))
+ ("b", llsd::array("object", LLUUID::generateNewID(), LLDate::now(), LLURI("http://wiki.lindenlab.com/wiki"), LLSD::Binary(boost::begin(binary), boost::end(binary)))));
LLSD array_overfull(array_full);
foreach(LLSD::String a, ab)
{
@@ -1280,20 +1280,20 @@ namespace tut
// parameter defaults should make NO DIFFERENCE WHATSOEVER. Every call
// should pass all params.
LLSD names(LLSDMap
- ("a", LLSDArray
- ("freena_map_allreq") ("smethodna_map_allreq") ("methodna_map_allreq")
- ("freena_map_leftreq")("smethodna_map_leftreq")("methodna_map_leftreq")
- ("freena_map_skipreq")("smethodna_map_skipreq")("methodna_map_skipreq")
- ("freena_map_adft") ("smethodna_map_adft") ("methodna_map_adft")
- ("freena_map_mdft") ("smethodna_map_mdft") ("methodna_map_mdft"))
- ("b", LLSDArray
- ("freenb_map_allreq") ("smethodnb_map_allreq") ("methodnb_map_allreq")
- ("freenb_map_leftreq")("smethodnb_map_leftreq")("methodnb_map_leftreq")
- ("freenb_map_skipreq")("smethodnb_map_skipreq")("methodnb_map_skipreq")
- ("freenb_map_adft") ("smethodnb_map_adft") ("methodnb_map_adft")
- ("freenb_map_mdft") ("smethodnb_map_mdft") ("methodnb_map_mdft")));
+ ("a", llsd::array
+ ("freena_map_allreq", "smethodna_map_allreq", "methodna_map_allreq",
+ "freena_map_leftreq", "smethodna_map_leftreq", "methodna_map_leftreq",
+ "freena_map_skipreq", "smethodna_map_skipreq", "methodna_map_skipreq",
+ "freena_map_adft", "smethodna_map_adft", "methodna_map_adft",
+ "freena_map_mdft", "smethodna_map_mdft", "methodna_map_mdft"))
+ ("b", llsd::array
+ ("freenb_map_allreq", "smethodnb_map_allreq", "methodnb_map_allreq",
+ "freenb_map_leftreq", "smethodnb_map_leftreq", "methodnb_map_leftreq",
+ "freenb_map_skipreq", "smethodnb_map_skipreq", "methodnb_map_skipreq",
+ "freenb_map_adft", "smethodnb_map_adft", "methodnb_map_adft",
+ "freenb_map_mdft", "smethodnb_map_mdft", "methodnb_map_mdft")));
// Treat (full | overfull) (array | map) the same.
- LLSD argssets(LLSDArray(array_full)(array_overfull)(map_full)(map_overfull));
+ LLSD argssets(llsd::array(array_full, array_overfull, map_full, map_overfull));
foreach(const LLSD& args, inArray(argssets))
{
foreach(LLSD::String a, ab)
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index c246f5ee56..5dbcf4c9b8 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -1817,10 +1817,10 @@ namespace tut
{
set_test_name("verify sequence to Python");
- LLSD cdata(LLSDArray(17)(3.14)
- ("This string\n"
- "has several\n"
- "lines."));
+ LLSD cdata(llsd::array(17, 3.14,
+ "This string\n"
+ "has several\n"
+ "lines."));
const char pydata[] =
"def verify(iterable):\n"
diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h
index 5461ce6c23..5b704e7198 100644
--- a/indra/llcommon/workqueue.h
+++ b/indra/llcommon/workqueue.h
@@ -516,37 +516,45 @@ namespace LL
// Here we believe target WorkQueue still exists. Post to it a
// lambda that packages our callable, our callback and a weak_ptr
// to this originating WorkQueue.
- tptr->post(
- [reply = super::getWeak(),
- callable = std::move(callable),
- callback = std::move(callback)]
- () mutable
- {
- // Use postMaybe() below in case this originating WorkQueue
- // has been closed or destroyed. Remember, the outer lambda is
- // now running on a thread servicing the target WorkQueue, and
- // real time has elapsed since postTo()'s tptr->post() call.
- try
- {
- // Make a reply lambda to repost to THIS WorkQueue.
- // Delegate to makeReplyLambda() so we can partially
- // specialize on void return.
- postMaybe(reply, makeReplyLambda(std::move(callable), std::move(callback)));
- }
- catch (...)
+ try
+ {
+ tptr->post(
+ [reply = super::getWeak(),
+ callable = std::move(callable),
+ callback = std::move(callback)]
+ () mutable
{
- // Either variant of makeReplyLambda() is responsible for
- // calling the caller's callable. If that throws, return
- // the exception to the originating thread.
- postMaybe(
- reply,
- // Bind the current exception to transport back to the
- // originating WorkQueue. Once there, rethrow it.
- [exc = std::current_exception()](){ std::rethrow_exception(exc); });
- }
- },
- // if caller passed a TimePoint, pass it along to post()
- std::forward<ARGS>(args)...);
+ // Use postMaybe() below in case this originating WorkQueue
+ // has been closed or destroyed. Remember, the outer lambda is
+ // now running on a thread servicing the target WorkQueue, and
+ // real time has elapsed since postTo()'s tptr->post() call.
+ try
+ {
+ // Make a reply lambda to repost to THIS WorkQueue.
+ // Delegate to makeReplyLambda() so we can partially
+ // specialize on void return.
+ postMaybe(reply, makeReplyLambda(std::move(callable), std::move(callback)));
+ }
+ catch (...)
+ {
+ // Either variant of makeReplyLambda() is responsible for
+ // calling the caller's callable. If that throws, return
+ // the exception to the originating thread.
+ postMaybe(
+ reply,
+ // Bind the current exception to transport back to the
+ // originating WorkQueue. Once there, rethrow it.
+ [exc = std::current_exception()](){ std::rethrow_exception(exc); });
+ }
+ },
+ // if caller passed a TimePoint, pass it along to post()
+ std::forward<ARGS>(args)...);
+ }
+ catch (const Closed&)
+ {
+ // target WorkQueue still exists, but is Closed
+ return false;
+ }
// looks like we were able to post()
return true;
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 0093958e6d..9358a0ae2c 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -92,14 +92,21 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- // Instantiate the ImageRequest right in the lambda, why not?
- mThreadPool->getQueue().post(
- [req = ImageRequest(image, discard, needs_aux, responder)]
- () mutable
- {
- auto done = req.processRequest();
- req.finishRequest(done);
- });
+ try
+ {
+ // Instantiate the ImageRequest right in the lambda, why not?
+ mThreadPool->getQueue().post(
+ [req = ImageRequest(image, discard, needs_aux, responder)]
+ () mutable
+ {
+ auto done = req.processRequest();
+ req.finishRequest(done);
+ });
+ }
+ catch (const LLThreadSafeQueueInterrupt&)
+ {
+ LL_DEBUGS() << "Tried to start decoding on shutdown" << LL_ENDL;
+ }
// It's important to our consumer (LLTextureFetchWorker) that we return a
// nonzero handle. It is NOT important that the nonzero handle be unique:
diff --git a/indra/llinventory/llsettingsdaycycle.cpp b/indra/llinventory/llsettingsdaycycle.cpp
index 241826604f..42dd5e3d10 100644
--- a/indra/llinventory/llsettingsdaycycle.cpp
+++ b/indra/llinventory/llsettingsdaycycle.cpp
@@ -440,8 +440,8 @@ LLSD LLSettingsDay::defaults()
}
LLSD tracks;
- tracks.append(LLSDArray(waterTrack));
- tracks.append(LLSDArray(skyTrack));
+ tracks.append(llsd::array(waterTrack));
+ tracks.append(llsd::array(skyTrack));
dfltsetting[SETTING_TRACKS] = tracks;
dfltsetting[SETTING_FRAMES] = frames;
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 8e801db2dc..eb8385281c 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -154,24 +154,24 @@ LLSettingsSky::validation_list_t legacyHazeValidationList()
{
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_AMBIENT, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(3.0f, 3.0f, 3.0f, "*"))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_DENSITY, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(3.0f, 3.0f, 3.0f, "*"))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_BLUE_HORIZON, false, LLSD::TypeArray,
boost::bind(&LLSettingsBase::Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(3.0f, 3.0f, 3.0f, "*"))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_DENSITY, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(5.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_HAZE_HORIZON, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(5.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 5.0f))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_MULTIPLIER, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0001f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 2.0f))));
legacyHazeValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DISTANCE_MULTIPLIER, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0001f)(1000.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0001f, 1000.0f))));
}
return legacyHazeValidation;
}
@@ -182,19 +182,19 @@ LLSettingsSky::validation_list_t rayleighValidationList()
if (rayleighValidation.empty())
{
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
rayleighValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return rayleighValidation;
}
@@ -205,19 +205,19 @@ LLSettingsSky::validation_list_t absorptionValidationList()
if (absorptionValidation.empty())
{
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
absorptionValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return absorptionValidation;
}
@@ -228,22 +228,22 @@ LLSettingsSky::validation_list_t mieValidationList()
if (mieValidation.empty())
{
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_WIDTH, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(32768.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 32768.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-1.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(-1.0f, 1.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_LINEAR_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(2.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 2.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_DENSITY_PROFILE_CONSTANT_TERM, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
mieValidation.push_back(LLSettingsBase::Validator(LLSettingsSky::SETTING_MIE_ANISOTROPY_FACTOR, false, LLSD::TypeReal,
- boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&LLSettingsBase::Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
}
return mieValidation;
}
@@ -548,92 +548,89 @@ LLSettingsSky::validation_list_t LLSettingsSky::validationList()
static validation_list_t validation;
if (validation.empty())
- { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
- // copy constructor for LLSDArray. Directly binding the LLSDArray as
- // a parameter without first wrapping it in a pure LLSD object will result
- // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
+ {
validation.push_back(Validator(SETTING_BLOOM_TEXTUREID, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_RAINBOW_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_HALO_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_CLOUD_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(1.0f, 1.0f, 1.0f, "*"))));
validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY1, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(1.0f)(1.0f)(3.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(1.0f, 1.0f, 3.0f, "*"))));
validation.push_back(Validator(SETTING_CLOUD_POS_DENSITY2, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(1.0f)(1.0f)(1.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(1.0f, 1.0f, 1.0f, "*"))));
validation.push_back(Validator(SETTING_CLOUD_SCALE, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.001f)(3.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.001f, 3.0f))));
validation.push_back(Validator(SETTING_CLOUD_SCROLL_RATE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(-50.0f)(-50.0f)),
- LLSD(LLSDArray(50.0f)(50.0f)))));
+ llsd::array(-50.0f, -50.0f),
+ llsd::array(50.0f, 50.0f))));
validation.push_back(Validator(SETTING_CLOUD_SHADOW, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_CLOUD_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_CLOUD_VARIANCE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_DOME_OFFSET, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_DOME_RADIUS, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(2000.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 2000.0f))));
validation.push_back(Validator(SETTING_GAMMA, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(20.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f))));
validation.push_back(Validator(SETTING_GLOW, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.2f)("*")(-10.0f)("*")),
- LLSD(LLSDArray(40.0f)("*")(10.0f)("*")))));
+ llsd::array(0.2f, "*", -10.0f, "*"),
+ llsd::array(40.0f, "*", 10.0f, "*"))));
validation.push_back(Validator(SETTING_MAX_Y, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(10000.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 10000.0f))));
validation.push_back(Validator(SETTING_MOON_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
validation.push_back(Validator(SETTING_MOON_SCALE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_MOON_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_MOON_BRIGHTNESS, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_STAR_BRIGHTNESS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(500.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 500.0f))));
validation.push_back(Validator(SETTING_SUNLIGHT_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)("*")),
- LLSD(LLSDArray(3.0f)(3.0f)(3.0f)("*")))));
+ llsd::array(0.0f, 0.0f, 0.0f, "*"),
+ llsd::array(3.0f, 3.0f, 3.0f, "*"))));
validation.push_back(Validator(SETTING_SUN_ROTATION, true, LLSD::TypeArray, &Validator::verifyQuaternionNormal));
validation.push_back(Validator(SETTING_SUN_SCALE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.25f)(20.0f))), LLSD::Real(1.0)));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.25f, 20.0f)), LLSD::Real(1.0)));
validation.push_back(Validator(SETTING_SUN_TEXTUREID, false, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_PLANET_RADIUS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
validation.push_back(Validator(SETTING_SKY_BOTTOM_RADIUS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
validation.push_back(Validator(SETTING_SKY_TOP_RADIUS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(1000.0f)(32768.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(1000.0f, 32768.0f))));
validation.push_back(Validator(SETTING_SUN_ARC_RADIANS, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(0.1f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 0.1f))));
validation.push_back(Validator(SETTING_SKY_MOISTURE_LEVEL, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_SKY_DROPLET_RADIUS, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(5.0f)(1000.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(5.0f, 1000.0f))));
validation.push_back(Validator(SETTING_SKY_ICE_LEVEL, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_REFLECTION_PROBE_AMBIANCE, false, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(10.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(llsd::array(0.0f, 10.0f)))));
validation.push_back(Validator(SETTING_RAYLEIGH_CONFIG, true, LLSD::TypeArray, &validateRayleighLayers));
validation.push_back(Validator(SETTING_ABSORPTION_CONFIG, true, LLSD::TypeArray, &validateAbsorptionLayers));
@@ -724,7 +721,7 @@ LLSD LLSettingsSky::defaults(const LLSettingsBase::TrackPosition& position)
dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue();
dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 0.0).getValue();
dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199);
- dfltsetting[SETTING_CLOUD_SCROLL_RATE] = LLSDArray(0.0f)(0.0f);
+ dfltsetting[SETTING_CLOUD_SCROLL_RATE] = llsd::array(0.0f, 0.0f);
dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699);
dfltsetting[SETTING_CLOUD_VARIANCE] = LLSD::Real(0.0);
diff --git a/indra/llinventory/llsettingswater.cpp b/indra/llinventory/llsettingswater.cpp
index 90f99e8198..f19beb5be5 100644
--- a/indra/llinventory/llsettingswater.cpp
+++ b/indra/llinventory/llsettingswater.cpp
@@ -222,42 +222,38 @@ LLSettingsWater::validation_list_t LLSettingsWater::validationList()
static validation_list_t validation;
if (validation.empty())
- { // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
- // copy constructor for LLSDArray. Directly binding the LLSDArray as
- // a parameter without first wrapping it in a pure LLSD object will result
- // in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
-
+ {
validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-0.5f)(0.5f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(-0.5f, 0.5f))));
validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
- LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
+ llsd::array(0.0f, 0.0f, 0.0f, 1.0f),
+ llsd::array(1.0f, 1.0f, 1.0f, 1.0f))));
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(-10.0f)(10.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(-10.0f, 10.0f))));
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(20.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 20.0f))));
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(1.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 1.0f))));
validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
- LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
+ llsd::array(0.0f, 0.0f, 0.0f),
+ llsd::array(10.0f, 10.0f, 10.0f))));
validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(3.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 3.0f))));
validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
- boost::bind(&Validator::verifyFloatRange, _1, _2, LLSD(LLSDArray(0.0f)(3.0f)))));
+ boost::bind(&Validator::verifyFloatRange, _1, _2, llsd::array(0.0f, 3.0f))));
validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(-20.0f)(-20.0f)),
- LLSD(LLSDArray(20.0f)(20.0f)))));
+ llsd::array(-20.0f, -20.0f),
+ llsd::array(20.0f, 20.0f))));
validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1, _2,
- LLSD(LLSDArray(-20.0f)(-20.0f)),
- LLSD(LLSDArray(20.0f)(20.0f)))));
+ llsd::array(-20.0f, -20.0f),
+ llsd::array(20.0f, 20.0f))));
}
return validation;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 2a906c8d41..b6cdcb2736 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -3351,12 +3351,12 @@ BOOL LLVolume::isFlat(S32 face)
bool LLVolumeParams::isSculpt() const
{
- return mSculptID.notNull();
+ return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE;
}
bool LLVolumeParams::isMeshSculpt() const
{
- return isSculpt() && ((mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH);
+ return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;
}
bool LLVolumeParams::operator==(const LLVolumeParams &params) const
@@ -3771,6 +3771,7 @@ bool LLVolumeParams::validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 h
void LLVolume::getLoDTriangleCounts(const LLVolumeParams& params, S32* counts)
{ //attempt to approximate the number of triangles that will result from generating a volume LoD set for the
//supplied LLVolumeParams -- inaccurate, but a close enough approximation for determining streaming cost
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
F32 detail[] = {1.f, 1.5f, 2.5f, 4.f};
for (S32 i = 0; i < 4; i++)
{
diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h
index 0bd65fadef..ad7784f6d1 100644
--- a/indra/llprimitive/llgltfmaterial.h
+++ b/indra/llprimitive/llgltfmaterial.h
@@ -167,6 +167,7 @@ public:
// set the contents of this LLGLTFMaterial from the given json
// returns true if successful
+ // if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned
// json - the json text to load from
// warn_msg - warning message from TinyGLTF if any
// error_msg - error_msg from TinyGLTF if any
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 04ac2476a7..b7f08aa9af 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -243,9 +243,9 @@ void LLGLSLShader::stopProfile()
}
}
-void LLGLSLShader::placeProfileQuery()
+void LLGLSLShader::placeProfileQuery(bool for_runtime)
{
- if (sProfileEnabled)
+ if (sProfileEnabled || for_runtime)
{
if (mTimerQuery == 0)
{
@@ -254,42 +254,70 @@ void LLGLSLShader::placeProfileQuery()
glGenQueries(1, &mPrimitivesQuery);
}
- glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
glBeginQuery(GL_TIME_ELAPSED, mTimerQuery);
- glBeginQuery(GL_PRIMITIVES_GENERATED, mPrimitivesQuery);
+
+ if (!for_runtime)
+ {
+ glBeginQuery(GL_SAMPLES_PASSED, mSamplesQuery);
+ glBeginQuery(GL_PRIMITIVES_GENERATED, mPrimitivesQuery);
+ }
}
}
-void LLGLSLShader::readProfileQuery()
+bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read)
{
- if (sProfileEnabled)
+ if (sProfileEnabled || for_runtime)
{
- glEndQuery(GL_TIME_ELAPSED);
- glEndQuery(GL_SAMPLES_PASSED);
- glEndQuery(GL_PRIMITIVES_GENERATED);
+ if (!mProfilePending)
+ {
+ glEndQuery(GL_TIME_ELAPSED);
+ if (!for_runtime)
+ {
+ glEndQuery(GL_SAMPLES_PASSED);
+ glEndQuery(GL_PRIMITIVES_GENERATED);
+ }
+ mProfilePending = for_runtime;
+ }
+
+ if (mProfilePending && for_runtime && !force_read)
+ {
+ GLuint64 result = 0;
+ glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result);
+
+ if (result != GL_TRUE)
+ {
+ return false;
+ }
+ }
GLuint64 time_elapsed = 0;
glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+ mTimeElapsed += time_elapsed;
+ mProfilePending = false;
- GLuint64 samples_passed = 0;
- glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
+ if (!for_runtime)
+ {
+ GLuint64 samples_passed = 0;
+ glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
- U64 primitives_generated = 0;
- glGetQueryObjectui64v(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated);
- sTotalTimeElapsed += time_elapsed;
- mTimeElapsed += time_elapsed;
+ U64 primitives_generated = 0;
+ glGetQueryObjectui64v(mPrimitivesQuery, GL_QUERY_RESULT, &primitives_generated);
+ sTotalTimeElapsed += time_elapsed;
- sTotalSamplesDrawn += samples_passed;
- mSamplesDrawn += samples_passed;
+ sTotalSamplesDrawn += samples_passed;
+ mSamplesDrawn += samples_passed;
- U32 tri_count = (U32)primitives_generated / 3;
+ U32 tri_count = (U32)primitives_generated / 3;
- mTrianglesDrawn += tri_count;
- sTotalTrianglesDrawn += tri_count;
+ mTrianglesDrawn += tri_count;
+ sTotalTrianglesDrawn += tri_count;
- sTotalBinds++;
- mBinds++;
+ sTotalBinds++;
+ mBinds++;
+ }
}
+
+ return true;
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 9d187c972c..3e7dae6669 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -168,8 +168,16 @@ public:
void unload();
void clearStats();
void dumpStats();
- void placeProfileQuery();
- void readProfileQuery();
+
+ // place query objects for profiling if profiling is enabled
+ // if for_runtime is true, will place timer query only whether or not profiling is enabled
+ void placeProfileQuery(bool for_runtime = false);
+
+ // Readback query objects if profiling is enabled
+ // If for_runtime is true, will readback timer query iff query is available
+ // Will return false if a query is pending (try again later)
+ // If force_read is true, will force an immediate readback (severe performance penalty)
+ bool readProfileQuery(bool for_runtime = false, bool force_read = false);
BOOL createShader(std::vector<LLStaticHashedString>* attributes,
std::vector<LLStaticHashedString>* uniforms,
@@ -292,6 +300,7 @@ public:
defines_map_t mDefines;
//statistics for profiling shader performance
+ bool mProfilePending = false;
U32 mTimerQuery;
U32 mSamplesQuery;
U32 mPrimitivesQuery;
@@ -308,6 +317,9 @@ public:
// this pointer should be set to whichever shader represents this shader's rigged variant
LLGLSLShader* mRiggedVariant = nullptr;
+ // hacky flag used for optimization in LLDrawPoolAlpha
+ bool mCanBindFast = false;
+
#ifdef LL_PROFILER_ENABLE_RENDER_DOC
void setLabel(const char* label);
#endif
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 651c04f32c..43bef5ff68 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -2308,8 +2308,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
LLWindowWin32* window_imp = (LLWindowWin32*)GetWindowLongPtr(h_wnd, GWLP_USERDATA);
- bool debug_window_proc = false; // gDebugWindowProc || debugLoggingEnabled("Window");
-
if (NULL != window_imp)
{
// Juggle to make sure we can get negative positions for when
@@ -2336,11 +2334,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_DEVICECHANGE:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_DEVICECHANGE");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
- << "; lParam=" << l_param << LL_ENDL;
- }
+ LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
+ << "; lParam=" << l_param << LL_ENDL;
if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
{
WINDOW_IMP_POST(window_imp->mCallbacks->handleDeviceChange(window_imp));
@@ -2404,14 +2399,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
BOOL activating = (BOOL)w_param;
BOOL minimized = window_imp->getMinimized();
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC ActivateApp "
- << " activating " << S32(activating)
- << " minimized " << S32(minimized)
- << " fullscreen " << S32(window_imp->mFullscreen)
- << LL_ENDL;
- }
+ LL_INFOS("Window") << "WINDOWPROC ActivateApp "
+ << " activating " << S32(activating)
+ << " minimized " << S32(minimized)
+ << " fullscreen " << S32(window_imp->mFullscreen)
+ << LL_ENDL;
if (window_imp->mFullscreen)
{
@@ -2456,13 +2448,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// JC - I'm not sure why, but if we don't report that we handled the
// WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work
// properly when we run fullscreen.
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC Activate "
- << " activating " << S32(activating)
- << " minimized " << S32(minimized)
- << LL_ENDL;
- }
+ LL_INFOS("Window") << "WINDOWPROC Activate "
+ << " activating " << S32(activating)
+ << " minimized " << S32(minimized)
+ << LL_ENDL;
});
break;
@@ -2541,12 +2530,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mRawLParam = l_param;
{
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
- << " key " << S32(w_param)
- << LL_ENDL;
- }
+ LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
+ << " key " << S32(w_param)
+ << LL_ENDL;
gKeyboard->handleKeyDown(w_param, mask);
}
@@ -2571,12 +2557,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
{
LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
- << " key " << S32(w_param)
- << LL_ENDL;
- }
+ LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
+ << " key " << S32(w_param)
+ << LL_ENDL;
gKeyboard->handleKeyUp(w_param, mask);
}
});
@@ -2586,10 +2569,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_SETCONTEXT:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_SETCONTEXT");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
l_param &= ~ISC_SHOWUICOMPOSITIONWINDOW;
@@ -2600,10 +2580,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_STARTCOMPOSITION:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_STARTCOMPOSITION");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
WINDOW_IMP_POST(window_imp->handleStartCompositionMessage());
@@ -2614,10 +2591,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_ENDCOMPOSITION:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_ENDCOMPOSITION");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
return 0;
@@ -2627,10 +2601,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_COMPOSITION:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_COMPOSITION");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WM_IME_COMPOSITION" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
WINDOW_IMP_POST(window_imp->handleCompositionMessage(l_param));
@@ -2641,10 +2612,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_REQUEST:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_IME_REQUEST");
- if (debug_window_proc)
- {
- LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WM_IME_REQUEST" << LL_ENDL;
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
LRESULT result;
@@ -2673,12 +2641,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// it is worth trying. The good old WM_CHAR works just fine even for supplementary
// characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
// by ourselves. It is not that tough. -- Alissa Sabre @ SL
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
- << " key " << S32(w_param)
- << LL_ENDL;
- }
+ LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
+ << " key " << S32(w_param)
+ << LL_ENDL;
// Even if LLWindowCallbacks::handleUnicodeChar(llwchar, BOOL) returned FALSE,
// we *did* processed the event, so I believe we should not pass it to DefWindowProc...
window_imp->handleUnicodeUTF16((U16)w_param, gKeyboard->currentMask(FALSE));
@@ -3006,19 +2971,17 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
S32 height = S32(HIWORD(l_param));
- if (debug_window_proc)
- {
- BOOL maximized = (w_param == SIZE_MAXIMIZED);
- BOOL restored = (w_param == SIZE_RESTORED);
- BOOL minimized = (w_param == SIZE_MINIMIZED);
-
- LL_INFOS("Window") << "WINDOWPROC Size "
- << width << "x" << height
- << " max " << S32(maximized)
- << " min " << S32(minimized)
- << " rest " << S32(restored)
- << LL_ENDL;
- }
+ LL_INFOS("Window");
+ BOOL maximized = (w_param == SIZE_MAXIMIZED);
+ BOOL restored = (w_param == SIZE_RESTORED);
+ BOOL minimized = (w_param == SIZE_MINIMIZED);
+
+ LL_CONT << "WINDOWPROC Size "
+ << width << "x" << height
+ << " max " << S32(maximized)
+ << " min " << S32(minimized)
+ << " rest " << S32(restored);
+ LL_ENDL;
// There's an odd behavior with WM_SIZE that I would call a bug. If
// the window is maximized, and you call MoveWindow() with a size smaller
@@ -3084,10 +3047,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_SETFOCUS:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_SETFOCUS");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
WINDOW_IMP_POST(window_imp->mCallbacks->handleFocus(window_imp));
return 0;
}
@@ -3095,10 +3055,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_KILLFOCUS:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_KILLFOCUS");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
- }
+ LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
WINDOW_IMP_POST(window_imp->mCallbacks->handleFocusLost(window_imp));
return 0;
}
@@ -3219,10 +3176,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
default:
{
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - default");
- if (debug_window_proc)
- {
- LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL;
- }
+ LL_INFOS("Window") << "Unhandled windows message code: 0x" << std::hex << U32(u_msg) << LL_ENDL;
}
break;
}
@@ -4898,8 +4852,6 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
{ // current usage is sometimes unreliable on Intel GPUs, fall back to estimated usage
cu_mb = llmax((U32)1, eu_mb);
}
- F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb;
-
U32 target_mb = budget_mb;
if (target_mb > 4096) // if 4GB are installed, try to leave 2GB free
@@ -4913,6 +4865,9 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
mAvailableVRAM = cu_mb < target_mb ? target_mb - cu_mb : 0;
+#if 0
+
+ F32 eu_error = (F32)((S32)eu_mb - (S32)cu_mb) / (F32)cu_mb;
LL_INFOS("Window") << "\nLocal\nAFR: " << info.AvailableForReservation / 1024 / 1024
<< "\nBudget: " << info.Budget / 1024 / 1024
<< "\nCR: " << info.CurrentReservation / 1024 / 1024
@@ -4920,12 +4875,7 @@ void LLWindowWin32::LLWindowWin32Thread::updateVRAMUsage()
<< "\nEU: " << eu_mb << llformat(" (%.2f)", eu_error)
<< "\nTU: " << target_mb
<< "\nAM: " << mAvailableVRAM << LL_ENDL;
-
- /*mDXGIAdapter->QueryVideoMemoryInfo(0, DXGI_MEMORY_SEGMENT_GROUP_NON_LOCAL, &info);
- LL_INFOS("Window") << "\nNon-Local\nAFR: " << info.AvailableForReservation / 1024 / 1024
- << "\nBudget: " << info.Budget / 1024 / 1024
- << "\nCR: " << info.CurrentReservation / 1024 / 1024
- << "\nCU: " << info.CurrentUsage / 1024 / 1024 << LL_ENDL;*/
+#endif
}
else if (mD3DDevice != NULL)
{ // fallback to D3D9
diff --git a/indra/newview/groupchatlistener.cpp b/indra/newview/groupchatlistener.cpp
index ef015a950d..a05caa961b 100644
--- a/indra/newview/groupchatlistener.cpp
+++ b/indra/newview/groupchatlistener.cpp
@@ -64,11 +64,11 @@ GroupChatListener::GroupChatListener():
"Leave a group chat in group with UUID [\"id\"]\n"
"Assumes a prior successful startIM request.",
&LLGroupActions::endIM,
- LLSDArray("id"));
- add("sendIM",
- "send a groupchat IM",
- &send_message_wrapper,
- LLSDArray("text")("session_id")("group_id"));
+ llsd::array("id"));
+ add("sendIM",
+ "send a groupchat IM",
+ &send_message_wrapper,
+ llsd::array("text", "session_id", "group_id"));
}
/*
static void sendMessage(const std::string& utf8_text, const LLUUID& im_session_id,
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b2349e9f74..6efbaeacf7 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3191,15 +3191,16 @@ LLSD LLAppViewer::getViewerInfo() const
// LLFloaterAbout.
LLSD info;
auto& versionInfo(LLVersionInfo::instance());
- info["VIEWER_VERSION"] = LLSDArray(versionInfo.getMajor())(versionInfo.getMinor())(versionInfo.getPatch())(versionInfo.getBuild());
+ info["VIEWER_VERSION"] = llsd::array(versionInfo.getMajor(), versionInfo.getMinor(),
+ versionInfo.getPatch(), versionInfo.getBuild());
info["VIEWER_VERSION_STR"] = versionInfo.getVersion();
info["CHANNEL"] = versionInfo.getChannel();
- info["ADDRESS_SIZE"] = ADDRESS_SIZE;
- std::string build_config = versionInfo.getBuildConfig();
- if (build_config != "Release")
- {
- info["BUILD_CONFIG"] = build_config;
- }
+ info["ADDRESS_SIZE"] = ADDRESS_SIZE;
+ std::string build_config = versionInfo.getBuildConfig();
+ if (build_config != "Release")
+ {
+ info["BUILD_CONFIG"] = build_config;
+ }
// return a URL to the release notes for this viewer, such as:
// https://releasenotes.secondlife.com/viewer/2.1.0.123456.html
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 6457c13ef3..31c5d2a16f 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -656,16 +656,18 @@ bool LLAppViewerWin32::init()
LL_VIEWER_VERSION_PATCH << '.' <<
LL_VIEWER_VERSION_BUILD));
- DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
- MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
-
- bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
- if (needs_log_file)
- {
- // Startup only!
- LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
- dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
- }
+ DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
+ MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
+
+ bool needs_log_file = !isSecondInstance();
+ LL_DEBUGS("BUGSPLAT");
+ if (needs_log_file)
+ {
+ // Startup only!
+ LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
+ dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
+ }
+ LL_ENDL;
// have to convert normal wide strings to strings of __wchar_t
sBugSplatSender = new MiniDmpSender(
@@ -676,12 +678,14 @@ bool LLAppViewerWin32::init()
dwFlags);
sBugSplatSender->setCallback(bugsplatSendLog);
- if (needs_log_file)
- {
- // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
- std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
- sBugSplatSender->setLogFilePath(WCSTR(log_file));
- }
+ LL_DEBUGS("BUGSPLAT");
+ if (needs_log_file)
+ {
+ // Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
+ std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
+ sBugSplatSender->setLogFilePath(WCSTR(log_file));
+ }
+ LL_ENDL;
// engage stringize() overload that converts from wstring
LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 04b6ebd14c..ea59a413fa 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -908,12 +908,6 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
- LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname()
- << " pos (ignored) " << pos
- << " cam pos " << cam_pos_from_agent
- << " box " << av_box[0] << "," << av_box[1]
- << " -> dist " << mDistanceWRTCamera
- << LL_ENDL;
mVObjp->updateLOD();
return;
}
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 34d8f8b9ce..187e290066 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -52,8 +52,6 @@
#include "llglcommonfunc.h"
#include "llvoavatar.h"
#include "llviewershadermgr.h"
-#include "llperfstats.h"
-
S32 LLDrawPool::sNumDrawPools = 0;
@@ -387,22 +385,11 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo *pparams = *k;
if (pparams)
{
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments(vobj, false, &ratPtr);
- }
- }
-#endif
pushBatch(*pparams, texture);
}
}
@@ -415,23 +402,11 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo* pparams = *k;
if (pparams)
{
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, true ,&ratPtr);
- }
- }
-#endif
-
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
uploadMatrixPalette(*pparams);
@@ -447,7 +422,6 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu
void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
@@ -455,16 +429,6 @@ void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures)
LLDrawInfo* pparams = *i;
LLCullResult::increment_iterator(i, end);
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, false, &ratPtr);
- }
- }
-#endif
pushBatch(*pparams, texture, batch_textures);
}
}
@@ -476,23 +440,11 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures
U64 lastMeshId = 0;
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
LLCullResult::increment_iterator(i, end);
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, true, &ratPtr);
- }
- }
-#endif
-
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{
uploadMatrixPalette(*pparams);
@@ -507,23 +459,12 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures
void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
LLCullResult::increment_iterator(i, end);
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if((*pparams).mFace)
- {
- LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, false, &ratPtr);
- }
- }
-#endif
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
pushBatch(*pparams, texture, batch_textures);
}
@@ -534,7 +475,6 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
auto* begin = gPipeline.beginRenderMap(type);
auto* end = gPipeline.endRenderMap(type);
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
@@ -544,16 +484,6 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text
LLCullResult::increment_iterator(i, end);
llassert(pparams);
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if((*pparams).mFace)
- {
- LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, true, &ratPtr);
- }
- }
-#endif
if (LLGLSLShader::sCurBoundShaderPtr)
{
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index da4c963a97..ec57e20d35 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -49,7 +49,6 @@
#include "llspatialpartition.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
-#include "llperfstats.h"
#include "llenvironment.h"
@@ -108,12 +107,10 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
// i.e. shaders\class1\deferred\alphaF.glsl
if (deferredEnvironment)
{
- gPipeline.bindDeferredShader( *shader );
- }
- else
- {
- shader->bind();
+ shader->mCanBindFast = false;
}
+
+ shader->bind();
shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
if (LLPipeline::sRenderingHUDs)
@@ -349,22 +346,10 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
-# if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-#endif
-
bool rigged = (params.mAvatar != nullptr);
gHighlightProgram.bind(rigged);
gGL.diffuseColor4f(1, 0, 0, 1);
@@ -548,17 +533,9 @@ void LLDrawPoolAlpha::renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives)
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLDrawInfo* draw : emissives)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
-# if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
- }
-#endif
bool tex_setup = TexSetup(draw, false);
if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
@@ -687,7 +664,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
@@ -700,18 +676,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
LLRenderPass::applyModelMatrix(params);
-# if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-#endif
-
LLMaterial* mat = NULL;
LLGLTFMaterial *gltf_mat = params.mGLTFMaterial;
@@ -905,8 +869,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
}
}
- ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
-
// render emissive faces into alpha channel for bloom effects
if (!depth_only)
{
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index c398087b20..19b23609a6 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -52,7 +52,6 @@
#include "llviewerpartsim.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewertexturelist.h"
-#include "llperfstats.h"
static U32 sShaderLevel = 0;
@@ -370,9 +369,8 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
{
return;
}
- LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS);
- LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
+ LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
// no shadows if the shadows are causing this avatar to breach the limit.
if (avatarp->isTooSlow() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
@@ -741,7 +739,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{
return;
}
- LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);
if (!single_avatar && !avatarp->isFullyLoaded() )
{
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index bd0b05fb33..38768a19c8 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -49,7 +49,6 @@
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
#include "llmodel.h"
-#include "llperfstats.h"
//#include "llimagebmp.h"
//#include "../tools/imdebug/imdebug.h"
@@ -407,19 +406,10 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture =
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
-#endif
-
applyModelMatrix(params);
params.mVertexBuffer->setBuffer();
@@ -569,25 +559,12 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLVOAvatar* avatar = nullptr;
U64 skin = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo& params = **i;
LLCullResult::increment_iterator(i, end);
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-#endif
-
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
LLDrawPoolBump::bindBumpMap(params, bump_channel);
@@ -1216,23 +1193,10 @@ void LLDrawPoolBump::pushBumpBatches(U32 type)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-#endif
-
if (LLDrawPoolBump::bindBumpMap(params))
{
if (mRigged)
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index e025651cce..6a7e05ac74 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -32,7 +32,6 @@
#include "pipeline.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
-#include "llperfstats.h"
LLDrawPoolMaterials::LLDrawPoolMaterials()
: LLRenderPass(LLDrawPool::POOL_MATERIALS)
@@ -151,7 +150,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
F32 lastIntensity = 0.f;
F32 lastFullbright = 0.f;
F32 lastMinimumAlpha = 0.f;
@@ -201,18 +199,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
LLCullResult::increment_iterator(i, end);
-#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-#endif
-
if (specular > -1 && params.mSpecColor != lastSpecular)
{
lastSpecular = params.mSpecColor;
diff --git a/indra/newview/llfloatereditsky.cpp b/indra/newview/llfloatereditsky.cpp
index 6bdc5ee823..2d5e86869d 100644
--- a/indra/newview/llfloatereditsky.cpp
+++ b/indra/newview/llfloatereditsky.cpp
@@ -523,7 +523,7 @@ void LLFloaterEditSky::refreshSkyPresetsList()
for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it)
{
- mSkyPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second));
+ mSkyPresetCombo->add((*it).first, llsd::array((*it).first, (*it).second));
}
mSkyPresetCombo->setLabel(getString("combo_label"));
diff --git a/indra/newview/llfloatereditwater.cpp b/indra/newview/llfloatereditwater.cpp
index 6e7b777e70..c44ae7faca 100644
--- a/indra/newview/llfloatereditwater.cpp
+++ b/indra/newview/llfloatereditwater.cpp
@@ -335,7 +335,7 @@ void LLFloaterEditWater::refreshWaterPresetsList()
for (LLEnvironment::list_name_id_t::iterator it = list.begin(); it != list.end(); ++it)
{
- mWaterPresetCombo->add((*it).first, LLSDArray((*it).first)((*it).second));
+ mWaterPresetCombo->add((*it).first, llsd::array((*it).first, (*it).second));
}
mWaterPresetCombo->setLabel(getString("combo_label"));
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 3321374f65..8c5745aa43 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -56,10 +56,6 @@ const S32 BAR_LEFT_PAD = 2;
const S32 BAR_RIGHT_PAD = 5;
const S32 BAR_BOTTOM_PAD = 9;
-constexpr auto AvType {LLPerfStats::ObjType_t::OT_AVATAR};
-constexpr auto AttType {LLPerfStats::ObjType_t::OT_ATTACHMENT};
-constexpr auto HudType {LLPerfStats::ObjType_t::OT_HUD};
-
class LLExceptionsContextMenu : public LLListContextMenu
{
public:
@@ -83,8 +79,7 @@ protected:
LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
: LLFloater(key),
- mUpdateTimer(new LLTimer()),
- mNearbyMaxComplexity(0)
+ mUpdateTimer(new LLTimer())
{
mContextMenu = new LLExceptionsContextMenu(this);
}
@@ -247,47 +242,82 @@ void LLFloaterPerformance::populateHUDList()
mHUDList->clearRows();
mHUDList->updateColumns(true);
- hud_complexity_list_t complexity_list = LLHUDRenderNotifier::getInstance()->getHUDComplexityList();
-
- hud_complexity_list_t::iterator iter = complexity_list.begin();
- hud_complexity_list_t::iterator end = complexity_list.end();
-
- auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY);
- for (iter = complexity_list.begin(); iter != end; ++iter)
- {
- LLHUDComplexity hud_object_complexity = *iter;
-
- auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY);
-
- LLSD item;
- item["special_id"] = hud_object_complexity.objectId;
- item["target"] = LLNameListCtrl::SPECIAL;
- LLSD& row = item["columns"];
- row[0]["column"] = "complex_visual";
- row[0]["type"] = "bar";
- LLSD& value = row[0]["value"];
- value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw;
- value["bottom"] = BAR_BOTTOM_PAD;
- value["left_pad"] = BAR_LEFT_PAD;
- value["right_pad"] = BAR_RIGHT_PAD;
-
- row[1]["column"] = "complex_value";
- row[1]["type"] = "text";
- row[1]["value"] = llformat( "%.f", llmax(LLPerfStats::raw_to_us(hud_render_time_raw), (double)1));
- row[1]["font"]["name"] = "SANSSERIF";
-
- row[2]["column"] = "name";
- row[2]["type"] = "text";
- row[2]["value"] = hud_object_complexity.objectName;
- row[2]["font"]["name"] = "SANSSERIF";
-
- LLScrollListItem* obj = mHUDList->addElement(item);
- if (obj)
+ LLVOAvatar* avatar = gAgentAvatarp;
+
+ gPipeline.profileAvatar(avatar, true);
+
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ // get max gpu render time of all attachments
+ F32 max_gpu_time = -1.f;
+
+ for (iter = begin; iter != end; ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->isHUDAttachment())
+ {
+ max_gpu_time = llmax(max_gpu_time, attached_object->mGPURenderTime);
+ }
+ }
+ }
+
+
+ for (iter = begin; iter != end; ++iter)
+ {
+ if (!iter->second)
+ {
+ continue;
+ }
+
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
- if (value_text)
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->isHUDAttachment())
{
- value_text->setAlignment(LLFontGL::HCENTER);
+ F32 gpu_time = attached_object->mGPURenderTime;
+
+ LLSD item;
+ item["special_id"] = attached_object->getID();
+ item["target"] = LLNameListCtrl::SPECIAL;
+ LLSD& row = item["columns"];
+ row[0]["column"] = "complex_visual";
+ row[0]["type"] = "bar";
+ LLSD& value = row[0]["value"];
+ value["ratio"] = gpu_time / max_gpu_time;
+ value["bottom"] = BAR_BOTTOM_PAD;
+ value["left_pad"] = BAR_LEFT_PAD;
+ value["right_pad"] = BAR_RIGHT_PAD;
+
+ row[1]["column"] = "complex_value";
+ row[1]["type"] = "text";
+ // show gpu time in us
+ row[1]["value"] = llformat("%.f", gpu_time * 1000.f);
+ row[1]["font"]["name"] = "SANSSERIF";
+
+ row[2]["column"] = "name";
+ row[2]["type"] = "text";
+ row[2]["value"] = attached_object->getAttachmentItemName();
+ row[2]["font"]["name"] = "SANSSERIF";
+
+ LLScrollListItem* obj = mHUDList->addElement(item);
+ if (obj)
+ {
+ LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+ if (value_text)
+ {
+ value_text->setAlignment(LLFontGL::HCENTER);
+ }
+ }
}
}
}
@@ -303,50 +333,82 @@ void LLFloaterPerformance::populateObjectList()
mObjectList->clearRows();
mObjectList->updateColumns(true);
- object_complexity_list_t complexity_list = LLAvatarRenderNotifier::getInstance()->getObjectComplexityList();
-
- object_complexity_list_t::iterator iter = complexity_list.begin();
- object_complexity_list_t::iterator end = complexity_list.end();
+ LLVOAvatar* avatar = gAgentAvatarp;
- // for consistency we lock the buffer while we build the list. In theory this is uncontended as the buffer should only toggle on end of frame
- {
- std::lock_guard<std::mutex> guard{ LLPerfStats::bufferToggleLock };
- auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED);
+ gPipeline.profileAvatar(avatar, true);
- for (iter = complexity_list.begin(); iter != end; ++iter)
- {
- LLObjectComplexity object_complexity = *iter;
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
- auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, object_complexity.objectId, LLPerfStats::StatType_t::RENDER_COMBINED);
- LLSD item;
- item["special_id"] = object_complexity.objectId;
- item["target"] = LLNameListCtrl::SPECIAL;
- LLSD& row = item["columns"];
- row[0]["column"] = "complex_visual";
- row[0]["type"] = "bar";
- LLSD& value = row[0]["value"];
- value["ratio"] = ((F32)attach_render_time_raw) / att_max_render_time_raw;
- value["bottom"] = BAR_BOTTOM_PAD;
- value["left_pad"] = BAR_LEFT_PAD;
- value["right_pad"] = BAR_RIGHT_PAD;
+ // get max gpu render time of all attachments
+ F32 max_gpu_time = -1.f;
- row[1]["column"] = "complex_value";
- row[1]["type"] = "text";
- row[1]["value"] = llformat("%.f", llmax(LLPerfStats::raw_to_us(attach_render_time_raw), (double)1));
- row[1]["font"]["name"] = "SANSSERIF";
+ for (iter = begin; iter != end; ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isHUDAttachment())
+ {
+ max_gpu_time = llmax(max_gpu_time, attached_object->mGPURenderTime);
+ }
+ }
+ }
- row[2]["column"] = "name";
- row[2]["type"] = "text";
- row[2]["value"] = object_complexity.objectName;
- row[2]["font"]["name"] = "SANSSERIF";
+ {
+ for (iter = begin; iter != end; ++iter)
+ {
+ if (!iter->second)
+ {
+ continue;
+ }
- LLScrollListItem* obj = mObjectList->addElement(item);
- if (obj)
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
- if (value_text)
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isHUDAttachment())
{
- value_text->setAlignment(LLFontGL::HCENTER);
+ F32 gpu_time = attached_object->mGPURenderTime;
+
+ LLSD item;
+ item["special_id"] = attached_object->getID();
+ item["target"] = LLNameListCtrl::SPECIAL;
+ LLSD& row = item["columns"];
+ row[0]["column"] = "complex_visual";
+ row[0]["type"] = "bar";
+ LLSD& value = row[0]["value"];
+ value["ratio"] = gpu_time / max_gpu_time;
+ value["bottom"] = BAR_BOTTOM_PAD;
+ value["left_pad"] = BAR_LEFT_PAD;
+ value["right_pad"] = BAR_RIGHT_PAD;
+
+ row[1]["column"] = "complex_value";
+ row[1]["type"] = "text";
+ // show gpu time in us
+ row[1]["value"] = llformat("%.f", gpu_time * 1000.f);
+ row[1]["font"]["name"] = "SANSSERIF";
+
+ row[2]["column"] = "name";
+ row[2]["type"] = "text";
+ row[2]["value"] = attached_object->getAttachmentItemName();
+ row[2]["font"]["name"] = "SANSSERIF";
+
+ LLScrollListItem* obj = mObjectList->addElement(item);
+ if (obj)
+ {
+ LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+ if (value_text)
+ {
+ value_text->setAlignment(LLFontGL::HCENTER);
+ }
+ }
}
}
}
@@ -358,6 +420,7 @@ void LLFloaterPerformance::populateObjectList()
void LLFloaterPerformance::populateNearbyList()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");
S32 prev_pos = mNearbyList->getScrollPos();
LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
@@ -366,22 +429,16 @@ void LLFloaterPerformance::populateNearbyList()
static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
std::vector<LLCharacter*> valid_nearby_avs;
- mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
+ mNearbyMaxGPUTime = LLWorld::getInstance()->getNearbyAvatarsAndMaxGPUTime(valid_nearby_avs);
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
- LLPerfStats::bufferToggleLock.lock();
- auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
- LLPerfStats::bufferToggleLock.unlock();
-
while (char_iter != valid_nearby_avs.end())
{
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
{
- LLPerfStats::bufferToggleLock.lock();
- auto render_av_raw = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED);
- LLPerfStats::bufferToggleLock.unlock();
+ F32 render_av_gpu_ms = avatar->getGPURenderTime();
auto is_slow = avatar->isTooSlow();
LLSD item;
@@ -392,7 +449,7 @@ void LLFloaterPerformance::populateNearbyList()
LLSD& value = row[0]["value"];
// The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the
// pre-tune value for the numerical column and sorting.
- value["ratio"] = (double)render_av_raw / av_render_max_raw;
+ value["ratio"] = render_av_gpu_ms / mNearbyMaxGPUTime;
value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD;
@@ -405,14 +462,15 @@ void LLFloaterPerformance::populateNearbyList()
}
else
{
- row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( render_av_raw ) );
+ // use GPU time in us
+ row[1]["value"] = llformat( "%.f", render_av_gpu_ms * 1000.f);
}
row[1]["font"]["name"] = "SANSSERIF";
- row[2]["column"] = "name";
- row[2]["type"] = "text";
- row[2]["value"] = avatar->getFullname();
- row[2]["font"]["name"] = "SANSSERIF";
+ row[3]["column"] = "name";
+ row[3]["type"] = "text";
+ row[3]["value"] = avatar->getFullname();
+ row[3]["font"]["name"] = "SANSSERIF";
LLScrollListItem* av_item = mNearbyList->addElement(item);
if(av_item)
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 00f904f6d6..620dbac5bb 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -94,7 +94,9 @@ private:
LLTimer* mUpdateTimer;
- S32 mNearbyMaxComplexity;
+ // maximum GPU time of nearby avatars in ms according to LLWorld::getNearbyAvatarsAndMaxGPUTime
+ // -1.f if no profile has happened yet
+ F32 mNearbyMaxGPUTime = -1.f;
boost::signals2::connection mMaxARTChangedSignal;
};
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 151d7fa969..99a052f719 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -219,40 +219,36 @@ public:
struct ReturnData
{
public:
- LLPointer<LLGLTFMaterial> mMaterial;
+ LLGLTFMaterial mMaterial;
S32 mSide;
bool mSuccess;
};
- // fromJson() is performance heavy offload to a thread.
- main_queue->postTo(
- general_queue,
- [object_override]() // Work done on general queue
+ if (!object_override.mSides.empty())
{
- std::vector<ReturnData> results;
-
- if (!object_override.mSides.empty())
+ // fromJson() is performance heavy offload to a thread.
+ main_queue->postTo(
+ general_queue,
+ [sides=object_override.mSides]() // Work done on general queue
{
- results.reserve(object_override.mSides.size());
+ std::vector<ReturnData> results;
+
+ results.reserve(sides.size());
// parse json
- std::unordered_map<S32, std::string>::const_iterator iter = object_override.mSides.begin();
- std::unordered_map<S32, std::string>::const_iterator end = object_override.mSides.end();
+ std::unordered_map<S32, std::string>::const_iterator iter = sides.begin();
+ std::unordered_map<S32, std::string>::const_iterator end = sides.end();
while (iter != end)
{
- LLPointer<LLGLTFMaterial> override_data = new LLGLTFMaterial();
std::string warn_msg, error_msg;
- bool success = override_data->fromJSON(iter->second, warn_msg, error_msg);
-
ReturnData result;
+
+ bool success = result.mMaterial.fromJSON(iter->second, warn_msg, error_msg);
+
result.mSuccess = success;
result.mSide = iter->first;
- if (success)
- {
- result.mMaterial = override_data;
- }
- else
+ if (!success)
{
LL_WARNS("GLTF") << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL;
}
@@ -260,64 +256,68 @@ public:
results.push_back(result);
iter++;
}
- }
- return results;
- },
- [object_override, this](std::vector<ReturnData> results) // Callback to main thread
+ return results;
+ },
+ [object_id=object_override.mObjectId, this](std::vector<ReturnData> results) // Callback to main thread
{
- LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId);
+ LLViewerObject * obj = gObjectList.findObject(object_id);
- if (results.size() > 0 )
- {
- std::unordered_set<S32> side_set;
-
- for (int i = 0; i < results.size(); ++i)
+ if (results.size() > 0 )
{
- if (results[i].mSuccess)
+ std::unordered_set<S32> side_set;
+
+ for (auto const & result : results)
{
- // flag this side to not be nulled out later
- side_set.insert(results[i].mSide);
+ S32 side = result.mSide;
+ if (result.mSuccess)
+ {
+ // copy to heap here because LLTextureEntry is going to take ownership with an LLPointer
+ LLGLTFMaterial * material = new LLGLTFMaterial(result.mMaterial);
+
+ // flag this side to not be nulled out later
+ side_set.insert(side);
- if (obj)
+ if (obj)
+ {
+ obj->setTEGLTFMaterialOverride(side, material);
+ }
+ }
+
+ // unblock material editor
+ if (obj && obj->getTE(side) && obj->getTE(side)->isSelected())
{
- obj->setTEGLTFMaterialOverride(results[i].mSide, results[i].mMaterial);
+ doSelectionCallbacks(object_id, side);
}
}
-
- // unblock material editor
- if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected())
- {
- doSelectionCallbacks(object_override.mObjectId, results[i].mSide);
- }
- }
- if (obj && side_set.size() != obj->getNumTEs())
- { // object exists and at least one texture entry needs to have its override data nulled out
- for (int i = 0; i < obj->getNumTEs(); ++i)
- {
- if (side_set.find(i) == side_set.end())
+ if (obj && side_set.size() != obj->getNumTEs())
+ { // object exists and at least one texture entry needs to have its override data nulled out
+ for (int i = 0; i < obj->getNumTEs(); ++i)
{
- obj->setTEGLTFMaterialOverride(i, nullptr);
- if (obj->getTE(i) && obj->getTE(i)->isSelected())
+ if (side_set.find(i) == side_set.end())
{
- doSelectionCallbacks(object_override.mObjectId, i);
+ obj->setTEGLTFMaterialOverride(i, nullptr);
+ if (obj->getTE(i) && obj->getTE(i)->isSelected())
+ {
+ doSelectionCallbacks(object_id, i);
+ }
}
}
}
}
- }
- else if (obj)
- { // override list was empty or an error occurred, null out all overrides for this object
- for (int i = 0; i < obj->getNumTEs(); ++i)
- {
- obj->setTEGLTFMaterialOverride(i, nullptr);
- if (obj->getTE(i) && obj->getTE(i)->isSelected())
+ else if (obj)
+ { // override list was empty or an error occurred, null out all overrides for this object
+ for (int i = 0; i < obj->getNumTEs(); ++i)
{
- doSelectionCallbacks(obj->getID(), i);
+ obj->setTEGLTFMaterialOverride(i, nullptr);
+ if (obj->getTE(i) && obj->getTE(i)->isSelected())
+ {
+ doSelectionCallbacks(obj->getID(), i);
+ }
}
}
- }
- });
+ });
+ }
}
private:
@@ -433,6 +433,19 @@ void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const L
}
}
+void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* material_override)
+{
+ if (asset_id.isNull() || material_override == nullptr)
+ {
+ queueApply(obj, side, asset_id);
+ }
+ else
+ {
+ LLGLTFMaterial* material = new LLGLTFMaterial(*material_override);
+ sApplyQueue.push_back({ obj->getID(), side, asset_id, material });
+ }
+}
+
void LLGLTFMaterialList::queueUpdate(const LLSD& data)
{
llassert(is_valid_update(data));
@@ -477,7 +490,7 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
}
sModifyQueue.clear();
- for (auto& e : sApplyQueue)
+ for (ApplyMaterialAssetData& e : sApplyQueue)
{
data[i]["object_id"] = e.object_id;
data[i]["side"] = e.side;
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
index 85e60aa17f..ce8781baba 100644
--- a/indra/newview/llgltfmateriallist.h
+++ b/indra/newview/llgltfmateriallist.h
@@ -70,6 +70,13 @@ public:
// NOTE: Implicitly clears most override data if present
static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
+ // Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
+ // object_id - ID of object to apply material asset to
+ // side - TextureEntry index to apply material to, or -1 for all sides
+ // asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
+ // mat - override material, if null, will clear most override data
+ static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* mat);
+
// flush pending material updates to the simulator
// Automatically called once per frame, but may be called explicitly
// for cases that care about the done_callback forwarded to LLCoros::instance().launch
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index e8411dd573..67bf6827ad 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1342,10 +1342,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
if (header_size > 0)
{
- const LLSD& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header["skin"]["offset"].asInteger();
- S32 size = header["skin"]["size"].asInteger();
+ const LLMeshHeader& header = header_it->second.second;
+
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mSkinOffset;
+ S32 size = header.mSkinSize;
mHeaderMutex->unlock();
@@ -1456,9 +1457,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
if (header_size > 0)
{
const auto& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header["physics_convex"]["offset"].asInteger();
- S32 size = header["physics_convex"]["size"].asInteger();
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mPhysicsConvexOffset;
+ S32 size = header.mPhysicsConvexSize;
mHeaderMutex->unlock();
@@ -1555,9 +1556,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
if (header_size > 0)
{
const auto& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header["physics_mesh"]["offset"].asInteger();
- S32 size = header["physics_mesh"]["size"].asInteger();
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mPhysicsMeshOffset;
+ S32 size = header.mPhysicsMeshSize;
mHeaderMutex->unlock();
@@ -1753,9 +1754,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
if (header_size > 0)
{
const auto& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger();
- S32 size = header[header_lod[lod]]["size"].asInteger();
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mLodOffset[lod];
+ S32 size = header.mLodSize[lod];
mHeaderMutex->unlock();
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
@@ -1857,8 +1858,10 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
{
const LLUUID mesh_id = mesh_params.getSculptID();
- LLSD header;
+ LLSD header_data;
+ LLMeshHeader header;
+
U32 header_size = 0;
if (data_size > 0)
{
@@ -1869,23 +1872,25 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size);
- if (!LLSDSerialize::fromBinary(header, stream, data_size))
+ if (!LLSDSerialize::fromBinary(header_data, stream, data_size))
{
LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id
<< LL_ENDL;
return MESH_PARSE_FAILURE;
}
- if (!header.isMap())
+ if (!header_data.isMap())
{
LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;
return MESH_INVALID;
}
- if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)
+ header.fromLLSD(header_data);
+
+ if (header.mVersion > MAX_MESH_VERSION)
{
LL_INFOS(LOG_MESH) << "Wrong version in header for " << mesh_id << LL_ENDL;
- header["404"] = 1;
+ header.m404 = true;
}
// make sure there is at least one lod, function returns -1 and marks as 404 otherwise
else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0)
@@ -1897,7 +1902,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
{
LL_INFOS(LOG_MESH) << "Non-positive data size. Marking header as non-existent, will not retry. ID: " << mesh_id
<< LL_ENDL;
- header["404"] = 1;
+ header.m404 = 1;
}
{
@@ -1907,7 +1912,6 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
mMeshHeader[mesh_id] = { header_size, header };
LLMeshRepository::sCacheBytesHeaders += header_size;
}
-
LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
@@ -2977,7 +2981,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
if (iter != mMeshHeader.end())
{
- LLSD& header = iter->second.second;
+ auto& header = iter->second.second;
return LLMeshRepository::getActualMeshLOD(header, lod);
}
@@ -2986,23 +2990,23 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
}
//static
-S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
+S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod)
{
lod = llclamp(lod, 0, 3);
- if (header.has("404"))
+ if (header.m404)
{
return -1;
}
- S32 version = header["version"];
+ S32 version = header.mVersion;
if (version > MAX_MESH_VERSION)
{
return -1;
}
- if (header[header_lod[lod]]["size"].asInteger() > 0)
+ if (header.mLodSize[lod] > 0)
{
return lod;
}
@@ -3010,7 +3014,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
//search down to find the next available lower lod
for (S32 i = lod-1; i >= 0; --i)
{
- if (header[header_lod[i]]["size"].asInteger() > 0)
+ if (header.mLodSize[i] > 0)
{
return i;
}
@@ -3019,15 +3023,16 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
//search up to find then ext available higher lod
for (S32 i = lod+1; i < 4; ++i)
{
- if (header[header_lod[i]]["size"].asInteger() > 0)
+ if (header.mLodSize[i] > 0)
{
return i;
}
}
//header exists and no good lod found, treat as 404
- header["404"] = 1;
- return -1;
+ header.m404 = true;
+
+ return -1;
}
// Handle failed or successful requests for mesh assets.
@@ -3216,7 +3221,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
{
// header was successfully retrieved from sim and parsed and is in cache
S32 header_bytes = 0;
- LLSD header;
+ LLMeshHeader header;
gMeshRepo.mThread->mHeaderMutex->lock();
LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id);
@@ -3227,8 +3232,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
}
if (header_bytes > 0
- && !header.has("404")
- && (!header.has("version") || header["version"].asInteger() <= MAX_MESH_VERSION))
+ && !header.m404
+ && (header.mVersion <= MAX_MESH_VERSION))
{
std::stringstream str;
@@ -3237,13 +3242,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i)
{
// figure out how many bytes we'll need to reserve in the file
- const std::string & lod_name = header_lod[i];
- lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger());
+ lod_bytes = llmax(lod_bytes, header.mLodOffset[i]+header.mLodSize[i]);
}
// just in case skin info or decomposition is at the end of the file (which it shouldn't be)
- lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
- lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
+ lod_bytes = llmax(lod_bytes, header.mSkinOffset+header.mSkinSize);
+ lod_bytes = llmax(lod_bytes, header.mPhysicsConvexOffset + header.mPhysicsConvexSize);
// Do not unlock mutex untill we are done with LLSD.
// LLSD is smart and can work like smart pointer, is not thread safe.
@@ -4257,8 +4261,8 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
if (iter != mMeshHeader.end() && iter->second.first > 0)
{
- LLSD &mesh = iter->second.second;
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+ LLMeshHeader &mesh = iter->second.second;
+ if (mesh.mPhysicsMeshSize > 0)
{
return true;
}
@@ -4281,20 +4285,21 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- const LLSD& header = iter->second.second;
+ const LLMeshHeader& header = iter->second.second;
- if (header.has("404"))
+ if (header.m404)
{
return -1;
}
- S32 size = header[header_lod[lod]]["size"].asInteger();
+ S32 size = header.mLodSize[lod];
return size;
}
@@ -4430,11 +4435,11 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by
// FIXME replace with calc based on LLMeshCostData
//static
-F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
+F32 LLMeshRepository::getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
- if (header.has("404")
- || !header.has("lowest_lod")
- || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION))
+ if (header.m404
+ || header.mLodSize[0] <= 0
+ || (header.mVersion > MAX_MESH_VERSION))
{
return 0.f;
}
@@ -4453,10 +4458,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
F32 minimum_size = (F32)minimum_size_ch;
F32 bytes_per_triangle = (F32)bytes_per_triangle_ch;
- S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
- S32 bytes_low = header["low_lod"]["size"].asInteger();
- S32 bytes_mid = header["medium_lod"]["size"].asInteger();
- S32 bytes_high = header["high_lod"]["size"].asInteger();
+ S32 bytes_lowest = header.mLodSize[0];
+ S32 bytes_low = header.mLodSize[1];
+ S32 bytes_mid = header.mLodSize[2];
+ S32 bytes_high = header.mLodSize[3];
if (bytes_high == 0)
{
@@ -4486,10 +4491,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
if (bytes)
{
*bytes = 0;
- *bytes += header["lowest_lod"]["size"].asInteger();
- *bytes += header["low_lod"]["size"].asInteger();
- *bytes += header["medium_lod"]["size"].asInteger();
- *bytes += header["high_lod"]["size"].asInteger();
+ *bytes += header.mLodSize[0];
+ *bytes += header.mLodSize[1];
+ *bytes += header.mLodSize[2];
+ *bytes += header.mLodSize[3];
}
if (bytes_visible)
@@ -4497,7 +4502,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
lod = LLMeshRepository::getActualMeshLOD(header, lod);
if (lod >= 0 && lod <= 3)
{
- *bytes_visible = header[header_lod[lod]]["size"].asInteger();
+ *bytes_visible = header.mLodSize[lod];
}
}
@@ -4539,33 +4544,29 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
LLMeshCostData::LLMeshCostData()
{
- mSizeByLOD.resize(4);
- mEstTrisByLOD.resize(4);
-
std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);
std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);
}
-bool LLMeshCostData::init(const LLSD& header)
+bool LLMeshCostData::init(const LLMeshHeader& header)
{
- mSizeByLOD.resize(4);
- mEstTrisByLOD.resize(4);
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);
std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);
- S32 bytes_high = header["high_lod"]["size"].asInteger();
- S32 bytes_med = header["medium_lod"]["size"].asInteger();
+ S32 bytes_high = header.mLodSize[3];
+ S32 bytes_med = header.mLodSize[2];
if (bytes_med == 0)
{
bytes_med = bytes_high;
}
- S32 bytes_low = header["low_lod"]["size"].asInteger();
+ S32 bytes_low = header.mLodSize[1];
if (bytes_low == 0)
{
bytes_low = bytes_med;
}
- S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
+ S32 bytes_lowest = header.mLodSize[0];
if (bytes_lowest == 0)
{
bytes_lowest = bytes_low;
@@ -4700,6 +4701,7 @@ F32 LLMeshCostData::getTriangleBasedStreamingCost()
bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
data = LLMeshCostData();
if (mThread && mesh_id.notNull())
@@ -4708,11 +4710,11 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- LLSD& header = iter->second.second;
+ LLMeshHeader& header = iter->second.second;
- bool header_invalid = (header.has("404")
- || !header.has("lowest_lod")
- || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION));
+ bool header_invalid = (header.m404
+ || header.mLodSize[0] <= 0
+ || header.mVersion > MAX_MESH_VERSION);
if (!header_invalid)
{
return getCostData(header, data);
@@ -4724,7 +4726,7 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
return false;
}
-bool LLMeshRepository::getCostData(LLSD& header, LLMeshCostData& data)
+bool LLMeshRepository::getCostData(LLMeshHeader& header, LLMeshCostData& data)
{
data = LLMeshCostData();
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 6922367ff7..619e076fa6 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -194,6 +194,63 @@ private:
LLFrameTimer mTimer;
};
+class LLMeshHeader
+{
+public:
+
+ LLMeshHeader() {}
+
+ explicit LLMeshHeader(const LLSD& header)
+ {
+ fromLLSD(header);
+ }
+
+ void fromLLSD(const LLSD& header)
+ {
+ const char* lod[] =
+ {
+ "lowest_lod",
+ "low_lod",
+ "medium_lod",
+ "high_lod"
+ };
+
+ mVersion = header["version"].asInteger();
+
+ for (U32 i = 0; i < 4; ++i)
+ {
+ mLodOffset[i] = header[lod[i]]["offset"].asInteger();
+ mLodSize[i] = header[lod[i]]["size"].asInteger();
+ }
+
+ mSkinOffset = header["skin"]["offset"].asInteger();
+ mSkinSize = header["skin"]["size"].asInteger();
+
+ mPhysicsConvexOffset = header["physics_convex"]["offset"].asInteger();
+ mPhysicsConvexSize = header["physics_convex"]["size"].asInteger();
+
+ mPhysicsMeshOffset = header["physics_mesh"]["offset"].asInteger();
+ mPhysicsMeshSize = header["physics_mesh"]["size"].asInteger();
+
+ m404 = header.has("404");
+ }
+
+ S32 mVersion = -1;
+ S32 mSkinOffset = -1;
+ S32 mSkinSize = -1;
+
+ S32 mPhysicsConvexOffset = -1;
+ S32 mPhysicsConvexSize = -1;
+
+ S32 mPhysicsMeshOffset = -1;
+ S32 mPhysicsMeshSize = -1;
+
+ S32 mLodOffset[4] = { -1 };
+ S32 mLodSize[4] = { -1 };
+
+ bool m404 = false;
+};
+
class LLMeshRepoThread : public LLThread
{
public:
@@ -210,7 +267,7 @@ public:
LLCondition* mSignal;
//map of known mesh headers
- typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data
+ typedef boost::unordered_map<LLUUID, std::pair<U32, LLMeshHeader>> mesh_header_map; // pair is header_size and data
mesh_header_map mMeshHeader;
class HeaderRequest : public RequestStats
@@ -497,7 +554,7 @@ class LLMeshCostData
public:
LLMeshCostData();
- bool init(const LLSD& header);
+ bool init(const LLMeshHeader& header);
// Size for given LOD
S32 getSizeByLOD(S32 lod);
@@ -532,10 +589,10 @@ public:
private:
// From the "size" field of the mesh header. LOD 0=lowest, 3=highest.
- std::vector<S32> mSizeByLOD;
+ std::array<S32,4> mSizeByLOD;
// Estimated triangle counts derived from the LOD sizes. LOD 0=lowest, 3=highest.
- std::vector<F32> mEstTrisByLOD;
+ std::array<F32,4> mEstTrisByLOD;
};
class LLMeshRepository
@@ -566,9 +623,9 @@ public:
F32 getEstTrianglesMax(LLUUID mesh_id);
F32 getEstTrianglesStreamingCost(LLUUID mesh_id);
F32 getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
- static F32 getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
+ static F32 getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
bool getCostData(LLUUID mesh_id, LLMeshCostData& data);
- bool getCostData(LLSD& header, LLMeshCostData& data);
+ bool getCostData(LLMeshHeader& header, LLMeshCostData& data);
LLMeshRepository();
@@ -588,7 +645,7 @@ public:
void notifyDecompositionReceived(LLModel::Decomposition* info);
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
- static S32 getActualMeshLOD(LLSD& header, S32 lod);
+ static S32 getActualMeshLOD(LLMeshHeader& header, S32 lod);
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr);
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index c63aae2089..b680d8761b 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -199,18 +199,7 @@ namespace LLPerfStats
// LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL;
}
}
-// Allow attachment times etc to update even when FPS limited or sleeping.
- auto& statsMap = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)];
- for(auto& stat_entry : statsMap)
- {
- auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)];
- if(val > SMOOTHING_PERIODS){
- auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)];
- stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
- }
- }
-
-
+
auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)];
for(auto& stat_entry : statsMapAv)
{
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index dbb88a141d..a4768272b9 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -69,8 +69,6 @@ namespace LLPerfStats
enum class ObjType_t{
OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery
OT_AVATAR,
- OT_ATTACHMENT,
- OT_HUD,
OT_COUNT
};
enum class StatType_t{
@@ -260,31 +258,6 @@ namespace LLPerfStats
doUpd(avKey, ot, type, val);
return;
}
-
- if (ot == ObjType_t::OT_ATTACHMENT)
- {
- if( !upd.isHUD ) // don't include HUD cost in self.
- {
- LL_PROFILE_ZONE_NAMED("Att as Av")
- // For all attachments that are not rigged we add them to the avatar (for all avatars) cost.
- doUpd(avKey, ObjType_t::OT_AVATAR, type, val);
- }
- if( avKey == focusAv )
- {
- LL_PROFILE_ZONE_NAMED("Att as Att")
- // For attachments that are for the focusAv (self for now) we record them for the attachment/complexity view
- if(upd.isHUD)
- {
- ot = ObjType_t::OT_HUD;
- }
- // LL_INFOS("perfstats") << "frame: " << gFrameCount << " Attachment update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << LL_ENDL;
- doUpd(key, ot, type, val);
- }
- // else
- // {
- // // LL_INFOS("perfstats") << "frame: " << gFrameCount << " non-self Att update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << " for av " << avKey.asString() << LL_ENDL;
- // }
- }
}
static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val)
@@ -409,51 +382,7 @@ namespace LLPerfStats
using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;
- using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>;
- using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>;
-
-};// namespace LLPerfStats
-
-// helper functions
-using RATptr = std::unique_ptr<LLPerfStats::RecordAttachmentTime>;
-using RSTptr = std::unique_ptr<LLPerfStats::RecordSceneTime>;
-template <typename T>
-static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp)
-{
- if( !vobj ){ ratPtrp->reset(); return;};
-
- const T* rootAtt{vobj};
- if (rootAtt->isAttachment())
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
-
- while( !rootAtt->isRootEdit() )
- {
- rootAtt = (T*)(rootAtt->getParent());
- }
-
- auto avPtr = (T*)(rootAtt->getParent());
- if(!avPtr){ratPtrp->reset(); return;}
-
- auto& av = avPtr->getID();
- auto& obj = rootAtt->getAttachmentItemID();
- if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av)
- {
- if (*ratPtrp)
- {
- // deliberately reset to ensure destruction before construction of replacement.
- ratPtrp->reset();
- };
- *ratPtrp = std::make_unique<LLPerfStats::RecordAttachmentTime>(
- av,
- obj,
- ( LLPipeline::sShadowRender?LLPerfStats::StatType_t::RENDER_SHADOWS : LLPerfStats::StatType_t::RENDER_GEOMETRY ),
- isRigged,
- rootAtt->isHUDAttachment());
- }
- }
- return;
-};
+};// namespace LLPerfStats
#endif
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 22c1176b05..71dcc56197 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -2188,8 +2188,8 @@ void LLSelectMgr::selectionRevertGLTFMaterials()
// Enqueue update to server
if (asset_id.notNull())
{
- // Restore overrides
- LLGLTFMaterialList::queueModify(objectp, te, nodep->mSavedGLTFOverrideMaterials[te]);
+ // Restore overrides and base material
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id, nodep->mSavedGLTFOverrideMaterials[te]);
}
else
{
@@ -5797,7 +5797,7 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (can_copy && can_transfer && node->getObject()->getVolume())
{
uuid_vec_t material_ids;
- gltf_materials_vec_t materials;
+ gltf_materials_vec_t override_materials;
LLVOVolume* vobjp = (LLVOVolume*)node->getObject();
for (int i = 0; i < vobjp->getNumTEs(); ++i)
{
@@ -5812,18 +5812,16 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (old_override)
{
LLPointer<LLGLTFMaterial> mat = new LLGLTFMaterial(*old_override);
- materials.push_back(mat);
+ override_materials.push_back(mat);
}
else
{
- materials.push_back(nullptr);
+ override_materials.push_back(nullptr);
}
}
- node->saveGLTFMaterialIds(material_ids);
-
// processObjectProperties does not include overrides so this
// might need to be moved to LLGLTFMaterialOverrideDispatchHandler
- node->saveGLTFOverrideMaterials(materials);
+ node->saveGLTFMaterials(material_ids, override_materials);
}
}
@@ -6576,8 +6574,7 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
}
saveTextures(nodep.mSavedTextures);
- saveGLTFMaterialIds(nodep.mSavedGLTFMaterialIds);
- saveGLTFOverrideMaterials(nodep.mSavedGLTFOverrideMaterials);
+ saveGLTFMaterials(nodep.mSavedGLTFMaterialIds, nodep.mSavedGLTFOverrideMaterials);
}
LLSelectNode::~LLSelectNode()
@@ -6711,28 +6708,21 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
-void LLSelectNode::saveGLTFMaterialIds(const uuid_vec_t& materials)
+void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials)
{
if (mObject.notNull())
{
mSavedGLTFMaterialIds.clear();
+ mSavedGLTFOverrideMaterials.clear();
for (uuid_vec_t::const_iterator materials_it = materials.begin();
materials_it != materials.end(); ++materials_it)
{
mSavedGLTFMaterialIds.push_back(*materials_it);
}
- }
-}
-
-void LLSelectNode::saveGLTFOverrideMaterials(const gltf_materials_vec_t& materials)
-{
- if (mObject.notNull())
- {
- mSavedGLTFOverrideMaterials.clear();
- for (gltf_materials_vec_t::const_iterator mat_it = materials.begin();
- mat_it != materials.end(); ++mat_it)
+ for (gltf_materials_vec_t::const_iterator mat_it = override_materials.begin();
+ mat_it != override_materials.end(); ++mat_it)
{
mSavedGLTFOverrideMaterials.push_back(*mat_it);
}
@@ -7833,7 +7823,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
- cost += iter->second;
+ cost += LLVOVolume::getTextureCost(*iter);
}
textures.clear();
@@ -7855,7 +7845,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
- cost += iter->second;
+ cost += LLVOVolume::getTextureCost(*iter);
}
textures.clear();
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 3ee78f9a58..ca9a32f0db 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -197,8 +197,7 @@ public:
// final gltf material that users see.
// Ids get applied and restored by tools floater,
// overrides get applied in live material editor
- void saveGLTFMaterialIds(const uuid_vec_t& materials);
- void saveGLTFOverrideMaterials(const gltf_materials_vec_t& materials);
+ void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials);
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 1427dbefa1..a7a5a9223c 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -574,11 +574,11 @@ void LLSettingsVOSky::convertAtmosphericsToLegacy(LLSD& legacy, LLSD& settings)
legacy[SETTING_BLUE_DENSITY] = ensure_array_4(legacyhaze[SETTING_BLUE_DENSITY], 1.0);
legacy[SETTING_BLUE_HORIZON] = ensure_array_4(legacyhaze[SETTING_BLUE_HORIZON], 1.0);
- legacy[SETTING_DENSITY_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f);
- legacy[SETTING_DISTANCE_MULTIPLIER] = LLSDArray(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal())(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_DENSITY_MULTIPLIER] = llsd::array(legacyhaze[SETTING_DENSITY_MULTIPLIER].asReal(), 0.0f, 0.0f, 1.0f);
+ legacy[SETTING_DISTANCE_MULTIPLIER] = llsd::array(legacyhaze[SETTING_DISTANCE_MULTIPLIER].asReal(), 0.0f, 0.0f, 1.0f);
- legacy[SETTING_HAZE_DENSITY] = LLSDArray(legacyhaze[SETTING_HAZE_DENSITY])(0.0f)(0.0f)(1.0f);
- legacy[SETTING_HAZE_HORIZON] = LLSDArray(legacyhaze[SETTING_HAZE_HORIZON])(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_HAZE_DENSITY] = llsd::array(legacyhaze[SETTING_HAZE_DENSITY], 0.0f, 0.0f, 1.0f);
+ legacy[SETTING_HAZE_HORIZON] = llsd::array(legacyhaze[SETTING_HAZE_HORIZON], 0.0f, 0.0f, 1.0f);
}
}
@@ -592,15 +592,15 @@ LLSD LLSettingsVOSky::convertToLegacy(const LLSettingsSky::ptr_t &psky, bool isA
legacy[SETTING_CLOUD_COLOR] = ensure_array_4(settings[SETTING_CLOUD_COLOR], 1.0);
legacy[SETTING_CLOUD_POS_DENSITY1] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY1], 1.0);
legacy[SETTING_CLOUD_POS_DENSITY2] = ensure_array_4(settings[SETTING_CLOUD_POS_DENSITY2], 1.0);
- legacy[SETTING_CLOUD_SCALE] = LLSDArray(settings[SETTING_CLOUD_SCALE])(LLSD::Real(0.0))(LLSD::Real(0.0))(LLSD::Real(1.0));
+ legacy[SETTING_CLOUD_SCALE] = llsd::array(settings[SETTING_CLOUD_SCALE], LLSD::Real(0.0), LLSD::Real(0.0), LLSD::Real(1.0));
legacy[SETTING_CLOUD_SCROLL_RATE] = settings[SETTING_CLOUD_SCROLL_RATE];
- legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = LLSDArray(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())))
- (LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));
- legacy[SETTING_CLOUD_SHADOW] = LLSDArray(settings[SETTING_CLOUD_SHADOW].asReal())(0.0f)(0.0f)(1.0f);
- legacy[SETTING_GAMMA] = LLSDArray(settings[SETTING_GAMMA])(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_LEGACY_ENABLE_CLOUD_SCROLL] = llsd::array(LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][0].asReal())),
+ LLSD::Boolean(!is_approx_zero(settings[SETTING_CLOUD_SCROLL_RATE][1].asReal())));
+ legacy[SETTING_CLOUD_SHADOW] = llsd::array(settings[SETTING_CLOUD_SHADOW].asReal(), 0.0f, 0.0f, 1.0f);
+ legacy[SETTING_GAMMA] = llsd::array(settings[SETTING_GAMMA], 0.0f, 0.0f, 1.0f);
legacy[SETTING_GLOW] = ensure_array_4(settings[SETTING_GLOW], 1.0);
legacy[SETTING_LIGHT_NORMAL] = ensure_array_4(psky->getLightDirection().getValue(), 0.0f);
- legacy[SETTING_MAX_Y] = LLSDArray(settings[SETTING_MAX_Y])(0.0f)(0.0f)(1.0f);
+ legacy[SETTING_MAX_Y] = llsd::array(settings[SETTING_MAX_Y], 0.0f, 0.0f, 1.0f);
legacy[SETTING_STAR_BRIGHTNESS] = settings[SETTING_STAR_BRIGHTNESS].asReal() / 250.0f; // convert from 0-500 -> 0-2 ala pre-FS-compat changes
legacy[SETTING_SUNLIGHT_COLOR] = ensure_array_4(settings[SETTING_SUNLIGHT_COLOR], 1.0f);
@@ -1113,7 +1113,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
newsettings[SETTING_NAME] = name;
- LLSD watertrack = LLSDArray(
+ LLSD watertrack = llsd::array(
LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
(SETTING_KEYNAME, "water:Default"));
@@ -1128,7 +1128,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyPreset(const std::string &n
skytrack.append(entry);
}
- newsettings[SETTING_TRACKS] = LLSDArray(watertrack)(skytrack);
+ newsettings[SETTING_TRACKS] = llsd::array(watertrack, skytrack);
LLSD frames(LLSD::emptyMap());
@@ -1216,7 +1216,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regio
watersettings[SETTING_NAME] = watername;
frames[watername] = watersettings;
- LLSD watertrack = LLSDArray(
+ LLSD watertrack = llsd::array(
LLSDMap(SETTING_KEYKFRAME, LLSD::Real(0.0f))
(SETTING_KEYNAME, watername));
@@ -1230,7 +1230,7 @@ LLSettingsDay::ptr_t LLSettingsVODay::buildFromLegacyMessage(const LLUUID &regio
LLSD newsettings = LLSDMap
( SETTING_NAME, "Region (legacy)" )
- ( SETTING_TRACKS, LLSDArray(watertrack)(skytrack))
+ ( SETTING_TRACKS, llsd::array(watertrack, skytrack))
( SETTING_FRAMES, frames )
( SETTING_TYPE, "daycycle" );
@@ -1411,7 +1411,7 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
skys[name.str()] = std::static_pointer_cast<LLSettingsSky>((*it).second);
F32 frame = ((tracksky.size() == 1) && (it == tracksky.begin())) ? -1.0f : (*it).first;
- llsdcycle.append( LLSDArray(LLSD::Real(frame))(name.str()) );
+ llsdcycle.append( llsd::array(LLSD::Real(frame), name.str()) );
}
LLSD llsdskylist(LLSD::emptyMap());
@@ -1424,7 +1424,7 @@ LLSD LLSettingsVODay::convertToLegacy(const LLSettingsVODay::ptr_t &pday)
llsdskylist[(*its).first] = llsdsky;
}
- return LLSDArray(LLSD::emptyMap())(llsdcycle)(llsdskylist)(llsdwater);
+ return llsd::array(LLSD::emptyMap(), llsdcycle, llsdskylist, llsdwater);
}
LLSettingsSkyPtr_t LLSettingsVODay::getDefaultSky() const
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 4d99ee1386..f7df4286fe 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1826,116 +1826,6 @@ void renderUpdateType(LLDrawable* drawablep)
}
}
-void renderComplexityDisplay(LLDrawable* drawablep)
-{
- LLViewerObject* vobj = drawablep->getVObj();
- if (!vobj)
- {
- return;
- }
-
- LLVOVolume *voVol = dynamic_cast<LLVOVolume*>(vobj);
-
- if (!voVol)
- {
- return;
- }
-
- if (!voVol->isRoot())
- {
- return;
- }
-
- LLVOVolume::texture_cost_t textures;
- F32 cost = (F32) voVol->getRenderCost(textures);
-
- // add any child volumes
- LLViewerObject::const_child_list_t children = voVol->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
- {
- const LLViewerObject *child = *iter;
- const LLVOVolume *child_volume = dynamic_cast<const LLVOVolume*>(child);
- if (child_volume)
- {
- cost += child_volume->getRenderCost(textures);
- }
- }
-
- // add texture cost
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
- {
- // add the cost of each individual texture in the linkset
- cost += iter->second;
- }
-
- F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax();
-
-
-
- // allow user to set a static color scale
- if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0)
- {
- cost_max = gSavedSettings.getS32("RenderComplexityStaticMax");
- }
-
- F32 cost_ratio = cost / cost_max;
-
- // cap cost ratio at 1.0f in case cost_max is at a low threshold
- cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio;
-
- LLGLEnable blend(GL_BLEND);
-
- LLColor4 color;
- const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin");
- const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid");
- const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax");
-
- if (cost_ratio < 0.5f)
- {
- color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2);
- }
- else
- {
- color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2);
- }
-
- LLSD color_val = color.getValue();
-
- // don't highlight objects below the threshold
- if (cost > gSavedSettings.getS32("RenderComplexityThreshold"))
- {
- glColor4f(color[0],color[1],color[2],0.5f);
-
-
- S32 num_faces = drawablep->getNumFaces();
- if (num_faces)
- {
- for (S32 i = 0; i < num_faces; ++i)
- {
- pushVerts(drawablep->getFace(i));
- }
- }
- LLViewerObject::const_child_list_t children = voVol->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
- {
- const LLViewerObject *child = *iter;
- if (child)
- {
- num_faces = child->getNumFaces();
- if (num_faces)
- {
- for (S32 i = 0; i < num_faces; ++i)
- {
- pushVerts(child->mDrawable->getFace(i));
- }
- }
- }
- }
- }
-
- voVol->setDebugText(llformat("%4.0f", cost));
-}
-
void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
{
if (set_color)
@@ -3261,10 +3151,6 @@ public:
{
renderUpdateType(drawable);
}
- if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
- {
- renderComplexityDisplay(drawable);
- }
if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
renderTexelDensity(drawable);
@@ -3575,7 +3461,6 @@ void LLSpatialPartition::renderDebug()
LLPipeline::RENDER_DEBUG_AGENT_TARGET |
//LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
- LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
return;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 1b19ba33a3..6633951db3 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -2150,12 +2150,14 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
if (nodep)
{
uuid_vec_t material_ids;
+ gltf_materials_vec_t override_materials;
S32 num_faces = obj->getNumTEs();
for (S32 face = 0; face < num_faces; face++)
{
material_ids.push_back(obj->getRenderMaterialID(face));
+ override_materials.push_back(nullptr);
}
- nodep->saveGLTFMaterialIds(material_ids);
+ nodep->saveGLTFMaterials(material_ids, override_materials);
}
}
else
@@ -2169,6 +2171,7 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
&& nodep->mSavedGLTFMaterialIds.size() > face)
{
nodep->mSavedGLTFMaterialIds[face] = obj->getRenderMaterialID(face);
+ nodep->mSavedGLTFOverrideMaterials[face] = nullptr;
}
}
}
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 00e1179896..5ce8f4023d 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -227,16 +227,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
return 0;
}
- // render time capture
- // This path does not appear to have attachments. Prove this then remove.
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- auto vobj = mFace->getViewerObject();
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
- LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL;
- }
-
U32 triangle_count = 0;
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 2f4274d0d0..77b4804076 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -369,7 +369,7 @@ LLViewerObject::~LLViewerObject()
}
// Delete memory associated with extra parameters.
- std::map<U16, ExtraParameter*>::iterator iter;
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
if(iter->second != NULL)
@@ -1555,7 +1555,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParticleSource(block_num, owner_id);
// Mark all extra parameters not used
- std::map<U16, ExtraParameter*>::iterator iter;
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
iter->second->in_use = FALSE;
@@ -1947,7 +1947,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
// Mark all extra parameters not used
- std::map<U16, ExtraParameter*>::iterator iter;
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
iter->second->in_use = FALSE;
@@ -3965,6 +3965,7 @@ U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const
// prim's scale. Should revisit at some point.
F32 LLViewerObject::recursiveGetScaledSurfaceArea() const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
F32 area = 0.f;
const LLDrawable* drawable = mDrawable;
if (drawable)
@@ -6241,7 +6242,8 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
{
- std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER;
+ std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
if (itor != mExtraParameterList.end())
{
return itor->second;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index fe27227e6b..a18d07d970 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -28,6 +28,7 @@
#define LL_LLVIEWEROBJECT_H
#include <map>
+#include <unordered_map>
#include "llassetstorage.h"
//#include "llhudicon.h"
@@ -122,7 +123,7 @@ protected:
BOOL in_use;
LLNetworkData *data;
};
- std::map<U16, ExtraParameter*> mExtraParameterList;
+ std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t;
@@ -941,6 +942,10 @@ public:
// reflection probe state
bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager
LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed
+
+ // the amount of GPU time (in ms) it took to render this object according to LLPipeline::profileAvatar
+ // -1.f if no profile data available
+ F32 mGPURenderTime = -1.f;
};
///////////////////
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 4babf5a7f6..609e8290da 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -829,12 +829,11 @@ void send_viewer_stats(bool include_preferences)
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
- if (debugLoggingEnabled("LogViewerStatsPacket"))
- {
- std::string filename("viewer_stats_packet.xml");
- llofstream of(filename.c_str());
- LLSDSerialize::toPrettyXML(body,of);
- }
+ LL_DEBUGS("LogViewerStatsPacket");
+ std::string filename("viewer_stats_packet.xml");
+ llofstream of(filename.c_str());
+ LLSDSerialize::toPrettyXML(body,of);
+ LL_ENDL;
// The session ID token must never appear in logs
body["session_id"] = gAgentSessionID;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 5b8f4767db..95e9321d6f 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1448,7 +1448,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
continue;
}
}
- if (vol && vol->isRiggedMesh())
+ if (vol && vol->isRiggedMeshFast())
{
continue;
}
@@ -2697,6 +2697,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)
{
+ // DEPRECATED
+ // replace with LLPipeline::profileAvatar?
+ // Avatar profile takes ~ 0.5ms while idleUpdateRenderComplexity takes ~5ms
+ // (both are unacceptably costly)
idleUpdateRenderComplexity();
}
idleUpdateDebugInfo();
@@ -8357,7 +8361,7 @@ void LLVOAvatar::updateTooSlow()
{
// use the cached values.
render_time_raw = mRenderTime;
- render_geom_time_raw = mGeomTime;
+ render_geom_time_raw = mGeomTime;
}
bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
@@ -10830,6 +10834,7 @@ void LLVOAvatar::updateVisualComplexity()
mVisualComplexityStale = true;
}
+
// Account for the complexity of a single top-level object associated
// with an avatar. This will be either an attached object or an animated
// object.
@@ -10841,144 +10846,146 @@ void LLVOAvatar::accountRenderComplexityForObject(
hud_complexity_list_t& hud_complexity_list,
object_complexity_list_t& object_complexity_list)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (attached_object && !attached_object->isHUDAttachment())
- {
+ {
mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount();
mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
- textures.clear();
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
- {
- const LLVOVolume* volume = drawable->getVOVolume();
- if (volume)
- {
- F32 attachment_total_cost = 0;
- F32 attachment_volume_cost = 0;
- F32 attachment_texture_cost = 0;
- F32 attachment_children_cost = 0;
+ textures.clear();
+ const LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable)
+ {
+ const LLVOVolume* volume = drawable->getVOVolume();
+ if (volume)
+ {
+ F32 attachment_total_cost = 0;
+ F32 attachment_volume_cost = 0;
+ F32 attachment_texture_cost = 0;
+ F32 attachment_children_cost = 0;
const F32 animated_object_attachment_surcharge = 1000;
- if (attached_object->isAnimatedObject())
+ if (volume->isAnimatedObjectFast())
{
attachment_volume_cost += animated_object_attachment_surcharge;
}
- attachment_volume_cost += volume->getRenderCost(textures);
+ attachment_volume_cost += volume->getRenderCost(textures);
- const_child_list_t children = volume->getChildren();
- for (const_child_list_t::const_iterator child_iter = children.begin();
- child_iter != children.end();
- ++child_iter)
- {
- LLViewerObject* child_obj = *child_iter;
- LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
- if (child)
- {
- attachment_children_cost += child->getRenderCost(textures);
- }
- }
+ const_child_list_t children = volume->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
+ {
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume* child = dynamic_cast<LLVOVolume*>(child_obj);
+ if (child)
+ {
+ attachment_children_cost += child->getRenderCost(textures);
+ }
+ }
- for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
- volume_texture != textures.end();
- ++volume_texture)
- {
- // add the cost of each individual texture in the linkset
- attachment_texture_cost += volume_texture->second;
- }
- attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
- LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
- << " total: " << attachment_total_cost
- << ", volume: " << attachment_volume_cost
- << ", " << textures.size()
- << " textures: " << attachment_texture_cost
- << ", " << volume->numChildren()
- << " children: " << attachment_children_cost
- << LL_ENDL;
- // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
- cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
-
- if (isSelf())
- {
- LLObjectComplexity object_complexity;
- object_complexity.objectName = attached_object->getAttachmentItemName();
- object_complexity.objectId = attached_object->getAttachmentItemID();
- object_complexity.objectCost = attachment_total_cost;
- object_complexity_list.push_back(object_complexity);
- }
- }
- }
- }
- if (isSelf()
- && attached_object
- && attached_object->isHUDAttachment()
- && !attached_object->isTempAttachment()
- && attached_object->mDrawable)
+ for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
+ volume_texture != textures.end();
+ ++volume_texture)
{
- textures.clear();
- BOOL is_rigged_mesh = attached_object->isRiggedMesh();
+ // add the cost of each individual texture in the linkset
+ attachment_texture_cost += LLVOVolume::getTextureCost(*volume_texture);
+ }
+ attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
+ LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
+ << " total: " << attachment_total_cost
+ << ", volume: " << attachment_volume_cost
+ << ", " << textures.size()
+ << " textures: " << attachment_texture_cost
+ << ", " << volume->numChildren()
+ << " children: " << attachment_children_cost
+ << LL_ENDL;
+ // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
+ cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
+
+ if (isSelf())
+ {
+ LLObjectComplexity object_complexity;
+ object_complexity.objectName = attached_object->getAttachmentItemName();
+ object_complexity.objectId = attached_object->getAttachmentItemID();
+ object_complexity.objectCost = attachment_total_cost;
+ object_complexity_list.push_back(object_complexity);
+ }
+ }
+ }
+ }
+ if (isSelf()
+ && attached_object
+ && attached_object->isHUDAttachment()
+ && !attached_object->isTempAttachment()
+ && attached_object->mDrawable)
+ {
+ textures.clear();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
- const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
- if (volume)
- {
- LLHUDComplexity hud_object_complexity;
- hud_object_complexity.objectName = attached_object->getAttachmentItemName();
- hud_object_complexity.objectId = attached_object->getAttachmentItemID();
- std::string joint_name;
- gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
- hud_object_complexity.jointName = joint_name;
- // get cost and individual textures
- hud_object_complexity.objectsCost += volume->getRenderCost(textures);
- hud_object_complexity.objectsCount++;
-
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* childp = *iter;
- is_rigged_mesh |= childp->isRiggedMesh();
- const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
- if (chld_volume)
- {
- // get cost and individual textures
- hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
- hud_object_complexity.objectsCount++;
- }
- }
- if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
- {
- LLSD args;
- LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
- args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
- args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
- LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
+ const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
+ if (volume)
+ {
+ BOOL is_rigged_mesh = volume->isRiggedMeshFast();
+ LLHUDComplexity hud_object_complexity;
+ hud_object_complexity.objectName = attached_object->getAttachmentItemName();
+ hud_object_complexity.objectId = attached_object->getAttachmentItemID();
+ std::string joint_name;
+ gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
+ hud_object_complexity.jointName = joint_name;
+ // get cost and individual textures
+ hud_object_complexity.objectsCost += volume->getRenderCost(textures);
+ hud_object_complexity.objectsCount++;
+
+ LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* childp = *iter;
+ const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
+ if (chld_volume)
+ {
+ is_rigged_mesh = is_rigged_mesh || chld_volume->isRiggedMeshFast();
+ // get cost and individual textures
+ hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
+ hud_object_complexity.objectsCount++;
+ }
+ }
+ if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
+ {
+ LLSD args;
+ LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
+ args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
+ args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
+ LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
- attached_object->mRiggedAttachedWarned = true;
- }
+ attached_object->mRiggedAttachedWarned = true;
+ }
- hud_object_complexity.texturesCount += textures.size();
+ hud_object_complexity.texturesCount += textures.size();
- for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
- volume_texture != textures.end();
- ++volume_texture)
- {
- // add the cost of each individual texture (ignores duplicates)
- hud_object_complexity.texturesCost += volume_texture->second;
- LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
- if (tex)
- {
- // Note: Texture memory might be incorect since texture might be still loading.
- hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
- if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
- {
- hud_object_complexity.largeTexturesCount++;
- }
- }
- }
- hud_complexity_list.push_back(hud_object_complexity);
+ for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
+ volume_texture != textures.end();
+ ++volume_texture)
+ {
+ // add the cost of each individual texture (ignores duplicates)
+ hud_object_complexity.texturesCost += LLVOVolume::getTextureCost(*volume_texture);
+ const LLViewerTexture* img = *volume_texture;
+ if (img->getType() == LLViewerTexture::FETCHED_TEXTURE)
+ {
+ LLViewerFetchedTexture* tex = (LLViewerFetchedTexture*)img;
+ // Note: Texture memory might be incorect since texture might be still loading.
+ hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
+ if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
+ {
+ hud_object_complexity.largeTexturesCount++;
}
}
+ }
+ hud_complexity_list.push_back(hud_object_complexity);
+ }
+ }
}
// Calculations for mVisualComplexity value
@@ -10990,16 +10997,18 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
* everyone. If you have suggested improvements, submit them to
* the official viewer for consideration.
*****************************************************************/
- static const U32 COMPLEXITY_BODY_PART_COST = 200;
- static LLCachedControl<F32> max_complexity_setting(gSavedSettings,"MaxAttachmentComplexity");
- F32 max_attachment_complexity = max_complexity_setting;
- max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
-
- // Diagnostic list of all textures on our avatar
- static std::set<LLUUID> all_textures;
-
if (mVisualComplexityStale)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ static const U32 COMPLEXITY_BODY_PART_COST = 200;
+ static LLCachedControl<F32> max_complexity_setting(gSavedSettings, "MaxAttachmentComplexity");
+ F32 max_attachment_complexity = max_complexity_setting;
+ max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
+
+ // Diagnostic list of all textures on our avatar
+ static std::unordered_set<const LLViewerTexture*> all_textures;
+
U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
LLVOVolume::texture_cost_t textures;
hud_complexity_list_t hud_complexity_list;
@@ -11067,44 +11076,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
}
- // Diagnostic output to identify all avatar-related textures.
- // Does not affect rendering cost calculation.
- if (isSelf() && debugLoggingEnabled("ARCdetail"))
- {
- // print any attachment textures we didn't already know about.
- for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
- {
- LLUUID image_id = it->first;
- if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- && (all_textures.find(image_id) == all_textures.end()))
- {
- // attachment texture not previously seen.
- LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL;
- all_textures.insert(image_id);
- }
- }
-
- // print any avatar textures we didn't already know about
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
- iter != LLAvatarAppearance::getDictionary()->getTextures().end();
- ++iter)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- // TODO: MULTI-WEARABLE: handle multiple textures for self
- const LLViewerTexture* te_image = getImage(iter->first,0);
- if (!te_image)
- continue;
- LLUUID image_id = te_image->getID();
- if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- continue;
- if (all_textures.find(image_id) == all_textures.end())
- {
- LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL;
- all_textures.insert(image_id);
- }
- }
- }
-
if ( cost != mVisualComplexity )
{
LL_DEBUGS("AvatarRender") << "Avatar "<< getID()
@@ -11466,3 +11437,43 @@ BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type,
// non-self avatars don't have wearables
return FALSE;
}
+
+void LLVOAvatar::placeProfileQuery()
+{
+ if (mGPUTimerQuery == 0)
+ {
+ glGenQueries(1, &mGPUTimerQuery);
+ }
+
+ glBeginQuery(GL_TIME_ELAPSED, mGPUTimerQuery);
+}
+
+void LLVOAvatar::readProfileQuery(S32 retries)
+{
+ if (!mGPUProfilePending)
+ {
+ glEndQuery(GL_TIME_ELAPSED);
+ mGPUProfilePending = true;
+ }
+
+ GLuint64 result = 0;
+ glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result);
+
+ if (result == GL_TRUE || --retries <= 0)
+ { // query available, readback result
+ GLuint64 time_elapsed = 0;
+ glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+ mGPURenderTime = time_elapsed / 1000000.f;
+ mGPUProfilePending = false;
+ }
+ else
+ { // wait until next frame
+ LLUUID id = getID();
+
+ LL::WorkQueue::getInstance("mainloop")->post([id, retries] {
+ LLVOAvatar* avatar = (LLVOAvatar*) gObjectList.findObject(id);
+ avatar->readProfileQuery(retries);
+ });
+ }
+}
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 1502c25b4d..2ca44b041a 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -305,8 +305,23 @@ public:
static const U32 VISUAL_COMPLEXITY_UNKNOWN;
void updateVisualComplexity();
- U32 getVisualComplexity() { return mVisualComplexity; }; // Numbers calculated here by rendering AV
- F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; }; // estimated surface area of attachments
+ void placeProfileQuery();
+ void readProfileQuery(S32 retries);
+
+ // get the GPU time in ms of rendering this avatar including all attachments
+ // returns -1 if this avatar has not been profiled using gPipeline.profileAvatar
+ F32 getGPURenderTime() { return mGPURenderTime; }
+
+ // get the CPU time in ms of rendering this avatar including all attachments
+ // return -1 if this avatar has not been profiled using gPipeline.mProfileAvatar
+ F32 getCPURenderTime() { return mCPURenderTime; }
+
+
+ // avatar render cost
+ U32 getVisualComplexity() { return mVisualComplexity; };
+
+ // surface area calculation
+ F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; };
U32 getReportedVisualComplexity() { return mReportedVisualComplexity; }; // Numbers as reported by the SL server
void setReportedVisualComplexity(U32 value) { mReportedVisualComplexity = value; };
@@ -523,6 +538,7 @@ public:
S32 mSpecialRenderMode; // special lighting
private:
+ friend class LLPipeline;
AvatarOverallAppearance mOverallAppearance;
F32 mAttachmentSurfaceArea; //estimated surface area of attachments
U32 mAttachmentVisibleTriangleCount;
@@ -535,7 +551,20 @@ private:
S32 mUpdatePeriod;
S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer.
+ // profile handle
+ U32 mGPUTimerQuery = 0;
+
+ // profile results
+
+ // GPU render time in ms
+ F32 mGPURenderTime = -1.f;
+ bool mGPUProfilePending = false;
+
+ // CPU render time in ms
+ F32 mCPURenderTime = -1.f;
+
// the isTooComplex method uses these mutable values to avoid recalculating too frequently
+ // DEPRECATED -- obsolete avatar render cost values
mutable U32 mVisualComplexity;
mutable bool mVisualComplexityStale;
U32 mReportedVisualComplexity; // from other viewers through the simulator
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index d8b82d3114..82dfb1ca2a 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1155,6 +1155,7 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (!gInventory.getItem(inv_item_id))
{
name = "ATTACHMENT_MISSING_ITEM";
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 12ceb86e52..aa60578cee 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -88,7 +88,6 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
-#include "llperfstats.h"
#include "llgltfmateriallist.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@@ -1604,7 +1603,9 @@ BOOL LLVOVolume::updateLOD()
{
return FALSE;
}
-
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
BOOL lod_changed = FALSE;
if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))
@@ -1618,16 +1619,6 @@ BOOL LLVOVolume::updateLOD()
if (lod_changed)
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- if (isAnimatedObject() && isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", this);
- F32 est_tris = getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " updateLOD to " << getLOD() << ", tris " << est_tris << LL_ENDL;
- }
- }
-
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
mLODChanged = TRUE;
}
@@ -3199,7 +3190,13 @@ void LLVOVolume::setLightCutoff(F32 cutoff)
BOOL LLVOVolume::getIsLight() const
{
- return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
+ mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
+ return mIsLight;
+}
+
+bool LLVOVolume::getIsLightFast() const
+{
+ return mIsLight;
}
LLColor3 LLVOVolume::getLightSRGBBaseColor() const
@@ -3585,6 +3582,31 @@ BOOL LLVOVolume::hasLightTexture() const
return FALSE;
}
+bool LLVOVolume::isFlexibleFast() const
+{
+ return mVolumep && mVolumep->getParams().getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE;
+}
+
+bool LLVOVolume::isSculptedFast() const
+{
+ return mVolumep && mVolumep->getParams().isSculpt();
+}
+
+bool LLVOVolume::isMeshFast() const
+{
+ return mVolumep && mVolumep->getParams().isMeshSculpt();
+}
+
+bool LLVOVolume::isRiggedMeshFast() const
+{
+ return mSkinInfo.notNull();
+}
+
+bool LLVOVolume::isAnimatedObjectFast() const
+{
+ return mIsAnimatedObject;
+}
+
BOOL LLVOVolume::isVolumeGlobal() const
{
if (mVolumeImpl)
@@ -3745,8 +3767,8 @@ bool LLVOVolume::canBeAnimatedObject() const
bool LLVOVolume::isAnimatedObject() const
{
LLVOVolume *root_vol = (LLVOVolume*)getRootEdit();
- bool root_is_animated_flag = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
- return root_is_animated_flag;
+ mIsAnimatedObject = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
+ return mIsAnimatedObject;
}
// Called any time parenting changes for a volume. Update flags and
@@ -3933,12 +3955,41 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
return mDrawable->getWorldMatrix();
}
+//static
+S32 LLVOVolume::getTextureCost(const LLViewerTexture* img)
+{
+ static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
+
+ S32 texture_cost = 0;
+ S8 type = img->getType();
+ if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ {
+ const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
+ if (fetched_texturep
+ && fetched_texturep->getFTType() == FTT_LOCAL_FILE
+ && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
+ )
+ {
+ // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
+ // Hardcode cost from larger one to not cause random complexity changes
+ texture_cost = 320;
+ }
+ }
+ if (texture_cost == 0)
+ {
+ texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ }
+
+ return texture_cost;
+}
+
// Returns a base cost and adds textures to passed in set.
// total cost is returned value + 5 * size of the resulting set.
// Cannot include cost of textures, as they may be re-used in linked
// children, and cost should only be increased for unique textures -Nyx
U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
/*****************************************************************
* This calculation should not be modified by third party viewers,
* since it is used to limit rendering and should be uniform for
@@ -3948,17 +3999,16 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
// Get access to params we'll need at various points.
// Skip if this is object doesn't have a volume (e.g. is an avatar).
- BOOL has_volume = (getVolume() != NULL);
- LLVolumeParams volume_params;
- LLPathParams path_params;
- LLProfileParams profile_params;
+ if (getVolume() == NULL)
+ {
+ return 0;
+ }
U32 num_triangles = 0;
// per-prim costs
static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
static const U32 ARC_PARTICLE_MAX = 2048; // default values
- static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
@@ -3993,45 +4043,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
const LLDrawable* drawablep = mDrawable;
U32 num_faces = drawablep->getNumFaces();
- if (has_volume)
- {
- volume_params = getVolume()->getParams();
- path_params = volume_params.getPathParams();
- profile_params = volume_params.getProfileParams();
+ const LLVolumeParams& volume_params = getVolume()->getParams();
- LLMeshCostData costs;
- if (getCostData(costs))
- {
- if (isAnimatedObject() && isRiggedMesh())
- {
- // Scaling here is to make animated object vs
- // non-animated object ARC proportional to the
- // corresponding calculations for streaming cost.
- num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06;
- }
- else
- {
- F32 radius = getScale().length()*0.5f;
- num_triangles = costs.getRadiusWeightedTris(radius);
- }
- }
+ LLMeshCostData costs;
+ if (getCostData(costs))
+ {
+ if (isAnimatedObjectFast() && isRiggedMeshFast())
+ {
+ // Scaling here is to make animated object vs
+ // non-animated object ARC proportional to the
+ // corresponding calculations for streaming cost.
+ num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06;
+ }
+ else
+ {
+ F32 radius = getScale().length()*0.5f;
+ num_triangles = costs.getRadiusWeightedTris(radius);
+ }
}
+
if (num_triangles <= 0)
{
num_triangles = 4;
}
- if (isSculpted())
+ if (isSculptedFast())
{
- if (isMesh())
+ if (isMeshFast())
{
// base cost is dependent on mesh complexity
// note that 3 is the highest LOD as of the time of this coding.
S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD());
if ( size > 0)
{
- if (isRiggedMesh())
+ if (isRiggedMeshFast())
{
// weighted attachment - 1 point for every 3 bytes
weighted_mesh = 1;
@@ -4045,21 +4091,15 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
}
else
{
- const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID sculpt_id = sculpt_params->getSculptTexture();
- if (textures.find(sculpt_id) == textures.end())
+ LLViewerFetchedTexture* texture = mSculptTexture;
+ if (texture && textures.find(texture) == textures.end())
{
- LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id);
- if (texture)
- {
- S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f));
- textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost));
- }
+ textures.insert(texture);
}
}
}
- if (isFlexible())
+ if (isFlexibleFast())
{
flexi = 1;
}
@@ -4068,85 +4108,66 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
particles = 1;
}
- if (getIsLight())
+ if (getIsLightFast())
{
produces_light = 1;
}
- for (S32 i = 0; i < num_faces; ++i)
- {
- const LLFace* face = drawablep->getFace(i);
- if (!face) continue;
- const LLTextureEntry* te = face->getTextureEntry();
- const LLViewerTexture* img = face->getTexture();
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list");
+ for (S32 i = 0; i < num_faces; ++i)
+ {
+ const LLFace* face = drawablep->getFace(i);
+ if (!face) continue;
+ const LLTextureEntry* te = face->getTextureEntry();
+ const LLViewerTexture* img = face->getTexture();
- if (img)
- {
- if (textures.find(img->getID()) == textures.end())
- {
- S32 texture_cost = 0;
- S8 type = img->getType();
- if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ if (img)
+ {
+ textures.insert(img);
+ }
+
+ if (face->isInAlphaPool())
+ {
+ alpha = 1;
+ }
+ else if (img && img->getPrimaryFormat() == GL_ALPHA)
+ {
+ invisi = 1;
+ }
+ if (face->hasMedia())
+ {
+ media_faces++;
+ }
+
+ if (te)
+ {
+ if (te->getBumpmap())
{
- const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
- if (fetched_texturep
- && fetched_texturep->getFTType() == FTT_LOCAL_FILE
- && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
- )
- {
- // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
- // Hardcode cost from larger one to not cause random complexity changes
- texture_cost = 320;
- }
+ // bump is a multiplier, don't add per-face
+ bump = 1;
}
- if (texture_cost == 0)
+ if (te->getShiny())
{
- texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ // shiny is a multiplier, don't add per-face
+ shiny = 1;
}
- textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
- }
- }
-
- if (face->isInAlphaPool())
- {
- alpha = 1;
- }
- else if (img && img->getPrimaryFormat() == GL_ALPHA)
- {
- invisi = 1;
- }
- if (face->hasMedia())
- {
- media_faces++;
- }
-
- if (te)
- {
- if (te->getBumpmap())
- {
- // bump is a multiplier, don't add per-face
- bump = 1;
- }
- if (te->getShiny())
- {
- // shiny is a multiplier, don't add per-face
- shiny = 1;
- }
- if (te->getGlow() > 0.f)
- {
- // glow is a multiplier, don't add per-face
- glow = 1;
- }
- if (face->mTextureMatrix != NULL)
- {
- animtex = 1;
- }
- if (te->getTexGen())
- {
- planar = 1;
- }
- }
- }
+ if (te->getGlow() > 0.f)
+ {
+ // glow is a multiplier, don't add per-face
+ glow = 1;
+ }
+ if (face->mTextureMatrix != NULL)
+ {
+ animtex = 1;
+ }
+ if (te->getTexGen())
+ {
+ planar = 1;
+ }
+ }
+ }
+ }
// shame currently has the "base" cost of 1 point per 15 triangles, min 2.
shame = num_triangles * 5.f;
@@ -4225,7 +4246,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
// Streaming cost for animated objects includes a fixed cost
// per linkset. Add a corresponding charge here translated into
// triangles, but not weighted by any graphics properties.
- if (isAnimatedObject() && isRootEdit())
+ if (isAnimatedObjectFast() && isRootEdit())
{
shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f;
}
@@ -4240,7 +4261,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
F32 LLVOVolume::getEstTrianglesMax() const
{
- if (isMesh() && getVolume())
+ if (isMeshFast() && getVolume())
{
return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID());
}
@@ -4249,7 +4270,7 @@ F32 LLVOVolume::getEstTrianglesMax() const
F32 LLVOVolume::getEstTrianglesStreamingCost() const
{
- if (isMesh() && getVolume())
+ if (isMeshFast() && getVolume())
{
return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID());
}
@@ -4264,7 +4285,7 @@ F32 LLVOVolume::getStreamingCost() const
LLMeshCostData costs;
if (getCostData(costs))
{
- if (isAnimatedObject() && isRootEdit())
+ if (isRootEdit() && isAnimatedObject())
{
// Root object of an animated object has this to account for skeleton overhead.
linkset_base_cost = ANIMATED_OBJECT_BASE_COST;
@@ -4294,7 +4315,9 @@ F32 LLVOVolume::getStreamingCost() const
// virtual
bool LLVOVolume::getCostData(LLMeshCostData& costs) const
{
- if (isMesh())
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ if (isMeshFast())
{
return gMeshRepo.getCostData(getVolume()->getParams().getSculptID(), costs);
}
@@ -4304,11 +4327,11 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const
S32 counts[4];
LLVolume::getLoDTriangleCounts(volume->getParams(), counts);
- LLSD header;
- header["lowest_lod"]["size"] = counts[0] * 10;
- header["low_lod"]["size"] = counts[1] * 10;
- header["medium_lod"]["size"] = counts[2] * 10;
- header["high_lod"]["size"] = counts[3] * 10;
+ LLMeshHeader header;
+ header.mLodSize[0] = counts[0] * 10;
+ header.mLodSize[1] = counts[1] * 10;
+ header.mLodSize[2] = counts[2] * 10;
+ header.mLodSize[3] = counts[3] * 10;
return gMeshRepo.getCostData(header, costs);
}
@@ -4533,16 +4556,6 @@ const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const
void LLVOVolume::markForUpdate(BOOL priority)
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- if (isAnimatedObject() && isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", this);
- F32 est_tris = getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markForUpdate, tris " << est_tris << LL_ENDL;
- }
- }
-
if (mDrawable)
{
shrinkWrap();
@@ -5657,7 +5670,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");
//get all the faces into a list
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
drawable_iter != group->getDataEnd(); ++drawable_iter)
{
@@ -5693,11 +5705,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
- if(vobj->isAttachment())
- {
- trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr);
- }
-
LLVolume* volume = vobj->getVolume();
if (volume)
{
@@ -6095,8 +6102,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
U32 buffer_count = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
@@ -6106,20 +6112,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if (!vobj) continue;
- if (vobj->isAttachment())
- {
- trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr );
- }
-
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- if (vobj->isAnimatedObject() && vobj->isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", vobj);
- F32 est_tris = vobj->getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL;
- }
- }
if (vobj->isNoLOD()) continue;
vobj->preRebuild();
@@ -6479,16 +6471,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 indices_index = 0;
U16 index_offset = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr;
while (face_iter < i)
{
//update face indices for new buffer
facep = *face_iter;
- LLViewerObject* vobj = facep->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
- }
+
if (buffer.isNull())
{
// Bulk allocation failed
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 9cfd90a940..d509a7e2ab 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -34,8 +34,8 @@
#include "lllocalbitmaps.h"
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
-#include <map>
-#include <set>
+#include <unordered_map>
+#include <unordered_set>
class LLViewerTextureAnim;
@@ -146,7 +146,8 @@ public:
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
/*virtual*/ const LLMatrix4 getRenderMatrix() const override;
- typedef std::map<LLUUID, S32> texture_cost_t;
+ typedef std::unordered_set<const LLViewerTexture*> texture_cost_t;
+ static S32 getTextureCost(const LLViewerTexture* img);
U32 getRenderCost(texture_cost_t &textures) const;
/*virtual*/ F32 getEstTrianglesMax() const override;
/*virtual*/ F32 getEstTrianglesStreamingCost() const override;
@@ -267,6 +268,7 @@ public:
void setSpotLightParams(LLVector3 params);
BOOL getIsLight() const;
+ bool getIsLightFast() const;
// Get the light color in sRGB color space NOT scaled by intensity.
@@ -315,7 +317,15 @@ public:
virtual BOOL isRiggedMesh() const override;
virtual BOOL hasLightTexture() const override;
-
+ // fast variants above that use state that is filled in later
+ // not reliable early in the life of an object, but should be used after
+ // object is loaded
+ bool isFlexibleFast() const;
+ bool isSculptedFast() const;
+ bool isMeshFast() const;
+ bool isRiggedMeshFast() const;
+ bool isAnimatedObjectFast() const;
+
BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible);
@@ -461,6 +471,13 @@ private:
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
+ // cached value of getIsLight to avoid redundant map lookups
+ // accessed by getIsLightFast
+ mutable bool mIsLight = false;
+
+ // cached value of getIsAnimatedObject to avoid redundant map lookups
+ // accessed by getIsAnimatedObjectFast
+ mutable bool mIsAnimatedObject = false;
bool mResetDebugText;
LLPointer<LLRiggedVolume> mRiggedVolume;
@@ -475,7 +492,6 @@ public:
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
-
protected:
static S32 sNumLODChanges;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 72c8cb371f..732ef1da6c 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1424,10 +1424,10 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
}
}
-S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs)
+F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs)
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
- S32 nearby_max_complexity = 0;
+ F32 nearby_max_complexity = 0;
F32 radius = render_far_clip * render_far_clip;
std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
while (char_iter != LLCharacter::sInstances.end())
@@ -1441,8 +1441,8 @@ S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_av
char_iter++;
continue;
}
- avatar->calculateUpdateRenderComplexity();
- nearby_max_complexity = llmax(nearby_max_complexity, (S32)avatar->getVisualComplexity());
+ gPipeline.profileAvatar(avatar);
+ nearby_max_complexity = llmax(nearby_max_complexity, avatar->getGPURenderTime());
valid_nearby_avs.push_back(*char_iter);
}
char_iter++;
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index b2be36d72c..f78cbcaa48 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -172,7 +172,9 @@ public:
// or if the circuit to this simulator had been lost.
bool isRegionListed(const LLViewerRegion* region) const;
- S32 getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs);
+ // profile nearby avatars using gPipeline.profileAvatar and update their render times
+ // return max GPU time
+ F32 getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs);
private:
void clearHoleWaterObjects();
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2912d0da82..4d9a8a594a 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3016,18 +3016,6 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
{
if (drawablep && !drawablep->isDead() && assertInitialized())
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- LLVOVolume *vol_obj = drawablep->getVOVolume();
- if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", vol_obj);
- F32 est_tris = vol_obj->getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markRebuild, tris " << est_tris
- << " priority " << (S32) priority << " flag " << std::hex << flag << LL_ENDL;
- }
- }
-
if (!drawablep->isState(LLDrawable::BUILT))
{
priority = true;
@@ -7697,10 +7685,18 @@ void LLPipeline::bindShadowMaps(LLGLSLShader& shader)
void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
{
- shader.bind();
- bindLightFunc(shader);
- bindShadowMaps(shader);
- bindReflectionProbes(shader);
+ if (shader.mCanBindFast)
+ { // was previously fully bound, use fast path
+ shader.bind();
+ bindLightFunc(shader);
+ bindShadowMaps(shader);
+ bindReflectionProbes(shader);
+ }
+ else
+ { //wasn't previously bound, use slow path
+ bindDeferredShader(shader);
+ shader.mCanBindFast = true;
+ }
}
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
@@ -10068,11 +10064,76 @@ void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture)
}
}
-static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");
+void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments)
+{
+ if (gGLManager.mGLVersion < 3.25f)
+ { // profiling requires GL 3.3 or later
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
+ LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ mRT->deferredScreen.bindTarget();
+ mRT->deferredScreen.clear();
+
+ if (!profile_attachments)
+ {
+ // profile entire avatar all at once and readback asynchronously
+ avatar->placeProfileQuery();
+
+ LLTimer cpu_timer;
+
+ generateImpostor(avatar, false, true);
+
+ avatar->mCPURenderTime = (F32)cpu_timer.getElapsedTimeF32() * 1000.f;
+
+ avatar->readProfileQuery(5); // allow up to 5 frames of latency
+ }
+ else
+ {
+ // profile attachments one at a time
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ for (iter = begin;
+ iter != end;
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ // use gDebugProgram to do the GPU queries
+ gDebugProgram.clearStats();
+ gDebugProgram.placeProfileQuery(true);
+
+ generateImpostor(avatar, false, true, attached_object);
+ gDebugProgram.readProfileQuery(true, true);
-void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
+ attached_object->mGPURenderTime = gDebugProgram.mTimeElapsed / 1000000.f;
+ }
+ }
+ }
+ }
+
+ mRT->deferredScreen.flush();
+
+ if (cur_shader)
+ {
+ cur_shader->bind();
+ }
+}
+
+void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool for_profile, LLViewerObject* specific_attachment)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
LL_PROFILE_GPU_ZONE("generateImpostor");
LLGLState::checkStates();
@@ -10090,11 +10151,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
assertInitialized();
// previews can't be muted or impostered
- bool visually_muted = !preview_avatar && avatar->isVisuallyMuted();
+ bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( visually_muted ? "" : "not ") << "visually muted"
<< LL_ENDL;
- bool too_complex = !preview_avatar && avatar->isTooComplex();
+ bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( too_complex ? "" : "not ") << "too complex"
<< LL_ENDL;
@@ -10120,6 +10181,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
RENDER_TYPE_TREE,
RENDER_TYPE_VOIDWATER,
RENDER_TYPE_WATER,
+ RENDER_TYPE_ALPHA_POST_WATER,
RENDER_TYPE_PASS_GRASS,
RENDER_TYPE_HUD,
RENDER_TYPE_PARTICLES,
@@ -10129,6 +10191,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
);
}
+ if (specific_attachment && specific_attachment->isHUDAttachment())
+ { //enable HUD rendering
+ setRenderTypeMask(RENDER_TYPE_HUD, END_RENDER_TYPES);
+ }
+
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
@@ -10185,20 +10252,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
}
else
{
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
+ if (specific_attachment)
{
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ markVisible(specific_attachment->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ else
+ {
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ for (iter = begin;
+ iter != end;
+ ++iter)
{
- LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object)
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
}
}
}
@@ -10296,9 +10373,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
LLDrawPoolAvatar::sMinimumAlpha = 0.f;
}
- if (preview_avatar)
+ if (preview_avatar || for_profile)
{
- // previews don't care about imposters
+ // previews and profiles don't care about imposters
renderGeomDeferred(camera);
renderGeomPostDeferred(camera);
}
@@ -10327,6 +10404,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+ if (!for_profile)
{ //create alpha mask based on depth buffer (grey out if muted)
if (LLPipeline::sRenderDeferred)
{
@@ -10405,7 +10483,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- if (!preview_avatar)
+ if (!preview_avatar && !for_profile)
{
avatar->mNeedsImpostorUpdate = FALSE;
avatar->cacheImpostorValues();
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index dbd1a34f61..e92fa32fc6 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -132,7 +132,17 @@ public:
bool allocateShadowBuffer(U32 resX, U32 resY);
void resetVertexBuffers(LLDrawable* drawable);
- void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);
+
+ // perform a profile of the given avatar
+ // if profile_attachments is true, run a profile for each attachment
+ void profileAvatar(LLVOAvatar* avatar, bool profile_attachments = false);
+
+ // generate an impostor for the given avatar
+ // preview_avatar - if true, a preview window render is being performed
+ // for_profile - if true, a profile is being performed, do not update actual impostor
+ // specific_attachment - specific attachment to profile, or nullptr to profile entire avatar
+ void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr);
+
void bindScreenToTexture();
void renderFinalize();
void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
@@ -593,7 +603,6 @@ public:
RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000,
RENDER_DEBUG_NORMALS = 0x04000000,
RENDER_DEBUG_LOD_INFO = 0x08000000,
- RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000,
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index b52c19d5e3..83db17b679 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -273,7 +273,7 @@
left="20"
name="environment_lbl"
width="100">
- Environment
+ Shadows
</text>
<text
follows="left|top"
@@ -285,29 +285,8 @@
left="160"
name="enhancements_desc"
width="350">
- Each enhancement improves realism but can reduce speed.
+ Shadows significantly improve visual quality but can reduce speed.
</text>
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- name="atmospheric_shaders"
- top_pad="5"
- left="157"
- width="280">
- </check_box>
- <check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting"
- layout="topleft"
- name="advanced_lighting_model"
- top_delta="24"
- width="280">
- </check_box>
<text
type="string"
length="1"
@@ -319,7 +298,7 @@
text_readonly_color="LabelDisabledColor"
top_pad="10"
width="128">
- Shadows:
+ Shadow Detail:
</text>
<combo_box
control_name="RenderShadowDetail"
@@ -372,7 +351,7 @@
left="160"
name="water_desc"
width="380">
- Reducing or turning off water effects can greatly improve frame rate.
+ Reducing or turning off transparent water may improve frame rate.
</text>
<check_box
control_name="RenderTransparentWater"
@@ -385,56 +364,6 @@
left="157"
width="280">
</check_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- name="ReflectionsText"
- text_readonly_color="LabelDisabledColor"
- top_pad="16"
- left="160"
- width="128">
- Water Reflections:
- </text>
- <combo_box
- control_name="RenderReflectionDetail"
- height="18"
- layout="topleft"
- left_delta="150"
- top_delta="0"
- name="Reflections"
- width="150">
- <combo_box.item
- label="None; opaque"
- name="0"
- value="-2"/>
- <combo_box.item
- label="None; transparent"
- name="0"
- value="-1"/>
- <combo_box.item
- label="Minimal"
- name="0"
- value="0"/>
- <combo_box.item
- label="Terrain and trees"
- name="1"
- value="1"/>
- <combo_box.item
- label="All static objects"
- name="2"
- value="2"/>
- <combo_box.item
- label="All avatars and objects"
- name="3"
- value="3"/>
- <combo_box.item
- label="Everything"
- name="4"
- value="4"/>
- </combo_box>
<view_border
bevel_style="in"
height="0"
diff --git a/indra/test/llsdutil_tut.cpp b/indra/test/llsdutil_tut.cpp
index 6fce53f335..22efd5439a 100644
--- a/indra/test/llsdutil_tut.cpp
+++ b/indra/test/llsdutil_tut.cpp
@@ -404,28 +404,28 @@ namespace tut
ensure("hash: equivalent values but different types do not match.", boost::hash<LLSD>{}(data_r1) != boost::hash<LLSD>{}(data_i1));
}
{
- LLSD data_a1 = LLSDArray("A")("B")("C");
- LLSD data_a2 = LLSDArray("A")("B")("C");
+ LLSD data_a1 = llsd::array("A", "B", "C");
+ LLSD data_a2 = llsd::array("A", "B", "C");
ensure("hash: identical arrays produce identical results", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2));
- data_a2.append(LLSDArray(1)(2));
+ data_a2.append(llsd::array(1, 2));
ensure("hash: changing the array changes the hash.", boost::hash<LLSD>{}(data_a1) != boost::hash<LLSD>{}(data_a2));
- data_a1.append(LLSDArray(1)(2));
+ data_a1.append(llsd::array(1, 2));
ensure("hash: identical arrays produce identical results with nested arrays", boost::hash<LLSD>{}(data_a1) == boost::hash<LLSD>{}(data_a2));
}
{
- LLSD data_m1 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
- LLSD data_m2 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+ LLSD data_m1 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
+ LLSD data_m2 = LLSDMap("key1", LLSD::Real(3.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
ensure("hash: identical maps produce identical results", boost::hash<LLSD>{}(data_m1) == boost::hash<LLSD>{}(data_m2));
- LLSD data_m3 = LLSDMap("key1", LLSD::Real(5.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+ LLSD data_m3 = LLSDMap("key1", LLSD::Real(5.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
ensure("hash: Different values in the map produce different hashes.", boost::hash<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m3));
- LLSD data_m4 = LLSDMap("keyA", LLSD::Real(3.0))("key2", "value2")("key3", LLSDArray(1)(2)(3));
+ LLSD data_m4 = LLSDMap("keyA", LLSD::Real(3.0))("key2", "value2")("key3", llsd::array(1, 2, 3));
ensure("hash: Different keys in the map produce different hashes.", boost::hash<LLSD>{}(data_m1) != boost::hash<LLSD>{}(data_m4));
}