diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index f9e66951af6..78db3d98805 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -98,8 +98,6 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources) ) endif(DARWIN) - target_precompile_headers(PROJECT_${project}_TEST_${name} REUSE_FROM llprecompiled_exe) - # # Per-codefile additional / external project dep and lib dep property extraction # @@ -246,7 +244,6 @@ FUNCTION(LL_ADD_INTEGRATION_TEST target_link_libraries(INTEGRATION_TEST_${testname} ${libraries}) target_include_directories (INTEGRATION_TEST_${testname} PRIVATE ${INDRA_SOURCE_DIR}/test ${INDRA_SOURCE_DIR}/llmath ${INDRA_SOURCE_DIR}/llui) - target_precompile_headers(INTEGRATION_TEST_${testname} REUSE_FROM llprecompiled_exe) # Create the test running command set(test_command ${ARGN}) diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 963b2a6c5bb..3bab9c48ce5 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -92,12 +92,6 @@ static const char USAGE[] = "\n" " Only valid for output j2c images.\n" " -f, --filter \n" " Apply the filter to the input images.\n" -" -log, --logmetrics \n" -" Log performance data for . Results in .slp\n" -" Note: so far, only ImageCompressionTester has been tested.\n" -" -a, --analyzeperformance\n" -" Create a report comparing _baseline.slp with current .slp\n" -" Results in _report.csv\n" " -s, --image-stats\n" " Output stats for each input and output image.\n" "\n"; @@ -316,34 +310,6 @@ void store_output_file(std::list &output_filenames, std::list input_filenames; std::list output_filenames; // Other optional parsed arguments - bool analyze_performance = false; bool image_stats = false; int* region = NULL; int discard_level = -1; @@ -369,7 +334,6 @@ int main(int argc, char** argv) // Init whatever is necessary ll_init_apr(); LLImage::initClass(); - LogThread* fast_timer_log_thread = NULL; // For performance and metric gathering // Analyze command line arguments for (int arg = 1; arg < argc; ++arg) @@ -515,29 +479,6 @@ int main(int argc, char** argv) { reversible = true; } - else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log")) - { - // '--logmetrics' needs to be specified with a named test metric argument - // Note: for the moment, only ImageCompressionTester has been tested - std::string test_name; - if ((arg + 1) < argc) - { - test_name = argv[arg+1]; - } - if (((arg + 1) >= argc) || (test_name[0] == '-')) - { - // We don't have an argument left in the arg list or the next argument is another option - std::cout << "No --logmetrics argument given, no perf data will be gathered" << std::endl; - } - else - { - LLFastTimer::sMetricLog = true; - LLFastTimer::sLogName = test_name; - arg += 1; // Skip that arg now we know it's a valid test name - if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list - break; - } - } else if (!strcmp(argv[arg], "--filter") || !strcmp(argv[arg], "-f")) { // '--filter' needs to be specified with a named filter argument @@ -557,10 +498,6 @@ int main(int argc, char** argv) break; } } - else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a")) - { - analyze_performance = true; - } else if (!strcmp(argv[arg], "--image-stats") || !strcmp(argv[arg], "-s")) { image_stats = true; @@ -573,20 +510,6 @@ int main(int argc, char** argv) std::cout << "No input file, nothing to do -> exit" << std::endl; return 0; } - if (analyze_performance && !LLFastTimer::sMetricLog) - { - std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log with -a) -> exit" << std::endl; - return 0; - } - - - // Create the logging thread if required - if (LLTrace::BlockTimer::sMetricLog) - { - LLTrace::BlockTimer::setLogLock(new LLMutex()); - fast_timer_log_thread = new LogThread(LLTrace::BlockTimer::sLogName); - fast_timer_log_thread->start(); - } // Load the filter once and for all LLImageFilter filter(filter_name); @@ -623,31 +546,8 @@ int main(int argc, char** argv) } } - // Output perf data if requested by user - if (analyze_performance) - { - std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; - std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; - std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; - - std::cout << "Analyzing performance, check report in : " << report_name << std::endl; - - LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name); - } - - // Stop the perf gathering system if needed - if (LLTrace::BlockTimer::sMetricLog) - { - LLMetricPerformanceTesterBasic::deleteTester(LLTrace::BlockTimer::sLogName); - sAllDone = true; - } - // Cleanup and exit SUBSYSTEM_CLEANUP(LLImage); - if (fast_timer_log_thread) - { - fast_timer_log_thread->shutdown(); - } return 0; } diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 97f4ccef5ab..53478b68ff5 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -884,7 +884,7 @@ void LLAvatarAppearance::buildCharacter() bool LLAvatarAppearance::loadAvatar() { -// LL_RECORD_BLOCK_TIME(FTM_LOAD_AVATAR); + LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; // avatar_skeleton.xml if( !buildSkeleton(sAvatarSkeletonInfo) ) diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp index da886fd4339..1ec8732a2bc 100644 --- a/indra/llappearance/llwearabletype.cpp +++ b/indra/llappearance/llwearabletype.cpp @@ -70,6 +70,10 @@ LLWearableType::~LLWearableType() { } +void LLWearableType::initSingleton() +{ +} + LLWearableType::EType LLWearableType::typeNameToType(const std::string& type_name) { const LLWearableType::EType wearable = mDictionary.lookup(type_name); diff --git a/indra/llappearance/llwearabletype.h b/indra/llappearance/llwearabletype.h index 45cdf3baf9b..19b9f30d45d 100644 --- a/indra/llappearance/llwearabletype.h +++ b/indra/llappearance/llwearabletype.h @@ -33,12 +33,12 @@ #include "llsingleton.h" #include "llinvtranslationbrdg.h" -class LLWearableType : public LLSimpleton +class LLWearableType : public LLParamSingleton { -public: - LLWearableType(LLTranslationBridge::ptr_t &trans); + LLSINGLETON(LLWearableType, LLTranslationBridge::ptr_t &trans); ~LLWearableType(); - + void initSingleton() override; +public: enum EType { WT_SHAPE = 0, diff --git a/indra/llappearanceutility/llappappearanceutility.cpp b/indra/llappearanceutility/llappappearanceutility.cpp index 2fa0b0b32d5..ce9c97ea015 100644 --- a/indra/llappearanceutility/llappappearanceutility.cpp +++ b/indra/llappearanceutility/llappappearanceutility.cpp @@ -34,7 +34,6 @@ #include "llapr.h" #include "llerrorcontrol.h" -#include "llfasttimer.h" #include "llgl.h" #include "llmd5.h" #include "llsd.h" @@ -44,7 +43,6 @@ #include "lltreeiterators.h" #include "v3color.h" #include "llwindow.h" -#include "lltrace.h" // appearance includes #include "llavatarappearance.h" @@ -208,7 +206,6 @@ LLAppAppearanceUtility::LLAppAppearanceUtility(int argc, char** argv) : mOutput(nullptr), mAppName(argv[0]), mDebugMode(false), - mTreeMapThreshold(1), mBakeTextureSize(512) { } @@ -301,12 +298,6 @@ void LLAppAppearanceUtility::parseArguments() case 'd': mDebugMode = true; break; - case 'm': - mTreeMapFilename.assign(opt_arg); - break; - case 's': - mTreeMapThreshold = atoi(opt_arg); - break; default: usage(std::cerr); throw LLAppException(RV_BAD_ARGUMENTS, "Unknown option."); @@ -459,7 +450,6 @@ bool LLAppAppearanceUtility::init() LLError::initForApplication(".", ".", true); if (mDebugMode) { - mRecording.start(); LLError::setDefaultLevel(LLError::LEVEL_DEBUG); } else @@ -479,7 +469,7 @@ bool LLAppAppearanceUtility::init() const bool SKIP_ANALYZE_ALPHA=true; LLTranslationBridge::ptr_t trans = std::make_shared(); - LLWearableType::createInstance(trans); + LLWearableType::initParamSingleton(trans); // *TODO: Create a texture bridge? LLAvatarAppearance::initClass(); @@ -492,91 +482,6 @@ bool LLAppAppearanceUtility::init() return true; } - -void add_cluster(LLTrace::Recording& recording, std::ostream& tree, LLTrace::BlockTimerStatHandle& node, std::vector < S32 > & clusters, F64Milliseconds threshold) -{ - LLMD5 hash; - hash.update((const unsigned char*)node.getName().c_str(), node.getName().size()); - hash.finalize(); - char buf[33]; - hash.hex_digest(buf); - buf[6] = 0; - LLColor3 color(buf); - if (color.brightness() < 0.25f) - { - color.normalize(); - } - std::ostringstream color_str; - color_str << "#" << std::hex << std::setfill('0') << std::setw(2) - << (S32) F32_to_U8(color.mV[0], 0.0f, 1.0f) - << (S32) F32_to_U8(color.mV[1], 0.0f, 1.0f) - << (S32) F32_to_U8(color.mV[2], 0.0f, 1.0f); - - std::vector::iterator iter = clusters.begin(); - std::vector::iterator end = clusters.end(); - std::ostringstream padding; - for(; iter != end; ++iter) - { - padding << " "; - } - - std::ostringstream node_id; - bool first = true; - iter = clusters.begin(); - for(; iter != end; ++iter) - { - if (!first) - { - node_id << "_"; - } - first = false; - node_id << (*iter); - } - - if (node.getChildren().size() == 0) - { - F64Milliseconds leaf_time_ms(recording.getSum(node)); - if (leaf_time_ms > threshold) - { - tree << padding.str() << "n" << node_id.str() << " [" - << "label=\"" << node.getName() << " (" << leaf_time_ms.value() << ")\" " - << "fillcolor=\"" << color_str.str() << "\" " - << "area=" << leaf_time_ms.value() / 10 << "]" << std::endl; - } - } - else - { - if (clusters.size()) - { - tree << padding.str() << "subgraph cluster" << node_id.str(); - tree << " {" << std::endl; - } - - S32Milliseconds node_area(recording.getSum(node)); - std::vector::iterator child_iter = node.getChildren().begin(); - for (S32 num=0; child_iter != node.getChildren().end(); ++child_iter, ++num) - { - clusters.push_back(num); - add_cluster(recording, tree, *(*child_iter), clusters, threshold); - clusters.pop_back(); - node_area -= recording.getSum(*(*child_iter)); - } - - S32Milliseconds node_time_ms(node_area); - if (node_time_ms > threshold) - { - tree << padding.str() << "n" << node_id.str() << " [" - << "label=\"" << node.getName() << " (" << node_time_ms.value() << ")\" " - << "fillcolor=\"" << color_str.str() << "\" " - << "area=" << node_time_ms.value() / 10 << "]" << std::endl; - } - if (clusters.size()) - { - tree << padding.str() << "}" << std::endl;; - } - } -} - bool LLAppAppearanceUtility::cleanup() { if (mProcess) @@ -584,72 +489,6 @@ bool LLAppAppearanceUtility::cleanup() mProcess->cleanup(); } - // Spam fast timer information in debug mode. - if (mDebugMode) - { - mRecording.stop(); - LLTrace::BlockTimer::processTimes(); - - S32Milliseconds max_time_ms(0); - for (LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(LLTrace::BlockTimer::getRootTimeBlock()); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - LLTrace::BlockTimerStatHandle* idp = (*it); - // Skip near-zero time leafs. - S32Milliseconds leaf_time_ms(mRecording.getSum(*idp)); - if (leaf_time_ms > max_time_ms) max_time_ms = leaf_time_ms; - if ((S32Milliseconds)0 == leaf_time_ms) continue; - - std::vector< LLTrace::BlockTimerStatHandle* > parents; - LLTrace::BlockTimerStatHandle* parentp = idp->getParent(); - while (parentp) - { - parents.push_back(parentp); - if (parentp->getParent() == parentp) break; - parentp = parentp->getParent(); - } - - std::ostringstream fullname; - bool is_first = true; - for ( std::vector< LLTrace::BlockTimerStatHandle* >::reverse_iterator iter = parents.rbegin(); - iter != parents.rend(); ++iter) - { - // Skip root - if (is_first) - { - is_first = false; - continue; - } - LLTrace::BlockTimerStatHandle* parent_idp = (*iter); - U32Milliseconds time_ms(mRecording.getSum(parent_idp->selfTime())); - fullname << parent_idp->getName() << " "; - fullname << "("; - if (time_ms > (U32Milliseconds)0) - { - fullname << time_ms.value() << " ms, "; - } - fullname << mRecording.getSum(parent_idp->callCount()) << " call)-> "; - } - LL_DEBUGS() << fullname.str() << LL_ENDL; - } - if (!mTreeMapFilename.empty()) - { - std::ofstream tree(mTreeMapFilename.c_str()); - tree << "graph G {" << std::endl; - tree << " node[style=filled]" << std::endl; - - LLTrace::BlockTimerStatHandle& root = LLTrace::BlockTimer::getRootTimeBlock(); - std::vector clusters; - add_cluster(mRecording, tree, root, clusters, (((F32) mTreeMapThreshold / 100.f) * max_time_ms) ); - - tree << "}" << std::endl; - - LL_DEBUGS() << "To generate a treemap of LLFrameTimer results, run:" << LL_ENDL; - LL_DEBUGS() << "patchwork " << mTreeMapFilename << " -Tpng > rendered.png" << LL_ENDL; - } - } - LLAvatarAppearance::cleanupClass(); LLImageGL::cleanupClass(); LLImage::cleanupClass(); diff --git a/indra/llappearanceutility/llappappearanceutility.h b/indra/llappearanceutility/llappappearanceutility.h index 80d1e8b1bf6..de67f100774 100644 --- a/indra/llappearanceutility/llappappearanceutility.h +++ b/indra/llappearanceutility/llappappearanceutility.h @@ -98,9 +98,6 @@ class LLAppAppearanceUtility : public LLApp LLUUID mAgentID; S32 mBakeTextureSize; bool mDebugMode; - LLTrace::Recording mRecording; - S32 mTreeMapThreshold; - std::string mTreeMapFilename; }; diff --git a/indra/llappearanceutility/llbakingtexlayer.cpp b/indra/llappearanceutility/llbakingtexlayer.cpp index 3427331a964..ae285060360 100644 --- a/indra/llappearanceutility/llbakingtexlayer.cpp +++ b/indra/llappearanceutility/llbakingtexlayer.cpp @@ -66,11 +66,9 @@ bool LLBakingTexLayerSetBuffer::render() return result; } -static LLFastTimer::DeclareTimer FTM_MID_RENDER("midRenderTexLayerSet"); -static LLFastTimer::DeclareTimer FTM_CREATE_J2C("Encode J2C image."); void LLBakingTexLayerSetBuffer::midRenderTexLayerSet(bool success) { - LL_RECORD_BLOCK_TIME(FTM_MID_RENDER); + LL_PROFILE_ZONE_SCOPED; if (!mTexLayerSet->isVisible()) { // Should have used IMG_INVISIBLE during hash id generation? @@ -124,7 +122,7 @@ void LLBakingTexLayerSetBuffer::midRenderTexLayerSet(bool success) } { - LL_RECORD_BLOCK_TIME(FTM_CREATE_J2C); + LL_PROFILE_ZONE_NAMED("Encode J2C image."); LL_DEBUGS() << "Creating J2C..." << LL_ENDL; mCompressedImage = new LLImageJ2C; const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask) diff --git a/indra/llappearanceutility/llbakingtexture.cpp b/indra/llappearanceutility/llbakingtexture.cpp index ae83081aefe..0bc5195251f 100644 --- a/indra/llappearanceutility/llbakingtexture.cpp +++ b/indra/llappearanceutility/llbakingtexture.cpp @@ -73,9 +73,3 @@ void LLBakingTexture::forceImmediateUpdate() { LL_ERRS() << "Not implemented." << LL_ENDL; } - -void LLBakingTexture::updateBindStatsForTester() -{ - LL_ERRS() << "Not implemented." << LL_ENDL; -} - diff --git a/indra/llappearanceutility/llbakingtexture.h b/indra/llappearanceutility/llbakingtexture.h index 50b4193b2ee..f4198bd649b 100644 --- a/indra/llappearanceutility/llbakingtexture.h +++ b/indra/llappearanceutility/llbakingtexture.h @@ -51,7 +51,6 @@ class LLBakingTexture : public LLGLTexture void setKnownDrawSize(S32 width, S32 height) override; bool bindDefaultImage(const S32 stage = 0) override ; void forceImmediateUpdate() override; - void updateBindStatsForTester() override ; bool bindDebugImage(const S32 stage = 0) override { return false; } bool isActiveFetching() override { return false; } diff --git a/indra/llappearanceutility/llprocesstexture.cpp b/indra/llappearanceutility/llprocesstexture.cpp index 527a6822f2f..f12c49f35bc 100644 --- a/indra/llappearanceutility/llprocesstexture.cpp +++ b/indra/llappearanceutility/llprocesstexture.cpp @@ -68,12 +68,11 @@ void LLProcessTexture::cleanup() delete mWindow; } -static LLFastTimer::DeclareTimer FTM_CREATE_TEXTURE_FROM_STREAM("Create texture from stream."); static LLPointer create_texture_from_stream(std::istream& input, S32 texture_size, const LLUUID& id) { - LL_RECORD_BLOCK_TIME(FTM_CREATE_TEXTURE_FROM_STREAM); + LL_PROFILE_ZONE_SCOPED; // Read compressed j2c texture data from the input stream. U8* buffer = (U8*) ll_aligned_malloc_16(texture_size); input.read((char*) buffer, texture_size); diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 5ea1c7f09b0..6d8e75ad5ce 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -1,6 +1,30 @@ # -*- cmake -*- -add_library(llcommon STATIC) +if (LL_COMMON_LINK_SHARED) + add_library(llcommon SHARED) + + target_compile_definitions(llcommon PUBLIC LL_COMMON_LINK_SHARED=1) + + add_custom_command( + TARGET llcommon POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "${SHARED_LIB_STAGING_DIR}" + COMMAND_EXPAND_LISTS + ) + + add_custom_command( + TARGET llcommon POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "${VIEWER_STAGING_DIR}" + COMMAND_EXPAND_LISTS + ) + + add_custom_command( + TARGET llcommon POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "$" "${VIEWER_STAGING_DIR}/llplugin" + COMMAND_EXPAND_LISTS + ) +else() + add_library(llcommon STATIC) +endif() target_sources(llcommon PRIVATE @@ -54,7 +78,6 @@ target_sources(llcommon llmemory.cpp llmemorystream.cpp llmetrics.cpp - llmetricperformancetester.cpp llmortician.cpp llmutex.cpp llpointer.cpp @@ -172,7 +195,6 @@ target_sources(llcommon llmemory.h llmemorystream.h llmetrics.h - llmetricperformancetester.h llmortician.h llmutex.h llnametable.h @@ -287,9 +309,6 @@ target_link_libraries( ) target_include_directories(llcommon PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(llcommon PRIVATE ${INDRA_SOURCE_DIR}/llmath) - -target_precompile_headers(llcommon REUSE_FROM llprecompiled) add_dependencies(llcommon stage_third_party_libs) @@ -334,7 +353,7 @@ if (BUILD_TESTING) LL_ADD_INTEGRATION_TEST(llsd "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llsdjson "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}" "${test_project}") - LL_ADD_INTEGRATION_TEST(llsdutil "" "llcommon;llmath" "${test_project}") + LL_ADD_INTEGRATION_TEST(llsdutil "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llsingleton "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llstreamtools "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}" "${test_project}") diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h index ec1a39f7b07..0ffc6e85b28 100644 --- a/indra/llcommon/apply.h +++ b/indra/llcommon/apply.h @@ -194,7 +194,7 @@ auto apply_impl(CALLABLE&& func, const std::vector& args, std::index_sequence } // produce suitable error if apply(func, vector) is the wrong size for func() -void apply_validate_size(size_t size, size_t arity); +LL_COMMON_API void apply_validate_size(size_t size, size_t arity); /// possible exception from apply() validation struct apply_error: public LLException diff --git a/indra/llcommon/hbxxh.h b/indra/llcommon/hbxxh.h index 142e140cf3a..8db17fb444e 100644 --- a/indra/llcommon/hbxxh.h +++ b/indra/llcommon/hbxxh.h @@ -39,7 +39,7 @@ // 64 bits hashing class -class HBXXH64 +class LL_COMMON_API HBXXH64 { friend std::ostream& operator<<(std::ostream&, HBXXH64); @@ -151,7 +151,7 @@ inline bool operator!=(const HBXXH64& a, const HBXXH64& b) // 128 bits hashing class -class HBXXH128 +class LL_COMMON_API HBXXH128 { friend std::ostream& operator<<(std::ostream&, HBXXH128); diff --git a/indra/llcommon/lazyeventapi.h b/indra/llcommon/lazyeventapi.h index 0e5df4e6f46..11f9ae1cd04 100644 --- a/indra/llcommon/lazyeventapi.h +++ b/indra/llcommon/lazyeventapi.h @@ -49,7 +49,7 @@ namespace LL */ // No LLInstanceTracker key: we don't need to find a specific instance, // LLLeapListener just needs to be able to enumerate all instances. - class LazyEventAPIBase: public LLInstanceTracker + class LL_COMMON_API LazyEventAPIBase: public LLInstanceTracker { public: LazyEventAPIBase(const std::string& name, const std::string& desc, diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index 58b48c59ba4..d6acd78a044 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -50,7 +50,7 @@ void clear_signals(); #endif -extern bool gDisconnected; +extern LL_COMMON_API bool gDisconnected; class LL_COMMON_API LLApp { diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 04a6dbefbda..9672a3262be 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -27,8 +27,45 @@ #include "linden_common.h" #include "llassettype.h" +#include "lldictionary.h" #include "llmemory.h" #include "llsd.h" +#include "llsingleton.h" + +///---------------------------------------------------------------------------- +/// Class LLAssetType +///---------------------------------------------------------------------------- +struct AssetEntry : public LLDictionaryEntry +{ + AssetEntry(const char *desc_name, + const char *type_name, // 8 character limit! + const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one + bool can_link, // can you create a link to this type? + bool can_fetch, // can you fetch this asset by ID? + bool can_know) // can you see this asset's ID? + : + LLDictionaryEntry(desc_name), + mTypeName(type_name), + mHumanName(human_name), + mCanLink(can_link), + mCanFetch(can_fetch), + mCanKnow(can_know) + { + llassert(strlen(mTypeName) <= 8); + } + + const char *mTypeName; + const char *mHumanName; + bool mCanLink; + bool mCanFetch; + bool mCanKnow; +}; + +class LLAssetDictionary : public LLSingleton, + public LLDictionary +{ + LLSINGLETON(LLAssetDictionary); +}; LLAssetDictionary::LLAssetDictionary() { diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 6b779877bee..17177d81c3c 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -27,9 +27,6 @@ #ifndef LL_LLASSETTYPE_H #define LL_LLASSETTYPE_H -#include "lldictionary.h" -#include "llsingleton.h" - #include class LL_COMMON_API LLAssetType @@ -177,40 +174,4 @@ class LL_COMMON_API LLAssetType ~LLAssetType() {} }; -///---------------------------------------------------------------------------- -/// Class LLAssetType -///---------------------------------------------------------------------------- -struct AssetEntry : public LLDictionaryEntry -{ - AssetEntry(const char *desc_name, - const char *type_name, // 8 character limit! - const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one - bool can_link, // can you create a link to this type? - bool can_fetch, // can you fetch this asset by ID? - bool can_know) // can you see this asset's ID? - : - LLDictionaryEntry(desc_name), - mTypeName(type_name), - mHumanName(human_name), - mCanLink(can_link), - mCanFetch(can_fetch), - mCanKnow(can_know) - { - llassert(strlen(mTypeName) <= 8); - } - - const char *mTypeName; - const char *mHumanName; - bool mCanLink; - bool mCanFetch; - bool mCanKnow; -}; - -class LLAssetDictionary : public LLSimpleton, - public LLDictionary -{ -public: - LLAssetDictionary(); -}; - #endif // LL_LLASSETTYPE_H diff --git a/indra/llcommon/llcallbacklist.h b/indra/llcommon/llcallbacklist.h index 036e575117d..66bbfd373a0 100644 --- a/indra/llcommon/llcallbacklist.h +++ b/indra/llcommon/llcallbacklist.h @@ -32,7 +32,7 @@ #include #include -class LLCallbackList +class LL_COMMON_API LLCallbackList { public: typedef void (*callback_t)(void*); @@ -64,17 +64,17 @@ typedef std::function nullary_func_t; typedef std::function bool_func_t; // Call a given callable once in idle loop. -void doOnIdleOneTime(nullary_func_t callable); +LL_COMMON_API void doOnIdleOneTime(nullary_func_t callable); // Repeatedly call a callable in idle loop until it returns true. -void doOnIdleRepeating(bool_func_t callable); +LL_COMMON_API void doOnIdleRepeating(bool_func_t callable); // Call a given callable once after specified interval. -void doAfterInterval(nullary_func_t callable, F32 seconds); +LL_COMMON_API void doAfterInterval(nullary_func_t callable, F32 seconds); // Call a given callable every specified number of seconds, until it returns true. -void doPeriodically(bool_func_t callable, F32 seconds); +LL_COMMON_API void doPeriodically(bool_func_t callable, F32 seconds); -extern LLCallbackList gIdleCallbacks; +extern LL_COMMON_API LLCallbackList gIdleCallbacks; #endif diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h index b120a5c4fe5..6e12af2353b 100644 --- a/indra/llcommon/llcleanup.h +++ b/indra/llcommon/llcleanup.h @@ -33,7 +33,7 @@ // Use ancient do { ... } while (0) macro trick to permit a block of // statements with the same syntax as a single statement. -void log_subsystem_cleanup(LLError::ELevel level, +LL_COMMON_API void log_subsystem_cleanup(LLError::ELevel level, const char* file, int line, const char* function, diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 8da91d1f0a4..b68bf00885a 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -31,6 +31,7 @@ // Precompiled header #include "linden_common.h" // associated header +#define LLCOROS_CPP #include "llcoros.h" // STL headers // std headers @@ -83,7 +84,7 @@ LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { CoroData* current{ nullptr }; // be careful about attempted accesses in the final throes of app shutdown - if (instanceExists()) + if (! wasDeleted()) { current = instance().mCurrent.get(); } @@ -148,6 +149,10 @@ LLCoros::LLCoros(): } LLCoros::~LLCoros() +{ +} + +void LLCoros::cleanupSingleton() { // Some of the coroutines (like voice) will depend onto // origin singletons, so clean coros before deleting those @@ -413,7 +418,7 @@ void LLCoros::toplevel(std::string name, callable_t callable) //static void LLCoros::checkStop() { - if (!instanceExists()) + if (wasDeleted()) { LLTHROW(Shutdown("LLCoros was deleted")); } @@ -456,3 +461,5 @@ LLCoros::CoroData::CoroData(int n): mCreationTime(LLTimer::getTotalSeconds()) { } + +template class LL_COMMON_API LLCoros* LLSingleton::getInstance(); diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index 0c73b4227a8..d36cf21954a 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -88,12 +88,13 @@ namespace boost { * can provide diagnostic info: we can look up the name of the * currently-running coroutine. */ -class LL_COMMON_API LLCoros: public LLSimpleton +class LL_COMMON_API LLCoros: public LLSingleton { -public: - LLCoros(); + LLSINGLETON(LLCoros); ~LLCoros(); + void cleanupSingleton() override; +public: // For debugging, return true if on the main coroutine for the current thread // Code that should not be executed from a coroutine should be protected by // llassert(LLCoros::on_main_coro()) @@ -372,4 +373,8 @@ std::string logname() { return LLCoros::logname(); } } // llcoro +#ifndef LLCOROS_CPP +extern template class LL_COMMON_API LLCoros* LLSingleton::getInstance(); +#endif + #endif /* ! defined(LL_LLCOROS_H) */ diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h index 364b79d9f4d..3be080f2787 100644 --- a/indra/llcommon/llerror.h +++ b/indra/llcommon/llerror.h @@ -263,7 +263,7 @@ namespace LLError }; - class End { }; + class LL_COMMON_API End { }; inline std::ostream& operator<<(std::ostream& s, const End&) { return s; } // used to indicate the end of a message @@ -293,14 +293,14 @@ namespace LLError }; // class which, when streamed, inserts the current stack trace - struct LLStacktrace + struct LL_COMMON_API LLStacktrace { friend std::ostream& operator<<(std::ostream& out, const LLStacktrace&); }; // Provides access to OS notification popup on error, since // not everything has access to OS's messages - class LLUserWarningMsg + class LL_COMMON_API LLUserWarningMsg { public: // error codes, tranlates to last_exec states like LAST_EXEC_OTHER_CRASH diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 25a8a98e368..ec56713be45 100644 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -77,17 +77,17 @@ namespace llcoro * runs without suspending for nontrivial time, sprinkle in calls to this * function to avoid stalling the rest of the viewer processing. */ -void suspend(); +LL_COMMON_API void suspend(); /** * Yield control from a coroutine for at least the specified number of seconds */ -void suspendUntilTimeout(float seconds); +LL_COMMON_API void suspendUntilTimeout(float seconds); /** * Yield control from a coroutine until the next mainloop's newFrame event. */ -void suspendUntilNextFrame(); +LL_COMMON_API void suspendUntilNextFrame(); /** * Post specified LLSD event on the specified LLEventPump, then suspend for a @@ -136,7 +136,7 @@ void suspendUntilNextFrame(); * @a replyPumpNamePath specifies the entry in the lowest-level structure in * @a event into which to store replyPump.getName(). */ -LLSD postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump, +LL_COMMON_API LLSD postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump, const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD()); /// Wait for the next event on the specified LLEventPump. Pass either the @@ -150,7 +150,7 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump) /// Like postAndSuspend(), but if we wait longer than @a timeout seconds, /// stop waiting and return @a timeoutResult instead. -LLSD postAndSuspendWithTimeout(const LLSD& event, +LL_COMMON_API LLSD postAndSuspendWithTimeout(const LLSD& event, const LLEventPumpOrPumpName& requestPump, const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath, diff --git a/indra/llcommon/lleventfilter.h b/indra/llcommon/lleventfilter.h index 8b917c23be1..e62024a93b7 100644 --- a/indra/llcommon/lleventfilter.h +++ b/indra/llcommon/lleventfilter.h @@ -62,7 +62,7 @@ class LL_COMMON_API LLEventFilter: public LLEventStream /** * Pass through only events matching a specified pattern */ -class LLEventMatching: public LLEventFilter +class LL_COMMON_API LLEventMatching: public LLEventFilter { public: /// Pass an LLSD map with keys and values the incoming event must match @@ -347,7 +347,7 @@ class LL_COMMON_API LLEventThrottleBase: public LLEventFilter /** * Production implementation of LLEventThrottle. */ -class LLEventThrottle: public LLEventThrottleBase +class LL_COMMON_API LLEventThrottle: public LLEventThrottleBase { public: LLEventThrottle(F32 interval); @@ -374,7 +374,7 @@ class LLEventThrottle: public LLEventThrottleBase * pending events into an LLSD Array, optionally flushing when the batch grows * to a certain size. */ -class LLEventBatchThrottle: public LLEventThrottle +class LL_COMMON_API LLEventBatchThrottle: public LLEventThrottle { public: // pass time interval and (optionally) max batch size; 0 means batch can @@ -408,7 +408,7 @@ class LLEventBatchThrottle: public LLEventThrottle * the iterator. Useful with boost::coroutine2! */ template -class LLStoreListener: public LLEventFilter +class LLStoreListener: public LLEventFilter // template: methods are inline; do NOT tag LL_COMMON_API { public: // pass target and optional path to element @@ -507,7 +507,7 @@ class LLCaptureListener: public LLVarHolder, * The proxy role means that LLEventLogProxy intercepts more of LLEventPump's * API than a typical LLEventFilter subclass. */ -class LLEventLogProxy: public LLEventFilter +class LL_COMMON_API LLEventLogProxy: public LLEventFilter { typedef LLEventFilter super; public: diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h index 68e609444ec..9b6fdbb5a81 100644 --- a/indra/llcommon/llexception.h +++ b/indra/llcommon/llexception.h @@ -39,7 +39,7 @@ * usage. However, most of the value of this base class is in the * diagnostic_information() available via Boost.Exception. */ -struct LLException: +struct LL_COMMON_API LLException : public std::runtime_error, public boost::exception { @@ -55,7 +55,7 @@ struct LLException: * derived from LLContinueError will still be logged, the viewer will attempt * to continue processing. */ -struct LLContinueError: public LLException +struct LL_COMMON_API LLContinueError : public LLException { LLContinueError(const std::string& what): LLException(what) @@ -89,18 +89,18 @@ do { \ /* Use the classic 'do { ... } while (0)' macro trick to wrap */ \ /* our multiple statements. */ \ } while (0) -void annotate_exception_(boost::exception& exc); +LL_COMMON_API void annotate_exception_(boost::exception& exc); /// Call this macro from a catch (...) clause #define CRASH_ON_UNHANDLED_EXCEPTION(CONTEXT) \ crash_on_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) -void crash_on_unhandled_exception_(const char*, int, const char*, const std::string&); +LL_COMMON_API void crash_on_unhandled_exception_(const char*, int, const char*, const std::string&); /// Call this from a catch (const LLContinueError&) clause, or from a catch /// (...) clause in which you do NOT want the viewer to crash. #define LOG_UNHANDLED_EXCEPTION(CONTEXT) \ log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT) -void log_unhandled_exception_(const char*, int, const char*, const std::string&); +LL_COMMON_API void log_unhandled_exception_(const char*, int, const char*, const std::string&); #if LL_WINDOWS @@ -108,7 +108,7 @@ void log_unhandled_exception_(const char*, int, const char*, const std::string&) // SEH exception filtering for use in __try __except // Separates C++ exceptions from C SEH exceptions // Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&); -U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop); +LL_COMMON_API U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop); #endif //LL_WINDOWS diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index c5a7a0e56b5..430ffa11132 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -290,14 +290,12 @@ void BlockTimer::updateTimes() } } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_TIMES("Process FastTimer Times"); - // not thread safe, so only call on main thread //static void BlockTimer::processTimes() { #if LL_TRACE_ENABLED - LL_RECORD_BLOCK_TIME(FTM_PROCESS_TIMES); + LL_PROFILE_ZONE_SCOPED; get_clock_count(); // good place to calculate clock frequency // set up initial tree diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 271dade0979..546661d9fab 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -53,7 +53,7 @@ namespace LLTrace // use to create blocktimer rvalue to be captured in a reference so that the BlockTimer lives to the end of the block. class BlockTimer timeThisBlock(class BlockTimerStatHandle& timer); -class BlockTimer +class LL_COMMON_API BlockTimer { public: typedef BlockTimer self_t; @@ -204,8 +204,10 @@ class BlockTimer BlockTimer(BlockTimerStatHandle& timer); // no-copy - BlockTimer(const BlockTimer& other); - BlockTimer& operator=(const BlockTimer& other); + BlockTimer(const BlockTimer& other) = delete; + BlockTimer(BlockTimer&& other) = delete; + BlockTimer& operator=(const BlockTimer& other) = delete; + BlockTimer& operator=(BlockTimer&& other) = delete; private: U64 mStartTime; @@ -213,9 +215,12 @@ class BlockTimer public: // statics + // NOTE: declared separately (not 'static bool sMetricLog, sLog;'): MSVC + // mis-handles a multi-declarator static in a dllexport class, flagging the + // second name with C2487. static std::string sLogName; - static bool sMetricLog, - sLog; + static bool sMetricLog; + static bool sLog; static U64 sClockResolution; }; @@ -231,7 +236,7 @@ LL_FORCE_INLINE class BlockTimer timeThisBlock(class BlockTimerStatHandle& timer } // stores a "named" timer instance to be reused via multiple BlockTimer stack instances -class BlockTimerStatHandle +class LL_COMMON_API BlockTimerStatHandle : public StatType { public: @@ -266,12 +271,12 @@ typedef LLTreeDFSIter block_timer_tree_df_post_iterator_t; typedef LLTreeBFSIter block_timer_tree_bf_iterator_t; -block_timer_tree_df_iterator_t begin_block_timer_tree_df(BlockTimerStatHandle& id); -block_timer_tree_df_iterator_t end_block_timer_tree_df(); -block_timer_tree_df_post_iterator_t begin_block_timer_tree_df_post(BlockTimerStatHandle& id); -block_timer_tree_df_post_iterator_t end_block_timer_tree_df_post(); -block_timer_tree_bf_iterator_t begin_block_timer_tree_bf(BlockTimerStatHandle& id); -block_timer_tree_bf_iterator_t end_block_timer_tree_bf(); +LL_COMMON_API block_timer_tree_df_iterator_t begin_block_timer_tree_df(BlockTimerStatHandle& id); +LL_COMMON_API block_timer_tree_df_iterator_t end_block_timer_tree_df(); +LL_COMMON_API block_timer_tree_df_post_iterator_t begin_block_timer_tree_df_post(BlockTimerStatHandle& id); +LL_COMMON_API block_timer_tree_df_post_iterator_t end_block_timer_tree_df_post(); +LL_COMMON_API block_timer_tree_bf_iterator_t begin_block_timer_tree_bf(BlockTimerStatHandle& id); +LL_COMMON_API block_timer_tree_bf_iterator_t end_block_timer_tree_bf(); LL_FORCE_INLINE BlockTimer::BlockTimer(BlockTimerStatHandle& timer) { diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h index 8de3f5c9b44..ea67665aa25 100644 --- a/indra/llcommon/llfile.h +++ b/indra/llcommon/llfile.h @@ -68,7 +68,7 @@ typedef FILE LLFILE; /// /// @nosubgrouping /// -class LLFile +class LL_COMMON_API LLFile { public: // ================================================================================ @@ -699,7 +699,7 @@ class LLFile * Does The Right Thing when passed a non-ASCII pathname. Sadly, that isn't * true of Microsoft's std::ifstream. */ -class llifstream : public std::ifstream +class LL_COMMON_API llifstream : public std::ifstream { // input stream associated with a C stream public: @@ -811,7 +811,7 @@ class LLUniqueFile * Right Thing when passed a non-ASCII pathname. Sadly, that isn't true of * Microsoft's std::ofstream. */ -class llofstream : public std::ofstream +class LL_COMMON_API llofstream : public std::ofstream { public: // Constructors: diff --git a/indra/llcommon/llheteromap.h b/indra/llcommon/llheteromap.h index 608e839f8b0..8a35007e52e 100644 --- a/indra/llcommon/llheteromap.h +++ b/indra/llcommon/llheteromap.h @@ -32,7 +32,7 @@ * LLHeteroMap collects objects WITHOUT a common base class, retrieves them by * object type and destroys them when the LLHeteroMap is destroyed. */ -class LLHeteroMap +class LL_COMMON_API LLHeteroMap { public: ~LLHeteroMap(); diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h index 7cc9c6b930a..9bdb5f3ae67 100644 --- a/indra/llcommon/llinitdestroyclass.h +++ b/indra/llcommon/llinitdestroyclass.h @@ -47,7 +47,7 @@ * LLInitClassList and LLDestroyClassList. It accumulates the initClass() or * destroyClass() callbacks for registered classes. */ -class LLCallbackRegistry +class LL_COMMON_API LLCallbackRegistry { public: typedef std::function func_t; diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 0dbbc956934..cf5b43dce93 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -615,7 +615,7 @@ namespace LLInitParam typedef LLPredicate::Rule predicate_rule_t; - predicate_rule_t default_parse_rules(); + LL_COMMON_API predicate_rule_t default_parse_rules(); // various callbacks and constraints associated with an individual param struct LL_COMMON_API ParamDescriptor diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index e6a69636850..6211ce4f5ec 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -57,7 +57,7 @@ namespace LLInstanceTrackerPrivate LL_PROFILE_MUTEX_NAMED(std::mutex, mMutex, "InstanceTracker Data"); }; - void logerrs(const char* cls, const std::string&, const std::string&, const std::string&); + LL_COMMON_API void logerrs(const char* cls, const std::string&, const std::string&, const std::string&); } // namespace LLInstanceTrackerPrivate /***************************************************************************** diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index 0a9d4600cca..c4aac859237 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -57,10 +57,10 @@ class LL_COMMON_API LLKeyData }; // One function can bind to multiple Key options -class LLKeyBind +class LL_COMMON_API LLKeyBind { public: - LLKeyBind() {} + LLKeyBind() = default; LLKeyBind(const LLSD &key_bind); bool operator==(const LLKeyBind& rhs); diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp deleted file mode 100644 index cc258e4609a..00000000000 --- a/indra/llcommon/llmetricperformancetester.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/** - * @file llmetricperformancetester.cpp - * @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes implementation - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "indra_constants.h" -#include "llerror.h" -#include "llsdserialize.h" -#include "lltreeiterators.h" -#include "llmetricperformancetester.h" -#include "llfasttimer.h" - -//---------------------------------------------------------------------------------------------- -// LLMetricPerformanceTesterBasic : static methods and testers management -//---------------------------------------------------------------------------------------------- - -LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ; - -/*static*/ -void LLMetricPerformanceTesterBasic::cleanupClass() -{ - for (name_tester_map_t::value_type& pair : sTesterMap) - { - delete pair.second; - } - sTesterMap.clear() ; -} - -/*static*/ -bool LLMetricPerformanceTesterBasic::addTester(LLMetricPerformanceTesterBasic* tester) -{ - llassert_always(tester != NULL); - std::string name = tester->getTesterName() ; - if (getTester(name)) - { - LL_ERRS() << "Tester name is already used by some other tester : " << name << LL_ENDL ; - return false; - } - - sTesterMap.insert(std::make_pair(name, tester)); - return true; -} - -/*static*/ -void LLMetricPerformanceTesterBasic::deleteTester(std::string name) -{ - name_tester_map_t::iterator tester = sTesterMap.find(name); - if (tester != sTesterMap.end()) - { - delete tester->second; - sTesterMap.erase(tester); - } -} - -/*static*/ -LLMetricPerformanceTesterBasic* LLMetricPerformanceTesterBasic::getTester(std::string name) -{ - // Check for the requested metric name - name_tester_map_t::iterator found_it = sTesterMap.find(name) ; - if (found_it != sTesterMap.end()) - { - return found_it->second ; - } - return NULL ; -} - -/*static*/ -// Return true if this metric is requested or if the general default "catch all" metric is requested -bool LLMetricPerformanceTesterBasic::isMetricLogRequested(std::string name) -{ - return (LLTrace::BlockTimer::sMetricLog && ((LLTrace::BlockTimer::sLogName == name) || (LLTrace::BlockTimer::sLogName == DEFAULT_METRIC_NAME))); -} - -/*static*/ -LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& is) -{ - LLSD ret; - LLSD cur; - - while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is)) - { - for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) - { - std::string label = iter->first; - - LLMetricPerformanceTesterBasic* tester = LLMetricPerformanceTesterBasic::getTester(iter->second["Name"].asString()) ; - if(tester) - { - ret[label]["Name"] = iter->second["Name"] ; - - auto num_of_metrics = tester->getNumberOfMetrics() ; - for(size_t index = 0 ; index < num_of_metrics ; index++) - { - ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ; - } - } - } - } - - return ret; -} - -/*static*/ -void LLMetricPerformanceTesterBasic::doAnalysisMetrics(std::string baseline, std::string target, std::string output) -{ - if(!LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) - { - return ; - } - - // Open baseline and current target, exit if one is inexistent - llifstream base_is(baseline.c_str()); - llifstream target_is(target.c_str()); - if (!base_is.is_open() || !target_is.is_open()) - { - LL_WARNS() << "'-analyzeperformance' error : baseline or current target file inexistent" << LL_ENDL; - base_is.close(); - target_is.close(); - return; - } - - //analyze baseline - LLSD base = analyzeMetricPerformanceLog(base_is); - base_is.close(); - - //analyze current - LLSD current = analyzeMetricPerformanceLog(target_is); - target_is.close(); - - //output comparision - llofstream os(output.c_str()); - - os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n"; - for (LLMetricPerformanceTesterBasic::name_tester_map_t::value_type& pair : LLMetricPerformanceTesterBasic::sTesterMap) - { - LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)pair.second); - tester->analyzePerformance(&os, &base, ¤t) ; - } - - os.flush(); - os.close(); -} - - -//---------------------------------------------------------------------------------------------- -// LLMetricPerformanceTesterBasic : Tester instance methods -//---------------------------------------------------------------------------------------------- - -LLMetricPerformanceTesterBasic::LLMetricPerformanceTesterBasic(std::string name) : - mName(name), - mCount(0) -{ - if (mName == std::string()) - { - LL_ERRS() << "LLMetricPerformanceTesterBasic construction invalid : Empty name passed to constructor" << LL_ENDL ; - } - - mValidInstance = LLMetricPerformanceTesterBasic::addTester(this) ; -} - -LLMetricPerformanceTesterBasic::~LLMetricPerformanceTesterBasic() -{ -} - -void LLMetricPerformanceTesterBasic::preOutputTestResults(LLSD* sd) -{ - incrementCurrentCount() ; -} - -void LLMetricPerformanceTesterBasic::postOutputTestResults(LLSD* sd) -{ - LLTrace::BlockTimer::pushLog(*sd); -} - -void LLMetricPerformanceTesterBasic::outputTestResults() -{ - LLSD sd; - - preOutputTestResults(&sd) ; - outputTestRecord(&sd) ; - postOutputTestResults(&sd) ; -} - -void LLMetricPerformanceTesterBasic::addMetric(std::string str) -{ - mMetricStrings.push_back(str) ; -} - -/*virtual*/ -void LLMetricPerformanceTesterBasic::analyzePerformance(llofstream* os, LLSD* base, LLSD* current) -{ - resetCurrentCount() ; - - std::string current_label = getCurrentLabelName(); - bool in_base = (*base).has(current_label) ; - bool in_current = (*current).has(current_label) ; - - while(in_base || in_current) - { - LLSD::String label = current_label ; - - if(in_base && in_current) - { - *os << llformat("%s\n", label.c_str()) ; - - for(U32 index = 0 ; index < mMetricStrings.size() ; index++) - { - switch((*current)[label][ mMetricStrings[index] ].type()) - { - case LLSD::TypeInteger: - compareTestResults(os, mMetricStrings[index], - (S32)((*base)[label][ mMetricStrings[index] ].asInteger()), (S32)((*current)[label][ mMetricStrings[index] ].asInteger())) ; - break ; - case LLSD::TypeReal: - compareTestResults(os, mMetricStrings[index], - (F32)((*base)[label][ mMetricStrings[index] ].asReal()), (F32)((*current)[label][ mMetricStrings[index] ].asReal())) ; - break; - default: - LL_ERRS() << "unsupported metric " << mMetricStrings[index] << " LLSD type: " << (S32)(*current)[label][ mMetricStrings[index] ].type() << LL_ENDL ; - } - } - } - - incrementCurrentCount(); - current_label = getCurrentLabelName(); - in_base = (*base).has(current_label) ; - in_current = (*current).has(current_label) ; - } -} - -/*virtual*/ -void LLMetricPerformanceTesterBasic::compareTestResults(llofstream* os, std::string metric_string, S32 v_base, S32 v_current) -{ - *os << llformat(" ,%s, %d, %d, %d, %.4f\n", metric_string.c_str(), v_base, v_current, - v_current - v_base, (v_base != 0) ? 100.f * v_current / v_base : 0) ; -} - -/*virtual*/ -void LLMetricPerformanceTesterBasic::compareTestResults(llofstream* os, std::string metric_string, F32 v_base, F32 v_current) -{ - *os << llformat(" ,%s, %.4f, %.4f, %.4f, %.4f\n", metric_string.c_str(), v_base, v_current, - v_current - v_base, (fabs(v_base) > 0.0001f) ? 100.f * v_current / v_base : 0.f ) ; -} - -//---------------------------------------------------------------------------------------------- -// LLMetricPerformanceTesterWithSession -//---------------------------------------------------------------------------------------------- - -LLMetricPerformanceTesterWithSession::LLMetricPerformanceTesterWithSession(std::string name) : - LLMetricPerformanceTesterBasic(name), - mBaseSessionp(NULL), - mCurrentSessionp(NULL) -{ -} - -LLMetricPerformanceTesterWithSession::~LLMetricPerformanceTesterWithSession() -{ - if (mBaseSessionp) - { - delete mBaseSessionp ; - mBaseSessionp = NULL ; - } - if (mCurrentSessionp) - { - delete mCurrentSessionp ; - mCurrentSessionp = NULL ; - } -} - -/*virtual*/ -void LLMetricPerformanceTesterWithSession::analyzePerformance(llofstream* os, LLSD* base, LLSD* current) -{ - // Load the base session - resetCurrentCount() ; - mBaseSessionp = loadTestSession(base) ; - - // Load the current session - resetCurrentCount() ; - mCurrentSessionp = loadTestSession(current) ; - - if (!mBaseSessionp || !mCurrentSessionp) - { - LL_ERRS() << "Error loading test sessions." << LL_ENDL ; - } - - // Compare - compareTestSessions(os) ; - - // Release memory - if (mBaseSessionp) - { - delete mBaseSessionp ; - mBaseSessionp = NULL ; - } - if (mCurrentSessionp) - { - delete mCurrentSessionp ; - mCurrentSessionp = NULL ; - } -} - - -//---------------------------------------------------------------------------------------------- -// LLTestSession -//---------------------------------------------------------------------------------------------- - -LLMetricPerformanceTesterWithSession::LLTestSession::~LLTestSession() -{ -} - diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h deleted file mode 100644 index 78abd536022..00000000000 --- a/indra/llcommon/llmetricperformancetester.h +++ /dev/null @@ -1,215 +0,0 @@ -/** - * @file llmetricperformancetester.h - * @brief LLMetricPerformanceTesterBasic and LLMetricPerformanceTesterWithSession classes definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_METRICPERFORMANCETESTER_H -#define LL_METRICPERFORMANCETESTER_H - -char const* const DEFAULT_METRIC_NAME = "metric"; - -/** - * @class LLMetricPerformanceTesterBasic - * @brief Performance Metric Base Class - */ -class LL_COMMON_API LLMetricPerformanceTesterBasic -{ -public: - /** - * @brief Creates a basic tester instance. - * @param[in] name - Unique string identifying this tester instance. - */ - LLMetricPerformanceTesterBasic(std::string name); - virtual ~LLMetricPerformanceTesterBasic(); - - /** - * @return Returns true if the instance has been added to the tester map. - * Need to be tested after creation of a tester instance so to know if the tester is correctly handled. - * A tester might not be added to the map if another tester with the same name already exists. - */ - bool isValid() const { return mValidInstance; } - - /** - * @brief Write a set of test results to the log LLSD. - */ - void outputTestResults() ; - - /** - * @brief Compare the test results. - * By default, compares the test results against the baseline one by one, item by item, - * in the increasing order of the LLSD record counter, starting from the first one. - */ - virtual void analyzePerformance(llofstream* os, LLSD* base, LLSD* current) ; - - static void doAnalysisMetrics(std::string baseline, std::string target, std::string output) ; - - /** - * @return Returns the number of the test metrics in this tester instance. - */ - auto getNumberOfMetrics() const { return mMetricStrings.size() ;} - /** - * @return Returns the metric name at index - * @param[in] index - Index on the list of metrics managed by this tester instance. - */ - std::string getMetricName(size_t index) const { return mMetricStrings[index] ;} - -protected: - /** - * @return Returns the name of this tester instance. - */ - std::string getTesterName() const { return mName ;} - - /** - * @brief Insert a new metric to be managed by this tester instance. - * @param[in] str - Unique string identifying the new metric. - */ - void addMetric(std::string str) ; - - /** - * @brief Compare test results, provided in 2 flavors: compare integers and compare floats. - * @param[out] os - Formatted output string holding the compared values. - * @param[in] metric_string - Name of the metric. - * @param[in] v_base - Base value of the metric. - * @param[in] v_current - Current value of the metric. - */ - virtual void compareTestResults(llofstream* os, std::string metric_string, S32 v_base, S32 v_current) ; - virtual void compareTestResults(llofstream* os, std::string metric_string, F32 v_base, F32 v_current) ; - - /** - * @brief Reset internal record count. Count starts with 1. - */ - void resetCurrentCount() { mCount = 1; } - /** - * @brief Increment internal record count. - */ - void incrementCurrentCount() { mCount++; } - /** - * @return Returns the label to be used for the current count. It's "TesterName"-"Count". - */ - std::string getCurrentLabelName() const { return llformat("%s-%d", mName.c_str(), mCount) ;} - - /** - * @brief Write a test record to the LLSD. Implementers need to overload this method. - * @param[out] sd - The LLSD record to store metric data into. - */ - virtual void outputTestRecord(LLSD* sd) = 0 ; - -private: - void preOutputTestResults(LLSD* sd) ; - void postOutputTestResults(LLSD* sd) ; - static LLSD analyzeMetricPerformanceLog(std::istream& is) ; - - std::string mName ; // Name of this tester instance - S32 mCount ; // Current record count - bool mValidInstance; // true if the instance is managed by the map - std::vector< std::string > mMetricStrings ; // Metrics strings - -// Static members managing the collection of testers -public: - // Map of all the tester instances in use - typedef std::map< std::string, LLMetricPerformanceTesterBasic* > name_tester_map_t; - static name_tester_map_t sTesterMap ; - - /** - * @return Returns a pointer to the tester - * @param[in] name - Name of the tester instance queried. - */ - static LLMetricPerformanceTesterBasic* getTester(std::string name) ; - - /** - * @return Delete the named tester from the list - * @param[in] name - Name of the tester instance to delete. - */ - static void deleteTester(std::string name); - - /** - * @return Returns true if that metric *or* the default catch all metric has been requested to be logged - * @param[in] name - Name of the tester queried. - */ - static bool isMetricLogRequested(std::string name); - - /** - * @return Returns true if there's a tester defined, false otherwise. - */ - static bool hasMetricPerformanceTesters() { return !sTesterMap.empty() ;} - /** - * @brief Delete all testers and reset the tester map - */ - static void cleanupClass() ; - -private: - // Add a tester to the map. Returns false if adding fails. - static bool addTester(LLMetricPerformanceTesterBasic* tester) ; -}; - -/** - * @class LLMetricPerformanceTesterWithSession - * @brief Performance Metric Class with custom session - */ -class LL_COMMON_API LLMetricPerformanceTesterWithSession : public LLMetricPerformanceTesterBasic -{ -public: - /** - * @param[in] name - Unique string identifying this tester instance. - */ - LLMetricPerformanceTesterWithSession(std::string name); - virtual ~LLMetricPerformanceTesterWithSession(); - - /** - * @brief Compare the test results. - * This will be loading the base and current sessions and compare them using the virtual - * abstract methods loadTestSession() and compareTestSessions() - */ - virtual void analyzePerformance(llofstream* os, LLSD* base, LLSD* current) ; - -protected: - /** - * @class LLMetricPerformanceTesterWithSession::LLTestSession - * @brief Defines an interface for the two abstract virtual functions loadTestSession() and compareTestSessions() - */ - class LL_COMMON_API LLTestSession - { - public: - virtual ~LLTestSession() ; - }; - - /** - * @brief Convert an LLSD log into a test session. - * @param[in] log - The LLSD record - * @return Returns the record as a test session - */ - virtual LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) = 0; - - /** - * @brief Compare the base session and the target session. Assumes base and current sessions have been loaded. - * @param[out] os - The comparison result as a standard stream - */ - virtual void compareTestSessions(llofstream* os) = 0; - - LLTestSession* mBaseSessionp; - LLTestSession* mCurrentSessionp; -}; - -#endif - diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index be1ae89a259..c4032db6b08 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -355,45 +355,6 @@ void LLCondition::broadcast() mCond.notify_all(); } - -//--------------------------------------------------------------------- -// -// LLMutexTrylock -// -LLMutexTrylock::LLMutexTrylock(LLMutex* mutex) - : mMutex(mutex), - mLocked(false) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; - if (mMutex) - mLocked = mMutex->trylock(); -} - -LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms) - : mMutex(mutex), - mLocked(false) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; - if (!mMutex) - return; - - for (U32 i = 0; i < aTries; ++i) - { - mLocked = mMutex->trylock(); - if (mLocked) - break; - ms_sleep(delay_ms); - } -} - -LLMutexTrylock::~LLMutexTrylock() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; - if (mMutex && mLocked) - mMutex->unlock(); -} - - //--------------------------------------------------------------------- // // LLScopedLock diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index bc3d8fed062..7e6ca5da8aa 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -225,9 +225,31 @@ using LLExclusiveMutexLock = LLSharedMutexLockTemplate; class LLMutexTrylock { public: - LLMutexTrylock(LLMutex* mutex); - LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10); - ~LLMutexTrylock(); + LLMutexTrylock(LLMutex* mutex) : mMutex(mutex), mLocked(false) + { + if (mMutex) + mLocked = mMutex->trylock(); + } + + LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms) : mMutex(mutex), mLocked(false) + { + if (!mMutex) + return; + + for (U32 i = 0; i < aTries; ++i) + { + mLocked = mMutex->trylock(); + if (mLocked) + break; + std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); + } + } + + ~LLMutexTrylock() + { + if (mMutex && mLocked) + mMutex->unlock(); + } bool isLocked() const { diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h index 7897b2b5066..c2f1db44eed 100644 --- a/indra/llcommon/llpointer.h +++ b/indra/llcommon/llpointer.h @@ -44,7 +44,7 @@ //---------------------------------------------------------------------------- -class LLPointerBase +class LL_COMMON_API LLPointerBase { protected: // alert the coder that a referenced type's destructor did something very diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h index 91c623eae13..45c947fbf58 100644 --- a/indra/llcommon/llpredicate.h +++ b/indra/llcommon/llpredicate.h @@ -33,7 +33,7 @@ namespace LLPredicate { template class Rule; - extern const U32 cPredicateFlagsFromEnum[5]; + extern LL_COMMON_API const U32 cPredicateFlagsFromEnum[5]; template class Value diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp index 39bbfc3eab5..0bf1ac706ae 100644 --- a/indra/llcommon/llprocess.cpp +++ b/indra/llcommon/llprocess.cpp @@ -25,6 +25,8 @@ */ #include "linden_common.h" +#include "llwin32headers.h" + #include "llprocess.h" #include "llsdutil.h" #include "llsdserialize.h" diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h index 0c71cfc4159..ecdedbbaa30 100644 --- a/indra/llcommon/llprocess.h +++ b/indra/llcommon/llprocess.h @@ -30,6 +30,7 @@ #include "llinitparam.h" #include "llsdparam.h" #include "llexception.h" +#include "llwin32headers.h" #include "apr_thread_proc.h" #include #include // std::ostream diff --git a/indra/llcommon/llrand.cpp b/indra/llcommon/llrand.cpp index 64a8e893ac3..810f32d1a83 100644 --- a/indra/llcommon/llrand.cpp +++ b/indra/llcommon/llrand.cpp @@ -29,6 +29,8 @@ #include "llrand.h" #include "lluuid.h" +#include + /** * Through analysis, we have decided that we want to take values which * are close enough to 1.0 to map back to 0.0. We came to this diff --git a/indra/llcommon/llregex.h b/indra/llcommon/llregex.h index 18da304aeee..5c1607e7be4 100644 --- a/indra/llcommon/llregex.h +++ b/indra/llcommon/llregex.h @@ -28,7 +28,7 @@ #include template -LL_COMMON_API bool ll_regex_match(const S& string, M& match, const R& regex) +inline bool ll_regex_match(const S& string, M& match, const R& regex) { try { @@ -43,7 +43,7 @@ LL_COMMON_API bool ll_regex_match(const S& string, M& match, const R& regex) } template -LL_COMMON_API bool ll_regex_match(const S& string, const R& regex) +inline bool ll_regex_match(const S& string, const R& regex) { try { @@ -58,7 +58,7 @@ LL_COMMON_API bool ll_regex_match(const S& string, const R& regex) } template -bool ll_regex_search(const S& string, M& match, const R& regex) +inline bool ll_regex_search(const S& string, M& match, const R& regex) { try { @@ -73,7 +73,7 @@ bool ll_regex_search(const S& string, M& match, const R& regex) } template -bool ll_regex_search(const S& string, const R& regex) +inline bool ll_regex_search(const S& string, const R& regex) { try { diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h index bee9e81b607..5ce80d91467 100644 --- a/indra/llcommon/llsdjson.h +++ b/indra/llcommon/llsdjson.h @@ -52,17 +52,17 @@ /// /// For maps and arrays child entries will be converted and added to the structure. /// Order is preserved for an array but not for objects. -LLSD LlsdFromJson(const simdjson::dom::element& val); +LL_COMMON_API LLSD LlsdFromJson(const simdjson::dom::element& val); /// Parse a JSON document from text and convert it into LLSD as above. /// Returns false (leaving out undefined) on a parse failure; if errmsg is /// non-null it receives a description of the failure. -bool LlsdFromJsonString(std::string_view json, LLSD& out, std::string* errmsg = nullptr); +LL_COMMON_API bool LlsdFromJsonString(std::string_view json, LLSD& out, std::string* errmsg = nullptr); /// As above, but parses the buffer in place with no internal copy. Callers /// that materialize a document from raw bytes should read directly into a /// simdjson::padded_string and use this overload. -bool LlsdFromJsonString(const simdjson::padded_string& json, LLSD& out, std::string* errmsg = nullptr); +LL_COMMON_API bool LlsdFromJsonString(const simdjson::padded_string& json, LLSD& out, std::string* errmsg = nullptr); /// disambiguate std::string and C strings against the string_view and /// padded_string overloads (padded_string converts implicitly from @@ -94,6 +94,6 @@ inline bool LlsdFromJsonString(const char* json, LLSD& out, std::string* errmsg /// TypeMap | object /// TypeArray | array /// TypeBinary | unsupported -std::string LlsdToJson(const LLSD& val); +LL_COMMON_API std::string LlsdToJson(const LLSD& val); #endif // LL_LLSDJSON_H diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index a70de156553..d2e062f4d29 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -46,6 +46,8 @@ #if !LL_WINDOWS #include // htonl & ntohl +#else +#include "llwin32headers.h" #endif #include "lldate.h" diff --git a/indra/llcommon/llsdutil.h b/indra/llcommon/llsdutil.h index 497c0ad3eb7..4f4fa13ea2a 100644 --- a/indra/llcommon/llsdutil.h +++ b/indra/llcommon/llsdutil.h @@ -85,7 +85,7 @@ LL_COMMON_API bool compare_llsd_with_template( // (3) The element of an array with exactly one element is taken as a template // for *all* the elements of the test array. If the template array is of // different size, compare_llsd_with_template() semantics apply. -bool filter_llsd_with_template( +LL_COMMON_API bool filter_llsd_with_template( const LLSD & llsd_to_test, const LLSD & template_llsd, LLSD & resultant_llsd); @@ -192,8 +192,8 @@ namespace llsd * By implication, if path.isUndefined() or otherwise equivalent to an empty * LLSD::Array, drill[_ref]() returns 'blob' as is. */ -LLSD drill(const LLSD& blob, const LLSD& path); -LLSD& drill_ref( LLSD& blob, const LLSD& path); +LL_COMMON_API LLSD drill(const LLSD& blob, const LLSD& path); +LL_COMMON_API LLSD& drill_ref(LLSD& blob, const LLSD& path); } @@ -535,12 +535,12 @@ class inMap // when encountered in a map. A key name of "*" can be specified as a wild card // and will specify the default behavior. If no wild card is given and the clone // encounters a name not in the filter, that value will be skipped. -LLSD llsd_clone(LLSD value, LLSD filter = LLSD()); +LL_COMMON_API LLSD llsd_clone(LLSD value, LLSD filter = LLSD()); // Creates a shallow copy of a map or array. If passed any other type of LLSD // object it simply returns that value. See llsd_clone for a description of // the filter parameter. -LLSD llsd_shallow(LLSD value, LLSD filter = LLSD()); +LL_COMMON_API LLSD llsd_shallow(LLSD value, LLSD filter = LLSD()); namespace llsd { @@ -722,7 +722,7 @@ namespace LL *****************************************************************************/ // validate incoming LLSD blob, and return an LLSD array suitable to pass to // the function of interest -LLSD apply_llsd_fix(size_t arity, const LLSD& args); +LL_COMMON_API LLSD apply_llsd_fix(size_t arity, const LLSD& args); // Derived from https://stackoverflow.com/a/20441189 // and https://en.cppreference.com/w/cpp/utility/apply . diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index 05dc3cde79d..1e8fb74b0ef 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -33,9 +33,12 @@ #include "llexception.h" #include "llcoros.h" #include +#include #include // std::cerr in dire emergency #include #include +#include +#include // Our master list of all LLSingletons is itself an LLSingleton. We used to // store it in a function-local static, but that could get destroyed before @@ -165,6 +168,35 @@ class LLSingletonBase::MasterList: } }; +// Process-wide count of LLSingletons currently between push_initializing() and +// pop_initializing(). See the declaration in llsingleton.h and getInstance(). +std::atomic LLSingletonBase::sInitializingDepth{0}; + +//static +LLSingletonBase::SingletonSlot& LLSingletonBase::getSlot(const char* type_name) +{ + // The canonical per-type slots live here, in a single translation unit -- + // hence a single module even in a multi-DLL build -- so every module that + // instantiates LLSingleton resolves the SAME slot for a given type. + // + // Keyed by the mangled name STRING (typeid(T).name()), NOT std::type_index. + // We build with -fvisibility=hidden, so each module has its own type_info + // object for T; comparing those by identity (which is what type_index does) + // would treat the same T as a different key in each module and duplicate the + // slot. The mangled name string is identical across modules for one ABI, so + // a value (string) compare collapses them to a single slot. + // + // The registry is heap-allocated and intentionally never freed so it + // outlives every LLSingleton (which are themselves leaked unless + // deleteAll()'d, and whose destructors re-lock their slot). unordered_map + // node addresses are stable across rehash, so the returned reference is + // valid for the life of the process. + static std::mutex* sRegistryMutex = new std::mutex(); + static auto* sRegistry = new std::unordered_map(); + std::lock_guard lk(*sRegistryMutex); + return (*sRegistry)[type_name]; +} + void LLSingletonBase::add_master() { // As each new LLSingleton is constructed, add to the master list. @@ -201,6 +233,10 @@ void LLSingletonBase::push_initializing(const char* name) // log BEFORE pushing so logging singletons don't cry circularity locked_list.log("Pushing", name); locked_list.get().push_back(this); + // A singleton is now mid-initialization: force getInstance() everywhere off + // its lock-free fast path so dependencies are still captured. Balanced by + // pop_initializing() / reset_initializing(). + sInitializingDepth.fetch_add(1, std::memory_order_release); } void LLSingletonBase::pop_initializing() @@ -219,6 +255,7 @@ void LLSingletonBase::pop_initializing() LLSingletonBase* back(list.back()); // and pop it list.pop_back(); + sInitializingDepth.fetch_sub(1, std::memory_order_release); // The viewer launches an open-ended number of coroutines. While we don't // expect most of them to initialize LLSingleton instances, our present @@ -259,6 +296,7 @@ void LLSingletonBase::reset_initializing(list_t::size_type size) while (list.size() > size) { list.pop_back(); + sInitializingDepth.fetch_sub(1, std::memory_order_release); } // as in pop_initializing() diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 2bd39918901..b2b8f9c1aef 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -25,13 +25,15 @@ #ifndef LLSINGLETON_H #define LLSINGLETON_H +#include #include #include #include #include #include #include -#include "lockstatic.h" +#include "llpreprocessor.h" // LL_COMMON_API +#include "lockstatic.h" // unrelated consumers rely on transitive include #include "llthread.h" // on_main_thread() #include "llmainthreadtask.h" #include "llprofiler.h" @@ -42,7 +44,7 @@ #pragma warning(disable : 4506) // no definition for inline function #endif -class LLSingletonBase +class LL_COMMON_API LLSingletonBase { public: class MasterList; @@ -75,6 +77,48 @@ class LLSingletonBase DELETED // deleteSingleton() or deleteAll() called } EInitState; + // Canonical per-type storage for one LLSingleton specialization. The class + // template LLSingleton deliberately keeps *no* instance storage of its + // own; it routes through getSlot() below. That matters for DLL safety: a + // function-local or template-static would be duplicated once per module in + // a multi-DLL build (each DLL getting its own "singleton"), whereas getSlot + // lives in exactly one translation unit, so every module resolves the same + // slot. See getSlot(). + struct SingletonSlot + { + // recursive so a constructor/initSingleton() may re-enter getInstance() + std::recursive_mutex mMutex; + // Lock-free fast-path handle. Published (release) ONLY once the instance + // is fully INITIALIZED, and cleared (release) on deletion. A non-null + // load therefore always yields a completely constructed instance. + std::atomic mFastInstance{nullptr}; + // Canonical instance pointer and state, both guarded by mMutex. These + // mirror the old per-type SingletonData exactly. + void* mInstance{nullptr}; + EInitState mInitState{UNINITIALIZED}; + }; + + // Return the one canonical slot for the singleton type whose mangled name + // is 'type_name' (pass typeid(T).name()). Defined in llsingleton.cpp, hence + // single-instance per process even across DLL boundaries. + // + // Keyed by the mangled NAME STRING, deliberately NOT by std::type_index: + // we build with -fvisibility=hidden, so each module gets its own type_info + // object for T. type_info identity / std::type_index therefore compare + // UNEQUAL across modules and would yield a separate slot per module -- the + // very duplication we are eliminating. The mangled name string, by + // contrast, is identical across modules for the same type under one ABI. + // The returned reference is stable for the life of the process. + static SingletonSlot& getSlot(const char* type_name); + + // Number of LLSingletons anywhere in the process currently between + // push_initializing() and pop_initializing(). When this is zero, no + // dependency can possibly be captured, so getInstance() may take the + // lock-free fast path and skip capture_dependency() entirely. A single + // shared (exported) counter; a conservative over-approximation across + // threads is fine -- see getInstance(). + static std::atomic sInitializingDepth; + // Define tag to pass to our template constructor. You can't explicitly // invoke a template constructor with ordinary template syntax: // http://stackoverflow.com/a/3960925/5533635 @@ -230,6 +274,10 @@ LLSingletonBase::LLSingletonBase(tag): LLSingleton_manage_master().push_initializing(this); } +// forward declare for friend directive within LLSingleton +template +class LLParamSingleton; + /** * LLSingleton implements the getInstance() method part of the Singleton * pattern. It can't make the derived class constructors protected, though, so @@ -290,40 +338,67 @@ template class LLSingleton : public LLSingletonBase { private: - // LLSingleton must have a distinct instance of - // SingletonData for every distinct DERIVED_TYPE. It's tempting to - // consider hoisting SingletonData up into LLSingletonBase. Don't do it. - struct SingletonData + // LLSingleton keeps NO instance storage of its own. All + // per-type state lives in the one canonical SingletonSlot returned by + // LLSingletonBase::getSlot() (defined in llsingleton.cpp, hence single- + // instance per process even in a multi-DLL build). sSlot below is merely a + // per-module *cache* of that slot's stable address. Caching the same + // pointer independently in each module is harmless -- and that is exactly + // what makes this DLL-safe, where a function-local/template static instance + // would silently give each module its own "singleton". + // + // sSlot must be a constant-initialized inline static (NOT a function-local + // static) so the fast path pays no magic-static guard. relaxed atomic: + // concurrent first-touchers merely race to store the identical value. + static inline std::atomic sSlot{nullptr}; + + static SingletonSlot& slot() { - // Use a recursive_mutex in case of constructor circularity. With a - // non-recursive mutex, that would result in deadlock. - typedef std::recursive_mutex mutex_t; - LL_PROFILE_MUTEX(mutex_t, mMutex); // LockStatic looks for mMutex + SingletonSlot* s = sSlot.load(std::memory_order_relaxed); + if (LL_UNLIKELY(! s)) + { + // first touch in this module: resolve once and cache + s = &getSlot(typeid(DERIVED_TYPE).name()); + sSlot.store(s, std::memory_order_relaxed); + } + return *s; + } - EInitState mInitState{UNINITIALIZED}; - DERIVED_TYPE* mInstance{nullptr}; + // RAII handle that locks our slot's recursive mutex and exposes the slot + // through operator->, so the construction logic below reads just like the + // old LockStatic-based code (lk->mInstance, lk->mInitState, lk.unlock()). + struct SlotLock + { + SingletonSlot& mSlot; + std::unique_lock mLock; + SlotLock(): SlotLock(slot()) {} + explicit SlotLock(SingletonSlot& s): mSlot(s), mLock(s.mMutex) {} + SingletonSlot* operator->() const { return &mSlot; } + SingletonSlot& operator*() const { return mSlot; } + void unlock() { mLock.unlock(); } }; - typedef llthread::LockStatic LockStatic; + + // Allow LLParamSingleton subclass -- but NOT DERIVED_TYPE itself -- to + // access our private members. + friend class LLParamSingleton; // LLSingleton only supports a nullary constructor. However, the specific // purpose for its subclass LLParamSingleton is to support Singletons // requiring constructor arguments. constructSingleton() supports both use // cases. - // Accepting LockStatic& requires that the caller has already locked our - // static data before calling. + // Accepting SlotLock& requires that the caller has already locked our slot + // before calling. template - static void constructSingleton(LockStatic& lk, Args&&... args) + static void constructSingleton(SlotLock& lk, Args&&... args) { auto prev_size = LLSingleton_manage_master().get_initializing_size(); // Any getInstance() calls after this point are from within constructor lk->mInitState = CONSTRUCTING; + DERIVED_TYPE* instance = nullptr; try { -#if defined(LL_PROFILER_CONFIGURATION) && LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY - std::string_view typeidname(typeid(DERIVED_TYPE).name()); - LockableName(lk->mMutex, typeidname.data(), typeidname.size()); -#endif - lk->mInstance = new DERIVED_TYPE(std::forward(args)...); + instance = new DERIVED_TYPE(std::forward(args)...); + lk->mInstance = instance; } catch (const std::exception& err) { @@ -349,23 +424,26 @@ class LLSingleton : public LLSingletonBase // initialize singleton after constructing it so that it can // reference other singletons which in turn depend on it, thus // breaking cyclic dependencies - lk->mInstance->initSingleton(); + instance->initSingleton(); lk->mInitState = INITIALIZED; + // Publish to the lock-free fast path ONLY now that the instance is + // fully constructed AND initialized: a non-null mFastInstance must + // always denote a usable instance. + lk->mFastInstance.store(instance, std::memory_order_release); // pop this off stack of initializing singletons - pop_initializing(lk->mInstance); + pop_initializing(instance); } catch (const std::exception& err) { // pop this off stack of initializing singletons here, too -- // BEFORE logging, so log-machinery LLSingletons don't record a // dependency on DERIVED_TYPE! - pop_initializing(lk->mInstance); + pop_initializing(instance); logwarns({"Error in ", classname(), "::initSingleton(): ", err.what()}); - // Get rid of the instance entirely. This call depends on our - // recursive_mutex. We could have a deleteSingleton(LockStatic&) - // overload and pass lk, but we don't strictly need it. + // Get rid of the instance entirely. This call re-enters our slot's + // recursive mutex. deleteSingleton(); // propagate the exception throw; @@ -420,7 +498,9 @@ class LLSingleton : public LLSingletonBase // deleteSingleton() to defend against manual deletion. When we moved // cleanup to deleteSingleton(), we hit crashes due to dangling // pointers in the MasterList. - LockStatic lk; LL_PROFILE_MUTEX_LOCK(lk->mMutex); + SlotLock lk; + // Stop lock-free readers BEFORE tearing anything down. + lk->mFastInstance.store(nullptr, std::memory_order_release); lk->mInstance = nullptr; lk->mInitState = DELETED; @@ -446,21 +526,36 @@ class LLSingleton : public LLSingletonBase static void deleteSingleton() { // Hold the lock while we call cleanupSingleton() and the destructor. - // Our destructor also instantiates LockStatic, requiring a recursive + // Our destructor also instantiates SlotLock, requiring a recursive // mutex. - LockStatic lk; LL_PROFILE_MUTEX_LOCK(lk->mMutex); + SlotLock lk; // of course, only cleanup and delete if there's something there if (lk->mInstance) { - lk->mInstance->cleanup_(); - delete lk->mInstance; - // destructor clears mInstance (and mInitState) + DERIVED_TYPE* instance = static_cast(lk->mInstance); + instance->cleanup_(); + delete instance; + // destructor clears mFastInstance, mInstance and mInitState } } static DERIVED_TYPE* getInstance() { //LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD; // TODO -- reenable this when we have a fix for using Tracy with coroutines + SingletonSlot& s = slot(); + + // Lock-free fast path. mFastInstance is published (non-null) only when + // the instance is fully INITIALIZED. The sInitializingDepth == 0 guard + // preserves dependency tracking: while ANY singleton is mid-init we + // fall through to the locked path below so capture_dependency() still + // runs. In steady state this is two atomic loads and a predicted + // branch -- no lock taken, no dependency bookkeeping. + if (void* p = s.mFastInstance.load(std::memory_order_acquire)) + { + if (LL_LIKELY(sInitializingDepth.load(std::memory_order_acquire) == 0)) + return static_cast(p); + } + // We know the viewer has LLSingleton dependency circularities. If you // feel strongly motivated to eliminate them, cheers and good luck. // (At that point we could consider a much simpler locking mechanism.) @@ -505,7 +600,7 @@ class LLSingleton : public LLSingletonBase { // nested scope for 'lk' // In case racing threads call getInstance() at the same moment, // serialize the calls. - LockStatic lk; LL_PROFILE_MUTEX_LOCK(lk->mMutex); + SlotLock lk(s); switch (lk->mInitState) { @@ -521,11 +616,14 @@ class LLSingleton : public LLSingletonBase // here if DERIVED_TYPE::initSingleton() (directly or indirectly) // calls DERIVED_TYPE::getInstance(): go ahead and allow it case INITIALIZED: + { // normal subsequent calls // record the dependency, if any: check if we got here from another // LLSingleton's constructor or initSingleton() method - capture_dependency(lk->mInstance); - return lk->mInstance; + DERIVED_TYPE* instance = static_cast(lk->mInstance); + capture_dependency(instance); + return instance; + } case DELETED: // called after deleteSingleton() @@ -549,8 +647,9 @@ class LLSingleton : public LLSingletonBase // On the main thread, directly construct the instance while // holding the lock. constructSingleton(lk); - capture_dependency(lk->mInstance); - return lk->mInstance; + DERIVED_TYPE* instance = static_cast(lk->mInstance); + capture_dependency(instance); + return instance; } // Here we need to construct a new instance, but we're on a secondary @@ -594,9 +693,9 @@ class LLSingleton : public LLSingletonBase // Use this to avoid accessing singletons before they can safely be constructed. static bool instanceExists() { - // defend any access to sData from racing threads - LockStatic lk; LL_PROFILE_MUTEX_LOCK(lk->mMutex); - return lk->mInitState == INITIALIZED; + // mFastInstance is published non-null iff INITIALIZED, so this is an + // exact, lock-free equivalent of the old (mInitState == INITIALIZED). + return slot().mFastInstance.load(std::memory_order_acquire) != nullptr; } // Has this singleton been deleted? This can be useful during shutdown @@ -604,12 +703,197 @@ class LLSingleton : public LLSingletonBase // cleaned up. static bool wasDeleted() { - // defend any access to sData from racing threads - LockStatic lk; LL_PROFILE_MUTEX_LOCK(lk->mMutex); + // DELETED is indistinguishable from UNINITIALIZED on the fast path, so + // take the lock for this (cold, shutdown-time) query. + SlotLock lk; return lk->mInitState == DELETED; } }; + +/** + * LLParamSingleton is like LLSingleton, except in the following ways: + * + * * It is NOT instantiated on demand (instance() or getInstance()). You must + * first call initParamSingleton(constructor args...). + * * Before initParamSingleton(), calling instance() or getInstance() dies with + * LL_ERRS. + * * initParamSingleton() may be called only once. A second call dies with + * LL_ERRS. + * * However, distinct initParamSingleton() calls can be used to engage + * different constructors, as long as only one such call is executed at + * runtime. + * * Unlike LLSingleton, an LLParamSingleton cannot be "revived" by an + * instance() or getInstance() call after deleteSingleton(). + * + * Importantly, though, each LLParamSingleton subclass does participate in the + * dependency-ordered LLSingletonBase::deleteAll() processing. + */ +template +class LLParamSingleton : public LLSingleton +{ +private: + typedef LLSingleton super; + // SingletonSlot is protected in LLSingletonBase; SlotLock is private in + // LLSingleton (reachable here via the friend declaration in LLSingleton). + using SingletonSlot = typename LLSingletonBase::SingletonSlot; + using typename super::SlotLock; + + // Passes arguments to DERIVED_TYPE's constructor and sets appropriate + // states, returning a pointer to the new instance. + template + static DERIVED_TYPE* initParamSingleton_(Args&&... args) + { + // In case racing threads both call initParamSingleton() at the same + // time, serialize them. One should initialize; the other should see + // mInitState already set. + SlotLock lk; + // For organizational purposes this function shouldn't be called twice + if (lk->mInitState != super::UNINITIALIZED && lk->mInitState != super::DELETED) + { + super::logerrs({"Tried to initialize singleton ", + super::template classname(), + " twice!"}); + return nullptr; + } + else if (on_main_thread()) + { + // on the main thread, simply construct instance while holding lock + super::logdebugs({super::template classname(), + "::initParamSingleton()"}); + super::constructSingleton(lk, std::forward(args)...); + return static_cast(lk->mInstance); + } + else + { + // on secondary thread, dispatch to main thread -- + // set state so we catch any other calls before the main thread + // picks up the task + lk->mInitState = super::QUEUED; + // very important to unlock here so main thread can actually process + lk.unlock(); + super::loginfos({super::template classname(), + "::initParamSingleton() dispatching to main thread"}); + // Normally it would be the height of folly to reference-bind + // 'args' into a lambda to be executed on some other thread! By + // the time that thread executed the lambda, the references would + // all be dangling, and Bad Things would result. But + // LLMainThreadTask::dispatch() promises to block until the passed + // task has completed. So in this case we know the references will + // remain valid until the lambda has run, so we dare to bind + // references. + auto instance = LLMainThreadTask::dispatch( + [&](){ + super::loginfos({super::template classname(), + "::initParamSingleton() on main thread"}); + return initParamSingleton_(std::forward(args)...); + }); + super::loginfos({super::template classname(), + "::initParamSingleton() returning on requesting thread"}); + return instance; + } + } + +public: + using super::deleteSingleton; + using super::instanceExists; + using super::wasDeleted; + + /// initParamSingleton() constructs the instance, returning a reference. + /// Pass whatever arguments are required to construct DERIVED_TYPE. + template + static DERIVED_TYPE& initParamSingleton(Args&&... args) + { + return *initParamSingleton_(std::forward(args)...); + } + + static DERIVED_TYPE* getInstance() + { + SingletonSlot& s = super::slot(); + // Lock-free fast path, identical in spirit to LLSingleton::getInstance(). + if (void* p = s.mFastInstance.load(std::memory_order_acquire)) + { + if (LL_LIKELY(LLSingletonBase::sInitializingDepth.load(std::memory_order_acquire) == 0)) + return static_cast(p); + } + + // In case racing threads call getInstance() at the same moment as + // initParamSingleton(), serialize the calls. + SlotLock lk(s); + + switch (lk->mInitState) + { + case super::UNINITIALIZED: + case super::QUEUED: + super::logerrs({"Uninitialized param singleton ", + super::template classname()}); + break; + + case super::CONSTRUCTING: + super::logerrs({"Tried to access param singleton ", + super::template classname(), + " from singleton constructor!"}); + break; + + case super::INITIALIZING: + // As with LLSingleton, explicitly permit circular calls from + // within initSingleton() + case super::INITIALIZED: + { + // for any valid call, capture dependencies + DERIVED_TYPE* instance = static_cast(lk->mInstance); + super::capture_dependency(instance); + return instance; + } + + case super::DELETED: + super::logerrs({"Trying to access deleted param singleton ", + super::template classname()}); + break; + } + + // should never actually get here; this is to pacify the compiler, + // which assumes control might return from logerrs() + return nullptr; + } + + // instance() is replicated here so it calls + // LLParamSingleton::getInstance() rather than LLSingleton::getInstance() + // -- avoid making getInstance() virtual + static DERIVED_TYPE& instance() + { + return *getInstance(); + } +}; + +/** + * Initialization locked singleton, only derived class can decide when to initialize. + * Starts locked. + * For cases when singleton has a dependency onto something or. + * + * LLLockedSingleton is like an LLParamSingleton with a nullary constructor. + * It cannot be instantiated on demand (instance() or getInstance() call) -- + * it must be instantiated by calling construct(). However, it does + * participate in dependency-ordered LLSingletonBase::deleteAll() processing. + */ +template +class LLLockedSingleton : public LLParamSingleton
+{ + typedef LLParamSingleton
super; + +public: + using super::deleteSingleton; + using super::getInstance; + using super::instance; + using super::instanceExists; + using super::wasDeleted; + + static DT* construct() + { + return &super::initParamSingleton(); + } +}; + /** * Use LLSINGLETON(Foo); at the start of an LLSingleton subclass body * when you want to declare an out-of-line constructor: diff --git a/indra/llcommon/llstaticstringtable.h b/indra/llcommon/llstaticstringtable.h index 55a966a76f5..514d0fff754 100644 --- a/indra/llcommon/llstaticstringtable.h +++ b/indra/llcommon/llstaticstringtable.h @@ -28,11 +28,16 @@ #ifndef LL_STATIC_STRING_TABLE_H #define LL_STATIC_STRING_TABLE_H +#include "llpreprocessor.h" + #include "lldefs.h" #include "llstl.h" #include +// Header-only: all methods are inline/defaulted, so do NOT tag LL_COMMON_API. +// Tagging would make consumers import a dtor (and, via the table below, boost +// unordered_map methods) that the DLL never emits. class LLStaticHashedString { public: @@ -42,6 +47,7 @@ class LLStaticHashedString string_hash = makehash(s); string = s; } + ~LLStaticHashedString() = default; const std::string& String() const { return string; } size_t Hash() const { return string_hash; } @@ -74,7 +80,7 @@ struct LLStaticStringHasher }; template< typename MappedObject > -class LL_COMMON_API LLStaticStringTable +class LLStaticStringTable : public boost::unordered_map< LLStaticHashedString, MappedObject, LLStaticStringHasher > { }; diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 51a6990809c..4332ff51c3a 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -1084,7 +1084,7 @@ unsigned long windows_get_last_error() } template<> -std::wstring windows_message(DWORD error) +LL_COMMON_API std::wstring windows_message(DWORD error) { // derived from https://stackoverflow.com/a/455533 wchar_t* rawptr = nullptr; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index bcca233cd4f..83a44fa1081 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -783,26 +783,33 @@ ll_convert_forms(ll_convert_alias, std::wstring, LLWString, ll_convert_wstring_t */ LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in); -/// Get Windows message string for passed GetLastError() code -// VS 2013 doesn't let us forward-declare this template, which is what we -// started with, so the implementation could reference the specialization we -// haven't yet declared. Somewhat weirdly, just stating the generic -// implementation in terms of the specialization works, even in this order... - -// the general case is just a conversion from the sole implementation +/// Get Windows message string for passed GetLastError() code. // Microsoft says DWORD is a typedef for unsigned long // https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types // so rather than drag windows.h into everybody's include space... +// +// Ordering matters for the DLL build: forward-declare the primary template, +// then declare the exported std::wstring specialization (defined in +// llstring.cpp), then define the primary in terms of that specialization. The +// specialization must be declared BEFORE the primary's body references it, +// else an implicit instantiation is assumed and clashes with the +// specialization's dll linkage (C2375 "different linkage"). The primary itself +// carries no LL_COMMON_API: it is defined inline and instantiated per-consumer, +// so dllexport/dllimport on it is both illegal and unnecessary. template -STRING windows_message(unsigned long error) -{ - return ll_convert(windows_message(error)); -} +STRING windows_message(unsigned long error); /// There's only one real implementation template<> LL_COMMON_API std::wstring windows_message(unsigned long error); +// the general case is just a conversion from the sole implementation +template +STRING windows_message(unsigned long error) +{ + return ll_convert(windows_message(error)); +} + /// Get Windows message string, implicitly calling GetLastError() LL_COMMON_API unsigned long windows_get_last_error(); diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 0f8af1d19fe..893145e5d74 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -34,6 +34,10 @@ #include "lltracethreadrecorder.h" #include "llexception.h" #include "workqueue.h" +#include "lockstatic.h" + +#include +#include #if LL_LINUX #include @@ -156,6 +160,74 @@ LL_COMMON_API bool assert_main_thread() return false; } +namespace llthread +{ +void* getCanonicalStatic(const char* name, void* (*factory)()) +{ + // The canonical per-type statics live here, in a single translation unit -- + // hence a single module even in a multi-DLL build -- so every module that + // instantiates LockStatic for a given Static resolves the SAME + // instance. Keyed by the mangled name string (typeid(Static).name()) rather + // than std::type_index: under -fvisibility=hidden each module has its own + // type_info object, so identity comparison would treat the same type as a + // different key per module and re-introduce the duplication we are removing. + // The mangled name string is identical across modules for one ABI. + // + // Heap-allocated and intentionally never freed so the statics outlive every + // user (LockStatic consumers' own statics may be torn down at process exit). + static std::mutex* sMutex = new std::mutex(); + static auto* sRegistry = new std::unordered_map(); + std::lock_guard lk(*sMutex); + void*& slot = (*sRegistry)[name]; + if (! slot) + { + slot = factory(); + } + return slot; +} + +// ---- DLL-safe thread-local slots (see lockstatic.h) ---- +namespace +{ + constexpr size_t MAX_THREAD_LOCAL_SLOTS = 256; + // The one and only thread_local store, owned by this module. Reached from + // every module through the exported accessors below, so all modules share a + // single per-thread value per slot. + thread_local void* sThreadLocalSlots[MAX_THREAD_LOCAL_SLOTS] = {}; +} + +size_t allocThreadLocalSlot(const char* name) +{ + // Assign a stable slot index per type name, once, shared across all modules. + // (The mangled name string is identical across modules for one ABI -- see + // getCanonicalStatic() above for the hidden-visibility rationale.) + static std::mutex* sMutex = new std::mutex(); + static auto* sIndices = new std::unordered_map(); + std::lock_guard lk(*sMutex); + auto it = sIndices->find(name); + if (it != sIndices->end()) + return it->second; + size_t index = sIndices->size(); + if (index >= MAX_THREAD_LOCAL_SLOTS) + { + LL_ERRS() << "Exceeded MAX_THREAD_LOCAL_SLOTS (" << MAX_THREAD_LOCAL_SLOTS + << ") allocating thread-local slot for " << name << LL_ENDL; + } + (*sIndices)[name] = index; + return index; +} + +void* getThreadLocalSlot(size_t slot) +{ + return sThreadLocalSlots[slot]; +} + +void setThreadLocalSlot(size_t slot, void* value) +{ + sThreadLocalSlots[slot] = value; +} +} // namespace llthread + // // Handed to the APR thread creation function // diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 3952dde719c..97565590bb6 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -30,7 +30,7 @@ #include "llrefcount.h" #include -extern void set_thread_name(const char* threadName); +extern LL_COMMON_API void set_thread_name(const char* threadName); namespace LLTrace { diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 151d8a666b9..84e18c7930c 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -29,26 +29,39 @@ #define LL_LLTHREADLOCALSTORAGE_H #include "llinstancetracker.h" +#include "lockstatic.h" // llthread DLL-safe thread-local slots +#include +// A per-DERIVED_TYPE thread-local pointer. The actual thread_local storage is +// NOT a member here: a plain `thread_local DERIVED_TYPE* sInstance;` would be +// duplicated once per module in a shared-library build, so setInstance() in one +// module and getInstance() inlined into another would see different storage. +// (And a thread_local cannot be dllexport'd to share it -- MSVC C2492.) Instead +// we key into a single canonical thread-local slot array owned by llcommon, +// reached through exported accessors -- one extra (non-inlinable) call per +// access, the price of cross-module correctness. template class LLThreadLocalSingletonPointer { public: LL_FORCE_INLINE static DERIVED_TYPE* getInstance() { - return sInstance; + return static_cast(llthread::getThreadLocalSlot(slot())); } static void setInstance(DERIVED_TYPE* instance) { - sInstance = instance; + llthread::setThreadLocalSlot(slot(), instance); } private: - static thread_local DERIVED_TYPE* sInstance; + // Stable slot index for DERIVED_TYPE, cached per module; the value is + // canonical (identical) across modules. + static size_t slot() + { + static size_t sSlot = llthread::allocThreadLocalSlot(typeid(DERIVED_TYPE).name()); + return sSlot; + } }; -template -thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer::sInstance = NULL; - #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h index d79f2505856..d8893c25261 100644 --- a/indra/llcommon/lltimer.h +++ b/indra/llcommon/lltimer.h @@ -114,7 +114,7 @@ class LL_COMMON_API LLTimer // // Various functions for initializing/accessing clock and timing stuff. Don't use these without REALLY knowing how they work. // -struct TimerInfo +struct LL_COMMON_API TimerInfo { TimerInfo(); void update(); @@ -126,7 +126,7 @@ struct TimerInfo U64 mLastTotalTimeClockCount; }; -TimerInfo& get_timer_info(); +LL_COMMON_API TimerInfo& get_timer_info(); LL_COMMON_API U64 get_clock_count(); diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index edb010b0a4d..c459bdf51e1 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -53,7 +53,7 @@ STORAGE_TYPE storage_value(LLUnit val) { return val.val template STORAGE_TYPE storage_value(LLUnitImplicit val) { return val.value(); } -class StatBase +class LL_COMMON_API StatBase { public: StatBase(const char* name, const char* description); diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h index 0a2e2bf997a..f524ee5a928 100644 --- a/indra/llcommon/lltraceaccumulators.h +++ b/indra/llcommon/lltraceaccumulators.h @@ -35,7 +35,9 @@ #include "llrefcount.h" #include "llthreadlocalstorage.h" #include "llmemory.h" +#include "lockstatic.h" // llthread::getCanonicalStatic (DLL-safe statics) #include +#include namespace LLTrace { @@ -67,8 +69,8 @@ namespace LLTrace { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; const AccumulatorBuffer& other = *getDefaultBuffer(); - resize(sNextStorageSlot); - for (S32 i = 0; i < sNextStorageSlot; i++) + resize(statics().mNextStorageSlot); + for (S32 i = 0; i < statics().mNextStorageSlot; i++) { mStorage[i] = other.mStorage[i]; } @@ -100,8 +102,8 @@ namespace LLTrace mStorage(NULL) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - resize(sNextStorageSlot); - for (S32 i = 0; i < sNextStorageSlot; i++) + resize(statics().mNextStorageSlot); + for (S32 i = 0; i < statics().mNextStorageSlot; i++) { mStorage[i] = other.mStorage[i]; } @@ -110,8 +112,8 @@ namespace LLTrace void addSamples(const AccumulatorBuffer& other, EBufferAppendType append_type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) + llassert(mStorageSize >= statics().mNextStorageSlot && other.mStorageSize >= statics().mNextStorageSlot); + for (size_t i = 0; i < statics().mNextStorageSlot; i++) { mStorage[i].addSamples(other.mStorage[i], append_type); } @@ -120,8 +122,8 @@ namespace LLTrace void copyFrom(const AccumulatorBuffer& other) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - llassert(mStorageSize >= sNextStorageSlot && other.mStorageSize >= sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) + llassert(mStorageSize >= statics().mNextStorageSlot && other.mStorageSize >= statics().mNextStorageSlot); + for (size_t i = 0; i < statics().mNextStorageSlot; i++) { mStorage[i] = other.mStorage[i]; } @@ -130,8 +132,8 @@ namespace LLTrace void reset(const AccumulatorBuffer* other = NULL) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - llassert(mStorageSize >= sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) + llassert(mStorageSize >= statics().mNextStorageSlot); + for (size_t i = 0; i < statics().mNextStorageSlot; i++) { mStorage[i].reset(other ? &other->mStorage[i] : NULL); } @@ -140,8 +142,8 @@ namespace LLTrace void sync(F64SecondsImplicit time_stamp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - llassert(mStorageSize >= sNextStorageSlot); - for (size_t i = 0; i < sNextStorageSlot; i++) + llassert(mStorageSize >= statics().mNextStorageSlot); + for (size_t i = 0; i < statics().mNextStorageSlot; i++) { mStorage[i].sync(time_stamp); } @@ -166,7 +168,7 @@ namespace LLTrace size_t reserveSlot() { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - size_t next_slot = sNextStorageSlot++; + size_t next_slot = statics().mNextStorageSlot++; if (next_slot >= mStorageSize) { // don't perform doubling, as this should only happen during startup @@ -215,35 +217,51 @@ namespace LLTrace static size_t getNumIndices() { - return sNextStorageSlot; + return statics().mNextStorageSlot; } static self_t* getDefaultBuffer() { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; - static bool sInitialized = false; - if (!sInitialized) + // (Previously gated on a function-local `static bool sInitialized`, + // which is per-module and would re-init the shared buffer from a + // second module. Gate on the shared pointer itself instead.) + Statics& s = statics(); + if (!s.mDefaultBuffer) { // this buffer is allowed to leak so that trace calls from global destructors have somewhere to put their data // so as not to trigger an access violation - sDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker()); - sInitialized = true; - sDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); + s.mDefaultBuffer = new AccumulatorBuffer(StaticAllocationMarker()); + s.mDefaultBuffer->resize(DEFAULT_ACCUMULATOR_BUFFER_SIZE); } - return sDefaultBuffer; + return s.mDefaultBuffer; } private: ACCUMULATOR* mStorage; size_t mStorageSize; - static size_t sNextStorageSlot; - static self_t* sDefaultBuffer; - }; - template size_t AccumulatorBuffer::sNextStorageSlot = 0; - template AccumulatorBuffer* AccumulatorBuffer::sDefaultBuffer = NULL; + // Per-ACCUMULATOR statics, kept as ONE canonical instance shared across + // all modules (DLLs). A plain template static member duplicates per + // module in a shared-library build, which splits slot numbering and + // buffer sizing across modules and crashes (out-of-bounds accumulator + // access). getCanonicalStatic() lives in a single TU, so every module + // resolves the same instance. Keyed by typeid(self_t).name(). + struct Statics + { + size_t mNextStorageSlot = 0; + self_t* mDefaultBuffer = nullptr; + }; + static Statics& statics() + { + static Statics* s = static_cast( + llthread::getCanonicalStatic(typeid(self_t).name(), + []() -> void* { return new Statics(); })); + return *s; + } + }; - class EventAccumulator + class LL_COMMON_API EventAccumulator { public: typedef F64 value_t; @@ -314,7 +332,7 @@ namespace LLTrace }; - class SampleAccumulator + class LL_COMMON_API SampleAccumulator { public: typedef F64 value_t; @@ -411,7 +429,7 @@ namespace LLTrace bool mHasValue; }; - class CountAccumulator + class LL_COMMON_API CountAccumulator { public: typedef F64 value_t; @@ -454,7 +472,7 @@ namespace LLTrace S32 mNumSamples; }; - class alignas(32) TimeBlockAccumulator + class LL_COMMON_API alignas(32) TimeBlockAccumulator { public: typedef F64Seconds value_t; diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index ad4c91d85be..5fd5ac24f43 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -40,7 +40,7 @@ #pragma warning(disable : 4244) // possible loss of data on conversions #endif -class LLStopWatchControlsMixinCommon +class LL_COMMON_API LLStopWatchControlsMixinCommon { public: virtual ~LLStopWatchControlsMixinCommon() {} @@ -112,6 +112,7 @@ class LLStopWatchControlsMixin self_t& operator = (const self_t& other) { // don't do anything, derived class must implement logic + return *this; } // atomically stop this object while starting the other @@ -154,7 +155,7 @@ namespace LLTrace typedef S32 sum_t; }; - class Recording + class LL_COMMON_API Recording : public LLStopWatchControlsMixin { public: @@ -668,9 +669,9 @@ namespace LLTrace size_t mNumRecordedPeriods; }; - PeriodicRecording& get_frame_recording(); + LL_COMMON_API PeriodicRecording& get_frame_recording(); - class ExtendableRecording + class LL_COMMON_API ExtendableRecording : public LLStopWatchControlsMixin { public: @@ -694,7 +695,7 @@ namespace LLTrace Recording mPotentialRecording; }; - class ExtendablePeriodicRecording + class LL_COMMON_API ExtendablePeriodicRecording : public LLStopWatchControlsMixin { public: diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index e3eadfb0bd2..2322e60243e 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -91,11 +91,11 @@ namespace LLTrace }; - ThreadRecorder* get_thread_recorder(); - void set_thread_recorder(ThreadRecorder*); + LL_COMMON_API ThreadRecorder* get_thread_recorder(); + LL_COMMON_API void set_thread_recorder(ThreadRecorder*); - void set_master_thread_recorder(ThreadRecorder*); - ThreadRecorder* get_master_thread_recorder(); + LL_COMMON_API void set_master_thread_recorder(ThreadRecorder*); + LL_COMMON_API ThreadRecorder* get_master_thread_recorder(); } #endif // LL_LLTRACETHREADRECORDER_H diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index 7164a6f2b84..17c16342130 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -49,6 +49,16 @@ // static LLMutex* LLUUID::mMutex = NULL; +// Defined here rather than as an inline constexpr in lluuid.h: LLUUID / +// LLTransactionID are exported (LL_COMMON_API), so these static members are +// dllimport in consumers and may not have an in-header definition. Both are +// constant-initialized (constexpr default ctors), so no static-init-order +// hazard -- they hold the all-zero UUID before any dynamic initialization runs. +// static +const LLUUID LLUUID::null; +// static +const LLTransactionID LLTransactionID::tnull; + /* diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index f5dc1b0c648..4d073cce21a 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -148,9 +148,12 @@ static_assert(std::is_trivially_copyable::value, "LLUUID must be trivial static_assert(std::is_trivially_move_assignable::value, "LLUUID must be trivial move"); static_assert(std::is_standard_layout::value, "LLUUID must be a standard layout type"); -// Defined as inline constexpr after the class definition because the static -// data member is of LLUUID type, which is incomplete inside the class body. -inline constexpr LLUUID LLUUID::null{}; +// LLUUID::null is defined out-of-line in lluuid.cpp, NOT as an inline constexpr +// variable here. LLUUID is exported (class LL_COMMON_API), which makes this +// static member dllimport in consumer modules, and a dllimport member may not +// have an in-header (inline) definition. So it is an ordinary exported constant +// defined once in the DLL. It is still constant-initialized (LLUUID has a +// constexpr default ctor), so there is no static-init-order hazard. typedef std::vector uuid_vec_t; typedef std::set uuid_set_t; @@ -185,7 +188,9 @@ class LL_COMMON_API LLTransactionID : public LLUUID LLAssetID makeAssetID(const LLUUID& session) const; }; -inline constexpr LLTransactionID LLTransactionID::tnull{}; +// As with LLUUID::null above: defined out-of-line in lluuid.cpp because an +// exported (dllimport-in-consumers) static member can't have an inline +// definition. // Canonical hash for LLUUID (also used by boost::container_hash via ADL). // Golden-ratio multiply with avalanche mixing: shift by 31 mixes the upper diff --git a/indra/llcommon/llwatchdog.h b/indra/llcommon/llwatchdog.h index f138fbccb05..467374eb5b4 100644 --- a/indra/llcommon/llwatchdog.h +++ b/indra/llcommon/llwatchdog.h @@ -37,7 +37,7 @@ // LLWatchdogEntry is the interface used by the tasks that // need to be watched. -class LLWatchdogEntry +class LL_COMMON_API LLWatchdogEntry { public: LLWatchdogEntry(const std::string &thread_name); @@ -59,7 +59,7 @@ class LLWatchdogEntry std::string mThreadName; }; -class LLWatchdogTimeout : public LLWatchdogEntry +class LL_COMMON_API LLWatchdogTimeout : public LLWatchdogEntry { public: LLWatchdogTimeout(const std::string& thread_name); @@ -83,12 +83,11 @@ class LLWatchdogTimeout : public LLWatchdogEntry }; class LLWatchdogTimerThread; // Defined in the cpp -class LLWatchdog : public LLSimpleton +class LL_COMMON_API LLWatchdog : public LLSingleton { -public: - LLWatchdog(); + LLSINGLETON(LLWatchdog); ~LLWatchdog(); - +public: // Add an entry to the watchdog. void add(LLWatchdogEntry* e); void remove(LLWatchdogEntry* e); diff --git a/indra/llcommon/llwin32headers.h b/indra/llcommon/llwin32headers.h index 1ff373bca87..b948adee127 100644 --- a/indra/llcommon/llwin32headers.h +++ b/indra/llcommon/llwin32headers.h @@ -30,7 +30,7 @@ #ifdef LL_WINDOWS #include // Does not include winsock.h because WIN32_LEAN_AND_MEAN is defined #include // Requires windows.h -#include +#include #endif #endif diff --git a/indra/llcommon/lockstatic.h b/indra/llcommon/lockstatic.h index db4c7af0ec4..4d240f37aa3 100644 --- a/indra/llcommon/lockstatic.h +++ b/indra/llcommon/lockstatic.h @@ -14,10 +14,32 @@ #define LL_LOCKSTATIC_H #include // std::unique_lock +#include // typeid +#include // size_t +#include "llpreprocessor.h" // LL_COMMON_API namespace llthread { +// Return THE canonical instance of the Static identified by 'name' +// (typeid(Static).name()), creating it once via factory() on first request. +// Defined in llthread.cpp -- a single translation unit -- so every module in a +// multi-DLL build shares one instance instead of each getting its own +// function-local static copy. Keyed by the mangled NAME STRING (not type_info +// identity), which is stable across modules even under -fvisibility=hidden. +LL_COMMON_API void* getCanonicalStatic(const char* name, void* (*factory)()); + +// DLL-safe thread-local slot store. A thread_local variable cannot carry a dll +// interface on MSVC (C2492), so it cannot simply be exported to share one +// instance across modules. Instead the underlying thread_local array lives in a +// single module (llcommon) and is reached through these exported accessors, so +// every module shares one per-thread value per slot. allocThreadLocalSlot() +// assigns a stable slot index per 'name' (pass typeid(T).name()), consistent +// across modules; the index is then used with get/setThreadLocalSlot(). +LL_COMMON_API size_t allocThreadLocalSlot(const char* name); +LL_COMMON_API void* getThreadLocalSlot(size_t slot); +LL_COMMON_API void setThreadLocalSlot(size_t slot, void* value); + // Instantiate this template to obtain a pointer to the canonical static // instance of Static while holding a lock on that instance. Use of // Static::mMutex presumes that Static declares some suitable mMutex. @@ -46,25 +68,24 @@ class LockStatic private: Static* getStatic() { - // Static::mMutex must be function-local static rather than class- - // static. Some of our consumers must function properly (therefore - // lock properly) even when the containing module's static variables - // have not yet been runtime-initialized. A mutex requires - // construction. A static class member might not yet have been - // constructed. - // - // We could store a dumb mutex_t*, notice when it's NULL and allocate a - // heap mutex -- but that's vulnerable to race conditions. And we can't - // defend the dumb pointer with another mutex. - // - // We could store a std::atomic -- but a default-constructed - // std::atomic does not contain a valid T, even a default-constructed - // T! Which means std::atomic, too, requires runtime initialization. + // One canonical Static per process, shared across module (DLL) + // boundaries: getCanonicalStatic() lives in a single translation unit, + // so every module resolves the SAME instance. This matters because a + // plain `static Static sData;` is duplicated once per module in a + // multi-DLL build -- each DLL would get its own copy of the tracked + // data, which (e.g. for LLInstanceTracker / LLTrace) silently splits + // registrations across modules. // - // But a function-local static is guaranteed to be initialized exactly - // once: the first time control reaches that declaration. - static Static sData; - return &sData; + // The cached pointer below is itself a function-local static, so it + // retains the original guarantee that matters: it is constructed + // exactly once, on first reach -- even when the containing module's + // other static variables have not yet been runtime-initialized -- and + // the underlying Static (with its mMutex) is created lazily at that + // same point. It simply now converges to the one canonical instance. + static Static* sData = static_cast( + getCanonicalStatic(typeid(Static).name(), + []() -> void* { return new Static(); })); + return sData; } }; diff --git a/indra/llcommon/tests/llcond_test.cpp b/indra/llcommon/tests/llcond_test.cpp index de9571c12bc..f2a302ed134 100644 --- a/indra/llcommon/tests/llcond_test.cpp +++ b/indra/llcommon/tests/llcond_test.cpp @@ -27,14 +27,6 @@ namespace tut { struct llcond_data { - llcond_data() - { - LLCoros::createInstance(); - } - ~llcond_data() - { - LLCoros::deleteSingleton(); - } LLScalarCond cond{0}; }; typedef test_group llcond_group; diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index 2d2541e2428..05c25e6627a 100644 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -92,15 +92,6 @@ namespace tut { struct test_data { - test_data() - { - LLCoros::createInstance(); - } - ~test_data() - { - LLCoros::deleteSingleton(); - } - Sync mSync; ImmediateAPI immediateAPI{mSync}; std::string replyName, errorName, threw, stringdata; diff --git a/indra/llcommon/tests/lleventfilter_test.cpp b/indra/llcommon/tests/lleventfilter_test.cpp index d7b80e2545f..2a93d1946c5 100644 --- a/indra/llcommon/tests/lleventfilter_test.cpp +++ b/indra/llcommon/tests/lleventfilter_test.cpp @@ -478,7 +478,6 @@ namespace tut } } // namespace tut -/***************************************************************************** -* Link dependencies -*****************************************************************************/ -#include "llsdutil.cpp" +// (llsdutil symbols formerly pulled in via #include "llsdutil.cpp" now come from +// the linked llcommon library -- including the .cpp here double-defines them and +// clashes with their dllimport declarations when llcommon is built shared.) diff --git a/indra/llcommon/tests/llsdutil_test.cpp b/indra/llcommon/tests/llsdutil_test.cpp index 4b25a02f30e..de6e0bede53 100644 --- a/indra/llcommon/tests/llsdutil_test.cpp +++ b/indra/llcommon/tests/llsdutil_test.cpp @@ -114,78 +114,6 @@ namespace tut template<> template<> void llsdutil_object::test<4>() - { - LLSD sd; - LLVector3 vec1(-1.0, 2.0, -3.0); - sd = ll_sd_from_vector3(vec1); - LLVector3 vec2 = ll_vector3_from_sd(sd); - ensure_equals("vector3 -> sd -> vector3: 1", vec1, vec2); - - LLVector3 vec3(sd); - ensure_equals("vector3 -> sd -> vector3: 2", vec1, vec3); - - sd.clear(); - vec1.setVec(0., 0., 0.); - sd = ll_sd_from_vector3(vec1); - vec2 = ll_vector3_from_sd(sd); - ensure_equals("vector3 -> sd -> vector3: 3", vec1, vec2); - sd.clear(); - } - - template<> template<> - void llsdutil_object::test<5>() - { - LLSD sd; - LLVector3d vec1((F64)(U64L(0xFEDCBA9876543210) << 2), -1., 0); - sd = ll_sd_from_vector3d(vec1); - LLVector3d vec2 = ll_vector3d_from_sd(sd); - ensure_equals("vector3d -> sd -> vector3d: 1", vec1, vec2); - - LLVector3d vec3(sd); - ensure_equals("vector3d -> sd -> vector3d : 2", vec1, vec3); - } - - template<> template<> - void llsdutil_object::test<6>() - { - LLSD sd; - LLVector2 vec((F32) -3., (F32) 4.2); - sd = ll_sd_from_vector2(vec); - LLVector2 vec1 = ll_vector2_from_sd(sd); - ensure_equals("vector2 -> sd -> vector2", vec, vec1); - - LLSD sd2 = ll_sd_from_vector2(vec1); - ensure_equals("sd -> vector2 -> sd: 2", sd, sd2); - } - - template<> template<> - void llsdutil_object::test<7>() - { - LLSD sd; - LLQuaternion quat((F32) 1., (F32) -0.98, (F32) 2.3, (F32) 0xffff); - sd = ll_sd_from_quaternion(quat); - LLQuaternion quat1 = ll_quaternion_from_sd(sd); - ensure_equals("LLQuaternion -> sd -> LLQuaternion", quat, quat1); - - LLSD sd2 = ll_sd_from_quaternion(quat1); - ensure_equals("sd -> LLQuaternion -> sd ", sd, sd2); - } - - template<> template<> - void llsdutil_object::test<8>() - { - LLSD sd; - LLColor4 c(1.0f, 2.2f, 4.0f, 7.f); - sd = ll_sd_from_color4(c); - LLColor4 c1 =ll_color4_from_sd(sd); - ensure_equals("LLColor4 -> sd -> LLColor4", c, c1); - - LLSD sd1 = ll_sd_from_color4(c1); - ensure_equals("sd -> LLColor4 -> sd", sd, sd1); - } - - template<> template<> - void llsdutil_object::test<9>() { set_test_name("llsd_matches"); @@ -388,7 +316,7 @@ namespace tut } template<> template<> - void llsdutil_object::test<10>() + void llsdutil_object::test<5>() { set_test_name("llsd_hashing"); diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp index 9ebc267fbd7..adf58042722 100644 --- a/indra/llcommon/tests/llsingleton_test.cpp +++ b/indra/llcommon/tests/llsingleton_test.cpp @@ -204,4 +204,121 @@ namespace tut private: \ LLSD mDesc; \ } + + // Declare two otherwise-identical LLParamSingleton classes so we can + // validly initialize each using two different constructors. If we tried + // to test that with a single LLParamSingleton class within the same test + // program, we'd get 'trying to use deleted LLParamSingleton' errors. + PARAMSINGLETON(PSing1); + PARAMSINGLETON(PSing2); + + template<> template<> + void singleton_object_t::test<12>() + { + set_test_name("LLParamSingleton"); + + WrapLLErrs catcherr; + // query methods + ensure("false positive on instanceExists()", ! PSing1::instanceExists()); + ensure("false positive on wasDeleted()", ! PSing1::wasDeleted()); + // try to reference before initializing + std::string threw = catcherr.catch_llerrs([](){ + (void)PSing1::instance(); + }); + ensure_contains("too-early instance() didn't throw", threw, "Uninitialized"); + // getInstance() behaves the same as instance() + threw = catcherr.catch_llerrs([](){ + (void)PSing1::getInstance(); + }); + ensure_contains("too-early getInstance() didn't throw", threw, "Uninitialized"); + // initialize using LLSD::String constructor + PSing1::initParamSingleton("string"); + ensure_equals(PSing1::instance().desc(), "string"); + ensure("false negative on instanceExists()", PSing1::instanceExists()); + // try to initialize again + threw = catcherr.catch_llerrs([](){ + PSing1::initParamSingleton("again"); + }); + ensure_contains("second ctor(string) didn't throw", threw, "twice"); + // try to initialize using the other constructor -- should be + // well-formed, but illegal at runtime + threw = catcherr.catch_llerrs([](){ + PSing1::initParamSingleton(17); + }); + ensure_contains("other ctor(int) didn't throw", threw, "twice"); + PSing1::deleteSingleton(); + ensure("false negative on wasDeleted()", PSing1::wasDeleted()); + threw = catcherr.catch_llerrs([](){ + (void)PSing1::instance(); + }); + ensure_contains("accessed deleted LLParamSingleton", threw, "deleted"); + } + + template<> template<> + void singleton_object_t::test<13>() + { + set_test_name("LLParamSingleton alternate ctor"); + + WrapLLErrs catcherr; + // We don't have to restate all the tests for PSing1. Only test validly + // using the other constructor. + PSing2::initParamSingleton(17); + ensure_equals(PSing2::instance().desc(), "17"); + // can't do it twice + std::string threw = catcherr.catch_llerrs([](){ + PSing2::initParamSingleton(34); + }); + ensure_contains("second ctor(int) didn't throw", threw, "twice"); + // can't use the other constructor either + threw = catcherr.catch_llerrs([](){ + PSing2::initParamSingleton("string"); + }); + ensure_contains("other ctor(string) didn't throw", threw, "twice"); + } + + class CircularPCtor: public LLParamSingleton + { + LLSINGLETON(CircularPCtor) + { + // never mind indirection, just go straight for the circularity + (void)instance(); + } + }; + + template<> template<> + void singleton_object_t::test<14>() + { + set_test_name("Circular LLParamSingleton constructor"); + WrapLLErrs catcherr; + std::string threw = catcherr.catch_llerrs([](){ + CircularPCtor::initParamSingleton(); + }); + ensure_contains("constructor circularity didn't throw", threw, "constructor"); + } + + class CircularPInit: public LLParamSingleton + { + LLSINGLETON_EMPTY_CTOR(CircularPInit); + public: + virtual void initSingleton() override + { + // never mind indirection, just go straight for the circularity + CircularPInit *pt = getInstance(); + if (!pt) + { + throw; + } + } + }; + + template<> template<> + void singleton_object_t::test<15>() + { + set_test_name("Circular LLParamSingleton initSingleton()"); + WrapLLErrs catcherr; + std::string threw = catcherr.catch_llerrs([](){ + CircularPInit::initParamSingleton(); + }); + ensure("initSingleton() circularity threw", threw.empty()); + } } diff --git a/indra/llcommon/tests/lluuid_test.cpp b/indra/llcommon/tests/lluuid_test.cpp index d22101b8ae4..2525fad1b18 100644 --- a/indra/llcommon/tests/lluuid_test.cpp +++ b/indra/llcommon/tests/lluuid_test.cpp @@ -38,8 +38,9 @@ namespace tut // Compile-time verification that LLUUID is constexpr-constructible. static_assert(LLUUID{}.mData[0] == 0, "default LLUUID is zero-initialised at compile time"); - static_assert(LLUUID::null.mData[0] == 0, "LLUUID::null is a compile-time constant"); - static_assert(LLTransactionID::tnull.mData[0] == 0, "LLTransactionID::tnull is a compile-time constant"); + // LLUUID::null / LLTransactionID::tnull are exported out-of-line constants + // (dllimport in consumers), so they are no longer constexpr. Their all-zero + // value is verified at runtime in test<1> instead. constexpr U8 kConstexprBytes[UUID_BYTES] = { 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, @@ -63,6 +64,10 @@ namespace tut ensure("default-constructed isNull", id.isNull()); ensure("default-constructed !notNull", !id.notNull()); ensure("default-constructed == LLUUID::null", id == LLUUID::null); + // null / tnull are the all-zero UUID (verified at runtime since they are + // exported out-of-line constants, no longer constexpr). + ensure("LLUUID::null isNull", LLUUID::null.isNull()); + ensure("LLTransactionID::tnull isNull", LLTransactionID::tnull.isNull()); for (int i = 0; i < UUID_BYTES; ++i) { ensure_equals("default byte zero", (int)id.mData[i], 0); diff --git a/indra/llcommon/tests/workqueue_test.cpp b/indra/llcommon/tests/workqueue_test.cpp index 7b0683a7478..209b6b868c2 100644 --- a/indra/llcommon/tests/workqueue_test.cpp +++ b/indra/llcommon/tests/workqueue_test.cpp @@ -38,14 +38,6 @@ namespace tut { struct workqueue_data { - workqueue_data() - { - LLCoros::createInstance(); - } - ~workqueue_data() - { - LLCoros::deleteSingleton(); - } WorkSchedule queue{"queue"}; }; typedef test_group workqueue_group; diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index ac4f415f3ed..a9046a86bfa 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -24,7 +24,7 @@ namespace LL { - class ThreadPoolBase: public LLInstanceTracker + class LL_COMMON_API ThreadPoolBase: public LLInstanceTracker { private: using super = LLInstanceTracker; @@ -101,7 +101,7 @@ namespace LL * Specialize with WorkQueue or, for timestamped tasks, WorkSchedule */ template - struct ThreadPoolUsing: public ThreadPoolBase + struct LL_COMMON_API ThreadPoolUsing : public ThreadPoolBase { using queue_t = QUEUE; diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 69f3286c1b9..13170035092 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -35,7 +35,7 @@ namespace LL /** * A typical WorkQueue has a string name that can be used to find it. */ - class WorkQueueBase: public LLInstanceTracker + class LL_COMMON_API WorkQueueBase : public LLInstanceTracker { private: using super = LLInstanceTracker; @@ -213,7 +213,7 @@ namespace LL /***************************************************************************** * WorkQueue: no timestamped task support *****************************************************************************/ - class WorkQueue: public LLInstanceTrackerSubclass + class LL_COMMON_API WorkQueue : public LLInstanceTrackerSubclass { private: using super = LLInstanceTrackerSubclass; @@ -276,12 +276,16 @@ namespace LL /***************************************************************************** * WorkSchedule: add support for timestamped tasks *****************************************************************************/ - class WorkSchedule: public LLInstanceTrackerSubclass + class LL_COMMON_API WorkSchedule : public LLInstanceTrackerSubclass { private: using super = LLInstanceTrackerSubclass; using Queue = ThreadSafeSchedule; // helper for postEvery() + // NOT LL_COMMON_API: BackJack is instantiated with caller-local types + // (the lambda passed to postEvery()), so each consumer must emit its own + // instantiation -- tagging it makes consumers try to import an + // instantiation the DLL can never contain. template class BackJack; diff --git a/indra/llfilesystem/lldiskcache.h b/indra/llfilesystem/lldiskcache.h index f1dc617051e..48d72fb7c42 100644 --- a/indra/llfilesystem/lldiskcache.h +++ b/indra/llfilesystem/lldiskcache.h @@ -65,10 +65,17 @@ #include "llsingleton.h" class LLDiskCache : - public LLSimpleton + public LLParamSingleton { public: - LLDiskCache( + /** + * Since this is using the LLSingleton pattern but we + * want to allow the constructor to be called first + * with various parameters, we also invoke the + * LLParamSingleton idiom and use it to initialize + * the class via a call in LLAppViewer. + */ + LLSINGLETON(LLDiskCache, /** * The full name of the cache folder - typically a * a child of the main Viewer cache directory. Defined diff --git a/indra/llfilesystem/llfilesystem.cpp b/indra/llfilesystem/llfilesystem.cpp index 9c87ac7dcc4..21691cef395 100644 --- a/indra/llfilesystem/llfilesystem.cpp +++ b/indra/llfilesystem/llfilesystem.cpp @@ -39,8 +39,6 @@ constexpr S32 LLFileSystem::WRITE = 0x00000002; constexpr S32 LLFileSystem::READ_WRITE = 0x00000003; // LLFileSystem::READ & LLFileSystem::WRITE constexpr S32 LLFileSystem::APPEND = 0x00000006; // 0x00000004 & LLFileSystem::WRITE -static LLTrace::BlockTimerStatHandle FTM_VFILE_WAIT("VFile Wait"); - LLFileSystem::LLFileSystem(const LLUUID& file_id, const LLAssetType::EType file_type, S32 mode) { mFileType = file_type; diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index ab05f774b78..e5b127ee8d2 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -37,10 +37,6 @@ // linked. LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl(); -// Test data gathering handle -LLImageCompressionTester* LLImageJ2C::sTesterp = NULL ; -const std::string sTesterName("ImageCompressionTester"); - //static std::string LLImageJ2C::getEngineInfo() { @@ -64,17 +60,6 @@ LLImageJ2C::LLImageJ2C() : LLImageFormatted(IMG_CODEC_J2C), { // Array size is MAX_DISCARD_LEVEL+1 mDataSizes[i] = 0; } - - // If that test log has ben requested but not yet created, create it - if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) - { - sTesterp = new LLImageCompressionTester() ; - if (!sTesterp->isValid()) - { - delete sTesterp; - sTesterp = NULL; - } - } } // virtual @@ -205,21 +190,6 @@ bool LLImageJ2C::decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 fir LLImage::setLastError(mLastError); } - LLImageCompressionTester* tester = (LLImageCompressionTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - // Decompression stat gathering - // Note that we *do not* take into account the decompression failures data so we might overestimate the time spent processing - - // Always add the decompression time to the stat - tester->updateDecompressionStats(elapsed.getElapsedTimeF32()) ; - if (res) - { - // The whole data stream is finally decompressed when res is returned as true - tester->updateDecompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; - } - } - return res; } @@ -240,21 +210,6 @@ bool LLImageJ2C::encode(const LLImageRaw *raw_imagep, const char* comment_text, LLImage::setLastError(mLastError); } - LLImageCompressionTester* tester = (LLImageCompressionTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - // Compression stat gathering - // Note that we *do not* take into account the compression failures cases so we night overestimate the time spent processing - - // Always add the compression time to the stat - tester->updateCompressionStats(elapsed.getElapsedTimeF32()) ; - if (res) - { - // The whole data stream is finally compressed when res is returned as true - tester->updateCompressionStats(this->getDataSize(), raw_imagep->getDataSize()) ; - } - } - return res; } @@ -492,133 +447,3 @@ void LLImageJ2C::updateRawDiscardLevel() LLImageJ2CImpl::~LLImageJ2CImpl() { } - -//---------------------------------------------------------------------------------------------- -// Start of LLImageCompressionTester -//---------------------------------------------------------------------------------------------- -LLImageCompressionTester::LLImageCompressionTester() : LLMetricPerformanceTesterBasic(sTesterName) -{ - addMetric("Time Decompression (s)"); - addMetric("Volume In Decompression (kB)"); - addMetric("Volume Out Decompression (kB)"); - addMetric("Decompression Ratio (x:1)"); - addMetric("Perf Decompression (kB/s)"); - - addMetric("Time Compression (s)"); - addMetric("Volume In Compression (kB)"); - addMetric("Volume Out Compression (kB)"); - addMetric("Compression Ratio (x:1)"); - addMetric("Perf Compression (kB/s)"); - - mRunBytesInDecompression = 0; - mRunBytesOutDecompression = 0; - mRunBytesInCompression = 0; - - mTotalBytesInDecompression = 0; - mTotalBytesOutDecompression = 0; - mTotalBytesInCompression = 0; - mTotalBytesOutCompression = 0; - - mTotalTimeDecompression = 0.0f; - mTotalTimeCompression = 0.0f; - mRunTimeDecompression = 0.0f; -} - -LLImageCompressionTester::~LLImageCompressionTester() -{ - outputTestResults(); - LLImageJ2C::sTesterp = NULL; -} - -//virtual -void LLImageCompressionTester::outputTestRecord(LLSD *sd) -{ - std::string currentLabel = getCurrentLabelName(); - - F32 decompressionPerf = 0.0f; - F32 compressionPerf = 0.0f; - F32 decompressionRate = 0.0f; - F32 compressionRate = 0.0f; - - F32 totalkBInDecompression = (F32)(mTotalBytesInDecompression) / 1000.f; - F32 totalkBOutDecompression = (F32)(mTotalBytesOutDecompression) / 1000.f; - F32 totalkBInCompression = (F32)(mTotalBytesInCompression) / 1000.f; - F32 totalkBOutCompression = (F32)(mTotalBytesOutCompression) / 1000.f; - - if (!is_approx_zero(mTotalTimeDecompression)) - { - decompressionPerf = totalkBInDecompression / mTotalTimeDecompression; - } - if (!is_approx_zero(totalkBInDecompression)) - { - decompressionRate = totalkBOutDecompression / totalkBInDecompression; - } - if (!is_approx_zero(mTotalTimeCompression)) - { - compressionPerf = totalkBInCompression / mTotalTimeCompression; - } - if (!is_approx_zero(totalkBOutCompression)) - { - compressionRate = totalkBInCompression / totalkBOutCompression; - } - - (*sd)[currentLabel]["Time Decompression (s)"] = (LLSD::Real)mTotalTimeDecompression; - (*sd)[currentLabel]["Volume In Decompression (kB)"] = (LLSD::Real)totalkBInDecompression; - (*sd)[currentLabel]["Volume Out Decompression (kB)"]= (LLSD::Real)totalkBOutDecompression; - (*sd)[currentLabel]["Decompression Ratio (x:1)"] = (LLSD::Real)decompressionRate; - (*sd)[currentLabel]["Perf Decompression (kB/s)"] = (LLSD::Real)decompressionPerf; - - (*sd)[currentLabel]["Time Compression (s)"] = (LLSD::Real)mTotalTimeCompression; - (*sd)[currentLabel]["Volume In Compression (kB)"] = (LLSD::Real)totalkBInCompression; - (*sd)[currentLabel]["Volume Out Compression (kB)"] = (LLSD::Real)totalkBOutCompression; - (*sd)[currentLabel]["Compression Ratio (x:1)"] = (LLSD::Real)compressionRate; - (*sd)[currentLabel]["Perf Compression (kB/s)"] = (LLSD::Real)compressionPerf; -} - -void LLImageCompressionTester::updateCompressionStats(const F32 deltaTime) -{ - mTotalTimeCompression += deltaTime; -} - -void LLImageCompressionTester::updateCompressionStats(const S32 bytesCompress, const S32 bytesRaw) -{ - mTotalBytesInCompression += bytesRaw; - mRunBytesInCompression += bytesRaw; - mTotalBytesOutCompression += bytesCompress; - if (mRunBytesInCompression > (1000000)) - { - // Output everything - outputTestResults(); - // Reset the compression data of the run - mRunBytesInCompression = 0; - } -} - -void LLImageCompressionTester::updateDecompressionStats(const F32 deltaTime) -{ - mTotalTimeDecompression += deltaTime; -} - -void LLImageCompressionTester::updateDecompressionStats(const S32 bytesIn, const S32 bytesOut) -{ - mTotalBytesInDecompression += bytesIn; - mRunBytesInDecompression += bytesIn; - mTotalBytesOutDecompression += bytesOut; - mRunBytesOutDecompression += bytesOut; - //if (mRunBytesInDecompression > (1000000)) - if (mRunBytesOutDecompression > (10000000)) - //if ((mTotalTimeDecompression - mRunTimeDecompression) >= (5.0f)) - { - // Output everything - outputTestResults(); - // Reset the decompression data of the run - mRunBytesInDecompression = 0; - mRunBytesOutDecompression = 0; - mRunTimeDecompression = mTotalTimeDecompression; - } -} - -//---------------------------------------------------------------------------------------------- -// End of LLTexturePipelineTester -//---------------------------------------------------------------------------------------------- - diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index 19744a7f87b..8158347fb27 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -29,13 +29,11 @@ #include "llimage.h" #include "llassettype.h" -#include "llmetricperformancetester.h" // JPEG2000 : compression rate used in j2c conversion. const F32 DEFAULT_COMPRESSION_RATE = 1.f/8.f; class LLImageJ2CImpl; -class LLImageCompressionTester ; class LLImageJ2C : public LLImageFormatted { @@ -82,7 +80,6 @@ class LLImageJ2C : public LLImageFormatted friend class LLImageJ2CImpl; friend class LLImageJ2COJ; friend class LLImageJ2CKDU; - friend class LLImageCompressionTester; void decodeFailed(); void updateRawDiscardLevel(); @@ -96,9 +93,6 @@ class LLImageJ2C : public LLImageFormatted bool mReversible; std::unique_ptr mImpl; std::string mLastError; - - // Image compression/decompression tester - static LLImageCompressionTester* sTesterp; }; // Derive from this class to implement JPEG2000 decoding @@ -131,42 +125,4 @@ class LLImageJ2CImpl #define LINDEN_J2C_COMMENT_PREFIX "LL_" // Used by LLAppearanceUtility -// -// This class is used for performance data gathering only. -// Tracks the image compression / decompression data, -// records and outputs them to the log file. -// -class LLImageCompressionTester : public LLMetricPerformanceTesterBasic -{ - public: - LLImageCompressionTester(); - ~LLImageCompressionTester(); - - void updateDecompressionStats(const F32 deltaTime) ; - void updateDecompressionStats(const S32 bytesIn, const S32 bytesOut) ; - void updateCompressionStats(const F32 deltaTime) ; - void updateCompressionStats(const S32 bytesIn, const S32 bytesOut) ; - - protected: - /*virtual*/ void outputTestRecord(LLSD* sd); - - private: - // - // Data size - // - U32 mTotalBytesInDecompression; // Total bytes fed to decompressor - U32 mTotalBytesOutDecompression; // Total bytes produced by decompressor - U32 mTotalBytesInCompression; // Total bytes fed to compressor - U32 mTotalBytesOutCompression; // Total bytes produced by compressor - U32 mRunBytesInDecompression; // Bytes fed to decompressor in this run - U32 mRunBytesOutDecompression; // Bytes produced by the decompressor in this run - U32 mRunBytesInCompression; // Bytes fed to compressor in this run - // - // Time - // - F32 mTotalTimeDecompression; // Total time spent in computing decompression - F32 mTotalTimeCompression; // Total time spent in computing compression - F32 mRunTimeDecompression; // Time in this run (we output every 5 sec in decompress) - }; - #endif diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp index 4ec97f35ada..573d7d4778f 100644 --- a/indra/llinventory/llfoldertype.cpp +++ b/indra/llinventory/llfoldertype.cpp @@ -32,6 +32,41 @@ #include "llsd.h" #include "llsingleton.h" +///---------------------------------------------------------------------------- +/// Class LLFolderType +///---------------------------------------------------------------------------- +struct FolderEntry : public LLDictionaryEntry +{ + FolderEntry(const std::string &type_name, // 8 character limit! + bool is_protected, // can the viewer change categories of this type? + bool is_automatic, // always made before first login? + bool is_singleton // should exist as a unique copy under root + ) + : + LLDictionaryEntry(type_name), + mIsProtected(is_protected), + mIsAutomatic(is_automatic), + mIsSingleton(is_singleton) + { + llassert(type_name.length() <= 8); + } + + const bool mIsProtected; + const bool mIsAutomatic; + const bool mIsSingleton; +}; + +class LLFolderDictionary : public LLSingleton, + public LLDictionary +{ + LLSINGLETON(LLFolderDictionary); +protected: + virtual LLFolderType::EType notFound() const override + { + return LLFolderType::FT_NONE; + } +}; + // Folder types // // PROTECTED means that folders of this type can't be moved, deleted diff --git a/indra/llinventory/llfoldertype.h b/indra/llinventory/llfoldertype.h index e0719566b60..ad1d84c6c7b 100644 --- a/indra/llinventory/llfoldertype.h +++ b/indra/llinventory/llfoldertype.h @@ -29,12 +29,10 @@ #include #include "llassettype.h" -#include "lldictionary.h" -#include "llsingleton.h" // This class handles folder types (similar to assettype, except for folders) // and operations on those. -class LL_COMMON_API LLFolderType +class LLFolderType { public: // ! BACKWARDS COMPATIBILITY ! Folder type enums must match asset type enums. @@ -127,36 +125,4 @@ class LL_COMMON_API LLFolderType ~LLFolderType() {} }; -///---------------------------------------------------------------------------- -/// Class LLFolderType -///---------------------------------------------------------------------------- -struct FolderEntry : public LLDictionaryEntry -{ - FolderEntry(const std::string& type_name, // 8 character limit! - bool is_protected, // can the viewer change categories of this type? - bool is_automatic, // always made before first login? - bool is_singleton // should exist as a unique copy under root - ) : - LLDictionaryEntry(type_name), - mIsProtected(is_protected), - mIsAutomatic(is_automatic), - mIsSingleton(is_singleton) - { - llassert(type_name.length() <= 8); - } - - const bool mIsProtected; - const bool mIsAutomatic; - const bool mIsSingleton; -}; - -class LLFolderDictionary : public LLSimpleton, public LLDictionary -{ -public: - LLFolderDictionary(); - -protected: - virtual LLFolderType::EType notFound() const override { return LLFolderType::FT_NONE; } -}; - #endif // LL_LLFOLDERTYPE_H diff --git a/indra/llinventory/llinventorysettings.h b/indra/llinventory/llinventorysettings.h index 6d6bc836d89..6b6685d088d 100644 --- a/indra/llinventory/llinventorysettings.h +++ b/indra/llinventory/llinventorysettings.h @@ -32,14 +32,14 @@ #include "llinvtranslationbrdg.h" #include "llsingleton.h" -class LLSettingsType : public LLSimpleton +class LLSettingsType : public LLParamSingleton { + LLSINGLETON(LLSettingsType, LLTranslationBridge::ptr_t &trans); + ~LLSettingsType(); + friend struct SettingsEntry; public: - LLSettingsType(LLTranslationBridge::ptr_t& trans); - ~LLSettingsType(); - enum type_e { ST_SKY = 0, diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 2bbdc146789..8fa8983d3c4 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -27,9 +27,46 @@ #include "linden_common.h" #include "llinventorytype.h" +#include "lldictionary.h" +#include "llmemory.h" +#include "llsingleton.h" static const std::string empty_string; +///---------------------------------------------------------------------------- +/// Class LLInventoryType +///---------------------------------------------------------------------------- +struct InventoryEntry : public LLDictionaryEntry +{ + InventoryEntry(const std::string &name, // unlike asset type names, not limited to 8 characters; need not match asset type names + const std::string &human_name, // for decoding to human readable form; put any and as many printable characters you want in each one. + int num_asset_types = 0, ...) + : + LLDictionaryEntry(name), + mHumanName(human_name) + { + va_list argp; + va_start(argp, num_asset_types); + // Read in local textures + for (U8 i=0; i < num_asset_types; i++) + { + LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int); + mAssetTypes.push_back(t); + } + va_end(argp); + } + + const std::string mHumanName; + typedef std::vector asset_vec_t; + asset_vec_t mAssetTypes; +}; + +class LLInventoryDictionary : public LLSingleton, + public LLDictionary +{ + LLSINGLETON(LLInventoryDictionary); +}; + LLInventoryDictionary::LLInventoryDictionary() { addEntry(LLInventoryType::IT_TEXTURE, new InventoryEntry("texture", "texture", 1, LLAssetType::AT_TEXTURE)); diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index 2b621f02c6f..0627b8df3c7 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -28,8 +28,6 @@ #define LLINVENTORYTYPE_H #include "llassettype.h" -#include "lldictionary.h" -#include "llsingleton.h" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLInventoryType @@ -165,39 +163,4 @@ enum ScriptSubtype_t bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type, LLAssetType::EType asset_type); -///---------------------------------------------------------------------------- -/// Class LLInventoryType -///---------------------------------------------------------------------------- -struct InventoryEntry : public LLDictionaryEntry -{ - InventoryEntry(const std::string &name, // unlike asset type names, not limited to 8 characters; need not match asset type names - const std::string &human_name, // for decoding to human readable form; put any and as many printable characters you want in each one. - int num_asset_types = 0, ...) - : - LLDictionaryEntry(name), - mHumanName(human_name) - { - va_list argp; - va_start(argp, num_asset_types); - // Read in local textures - for (U8 i=0; i < num_asset_types; i++) - { - LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int); - mAssetTypes.push_back(t); - } - va_end(argp); - } - - const std::string mHumanName; - typedef std::vector asset_vec_t; - asset_vec_t mAssetTypes; -}; - -class LLInventoryDictionary : public LLSimpleton, - public LLDictionary -{ -public: - LLInventoryDictionary(); -}; - #endif diff --git a/indra/llinventory/tests/inventorymisc_test.cpp b/indra/llinventory/tests/inventorymisc_test.cpp index 9ca59d2c1df..f11a4c3bf71 100644 --- a/indra/llinventory/tests/inventorymisc_test.cpp +++ b/indra/llinventory/tests/inventorymisc_test.cpp @@ -127,18 +127,6 @@ namespace tut { struct inventory_data { - inventory_data() - { - LLAssetDictionary::createInstance(); - LLFolderDictionary::createInstance(); - LLInventoryDictionary::createInstance(); - } - ~inventory_data() - { - LLInventoryDictionary::deleteSingleton(); - LLFolderDictionary::deleteSingleton(); - LLAssetDictionary::deleteSingleton(); - } }; typedef test_group inventory_test; typedef inventory_test::object inventory_object; diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt index e885c9f06bb..ea48bf25c0a 100644 --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -117,6 +117,7 @@ if (BUILD_TESTING) LL_ADD_INTEGRATION_TEST(alignment "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(llquaternion llquaternion.cpp "${test_libs}" "${test_project}") + LL_ADD_INTEGRATION_TEST(llsdutil_math "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(mathmisc "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(m3math "" "${test_libs}" "${test_project}") LL_ADD_INTEGRATION_TEST(v3dmath v3dmath.cpp "${test_libs}" "${test_project}") diff --git a/indra/llmath/tests/llsdutil_math_test.cpp b/indra/llmath/tests/llsdutil_math_test.cpp new file mode 100644 index 00000000000..f7f096e59a2 --- /dev/null +++ b/indra/llmath/tests/llsdutil_math_test.cpp @@ -0,0 +1,153 @@ +/** + * @file llsdutil_tut.cpp + * @author Adroit + * @date 2007-02 + * @brief LLSD conversion routines test cases. + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "lltut.h" +#include "m4math.h" +#include "v2math.h" +#include "v2math.h" +#include "v3color.h" +#include "v3math.h" +#include "v3dmath.h" +#include "v4coloru.h" +#include "v4math.h" +#include "llquaternion.h" +#include "llsdutil.h" +#include "llsdutil_math.h" +#include "stringize.h" +#include +#include + +namespace tut +{ + struct llsdutil_math_data + { + void test_matches(const std::string& proto_key, const LLSD& possibles, + const char** begin, const char** end) + { + std::set succeed(begin, end); + LLSD prototype(possibles[proto_key]); + for (LLSD::map_const_iterator pi(possibles.beginMap()), pend(possibles.endMap()); + pi != pend; ++pi) + { + std::string match(llsd_matches(prototype, pi->second)); + std::set::const_iterator found = succeed.find(pi->first); + if (found != succeed.end()) + { + // This test is supposed to succeed. Comparing to the + // empty string ensures that if the test fails, it will + // display the string received so we can tell what failed. + ensure_equals("match", match, ""); + } + else + { + // This test is supposed to fail. If we get a false match, + // the string 'match' will be empty, which doesn't tell us + // much about which case went awry. So construct a more + // detailed description string. + ensure(proto_key + " shouldn't match " + pi->first, ! match.empty()); + } + } + } + }; + typedef test_group llsdutil_math_test; + typedef llsdutil_math_test::object llsdutil_math_object; + tut::llsdutil_math_test tutil("llsdutil_math"); + + template<> template<> + void llsdutil_math_object::test<1>() + { + LLSD sd; + LLVector3 vec1(-1.0, 2.0, -3.0); + sd = ll_sd_from_vector3(vec1); + LLVector3 vec2 = ll_vector3_from_sd(sd); + ensure_equals("vector3 -> sd -> vector3: 1", vec1, vec2); + + LLVector3 vec3(sd); + ensure_equals("vector3 -> sd -> vector3: 2", vec1, vec3); + + sd.clear(); + vec1.setVec(0., 0., 0.); + sd = ll_sd_from_vector3(vec1); + vec2 = ll_vector3_from_sd(sd); + ensure_equals("vector3 -> sd -> vector3: 3", vec1, vec2); + sd.clear(); + } + + template<> template<> + void llsdutil_math_object::test<2>() + { + LLSD sd; + LLVector3d vec1((F64)(U64L(0xFEDCBA9876543210) << 2), -1., 0); + sd = ll_sd_from_vector3d(vec1); + LLVector3d vec2 = ll_vector3d_from_sd(sd); + ensure_equals("vector3d -> sd -> vector3d: 1", vec1, vec2); + + LLVector3d vec3(sd); + ensure_equals("vector3d -> sd -> vector3d : 2", vec1, vec3); + } + + template<> template<> + void llsdutil_math_object::test<3>() + { + LLSD sd; + LLVector2 vec((F32) -3., (F32) 4.2); + sd = ll_sd_from_vector2(vec); + LLVector2 vec1 = ll_vector2_from_sd(sd); + ensure_equals("vector2 -> sd -> vector2", vec, vec1); + + LLSD sd2 = ll_sd_from_vector2(vec1); + ensure_equals("sd -> vector2 -> sd: 2", sd, sd2); + } + + template<> template<> + void llsdutil_math_object::test<4>() + { + LLSD sd; + LLQuaternion quat((F32) 1., (F32) -0.98, (F32) 2.3, (F32) 0xffff); + sd = ll_sd_from_quaternion(quat); + LLQuaternion quat1 = ll_quaternion_from_sd(sd); + ensure_equals("LLQuaternion -> sd -> LLQuaternion", quat, quat1); + + LLSD sd2 = ll_sd_from_quaternion(quat1); + ensure_equals("sd -> LLQuaternion -> sd ", sd, sd2); + } + + template<> template<> + void llsdutil_math_object::test<5>() + { + LLSD sd; + LLColor4 c(1.0f, 2.2f, 4.0f, 7.f); + sd = ll_sd_from_color4(c); + LLColor4 c1 =ll_color4_from_sd(sd); + ensure_equals("LLColor4 -> sd -> LLColor4", c, c1); + + LLSD sd1 = ll_sd_from_color4(c1); + ensure_equals("sd -> LLColor4 -> sd", sd, sd1); + } +} diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 7b0e8053a9e..75837466d78 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -38,12 +38,11 @@ class LLSD; class LLUUID; -class LLAvatarNameCache : public LLSimpleton +class LLAvatarNameCache : public LLSingleton { -public: - LLAvatarNameCache(); + LLSINGLETON(LLAvatarNameCache); ~LLAvatarNameCache(); - +public: typedef boost::signals2::signal use_display_name_signal_t; typedef std::function account_name_changed_callback_t; diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index 54820330fd1..22bcb523a90 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -34,6 +34,7 @@ #include #endif +#include "llwin32headers.h" #include "apr_poll.h" #include "apr_pools.h" #include "llbuffer.h" diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index 012f6bfea01..79182eef6ff 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -525,12 +525,10 @@ void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S3 gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET); } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_MESSAGES("Process Messages"); - // decode a given message bool LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender, bool custom ) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_MESSAGES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; llassert( mReceiveSize >= 0 ); llassert( mCurrentRMessageTemplate); diff --git a/indra/llmessage/tests/io_test.cpp b/indra/llmessage/tests/io_test.cpp index f77402065a7..68a5c100602 100644 --- a/indra/llmessage/tests/io_test.cpp +++ b/indra/llmessage/tests/io_test.cpp @@ -31,6 +31,7 @@ #include +#include "llwin32headers.h" #include "apr_pools.h" #include "llbuffer.h" diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index a6514b79e8d..0a77fd218b0 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -74,13 +74,11 @@ namespace tut { coproceduremanager_test() { - LLCoros::createInstance(); } ~coproceduremanager_test() { LLCoprocedureManager::instance().close(); - LLCoros::deleteSingleton(); } }; typedef test_group coproceduremanager_t; diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 9ea8c19a32f..11a165cd145 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -44,8 +44,6 @@ target_link_libraries(SLPlugin ll::pluginlibraries ) -target_precompile_headers(SLPlugin REUSE_FROM llprecompiled_exe) - if(WINDOWS) set_target_properties(SLPlugin PROPERTIES diff --git a/indra/llprecompiled/CMakeLists.txt b/indra/llprecompiled/CMakeLists.txt index f3303cb8c1e..813b1afa6d4 100644 --- a/indra/llprecompiled/CMakeLists.txt +++ b/indra/llprecompiled/CMakeLists.txt @@ -6,10 +6,6 @@ set(llprecompiled_SOURCE_FILES add_library (llprecompiled STATIC ${llprecompiled_SOURCE_FILES}) -target_include_directories(llprecompiled PRIVATE - ${INDRA_SOURCE_DIR}/llmath - ) - target_link_libraries(llprecompiled llcommon ll::apr @@ -25,7 +21,6 @@ target_precompile_headers(llprecompiled PRIVATE [["linden_common.h"]] [["llwin32headers.h"]] [["llprofiler.h"]] - [["llmath.h"]] @@ -41,10 +36,6 @@ target_precompile_headers(llprecompiled PRIVATE add_executable(llprecompiled_exe ${llprecompiled_SOURCE_FILES}) -target_include_directories(llprecompiled_exe PRIVATE - ${INDRA_SOURCE_DIR}/llmath - ) - target_link_libraries(llprecompiled_exe llcommon ll::apr @@ -60,7 +51,6 @@ target_precompile_headers(llprecompiled_exe PRIVATE [["linden_common.h"]] [["llwin32headers.h"]] [["llprofiler.h"]] - [["llmath.h"]] diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 7e84249082e..dbeea1a1f5e 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -29,7 +29,6 @@ #include #include "../llgltfmaterial.h" -#include "lluuid.cpp" // Import & define single-header gltf import/export lib #define TINYGLTF_IMPLEMENTATION diff --git a/indra/llprimitive/tests/llmaterial_test.cpp b/indra/llprimitive/tests/llmaterial_test.cpp index c24492e5f67..dfc44840ff9 100644 --- a/indra/llprimitive/tests/llmaterial_test.cpp +++ b/indra/llprimitive/tests/llmaterial_test.cpp @@ -22,7 +22,6 @@ #include "lltut.h" #include "../llmaterial.h" -#include "lluuid.cpp" namespace tut { diff --git a/indra/llprimitive/tests/llmaterialid_test.cpp b/indra/llprimitive/tests/llmaterialid_test.cpp index 04683fff8c1..89c5883287d 100644 --- a/indra/llprimitive/tests/llmaterialid_test.cpp +++ b/indra/llprimitive/tests/llmaterialid_test.cpp @@ -24,7 +24,6 @@ #include #include "../llmaterialid.h" -#include "lluuid.cpp" namespace tut { diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 62b5583aedf..c29d0e9c546 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -242,8 +242,7 @@ bool LLTexUnit::bind(LLTexture* texture, bool for_rendering, bool forceBind) glBindTexture(sGLTextureType[gl_tex->getTarget()], mCurrTexture); if(gl_tex->updateBindStats()) { - texture->setActive() ; - texture->updateBindStatsForTester() ; + texture->setActive(); } mHasMipMaps = gl_tex->mHasMipMaps; if (gl_tex->mTexOptionsDirty) diff --git a/indra/llrender/lltexture.cpp b/indra/llrender/lltexture.cpp index 980c0950f9a..0ee482cc523 100644 --- a/indra/llrender/lltexture.cpp +++ b/indra/llrender/lltexture.cpp @@ -40,4 +40,3 @@ S32 LLTexture::getWidth(S32 discard_level) const { llassert(false); return 0; } S32 LLTexture::getHeight(S32 discard_level) const { llassert(false); return 0; } bool LLTexture::isActiveFetching() { llassert(false); return false; } LLImageGL* LLTexture::getGLTexture() const { llassert(false); return nullptr; } -void LLTexture::updateBindStatsForTester() { } diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h index 35cded86f22..c6b446e2066 100644 --- a/indra/llrender/lltexture.h +++ b/indra/llrender/lltexture.h @@ -67,9 +67,6 @@ class LLTexture : public virtual LLRefCount virtual S32 getHeight(S32 discard_level = -1) const; virtual bool isActiveFetching(); virtual LLImageGL* getGLTexture() const; - -private: - virtual void updateBindStatsForTester(); }; #endif diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h index 6e1742ab89c..e6df0d3a4bf 100644 --- a/indra/llui/llcommandmanager.h +++ b/indra/llui/llcommandmanager.h @@ -171,12 +171,12 @@ class LLCommand class LLCommandManager -: public LLSimpleton +: public LLSingleton { -public: - LLCommandManager(); + LLSINGLETON(LLCommandManager); ~LLCommandManager(); +public: struct Params : public LLInitParam::Block { Multiple< LLCommand::Params, AtLeast<1> > commands; diff --git a/indra/llui/llemojidictionary.cpp b/indra/llui/llemojidictionary.cpp index a8403746726..919a9e98f1b 100644 --- a/indra/llui/llemojidictionary.cpp +++ b/indra/llui/llemojidictionary.cpp @@ -144,8 +144,7 @@ LLEmojiDictionary::LLEmojiDictionary() // static void LLEmojiDictionary::initClass() { - LLEmojiDictionary::createInstance(); - LLEmojiDictionary* pThis = LLEmojiDictionary::getInstance(); + LLEmojiDictionary* pThis = &LLEmojiDictionary::initParamSingleton(); pThis->loadTranslations(); pThis->loadGroups(); diff --git a/indra/llui/llemojidictionary.h b/indra/llui/llemojidictionary.h index aea5f8cfe21..ade9e5bdd9f 100644 --- a/indra/llui/llemojidictionary.h +++ b/indra/llui/llemojidictionary.h @@ -105,12 +105,12 @@ struct LLEmojiSearchResult // LLEmojiDictionary class // -class LLEmojiDictionary : public LLSimpleton, public LLInitClass +class LLEmojiDictionary : public LLParamSingleton, public LLInitClass { -public: - LLEmojiDictionary(); - ~LLEmojiDictionary() = default; + LLSINGLETON(LLEmojiDictionary); + ~LLEmojiDictionary() override {}; +public: typedef std::map cat2cat_map_t; typedef std::map cat2group_map_t; // Keyed by full emoji sequence (LLWString) so ZWJ families and flag diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index aa31b64b8a1..af9f771e0ba 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -1717,14 +1717,12 @@ void LLFolderView::setShowSingleSelection(bool show) } } -static LLTrace::BlockTimerStatHandle FTM_INVENTORY("Inventory"); - // Main idle routine void LLFolderView::update() { // If this is associated with the user's inventory, don't do anything // until that inventory is loaded up. - LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_INVENTORY); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // If there's no model, the view is in suspended state (being deleted) and shouldn't be updated if (getFolderViewModel() == NULL) diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 0bf4a5fa8d4..1eecdffab92 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -1320,8 +1320,6 @@ void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder) } } -static LLTrace::BlockTimerStatHandle FTM_ARRANGE("Arrange"); - // Make everything right and in the right place ready for drawing (CHUI-849) // * Sort everything correctly if necessary // * Turn widgets visible/invisible according to their model filtering state @@ -1331,6 +1329,8 @@ static LLTrace::BlockTimerStatHandle FTM_ARRANGE("Arrange"); // * Makes sure that this view and its children are the right size S32 LLFolderViewFolder::arrange( S32* width, S32* height ) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + // Sort before laying out contents // Note that we sort from the root (CHUI-849) if (mAreChildrenInited) @@ -1338,8 +1338,6 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) getRoot()->getFolderViewModel()->sort(this); } - LL_RECORD_BLOCK_TIME(FTM_ARRANGE); - // evaluate mHasVisibleChildren mHasVisibleChildren = false; if (mAreChildrenInited && getViewModelItem()->descendantsPassedFilter()) @@ -1368,13 +1366,12 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) mHasVisibleChildren = found; } + if (!mIsFolderComplete && mAreChildrenInited) { mIsFolderComplete = getFolderViewModel()->isFolderComplete(this); } - - // calculate height as a single item (without any children), and reshapes rectangle to match LLFolderViewItem::arrange( width, height ); diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index a390b2a348c..37526ee1eae 100644 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -494,7 +494,6 @@ bool LLKeywords::WStringMapIndex::operator<(const LLKeywords::WStringMapIndex &o return result; } -LLTrace::BlockTimerStatHandle FTM_SYNTAX_COLORING("Syntax Coloring"); constexpr size_t AVERAGE_SEGMENT_LENGTH = 8; void LLKeywords::collectSegmentOps(segment_ops_t& ops, const LLWString& wtext, bool disable_syntax_highlighting) const @@ -894,7 +893,7 @@ void LLKeywords::applySegmentOps(std::vector *seg_list, // create a list of color segments. void LLKeywords::findSegments(std::vector* seg_list, const LLWString& wtext, LLTextEditor& editor, LLStyleConstSP style) { - LL_RECORD_BLOCK_TIME(FTM_SYNTAX_COLORING); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if( wtext.empty() ) { diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp index 3059f6c6d7e..a9bb27007f7 100644 --- a/indra/llui/llpanel.cpp +++ b/indra/llui/llpanel.cpp @@ -360,10 +360,10 @@ void LLPanel::setBorderVisible(bool b) } } -LLTrace::BlockTimerStatHandle FTM_PANEL_CONSTRUCTION("Panel Construction"); - LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_node) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; + std::string name("panel"); node->getAttributeString("name", name); @@ -372,8 +372,7 @@ LLView* LLPanel::fromXML(LLXMLNodePtr node, LLView* parent, LLXMLNodePtr output_ LLPanel* panelp = NULL; - { LL_RECORD_BLOCK_TIME(FTM_PANEL_CONSTRUCTION); - + { if(!class_attr.empty()) { panelp = LLRegisterPanelClass::instance().createPanelClass(class_attr); @@ -476,16 +475,11 @@ void LLPanel::initFromParams(const LLPanel::Params& p) setAcceptsBadge(p.accepts_badge); } -static LLTrace::BlockTimerStatHandle FTM_PANEL_SETUP("Panel Setup"); -static LLTrace::BlockTimerStatHandle FTM_EXTERNAL_PANEL_LOAD("Load Extern Panel Reference"); -static LLTrace::BlockTimerStatHandle FTM_PANEL_POSTBUILD("Panel PostBuild"); - bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr output_node, const LLPanel::Params& default_params) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; Params params(default_params); { - LL_RECORD_BLOCK_TIME(FTM_PANEL_SETUP); - LLXMLNodePtr referenced_xml; std::string xml_filename = mXMLFilename; @@ -514,7 +508,7 @@ bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu LLUICtrlFactory::instance().pushFileName(xml_filename); - LL_RECORD_BLOCK_TIME(FTM_EXTERNAL_PANEL_LOAD); + LL_PROFILE_ZONE_NAMED_CATEGORY_UI("Load Extern Panel Reference"); if (!LLUICtrlFactory::getLayeredXMLNode(xml_filename, referenced_xml)) { LL_WARNS() << "Couldn't parse panel from: " << xml_filename << LL_ENDL; @@ -545,7 +539,7 @@ bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu params.from_xui = true; applyXUILayout(params, parent); { - LL_RECORD_BLOCK_TIME(FTM_PANEL_CONSTRUCTION); + LL_PROFILE_ZONE_NAMED_CATEGORY_UI("Panel Construction"); initFromParams(params); } @@ -562,7 +556,7 @@ bool LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu } { - LL_RECORD_BLOCK_TIME(FTM_PANEL_POSTBUILD); + LL_PROFILE_ZONE_NAMED_CATEGORY_UI("Panel PostBuild"); postBuild(); } } diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index b4cb6084728..6fca1a0cbf3 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -157,7 +157,6 @@ mRootView(NULL), mHelpImpl(NULL) { LL_PROFILE_ZONE_SCOPED; - LLUICtrlFactory::createInstance(); LLRender2D::createInstance(image_provider); LLSpellChecker::createInstance(); @@ -198,17 +197,14 @@ mHelpImpl(NULL) LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.CanShow", boost::bind(&LLFloaterReg::canShowInstance, _2, LLSD())); // [/RLVa:KB] - // Create the command manager and parse the master list of commands - LLCommandManager::createInstance(); + // Parse the master list of commands LLCommandManager::load(); } LLUI::~LLUI() { - LLCommandManager::deleteSingleton(); LLSpellChecker::deleteSingleton(); LLRender2D::deleteSingleton(); - LLUICtrlFactory::deleteSingleton(); } void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup, const clear_popups_t& clear_popups) diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h index 85a49e9bdaa..6f6f8b834bb 100644 --- a/indra/llui/lluicolortable.h +++ b/indra/llui/lluicolortable.h @@ -36,16 +36,15 @@ class LLUIColor; -class LLUIColorTable : public LLSimpleton +class LLUIColorTable : public LLSingleton { + LLSINGLETON_EMPTY_CTOR(LLUIColorTable); LOG_CLASS(LLUIColorTable); // consider using sorted vector, can be much faster typedef boost::unordered_map> string_color_map_t; public: - LLUIColorTable() = default; - struct ColorParams : LLInitParam::ChoiceBlock { Alternative value; diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 740f187ed8d..33ffc3dfc63 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -67,7 +67,7 @@ class LLUICtrlLocate : public LLUICtrl static LLDefaultChildRegistry::Register r1("locate"); // Build time optimization, generate this once in .cpp file -template class LLUICtrlFactory* LLSimpleton::getInstance(); +template class LLUICtrlFactory* LLSingleton::getInstance(); //----------------------------------------------------------------------------- // LLUICtrlFactory() diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index 1ad27e4c069..f44b4ba4dcf 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -81,16 +81,14 @@ class LLWidgetNameRegistry // Build time optimization, generate this once in .cpp file #ifndef LLUICTRLFACTORY_CPP -extern template class LLUICtrlFactory* LLSimpleton::getInstance(); +extern template class LLUICtrlFactory* LLSingleton::getInstance(); #endif -class LLUICtrlFactory : public LLSimpleton +class LLUICtrlFactory : public LLSingleton { -public: - LLUICtrlFactory(); + LLSINGLETON(LLUICtrlFactory); ~LLUICtrlFactory(); -private: // only partial specialization allowed in inner classes, so use extra dummy parameter template class ParamDefaults @@ -316,7 +314,7 @@ LLChildRegistry::Register::Register(const char* tag, LLWidgetCreator : LLChildRegistry::StaticRegistrar(tag, func == nullptr ? (LLWidgetCreatorFunc)&LLUICtrlFactory::defaultBuilder : func) { // add this widget to various registries - LLUICtrlFactory::registerWidget(typeid(T), typeid(typename T::Params), tag); + LLUICtrlFactory::instance().registerWidget(typeid(T), typeid(typename T::Params), tag); // since registry_t depends on T, do this in line here // TODO: uncomment this for schema generation diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp index ab6de16639b..0d9c66d4cf7 100644 --- a/indra/llui/lluistring.cpp +++ b/indra/llui/lluistring.cpp @@ -31,9 +31,6 @@ #include "llsd.h" #include "lltrans.h" -LLTrace::BlockTimerStatHandle FTM_UI_STRING("UI String"); - - LLUIString::LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args) : mOrig(instring), mArgs(new LLStringUtil::format_map_t(args)) @@ -62,7 +59,7 @@ void LLUIString::setArgList(const LLStringUtil::format_map_t& args) void LLUIString::setArgs(const LLSD& sd) { - LL_RECORD_BLOCK_TIME(FTM_UI_STRING); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (!sd.isMap()) return; for(LLSD::map_const_iterator sd_it = sd.beginMap(); @@ -123,9 +120,9 @@ void LLUIString::dirty() void LLUIString::updateResult() const { - mNeedsResult = false; + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; - LL_RECORD_BLOCK_TIME(FTM_UI_STRING); + mNeedsResult = false; // optimize for empty strings (don't attempt string replacement) if (mOrig.empty()) diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index a818a5fec13..035c9450b09 100644 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -672,12 +672,11 @@ LLXUIParser::LLXUIParser() } } -static LLTrace::BlockTimerStatHandle FTM_PARSE_XUI("XUI Parsing"); const LLXMLNodePtr DUMMY_NODE = new LLXMLNode(); void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename, bool silent) { - LL_RECORD_BLOCK_TIME(FTM_PARSE_XUI); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (node.isNull()) { @@ -1389,7 +1388,7 @@ LLSimpleXUIParser::~LLSimpleXUIParser() bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent) { - LL_RECORD_BLOCK_TIME(FTM_PARSE_XUI); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; mParser = XML_ParserCreate(NULL); XML_SetUserData(mParser, this); diff --git a/indra/llui/tests/llemojidictionary_test.cpp b/indra/llui/tests/llemojidictionary_test.cpp index 90afd849100..29acd3e71bf 100644 --- a/indra/llui/tests/llemojidictionary_test.cpp +++ b/indra/llui/tests/llemojidictionary_test.cpp @@ -98,10 +98,14 @@ namespace tut { struct llemojidictionary_data { - // Construct a dictionary directly. Only pure-logic methods are - // exercised, so the singleton's normal initClass() flow (which - // touches gDirUtilp) is intentionally bypassed. - LLEmojiDictionary dict; + llemojidictionary_data() + { + LLEmojiDictionary::initParamSingleton(); + } + ~llemojidictionary_data() + { + LLEmojiDictionary::deleteSingleton(); + } }; typedef test_group factory; typedef factory::object object; @@ -119,7 +123,7 @@ namespace tut void object::test<1>() { LLEmojiDescriptor d = make_thumbs_up_descriptor(); - const LLEmojiVariant* v = dict.findVariant(d, 3, -1); + const LLEmojiVariant* v = LLEmojiDictionary::instance().findVariant(d, 3, -1); ensure("tone-3 variant found", v != nullptr); ensure_equals("tone matches", v->Tone, U8(3)); } @@ -129,7 +133,7 @@ namespace tut void object::test<2>() { LLEmojiDescriptor d = make_thumbs_up_descriptor(); - const LLEmojiVariant* v = dict.findVariant(d, 0, -1); + const LLEmojiVariant* v = LLEmojiDictionary::instance().findVariant(d, 0, -1); ensure("no preference returns nullptr", v == nullptr); } @@ -139,7 +143,7 @@ namespace tut { LLEmojiDescriptor empty; empty.Character = utf8str_to_wstring("\xF0\x9F\x92\xA9"); // 💩 - const LLEmojiVariant* v = dict.findVariant(empty, 3, -1); + const LLEmojiVariant* v = LLEmojiDictionary::instance().findVariant(empty, 3, -1); ensure("no variants returns nullptr", v == nullptr); } @@ -148,7 +152,7 @@ namespace tut void object::test<4>() { LLEmojiDescriptor d = make_astronaut_descriptor(); - const LLEmojiVariant* v = dict.findVariant(d, 3, 0); // tone=3, man + const LLEmojiVariant* v = LLEmojiDictionary::instance().findVariant(d, 3, 0); // tone=3, man ensure("variant found", v != nullptr); ensure_equals("tone matches", v->Tone, U8(3)); ensure_equals("gender matches", v->Gender, S8(0)); @@ -161,7 +165,7 @@ namespace tut void object::test<5>() { LLEmojiDescriptor d = make_astronaut_descriptor(); - const LLEmojiVariant* v = dict.findVariant(d, 3, -1); + const LLEmojiVariant* v = LLEmojiDictionary::instance().findVariant(d, 3, -1); ensure("variant found", v != nullptr); ensure_equals("tone matches", v->Tone, U8(3)); // Gender preference unset — best match should have Gender=2 @@ -181,7 +185,7 @@ namespace tut // Ask tone=3, gender=woman, but the descriptor has only // gender-neutral variants. Should still return the tone-3 // variant (partial match). - const LLEmojiVariant* v = dict.findVariant(d, 3, 1); + const LLEmojiVariant* v = LLEmojiDictionary::instance().findVariant(d, 3, 1); ensure("partial match accepted", v != nullptr); ensure_equals("tone matches", v->Tone, U8(3)); } @@ -289,9 +293,9 @@ namespace tut template<> template<> void object::test<10>() { - dict.loadEmojisFromSD(make_thumbs_up_dictionary_blob()); + LLEmojiDictionary::instance().loadEmojisFromSD(make_thumbs_up_dictionary_blob()); ensure("base char returned", - dict.getEmojiFromShortCode(":thumbs_up:") == utf8str_to_wstring("\xF0\x9F\x91\x8D")); + LLEmojiDictionary::instance().getEmojiFromShortCode(":thumbs_up:") == utf8str_to_wstring("\xF0\x9F\x91\x8D")); } // getEmojiFromShortCode returns the VARIANT character for a variant @@ -299,9 +303,9 @@ namespace tut template<> template<> void object::test<11>() { - dict.loadEmojisFromSD(make_thumbs_up_dictionary_blob()); + LLEmojiDictionary::instance().loadEmojisFromSD(make_thumbs_up_dictionary_blob()); ensure("variant char returned", - dict.getEmojiFromShortCode(":thumbs_up_dark_skin_tone:") + LLEmojiDictionary::instance().getEmojiFromShortCode(":thumbs_up_dark_skin_tone:") == utf8str_to_wstring("\xF0\x9F\x91\x8D\xF0\x9F\x8F\xBF")); } @@ -309,8 +313,8 @@ namespace tut template<> template<> void object::test<12>() { - dict.loadEmojisFromSD(make_thumbs_up_dictionary_blob()); - ensure("empty for unknown", dict.getEmojiFromShortCode(":nonsense:").empty()); + LLEmojiDictionary::instance().loadEmojisFromSD(make_thumbs_up_dictionary_blob()); + ensure("empty for unknown", LLEmojiDictionary::instance().getEmojiFromShortCode(":nonsense:").empty()); } // findByShortCode prefix-matching now surfaces variants — typing @@ -319,10 +323,10 @@ namespace tut template<> template<> void object::test<13>() { - dict.loadEmojisFromSD(make_thumbs_up_dictionary_blob()); + LLEmojiDictionary::instance().loadEmojisFromSD(make_thumbs_up_dictionary_blob()); std::vector results; - dict.findByShortCode(results, ":thumbs_up_d"); + LLEmojiDictionary::instance().findByShortCode(results, ":thumbs_up_d"); ensure("at least one result", !results.empty()); const LLWString expected_dark = utf8str_to_wstring("\xF0\x9F\x91\x8D\xF0\x9F\x8F\xBF"); diff --git a/indra/llwindow/llcursortypes.h b/indra/llwindow/llcursortypes.h index 9a0c2909bf8..619e07b5a0b 100644 --- a/indra/llwindow/llcursortypes.h +++ b/indra/llwindow/llcursortypes.h @@ -76,6 +76,6 @@ enum ECursorType { UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) }; -LL_COMMON_API ECursorType getCursorFromString(const std::string& cursor_string); +ECursorType getCursorFromString(const std::string& cursor_string); #endif // LL_LLCURSORTYPES_H diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 5fa1708d476..4abff070dd1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2308,9 +2308,6 @@ void LLWindowWin32::gatherInput() updateCursor(); } -static LLTrace::BlockTimerStatHandle FTM_KEYHANDLER("Handle Keyboard"); -static LLTrace::BlockTimerStatHandle FTM_MOUSEHANDLER("Handle Mouse"); - #define WINDOW_IMP_POST(x) window_imp->post([=]() { x; }) LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_param, LPARAM l_param) @@ -2709,7 +2706,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_LBUTTONDOWN"); { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); window_imp->postMouseButtonEvent([=]() { sHandleLeftMouseUp = true; @@ -2757,7 +2753,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { window_imp->postMouseButtonEvent([=]() { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); if (!sHandleLeftMouseUp) { sHandleLeftMouseUp = true; @@ -2779,7 +2774,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_RBUTTONDOWN"); { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); window_imp->post([=]() { if (LLWinImm::isAvailable() && window_imp->mPreeditor) @@ -2802,7 +2796,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_RBUTTONUP"); { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); window_imp->postMouseButtonEvent([=]() { MASK mask = gKeyboard->currentMask(true); @@ -2817,7 +2810,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MBUTTONDOWN"); { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); window_imp->postMouseButtonEvent([=]() { if (LLWinImm::isAvailable() && window_imp->mPreeditor) @@ -2836,7 +2828,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_MBUTTONUP"); { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); window_imp->postMouseButtonEvent([=]() { MASK mask = gKeyboard->currentMask(true); @@ -2850,7 +2841,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_XBUTTONDOWN"); window_imp->postMouseButtonEvent([=]() { - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); S32 button = GET_XBUTTON_WPARAM(w_param); if (LLWinImm::isAvailable() && window_imp->mPreeditor) { @@ -2870,9 +2860,6 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_XBUTTONUP"); window_imp->postMouseButtonEvent([=]() { - - LL_RECORD_BLOCK_TIME(FTM_MOUSEHANDLER); - S32 button = GET_XBUTTON_WPARAM(w_param); MASK mask = gKeyboard->currentMask(true); // Windows uses numbers 1 and 2 for buttons, remap to 4, 5 diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d5746890610..662af9a61b9 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -312,7 +312,6 @@ set(viewer_SOURCE_FILES llexperiencelog.cpp llexternaleditor.cpp llface.cpp - llfasttimerview.cpp llfavoritesbar.cpp llfeaturemanager.cpp llfetchedgltfmaterial.cpp @@ -1081,7 +1080,6 @@ set(viewer_HEADER_FILES llexperiencelog.h llexternaleditor.h llface.h - llfasttimerview.h llfavoritesbar.h llfeaturemanager.h llfetchedgltfmaterial.h diff --git a/indra/newview/alstreaminfo.h b/indra/newview/alstreaminfo.h index 85b82cc40cc..a0813f96e99 100644 --- a/indra/newview/alstreaminfo.h +++ b/indra/newview/alstreaminfo.h @@ -33,13 +33,11 @@ #include "llsingleton.h" -class ALStreamInfo : public LLSimpleton +class ALStreamInfo : public LLSingleton { -public: - ALStreamInfo(); + LLSINGLETON(ALStreamInfo); ~ALStreamInfo(); -private: void handleMetadataUpdate(const LLSD& metadata); boost::signals2::connection mMetadataConnection; diff --git a/indra/newview/altoolalign.h b/indra/newview/altoolalign.h index 5bbe44298cc..28857ddf084 100644 --- a/indra/newview/altoolalign.h +++ b/indra/newview/altoolalign.h @@ -33,12 +33,12 @@ class LLPickInfo; class LLToolSelectRect; class ALToolAlign final -: public LLTool, public LLSimpleton +: public LLTool, public LLSingleton { -public: - ALToolAlign(); + LLSINGLETON(ALToolAlign); ~ALToolAlign() = default; +public: void handleSelect() override; void handleDeselect() override; bool handleMouseDown(S32 x, S32 y, MASK mask) override; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index d7f1344a8db..a0e2434c109 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2131,6 +2131,8 @@ void LLAgent::propagate(const F32 dt) //----------------------------------------------------------------------------- void LLAgent::updateAgentPosition(const F32 dt, const F32 yaw_radians, const S32 mouse_x, const S32 mouse_y) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + static LLCachedControl hint_timeout(gSavedSettings, "NotMovingHintTimeout"); if (mMoveTimer.getStarted() && mMoveTimer.getElapsedTimeF32() > hint_timeout) { diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 6bfba67e565..41f349b148e 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -1245,8 +1245,6 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y) } } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera"); - extern bool gCubeSnapshot; //----------------------------------------------------------------------------- @@ -1254,7 +1252,7 @@ extern bool gCubeSnapshot; //----------------------------------------------------------------------------- void LLAgentCamera::updateCamera() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER; if (gCubeSnapshot) { return; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index fcc2161f1ac..5d3182595c1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -92,7 +92,6 @@ #include "lltoast.h" #include "llsdutil_math.h" #include "lllocationhistory.h" -#include "llfasttimerview.h" #include "llvector4a.h" #include "llviewermenufile.h" #include "llvoicechannel.h" @@ -231,7 +230,6 @@ #include "llfloatersimplesnapshot.h" #include "llfloatersnapshot.h" #include "llsidepanelinventory.h" -#include "llinventorymodelbackgroundfetch.h" // includes for idle() idleShutdown() #include "llviewercontrol.h" @@ -261,26 +259,9 @@ using namespace LL; #include "llmachineid.h" #include "llcleanup.h" -#include "altoolalign.h" #include "llinventoryicon.h" #include "llcoproceduremanager.h" #include "llviewereventrecorder.h" -#include "llcontrolavatar.h" -#include "lldonotdisturbnotificationstorage.h" -#include "llemojidictionary.h" -#include "llfoldertype.h" -#include "llmaterialmgr.h" -#include "llpersistentnotificationstorage.h" -#include "lltoolcomp.h" -#include "lltooldraganddrop.h" -#include "lltoolface.h" -#include "lltoolfocus.h" -#include "lltoolgrab.h" -#include "lltoolindividual.h" -#include "lltoolpie.h" -#include "lltoolpipette.h" -#include "lltoolselectland.h" -#include "llviewerfoldertype.h" #include "alstreaminfo.h" @@ -626,32 +607,6 @@ static void settings_modify() gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); } -class LLFastTimerLogThread : public LLThread -{ -public: - std::string mFile; - - LLFastTimerLogThread(std::string& test_name) : LLThread("fast timer log") - { - std::string file_name = test_name + std::string(".slp"); - mFile = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, file_name); - } - - void run() - { - llofstream os(mFile.c_str()); - - while (!LLAppViewer::instance()->isQuitting()) - { - LLTrace::BlockTimer::writeLog(os); - os.flush(); - ms_sleep(32); - } - - os.close(); - } -}; - //virtual bool LLAppViewer::initSLURLHandler() { @@ -701,7 +656,6 @@ LLAppViewer::LLAppViewer() mAgentRegionLastAlive(false), mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", false)), mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", false)), - mFastTimerLogThread(NULL), mSettingsLocationList(NULL), mIsFirstRun(false) { @@ -820,7 +774,7 @@ bool LLAppViewer::init() // initialize the LLSettingsType translation bridge. LLTranslationBridge::ptr_t trans = std::make_shared(); - LLSettingsType::createInstance(trans); + LLSettingsType::initParamSingleton(trans); // initialize SSE options LLVector4a::initClass(); @@ -839,9 +793,6 @@ bool LLAppViewer::init() // init_default_trans_args(); - // Initialize ui color table singleton - LLUIColorTable::createInstance(); - // Initalize libxml2 xmlInitParser(); @@ -855,17 +806,6 @@ bool LLAppViewer::init() LL_INFOS("InitInfo") << "Configuration initialized." << LL_ENDL ; - // Init dictionary simpletons - LLInventoryDictionary::createInstance(); - LLAssetDictionary::createInstance(); - LLFolderDictionary::createInstance(); - LLViewerFolderDictionary::createInstance(); - LLIconDictionary::createInstance(); - RlvBehaviourDictionary::createInstance(); - - // Init coroutine manager - LLCoros::createInstance(); - //set the max heap size. initMaxHeapSize() ; LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize")); @@ -938,7 +878,7 @@ bool LLAppViewer::init() // initialize LLWearableType translation bridge. // Will immediately use LLTranslationBridge to init LLWearableDictionary - LLWearableType::createInstance(trans); + LLWearableType::initParamSingleton(trans); // Setup notifications after LLUI::initClass() has been called. LLNotifications::instance(); @@ -988,6 +928,8 @@ bool LLAppViewer::init() ///////////////////////////////////////////////// + LLToolMgr::getInstance(); // Initialize tool manager if not already instantiated + LLViewerFloaterReg::registerFloaters(); ///////////////////////////////////////////////// @@ -1054,18 +996,8 @@ bool LLAppViewer::init() // Initialize event recorder LLViewerEventRecorder::createInstance(); - LLWatchdog::createInstance(); - - // Init parcel manager, name cache, and mute list simpletons - LLViewerParcelMgr::createInstance(); - LLAvatarNameCache::createInstance(); - LLMuteList::createInstance(); + LLWatchdog::getInstance(); // Initialize watchdog timer - // Init media before initWindow(): main_view.xml constructs LLProgressView, - // whose postBuild() calls LLViewerMedia::getInstance(). - LLViewerMedia::createInstance(); - - // Initialize tool manager if not already instantiated // // Initialize the window // @@ -1220,17 +1152,9 @@ bool LLAppViewer::init() gSimLastTime = gRenderStartTime.getElapsedTimeF32(); gSimFrames = (F32)gFrameCount; - // Create joystick singleton and init if enabled + if (gSavedSettings.getBOOL("JoystickEnabled")) { - LLViewerJoystick::createInstance(); - - if (gSavedSettings.getBOOL("JoystickEnabled")) - { - LLViewerJoystick::getInstance()->init(false); - } - - joystick = LLViewerJoystick::getInstance(); - joystick->setNeedsReset(true); + LLViewerJoystick::getInstance()->init(false); } try @@ -1328,42 +1252,21 @@ bool LLAppViewer::init() // Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. LLVoiceChannel::initClass(); - LLVoiceClient::createInstance(gServicePump); + LLVoiceClient::initParamSingleton(gServicePump); LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + joystick = LLViewerJoystick::getInstance(); + joystick->setNeedsReset(true); /*----------------------------------------------------------------------*/ // Load User's bindings loadKeyBindings(); //LLSimpleton creations LLEnvironment::createInstance(); - LLViewerPartSim::createInstance(); LLWorld::createInstance(); LLViewerStatsRecorder::createInstance(); LLSelectMgr::createInstance(); LLViewerCamera::createInstance(); - LLMaterialMgr::createInstance(); - LLHUDManager::createInstance(); - LLWorldMap::createInstance(); - LLObjectSignaledAnimationMap::createInstance(); - - // Initialize tool manager and tools - LLToolSelectLand::createInstance(); - LLToolIndividual::createInstance(); - LLToolCompInspect::createInstance(); - LLToolCompTranslate::createInstance(); - LLToolCompScale::createInstance(); - LLToolCompRotate::createInstance(); - LLToolCompCreate::createInstance(); - ALToolAlign::createInstance(); - LLToolCompGun::createInstance(); - LLToolFace::createInstance(); - LLToolPipette::createInstance(); - LLToolGrab::createInstance(); - LLToolCamera::createInstance(); - LLToolDragAndDrop::createInstance(); - LLToolPie::createInstance(); - LLToolMgr::createInstance(); gSavedSettings.setU32("DebugQualityPerformance", gSavedSettings.getU32("RenderQualityPerformance")); @@ -1403,8 +1306,6 @@ void LLAppViewer::initMaxHeapSize() // externally visible timers -LLTrace::BlockTimerStatHandle FTM_FRAME("Frame"); - bool LLAppViewer::frame() { bool ret = false; @@ -1447,8 +1348,8 @@ bool LLAppViewer::frame() bool LLAppViewer::doFrame() { - LL_RECORD_BLOCK_TIME(FTM_FRAME); - LL_PROFILE_GPU_ZONE("Frame"); + LL_PROFILE_ZONE_SCOPED; + LL_PROFILE_GPU_ZONE("doFrame"); resumeMainloopTimeout("Main:doFrameStart"); @@ -1478,13 +1379,7 @@ bool LLAppViewer::doFrame() LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); // perf stats { LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace"); - if (LLFloaterReg::instanceVisible("block_timers")) - { - LLTrace::BlockTimer::processTimes(); - } - LLTrace::get_frame_recording().nextPeriod(); - LLTrace::BlockTimer::logStats(); } LLTrace::get_thread_recorder()->pullFromChildren(); @@ -1845,13 +1740,6 @@ bool LLAppViewer::cleanup() LLSceneMonitor::deleteSingleton(); } - // There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block - // here, completely redundant with the one that occurs later in this same - // function. Presumably the duplication was due to an automated merge gone - // bad. Not knowing which instance to prefer, we chose to retain the later - // one because it happens just after mFastTimerLogThread is deleted. This - // comment is in case we guessed wrong, so we can move it here instead. - #if LL_LINUX // remove any old breakpad minidump files from the log directory if (! isError()) @@ -1918,7 +1806,7 @@ bool LLAppViewer::cleanup() // Note: this is where gHUDManager used to be deleted. if(LLHUDManager::instanceExists()) { - LLHUDManager::deleteSingleton(); + LLHUDManager::getInstance()->shutdownClass(); } delete gAssetStorage; @@ -1990,7 +1878,6 @@ bool LLAppViewer::cleanup() // Cleanup Inventory after the UI since it will delete any remaining observers // (Deleted observers should have already removed themselves) gInventory.cleanupInventory(); - LLInventoryModelBackgroundFetch::deleteSingleton(); LLCoros::getInstance()->printActiveCoroutines(); @@ -2188,9 +2075,6 @@ bool LLAppViewer::cleanup() { // Turn off Space Navigator and similar devices LLViewerJoystick::getInstance()->terminate(); - - // Cleanup joystick singleton - LLViewerJoystick::deleteSingleton(); } LL_INFOS() << "Shutting down message system" << LL_ENDL; @@ -2214,36 +2098,16 @@ bool LLAppViewer::cleanup() } delete sImageDecodeThread; sImageDecodeThread = NULL; - delete mFastTimerLogThread; - mFastTimerLogThread = NULL; delete sPurgeDiskCacheThread; sPurgeDiskCacheThread = NULL; delete mGeneralThreadPool; mGeneralThreadPool = NULL; - if (LLFastTimerView::sAnalyzePerformance) - { - LL_INFOS() << "Analyzing performance" << LL_ENDL; - - std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp"; - std::string current_name = LLTrace::BlockTimer::sLogName + ".slp"; - std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv"; - - LLFastTimerView::doAnalysis( - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, baseline_name), - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, current_name), - gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name)); - } - - SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ; - LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL; //Note: //SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown() //because some new image might be generated during cleaning up media. --bao - LLViewerMedia::deleteSingleton(); - gTextureList.shutdown(); // shutdown again in case a callback added something LLUIImageList::getInstance()->cleanUp(); @@ -2283,41 +2147,13 @@ bool LLAppViewer::cleanup() ll_close_fail_log(); LLError::LLCallStacks::cleanup(); - - // Cleanup simpletons - LLPersistentNotificationStorage::deleteSingleton(); - LLDoNotDisturbNotificationStorage::deleteSingleton(); - LLObjectSignaledAnimationMap::deleteSingleton(); - LLWorldMap::deleteSingleton(); - LLAvatarNameCache::deleteSingleton(); - LLMaterialMgr::deleteSingleton(); + LLEnvironment::deleteSingleton(); LLSelectMgr::deleteSingleton(); - LLToolMgr::deleteSingleton(); - LLToolPie::deleteSingleton(); - LLToolDragAndDrop::deleteSingleton(); - LLToolCamera::deleteSingleton(); - LLToolGrab::deleteSingleton(); - LLToolPipette::deleteSingleton(); - LLToolFace::deleteSingleton(); - ALToolAlign::deleteSingleton(); - LLToolCompGun::deleteSingleton(); - LLToolCompCreate::deleteSingleton(); - LLToolCompRotate::deleteSingleton(); - LLToolCompScale::deleteSingleton(); - LLToolCompTranslate::deleteSingleton(); - LLToolCompInspect::deleteSingleton(); - LLToolIndividual::deleteSingleton(); - LLToolSelectLand::deleteSingleton(); LLViewerStatsRecorder::deleteSingleton(); LLViewerEventRecorder::deleteSingleton(); LLWorld::deleteSingleton(); - LLViewerPartSim::deleteSingleton(); - LLEnvironment::deleteSingleton(); LLVoiceClient::deleteSingleton(); LLUI::deleteSingleton(); - LLMuteList::deleteSingleton(); - LLAvatarNameCache::deleteSingleton(); - LLViewerParcelMgr::deleteSingleton(); // It's not at first obvious where, in this long sequence, a generic cleanup // call OUGHT to go. So let's say this: as we migrate cleanup from @@ -2330,26 +2166,6 @@ bool LLAppViewer::cleanup() // deleteSingleton() methods. LLSingletonBase::deleteAll(); - LLDiskCache::deleteSingleton(); - - // Destroy simpletons that singletons depend on - LLGridManager::deleteSingleton(); - LLUIColorTable::deleteSingleton(); - - // Destroy coroutine manager after everything besides dictionaries - LLCoros::deleteSingleton(); - - // Destroy static dictionaries - RlvBehaviourDictionary::deleteSingleton(); - LLSettingsType::deleteSingleton(); - LLWearableType::deleteSingleton(); - LLEmojiDictionary::deleteSingleton(); - LLIconDictionary::deleteSingleton(); - LLViewerFolderDictionary::deleteSingleton(); - LLFolderDictionary::deleteSingleton(); - LLAssetDictionary::deleteSingleton(); - LLInventoryDictionary::deleteSingleton(); - LLSplashScreen::hide(); LL_INFOS() << "Goodbye!" << LL_ENDL; @@ -2417,13 +2233,6 @@ bool LLAppViewer::initThreads() LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread(); - if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog) - { - LLTrace::BlockTimer::setLogLock(new LLMutex()); - mFastTimerLogThread = new LLFastTimerLogThread(LLTrace::BlockTimer::sLogName); - mFastTimerLogThread->start(); - } - // Mesh streaming and caching gMeshRepo.init(); @@ -2986,22 +2795,6 @@ bool LLAppViewer::initConfiguration() // If we have specified crash on startup, set the global so we'll trigger the crash at the right time gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup"); - if (gSavedSettings.getBOOL("LogPerformance")) - { - LLTrace::BlockTimer::sLog = true; - LLTrace::BlockTimer::sLogName = std::string("performance"); - } - - std::string test_name(gSavedSettings.getString("LogMetrics")); - if (!test_name.empty()) - { - LLTrace::BlockTimer::sMetricLog = true; - // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test - // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...) - LL_INFOS() << "'--logmetrics' argument : " << test_name << LL_ENDL; - LLTrace::BlockTimer::sLogName = test_name; - } - if (clp.hasOption("graphicslevel")) { // User explicitly requested --graphicslevel on the command line. We @@ -3014,7 +2807,6 @@ bool LLAppViewer::initConfiguration() mForceGraphicsLevel = gSavedSettings.getU32("RenderQualityPerformance"); } - LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance"); gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession")); if (gSavedSettings.getBOOL("DebugSession")) @@ -3060,9 +2852,6 @@ bool LLAppViewer::initConfiguration() llassert_always(!gSavedSettings.getBOOL("SLURLPassToOtherInstance")); } - // Init grid manager - LLGridManager::createInstance(); - // Handle slurl use. NOTE: Don't let SL-55321 reappear. // This initial-SLURL logic, up through the call to // sendURLToOtherInstance(), must precede LLSplashScreen::show() -- @@ -4675,7 +4464,7 @@ bool LLAppViewer::initCache() mPurgeCache = false; bool read_only = mSecondInstance; LLAppViewer::getTextureCache()->setReadOnly(read_only) ; - LLVOCache::createInstance(read_only); + LLVOCache::initParamSingleton(read_only); // initialize the new disk cache using saved settings const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); @@ -4747,7 +4536,7 @@ bool LLAppViewer::initCache() } const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); - LLDiskCache::createInstance(cache_dir, disk_cache_size, enable_cache_debug_info); + LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info); if (!read_only) { @@ -5150,20 +4939,6 @@ class LLFrameStatsTimer : public LLFrameTimer } }; -static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio"); -static LLTrace::BlockTimerStatHandle FTM_CLEANUP("Cleanup"); -static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLES("Drawables"); -static LLTrace::BlockTimerStatHandle FTM_IDLE_CB("Idle Callbacks"); -static LLTrace::BlockTimerStatHandle FTM_LOD_UPDATE("Update LOD"); -static LLTrace::BlockTimerStatHandle FTM_OBJECTLIST_UPDATE("Update Objectlist"); -static LLTrace::BlockTimerStatHandle FTM_REGION_UPDATE("Update Region"); -static LLTrace::BlockTimerStatHandle FTM_WORLD_UPDATE("Update World"); -static LLTrace::BlockTimerStatHandle FTM_NETWORK("Network"); -static LLTrace::BlockTimerStatHandle FTM_AGENT_NETWORK("Agent Network"); -static LLTrace::BlockTimerStatHandle FTM_VLMANAGER("VL Manager"); -static LLTrace::BlockTimerStatHandle FTM_AGENT_POSITION("Agent Position"); -static LLTrace::BlockTimerStatHandle FTM_HUD_EFFECTS("HUD Effects"); - /////////////////////////////////////////////////////// // idle() // @@ -5411,11 +5186,9 @@ void LLAppViewer::idle() { // Teleported, but waiting for things to load, start processing surface data { - LL_RECORD_BLOCK_TIME(FTM_NETWORK); gVLManager.unpackData(); } { - LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE); const F32 max_region_update_time = .001f; // 1ms LLWorld::getInstance()->updateRegions(max_region_update_time); } @@ -5438,15 +5211,12 @@ void LLAppViewer::idle() { // Handle pending gesture processing - LL_RECORD_BLOCK_TIME(FTM_AGENT_POSITION); LLGestureMgr::instance().update(); gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); } { - LL_RECORD_BLOCK_TIME(FTM_OBJECTLIST_UPDATE); - if (!(logoutRequestSent() && hasSavedFinalSnapshot())) { gObjectList.update(gAgent); @@ -5460,12 +5230,10 @@ void LLAppViewer::idle() // { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP); { gObjectList.cleanDeadObjects(); } { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP_DRAWABLES); LLDrawable::cleanupDeadDrawables(); } } @@ -5484,7 +5252,7 @@ void LLAppViewer::idle() // { - LL_RECORD_BLOCK_TIME(FTM_HUD_EFFECTS); + LL_PROFILE_ZONE_NAMED("Update HUD Effects"); LLSelectMgr::getInstance()->updateEffects(); LLHUDManager::getInstance()->cleanupEffects(); LLHUDManager::getInstance()->sendEffects(); @@ -5496,7 +5264,6 @@ void LLAppViewer::idle() // { - LL_RECORD_BLOCK_TIME(FTM_NETWORK); gVLManager.unpackData(); } @@ -5508,7 +5275,6 @@ void LLAppViewer::idle() LLWorld::getInstance()->updateVisibilities(); { const F32 max_region_update_time = .001f; // 1ms - LL_RECORD_BLOCK_TIME(FTM_REGION_UPDATE); LLWorld::getInstance()->updateRegions(max_region_update_time); } @@ -5578,7 +5344,6 @@ void LLAppViewer::idle() // objects and camera should be in sync, do LOD calculations now { - LL_RECORD_BLOCK_TIME(FTM_LOD_UPDATE); gObjectList.updateApparentAngles(gAgent); } @@ -5930,13 +5695,6 @@ void LLAppViewer::idleNameCache() constexpr F32 CHECK_MESSAGES_DEFAULT_MAX_TIME = 0.020f; // 50 ms = 50 fps (just for messages!) static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; -static LLTrace::BlockTimerStatHandle FTM_IDLE_NETWORK("Idle Network"); -static LLTrace::BlockTimerStatHandle FTM_MESSAGE_ACKS("Message Acks"); -static LLTrace::BlockTimerStatHandle FTM_RETRANSMIT("Retransmit"); -static LLTrace::BlockTimerStatHandle FTM_TIMEOUT_CHECK("Timeout Check"); -static LLTrace::BlockTimerStatHandle FTM_DYNAMIC_THROTTLE("Dynamic Throttle"); -static LLTrace::BlockTimerStatHandle FTM_CHECK_REGION_CIRCUIT("Check Region Circuit"); - void LLAppViewer::idleNetwork() { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; @@ -5948,7 +5706,7 @@ void LLAppViewer::idleNetwork() static LLCachedControl speed_test(gSavedSettings, "SpeedTest", false); if (!speed_test()) { - LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); //LL_RECORD_BLOCK_TIME(FTM_IDLE_NETWORK); // decode + LL_PROFILE_ZONE_NAMED_CATEGORY_NETWORK("idle network"); // decode LLTimer check_message_timer; // Read all available packets from network diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 616a7202bd4..f8c0a831bed 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -371,9 +371,6 @@ class LLAppViewer : public LLApp LLWatchdogTimeout* mMainloopTimeout; - // For performance and metric gathering - class LLThread* mFastTimerLogThread; - // for tracking viewer<->region circuit death bool mAgentRegionLastAlive; LLUUID mAgentRegionLastID; @@ -426,7 +423,6 @@ extern LLFrameTimer gRestoreGLTimer; extern bool gRestoreGL; extern bool gUseWireframe; -extern LLMemoryInfo gSysMemory; extern U64Bytes gMemoryAllocated; extern std::string gLastVersionChannel; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 39a31fb630f..013709363bd 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -1299,11 +1299,9 @@ void LLChatHistory::clear() mLastFromID = LLUUID::null; } -static LLTrace::BlockTimerStatHandle FTM_APPEND_MESSAGE("Append Chat Message"); - void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LLStyle::Params& input_append_params) { - LL_RECORD_BLOCK_TIME(FTM_APPEND_MESSAGE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; bool use_plain_text_chat_history = args["chat_history_style"].asInteger() >= 1; bool use_irssi_text_chat_history = args["chat_history_style"].asInteger() >= 2; bool square_brackets = false; // square brackets necessary for a system messages diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h index 0fd59d596c8..0d94fe08ee0 100644 --- a/indra/newview/llcontrolavatar.h +++ b/indra/newview/llcontrolavatar.h @@ -111,11 +111,11 @@ typedef std::map signaled_animation_map_t; typedef std::map object_signaled_animation_map_t; // Stores information about previously requested animations, by object id. -class LLObjectSignaledAnimationMap: public LLSimpleton +class LLObjectSignaledAnimationMap: public LLSingleton { -public: - LLObjectSignaledAnimationMap() = default; + LLSINGLETON_EMPTY_CTOR(LLObjectSignaledAnimationMap); +public: object_signaled_animation_map_t mMap; object_signaled_animation_map_t& getMap() { return mMap; } diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 53da9826ed7..b77195928bb 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -29,7 +29,6 @@ #include "lldebugview.h" // library includes -#include "llfasttimerview.h" #include "llconsole.h" #include "lltextureview.h" #include "llresmgr.h" @@ -53,7 +52,6 @@ static LLDefaultChildRegistry::Register r("debug_view"); LLDebugView::LLDebugView(const LLDebugView::Params& p) : LLView(p), - mFastTimerView(NULL), mDebugConsolep(NULL), mFloaterSnapRegion(NULL) {} @@ -89,8 +87,6 @@ void LLDebugView::init() r.setLeftTopAndSize(25, rect.getHeight() - 50, (S32) (gViewerWindow->getWindowRectScaled().getWidth() * 0.75f), (S32) (gViewerWindow->getWindowRectScaled().getHeight() * 0.75f)); - mFastTimerView = dynamic_cast(LLFloaterReg::getInstance("block_timers")); - gSceneView = new LLSceneView(r); gSceneView->setFollowsTop(); gSceneView->setFollowsLeft(); diff --git a/indra/newview/lldebugview.h b/indra/newview/lldebugview.h index 8fa2acc3c9d..4ba9cb360bc 100644 --- a/indra/newview/lldebugview.h +++ b/indra/newview/lldebugview.h @@ -35,7 +35,6 @@ // declarations class LLButton; class LLStatusPanel; -class LLFastTimerView; class LLConsole; class LLTextureView; class LLFloaterStats; @@ -59,7 +58,6 @@ class LLDebugView : public LLView void setStatsVisible(bool visible); - LLFastTimerView* mFastTimerView; LLConsole* mDebugConsolep; LLView* mFloaterSnapRegion; }; diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp index b4ced668d01..2039bab8437 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.cpp +++ b/indra/newview/lldonotdisturbnotificationstorage.cpp @@ -130,11 +130,9 @@ void LLDoNotDisturbNotificationStorage::saveNotifications() resetDirty(); } -static LLTrace::BlockTimerStatHandle FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications"); - void LLDoNotDisturbNotificationStorage::loadNotifications() { - LL_RECORD_BLOCK_TIME(FTM_LOAD_DND_NOTIFICATIONS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; LL_INFOS("LLDoNotDisturbNotificationStorage") << "start loading notifications" << LL_ENDL; diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h index 87e57633905..6683646a9b7 100644 --- a/indra/newview/lldonotdisturbnotificationstorage.h +++ b/indra/newview/lldonotdisturbnotificationstorage.h @@ -45,13 +45,13 @@ class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer bool tick(); }; -class LLDoNotDisturbNotificationStorage : public LLSimpleton, public LLNotificationStorage +class LLDoNotDisturbNotificationStorage : public LLParamSingleton, public LLNotificationStorage { - LOG_CLASS(LLDoNotDisturbNotificationStorage); -public: - LLDoNotDisturbNotificationStorage(); + LLSINGLETON(LLDoNotDisturbNotificationStorage); ~LLDoNotDisturbNotificationStorage(); + LOG_CLASS(LLDoNotDisturbNotificationStorage); +public: static const char * toastName; static const char * offerName; diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index da9378ad129..eef20cec763 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -287,6 +287,7 @@ void LLDrawable::removeFromOctree() void LLDrawable::cleanupDeadDrawables() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; /* S32 i; for (i = 0; i < sDeadList.size(); i++) diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 1cca08c20bc..728f00c260a 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -853,8 +853,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) } } -static LLTrace::BlockTimerStatHandle FTM_RIGGED_VBO("Rigged VBO"); - //----------------------------------------------------------------------------- // getDebugTexture() //----------------------------------------------------------------------------- diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 6de7a968d0f..a66b2280660 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -37,10 +37,6 @@ #include "llviewershadermgr.h" #include "llrender.h" -static LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple"); -static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass"); - - void LLDrawPoolGlow::renderPostDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; @@ -107,8 +103,6 @@ LLDrawPoolSimple::LLDrawPoolSimple() : { } -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask"); - LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() : LLRenderPass(POOL_ALPHA_MASK) { @@ -142,9 +136,6 @@ void LLDrawPoolSimple::renderDeferred(S32 pass) pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, true, true); } -static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask"); - - void LLDrawPoolAlphaMask::renderDeferred(S32 pass) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_DEFERRED); diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index d0536b0b406..8b5ce00fc46 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -58,8 +58,6 @@ S32 LLDrawPoolTerrain::sPBRDetailMode = 0; F32 LLDrawPoolTerrain::sDetailScale = DETAIL_SCALE; F32 LLDrawPoolTerrain::sPBRDetailScale = DETAIL_SCALE; static LLGLSLShader* sShader = NULL; -static LLTrace::BlockTimerStatHandle FTM_SHADOW_TERRAIN("Terrain Shadow"); - LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) : LLFacePool(POOL_TERRAIN), diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index 5e675003d6c..489a2e27b83 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -55,7 +55,7 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) : //============================================ void LLDrawPoolTree::beginDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; shader = &gDeferredTreeProgram; shader->bind(); @@ -99,7 +99,7 @@ void LLDrawPoolTree::renderDeferred(S32 pass) void LLDrawPoolTree::endDeferredPass(S32 pass) { - LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; shader->unbind(); } diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 9d24ac2b1c0..e58dfe1e6af 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -105,8 +105,6 @@ namespace const std::string LOCAL_ENV_STORAGE_FILE("local_environment_data.bin"); //--------------------------------------------------------------------- - LLTrace::BlockTimerStatHandle FTM_ENVIRONMENT_UPDATE("Update Environment Tick"); - LLSettingsBase::Seconds DEFAULT_UPDATE_THRESHOLD(10.0); const LLSettingsBase::Seconds MINIMUM_SPANLENGTH(0.01f); diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp deleted file mode 100644 index e3acb8e9268..00000000000 --- a/indra/newview/llfasttimerview.cpp +++ /dev/null @@ -1,1667 +0,0 @@ -/** - * @file llfasttimerview.cpp - * @brief LLFastTimerView class implementation - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfasttimerview.h" - -#include "llviewerwindow.h" -#include "llrect.h" -#include "llcombobox.h" -#include "llerror.h" -#include "llgl.h" -#include "llimagepng.h" -#include "llrender.h" -#include "llrendertarget.h" -#include "lllocalcliprect.h" -#include "lllayoutstack.h" -#include "llmath.h" -#include "llfontgl.h" -#include "llsdserialize.h" -#include "lltooltip.h" -#include "llbutton.h" -#include "llscrollbar.h" - -#include "llappviewer.h" -#include "llviewertexturelist.h" -#include "llui.h" -#include "llviewercontrol.h" - -#include "llfasttimer.h" -#include "lltreeiterators.h" -#include "llmetricperformancetester.h" -#include "llviewerstats.h" - -////////////////////////////////////////////////////////////////////////////// - -using namespace LLTrace; - -extern LLTrace::BlockTimerStatHandle FTM_FRAME; - -static constexpr S32 MAX_VISIBLE_HISTORY = 12; -static constexpr S32 LINE_GRAPH_HEIGHT = 240; -static constexpr S32 MIN_BAR_HEIGHT = 3; -static constexpr S32 RUNNING_AVERAGE_WIDTH = 100; -static constexpr S32 NUM_FRAMES_HISTORY = 200; - -std::vector ft_display_idx; // line of table entry for display purposes (for collapse) - -bool LLFastTimerView::sAnalyzePerformance = false; - -S32 get_depth(const BlockTimerStatHandle* blockp) -{ - S32 depth = 0; - BlockTimerStatHandle* timerp = blockp->getParent(); - while(timerp) - { - depth++; - if (timerp->getParent() == timerp) break; - timerp = timerp->getParent(); - } - return depth; -} - -LLFastTimerView::LLFastTimerView(const LLSD& key) -: LLFloater(key), - mHoverTimer(NULL), - mDisplayMode(0), - mDisplayType(DISPLAY_TIME), - mScrollIndex(0), - mHoverID(NULL), - mHoverBarIndex(-1), - mStatsIndex(-1), - mPauseHistory(false), - mRecording(NUM_FRAMES_HISTORY) -{ - mTimerBarRows.resize(NUM_FRAMES_HISTORY); -} - -LLFastTimerView::~LLFastTimerView() -{ -} - -void LLFastTimerView::onPause() -{ - setPauseState(!mPauseHistory); -} - -void LLFastTimerView::setPauseState(bool pause_state) -{ - if (pause_state == mPauseHistory) return; - - // reset scroll to bottom when unpausing - if (!pause_state) - { - - getChild("pause_btn")->setLabel(getString("pause")); - } - else - { - mScrollIndex = 0; - - getChild("pause_btn")->setLabel(getString("run")); - } - - mPauseHistory = pause_state; -} - -bool LLFastTimerView::postBuild() -{ - LLButton& pause_btn = getChildRef("pause_btn"); - mScrollBar = getChild("scroll_vert"); - - pause_btn.setCommitCallback(boost::bind(&LLFastTimerView::onPause, this)); - return true; -} - -bool LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask) -{ - if (mHoverTimer ) - { - // right click collapses timers - if (!mHoverTimer->getTreeNode().mCollapsed) - { - mHoverTimer->getTreeNode().mCollapsed = true; - } - else if (mHoverTimer->getParent()) - { - mHoverTimer->getParent()->getTreeNode().mCollapsed = true; - } - return true; - } - else if (mBarRect.pointInRect(x, y)) - { - S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()); - bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY); - mStatsIndex = mScrollIndex + bar_idx; - return true; - } - return LLFloater::handleRightMouseDown(x, y, mask); -} - -BlockTimerStatHandle* LLFastTimerView::getLegendID(S32 y) -{ - S32 idx = (mLegendRect.mTop - y) / (LLFontGL::getFontMonospace()->getLineHeight() + 2); - - if (idx >= 0 && idx < (S32)ft_display_idx.size()) - { - return ft_display_idx[idx]; - } - - return NULL; -} - -bool LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) -{ - for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - (*it)->getTreeNode().mCollapsed = false; - } - return true; -} - -bool LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask) -{ - if (x < mScrollBar->getRect().mLeft) - { - BlockTimerStatHandle* idp = getLegendID(y); - if (idp) - { - idp->getTreeNode().mCollapsed = !idp->getTreeNode().mCollapsed; - } - } - else if (mHoverTimer) - { - //left click drills down by expanding timers - mHoverTimer->getTreeNode().mCollapsed = false; - } - else if (mGraphRect.pointInRect(x, y)) - { - gFocusMgr.setMouseCapture(this); - return true; - } - - return LLFloater::handleMouseDown(x, y, mask); -} - -bool LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask) -{ - if (hasMouseCapture()) - { - gFocusMgr.setMouseCapture(NULL); - } - return LLFloater::handleMouseUp(x, y, mask);; -} - -bool LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) -{ - if (hasMouseCapture()) - { - F32 lerp = llclamp(1.f - (F32) (x - mGraphRect.mLeft) / (F32) mGraphRect.getWidth(), 0.f, 1.f); - mScrollIndex = ll_round( lerp * (F32)(mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY)); - mScrollIndex = llclamp( mScrollIndex, 0, (S32)mRecording.getNumRecordedPeriods()); - return true; - } - mHoverTimer = NULL; - mHoverID = NULL; - - if(mPauseHistory && mBarRect.pointInRect(x, y)) - { - //const S32 bars_top = mBarRect.mTop; - const S32 bars_top = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); - - mHoverBarIndex = llmin((bars_top - y) / (mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2)) - 1, - (S32)mRecording.getNumRecordedPeriods() - 1, - MAX_VISIBLE_HISTORY); - if (mHoverBarIndex == 0) - { - return true; - } - else if (mHoverBarIndex < 0) - { - mHoverBarIndex = 0; - } - - TimerBarRow& row = mHoverBarIndex == 0 ? mAverageTimerRow : mTimerBarRows[mScrollIndex + mHoverBarIndex - 1]; - - TimerBar* hover_bar = NULL; - F32Seconds mouse_time_offset = ((F32)(x - mBarRect.mLeft) / (F32)mBarRect.getWidth()) * mTotalTimeDisplay; - for (size_t bar_index = 0, end_index = LLTrace::BlockTimerStatHandle::instance_tracker_t::instanceCount(); - bar_index < end_index; - ++bar_index) - { - TimerBar& bar = row.mBars[bar_index]; - if (bar.mSelfStart > mouse_time_offset) - { - break; - } - if (bar.mSelfEnd > mouse_time_offset) - { - hover_bar = &bar; - if (bar.mTimeBlock->getTreeNode().mCollapsed) - { - // stop on first collapsed BlockTimerStatHandle, since we can't select any children - break; - } - } - } - - if (hover_bar) - { - mHoverID = hover_bar->mTimeBlock; - if (mHoverTimer != mHoverID) - { - // could be that existing tooltip is for a parent and is thus - // covering region for this new timer, go ahead and unblock - // so we can create a new tooltip - LLToolTipMgr::instance().unblockToolTips(); - mHoverTimer = mHoverID; - mToolTipRect.set((S32)(mBarRect.mLeft + (hover_bar->mSelfStart / mTotalTimeDisplay) * mBarRect.getWidth()), - row.mTop, - (S32)(mBarRect.mLeft + (hover_bar->mSelfEnd / mTotalTimeDisplay) * mBarRect.getWidth()), - row.mBottom); - } - } - } - else if (x < mScrollBar->getRect().mLeft) - { - BlockTimerStatHandle* timer_id = getLegendID(y); - if (timer_id) - { - mHoverID = timer_id; - } - } - - return LLFloater::handleHover(x, y, mask); -} - - -static std::string get_tooltip(BlockTimerStatHandle& timer, S32 history_index, PeriodicRecording& frame_recording) -{ - std::string tooltip; - if (history_index == 0) - { - // by default, show average number of call - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)F64Milliseconds(frame_recording.getPeriodMean (timer, RUNNING_AVERAGE_WIDTH)).value(), (S32)frame_recording.getPeriodMean(timer.callCount(), RUNNING_AVERAGE_WIDTH)); - } - else - { - tooltip = llformat("%s (%d ms, %d calls)", timer.getName().c_str(), (S32)F64Milliseconds(frame_recording.getPrevRecording(history_index).getSum(timer)).value(), (S32)frame_recording.getPrevRecording(history_index).getSum(timer.callCount())); - } - return tooltip; -} - -bool LLFastTimerView::handleToolTip(S32 x, S32 y, MASK mask) -{ - if(mPauseHistory && mBarRect.pointInRect(x, y)) - { - // tooltips for timer bars - if (mHoverTimer) - { - LLRect screen_rect; - localRectToScreen(mToolTipRect, &screen_rect); - - std::string tooltip = get_tooltip(*mHoverTimer, mHoverBarIndex > 0 ? mScrollIndex + mHoverBarIndex : 0, mRecording); - - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(tooltip) - .sticky_rect(screen_rect) - .delay_time(0.f)); - - return true; - } - } - else - { - // tooltips for timer legend - if (x < mScrollBar->getRect().mLeft) - { - BlockTimerStatHandle* idp = getLegendID(y); - if (idp) - { - LLToolTipMgr::instance().show(get_tooltip(*idp, 0, mRecording)); - - return true; - } - } - } - - return LLFloater::handleToolTip(x, y, mask); -} - -bool LLFastTimerView::handleScrollWheel(S32 x, S32 y, LLScrollDelta delta) -{ - if (x < mBarRect.mLeft) - { - // Inside mScrollBar and list of timers - mScrollBar->handleScrollWheel(x,y,delta); - } - else - { - setPauseState(true); - mScrollIndex = llclamp( mScrollIndex + delta.mClicks, - 0, - llmin((S32)mRecording.getNumRecordedPeriods(), (S32)mRecording.getNumRecordedPeriods() - MAX_VISIBLE_HISTORY)); - } - return true; -} - -static BlockTimerStatHandle FTM_RENDER_TIMER("Timers"); -static const S32 MARGIN = 10; - -static std::vector sTimerColors; - -void LLFastTimerView::draw() -{ - LL_RECORD_BLOCK_TIME(FTM_RENDER_TIMER); - - if (!mPauseHistory) - { - mRecording.appendRecording(LLTrace::get_frame_recording().getLastRecording()); - mTimerBarRows.pop_back(); - mTimerBarRows.push_front(TimerBarRow()); - } - - mDisplayMode = llclamp(getChild("time_scale_combo")->getCurrentIndex(), 0, 3); - mDisplayType = (EDisplayType)llclamp(getChild("metric_combo")->getCurrentIndex(), 0, 2); - - generateUniqueColors(); - - LLView::drawChildren(); - //getChild("timer_bars_stack")->updateLayout(); - //getChild("legend_stack")->updateLayout(); - LLView* bars_panel = getChildView("bars_panel"); - bars_panel->localRectToOtherView(bars_panel->getLocalRect(), &mBarRect, this); - - LLView* lines_panel = getChildView("lines_panel"); - lines_panel->localRectToOtherView(lines_panel->getLocalRect(), &mGraphRect, this); - - LLView* legend_panel = getChildView("legend"); - legend_panel->localRectToOtherView(legend_panel->getLocalRect(), &mLegendRect, this); - - // Draw the window background - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gl_rect_2d(getLocalRect(), LLColor4(0.f, 0.f, 0.f, 0.25f)); - - drawHelp(getRect().getHeight() - MARGIN); - drawLegend(); - - //mBarRect.mLeft = MARGIN + LEGEND_WIDTH + 8; - //mBarRect.mTop = y; - //mBarRect.mRight = getRect().getWidth() - MARGIN; - //mBarRect.mBottom = MARGIN + LINE_GRAPH_HEIGHT; - - drawBars(); - drawLineGraph(); - printLineStats(); - LLView::draw(); - - mAllTimeMax = llmax(mAllTimeMax, mRecording.getLastRecording().getSum(FTM_FRAME)); - mHoverID = NULL; - mHoverBarIndex = -1; -} - -void LLFastTimerView::onOpen(const LLSD& key) -{ - setPauseState(false); - mRecording.reset(); - mRecording.appendPeriodicRecording(LLTrace::get_frame_recording()); - for(std::deque::iterator it = mTimerBarRows.begin(), end_it = mTimerBarRows.end(); - it != end_it; - ++it) - { - delete []it->mBars; - it->mBars = NULL; - } -} - -void LLFastTimerView::onClose(bool app_quitting) -{ - setVisible(false); -} - -void saveChart(const std::string& label, const char* suffix, LLImageRaw* scratch) -{ - // disable use of glReadPixels which messes up nVidia nSight graphics debugging - if (!LLRender::sNsightDebugSupport) - { - LLImageDataSharedLock lock(scratch); - - //read result back into raw image - glReadPixels(0, 0, 1024, 512, GL_RGB, GL_UNSIGNED_BYTE, scratch->getData()); - - //write results to disk - LLPointer result = new LLImagePNG(); - result->encode(scratch, 0.f); - - std::string ext = result->getExtension(); - std::string filename = llformat("%s_%s.%s", label.c_str(), suffix, ext.c_str()); - - std::string out_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename); - result->save(out_file); - } -} - -//static -void LLFastTimerView::exportCharts(const std::string& base, const std::string& target) -{ - //allocate render target for drawing charts - LLRenderTarget buffer; - buffer.allocate(1024,512, GL_RGB); - - - LLSD cur; - - LLSD base_data; - - { //read base log into memory - S32 i = 0; - llifstream is(base.c_str()); - while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is)) - { - base_data[i++] = cur; - } - is.close(); - } - - LLSD cur_data; - std::set chart_names; - - { //read current log into memory - S32 i = 0; - llifstream is(target.c_str()); - while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is)) - { - cur_data[i++] = cur; - - for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) - { - std::string label = iter->first; - chart_names.insert(label); - } - } - is.close(); - } - - //allocate raw scratch space - LLPointer scratch = new LLImageRaw(1024, 512, 3); - - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.loadIdentity(); - gGL.ortho(-0.05f, 1.05f, -0.05f, 1.05f, -1.0f, 1.0f); - - //render charts - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - buffer.bindTarget(); - - for (std::set::iterator iter = chart_names.begin(); iter != chart_names.end(); ++iter) - { - std::string label = *iter; - - LLSD::Real max_time = 0.0; - LLSD::Integer max_calls = 0; - LLSD::Real max_execution = 0.0; - - std::vector cur_execution; - std::vector cur_times; - std::vector cur_calls; - - std::vector base_execution; - std::vector base_times; - std::vector base_calls; - - for (U32 i = 0; i < cur_data.size(); ++i) - { - LLSD::Real time = cur_data[i][label]["Time"].asReal(); - LLSD::Integer calls = cur_data[i][label]["Calls"].asInteger(); - - LLSD::Real execution = 0.0; - if (calls > 0) - { - execution = time/calls; - cur_execution.push_back(execution); - cur_times.push_back(time); - } - - cur_calls.push_back(calls); - } - - for (U32 i = 0; i < base_data.size(); ++i) - { - LLSD::Real time = base_data[i][label]["Time"].asReal(); - LLSD::Integer calls = base_data[i][label]["Calls"].asInteger(); - - LLSD::Real execution = 0.0; - if (calls > 0) - { - execution = time/calls; - base_execution.push_back(execution); - base_times.push_back(time); - } - - base_calls.push_back(calls); - } - - std::sort(base_calls.begin(), base_calls.end()); - std::sort(base_times.begin(), base_times.end()); - std::sort(base_execution.begin(), base_execution.end()); - - std::sort(cur_calls.begin(), cur_calls.end()); - std::sort(cur_times.begin(), cur_times.end()); - std::sort(cur_execution.begin(), cur_execution.end()); - - //remove outliers - const U32 OUTLIER_CUTOFF = 512; - if (base_times.size() > OUTLIER_CUTOFF) - { - ll_remove_outliers(base_times, 1.f); - } - - if (base_execution.size() > OUTLIER_CUTOFF) - { - ll_remove_outliers(base_execution, 1.f); - } - - if (cur_times.size() > OUTLIER_CUTOFF) - { - ll_remove_outliers(cur_times, 1.f); - } - - if (cur_execution.size() > OUTLIER_CUTOFF) - { - ll_remove_outliers(cur_execution, 1.f); - } - - - max_time = llmax(base_times.empty() ? 0.0 : *base_times.rbegin(), cur_times.empty() ? 0.0 : *cur_times.rbegin()); - max_calls = llmax(base_calls.empty() ? 0 : *base_calls.rbegin(), cur_calls.empty() ? 0 : *cur_calls.rbegin()); - max_execution = llmax(base_execution.empty() ? 0.0 : *base_execution.rbegin(), cur_execution.empty() ? 0.0 : *cur_execution.rbegin()); - - - LLVector3 last_p; - - //==================================== - // basic - //==================================== - buffer.clear(); - - last_p.clear(); - - LLGLDisable cull(GL_CULL_FACE); - - LLVector3 base_col(0, 0.7f, 0.f); - LLVector3 cur_col(1.f, 0.f, 0.f); - - gGL.setSceneBlendType(LLRender::BT_ADD); - - gGL.color3fv(base_col.mV); - for (U32 i = 0; i < base_times.size(); ++i) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(last_p.mV); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - last_p.set((F32)i/(F32) base_times.size(), (F32)(base_times[i]/max_time), 0.f); - gGL.vertex3fv(last_p.mV); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.end(); - } - - gGL.flush(); - - - last_p.clear(); - { - LLGLEnable blend(GL_BLEND); - - gGL.color3fv(cur_col.mV); - for (U32 i = 0; i < cur_times.size(); ++i) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.vertex3fv(last_p.mV); - last_p.set((F32) i / (F32) cur_times.size(), (F32)(cur_times[i]/max_time), 0.f); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.vertex3fv(last_p.mV); - gGL.end(); - } - - gGL.flush(); - } - - saveChart(label, "time", scratch); - - //====================================== - // calls - //====================================== - buffer.clear(); - - last_p.clear(); - - gGL.color3fv(base_col.mV); - for (U32 i = 0; i < base_calls.size(); ++i) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(last_p.mV); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - last_p.set((F32) i / (F32) base_calls.size(), (F32)base_calls[i]/max_calls, 0.f); - gGL.vertex3fv(last_p.mV); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.end(); - } - - gGL.flush(); - - { - LLGLEnable blend(GL_BLEND); - gGL.color3fv(cur_col.mV); - last_p.clear(); - - for (U32 i = 0; i < cur_calls.size(); ++i) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.vertex3fv(last_p.mV); - last_p.set((F32) i / (F32) cur_calls.size(), (F32) cur_calls[i]/max_calls, 0.f); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.vertex3fv(last_p.mV); - gGL.end(); - - } - - gGL.flush(); - } - - saveChart(label, "calls", scratch); - - //====================================== - // execution - //====================================== - buffer.clear(); - - gGL.color3fv(base_col.mV); - U32 count = 0; - U32 total_count = static_cast(base_execution.size()); - - last_p.clear(); - - for (std::vector::iterator iter = base_execution.begin(); iter != base_execution.end(); ++iter) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3fv(last_p.mV); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - last_p.set((F32)count/(F32)total_count, (F32)(*iter/max_execution), 0.f); - gGL.vertex3fv(last_p.mV); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.end(); - count++; - } - - last_p.clear(); - - { - LLGLEnable blend(GL_BLEND); - gGL.color3fv(cur_col.mV); - count = 0; - total_count = static_cast(cur_execution.size()); - - for (std::vector::iterator iter = cur_execution.begin(); iter != cur_execution.end(); ++iter) - { - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.vertex3fv(last_p.mV); - last_p.set((F32)count/(F32)total_count, (F32)(*iter/max_execution), 0.f); - gGL.vertex3f(last_p.mV[0], 0.f, 0.f); - gGL.vertex3fv(last_p.mV); - gGL.end(); - count++; - } - - gGL.flush(); - } - - saveChart(label, "execution", scratch); - } - - buffer.flush(); - - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); -} - -//static -LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is) -{ - LLSD ret; - - LLSD cur; - - LLSD::Real total_time = 0.0; - LLSD::Integer total_frames = 0; - - typedef std::map stats_map_t; - stats_map_t time_stats; - stats_map_t sample_stats; - - while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is)) - { - for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter) - { - std::string label = iter->first; - - F64 time = iter->second["Time"].asReal(); - - // Skip the total figure - if(label.compare("Total") != 0) - { - total_time += time; - } - - if (time > 0.0) - { - LLSD::Integer samples = iter->second["Calls"].asInteger(); - - time_stats[label].push((F32)time); - sample_stats[label].push((F32)samples); - } - } - total_frames++; - } - - for(stats_map_t::iterator it = time_stats.begin(); it != time_stats.end(); ++it) - { - std::string label = it->first; - ret[label]["TotalTime"] = time_stats[label].getSum(); - ret[label]["MeanTime"] = time_stats[label].getMean(); - ret[label]["MaxTime"] = time_stats[label].getMaxValue(); - ret[label]["MinTime"] = time_stats[label].getMinValue(); - ret[label]["StdDevTime"] = time_stats[label].getStdDev(); - - ret[label]["Samples"] = sample_stats[label].getSum(); - ret[label]["MaxSamples"] = sample_stats[label].getMaxValue(); - ret[label]["MinSamples"] = sample_stats[label].getMinValue(); - ret[label]["StdDevSamples"] = sample_stats[label].getStdDev(); - - ret[label]["Frames"] = (LLSD::Integer)time_stats[label].getCount(); - } - - ret["SessionTime"] = total_time; - ret["FrameCount"] = total_frames; - - return ret; - -} - -//static -void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target, std::string output) -{ - // Open baseline and current target, exit if one is inexistent - llifstream base_is(baseline.c_str()); - llifstream target_is(target.c_str()); - if (!base_is.is_open() || !target_is.is_open()) - { - LL_WARNS() << "'-analyzeperformance' error : baseline or current target file inexistent" << LL_ENDL; - base_is.close(); - target_is.close(); - return; - } - - //analyze baseline - LLSD base = analyzePerformanceLogDefault(base_is); - base_is.close(); - - //analyze current - LLSD current = analyzePerformanceLogDefault(target_is); - target_is.close(); - - //output comparison - llofstream os(output.c_str()); - - LLSD::Real session_time = current["SessionTime"].asReal(); - os << - "Label, " - "% Change, " - "% of Session, " - "Cur Min, " - "Cur Max, " - "Cur Mean/sample, " - "Cur Mean/frame, " - "Cur StdDev/frame, " - "Cur Total, " - "Cur Frames, " - "Cur Samples, " - "Base Min, " - "Base Max, " - "Base Mean/sample, " - "Base Mean/frame, " - "Base StdDev/frame, " - "Base Total, " - "Base Frames, " - "Base Samples\n"; - - for (LLSD::map_iterator iter = base.beginMap(); iter != base.endMap(); ++iter) - { - LLSD::String label = iter->first; - - if (current[label]["Samples"].asInteger() == 0 || - base[label]["Samples"].asInteger() == 0) - { - //cannot compare - continue; - } - LLSD::Real a = base[label]["TotalTime"].asReal() / base[label]["Samples"].asReal(); - LLSD::Real b = current[label]["TotalTime"].asReal() / current[label]["Samples"].asReal(); - - LLSD::Real diff = b-a; - - LLSD::Real perc = diff/a * 100; - - os << llformat("%s, %.2f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %d, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %d\n", - label.c_str(), - (F32) perc, - (F32) (current[label]["TotalTime"].asReal()/session_time * 100.0), - - (F32) current[label]["MinTime"].asReal(), - (F32) current[label]["MaxTime"].asReal(), - (F32) b, - (F32) current[label]["MeanTime"].asReal(), - (F32) current[label]["StdDevTime"].asReal(), - (F32) current[label]["TotalTime"].asReal(), - current[label]["Frames"].asInteger(), - current[label]["Samples"].asInteger(), - (F32) base[label]["MinTime"].asReal(), - (F32) base[label]["MaxTime"].asReal(), - (F32) a, - (F32) base[label]["MeanTime"].asReal(), - (F32) base[label]["StdDevTime"].asReal(), - (F32) base[label]["TotalTime"].asReal(), - base[label]["Frames"].asInteger(), - base[label]["Samples"].asInteger()); - } - - exportCharts(baseline, target); - - os.flush(); - os.close(); -} - -//static -void LLFastTimerView::outputAllMetrics() -{ - if (LLMetricPerformanceTesterBasic::hasMetricPerformanceTesters()) - { - for (LLMetricPerformanceTesterBasic::name_tester_map_t::iterator iter = LLMetricPerformanceTesterBasic::sTesterMap.begin(); - iter != LLMetricPerformanceTesterBasic::sTesterMap.end(); ++iter) - { - LLMetricPerformanceTesterBasic* tester = ((LLMetricPerformanceTesterBasic*)iter->second); - tester->outputTestResults(); - } - } -} - -//static -void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output) -{ - if(BlockTimer::sLog) - { - doAnalysisDefault(baseline, target, output) ; - return ; - } - - if(BlockTimer::sMetricLog) - { - LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline, target, output) ; - return ; - } -} - - -void LLFastTimerView::printLineStats() -{ - // Output stats for clicked bar to log - if (mStatsIndex >= 0) - { - std::string legend_stat; - bool first = true; - for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - BlockTimerStatHandle* idp = (*it); - - if (!first) - { - legend_stat += ", "; - } - first = false; - legend_stat += idp->getName(); - - //if (idp->getTreeNode().mCollapsed) - //{ - // it.skipDescendants(); - //} - } - LL_INFOS() << legend_stat << LL_ENDL; - - std::string timer_stat; - first = true; - for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - BlockTimerStatHandle* idp = (*it); - - if (!first) - { - timer_stat += ", "; - } - first = false; - - F32Seconds ticks; - if (mStatsIndex == 0) - { - ticks = mRecording.getPeriodMean(*idp, RUNNING_AVERAGE_WIDTH); - } - else - { - ticks = mRecording.getPrevRecording(mStatsIndex).getSum(*idp); - } - F32Milliseconds ms = ticks; - - timer_stat += llformat("%.1f",ms.value()); - - //if (idp->getTreeNode().mCollapsed) - //{ - // it.skipDescendants(); - //} - } - LL_INFOS() << timer_stat << LL_ENDL; - mStatsIndex = -1; - } -} - -void LLFastTimerView::drawLineGraph() -{ - LL_PROFILE_ZONE_SCOPED; - //draw line graph history - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLLocalClipRect clip(mGraphRect); - - //normalize based on last frame's maximum - static F32Seconds max_time(0.000001f); - static U32 max_calls = 0; - static F32 alpha_interp = 0.f; - - //highlight visible range - { - S32 first_frame = static_cast(mRecording.getNumRecordedPeriods()) - mScrollIndex; - S32 last_frame = first_frame - MAX_VISIBLE_HISTORY; - - F32 frame_delta = ((F32) (mGraphRect.getWidth()))/(mRecording.getNumRecordedPeriods()-1); - - F32 right = (F32) mGraphRect.mLeft + frame_delta*first_frame; - F32 left = (F32) mGraphRect.mLeft + frame_delta*last_frame; - - gGL.color4f(0.5f,0.5f,0.5f,0.3f); - gl_rect_2d((S32) left, mGraphRect.mTop, (S32) right, mGraphRect.mBottom); - - if (mHoverBarIndex > 0) - { - S32 bar_frame = first_frame - (mScrollIndex + mHoverBarIndex) - 1; - F32 bar = (F32) mGraphRect.mLeft + frame_delta*bar_frame; - - gGL.color4f(0.5f,0.5f,0.5f,1); - - gGL.begin(LLRender::LINES); - gGL.vertex2i((S32)bar, mGraphRect.mBottom); - gGL.vertex2i((S32)bar, mGraphRect.mTop); - gGL.end(); - } - } - - F32Seconds cur_max(0); - U32 cur_max_calls = 0; - - for(LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - BlockTimerStatHandle* idp = (*it); - - //fatten highlighted timer - if (mHoverID == idp) - { - gGL.setLineWidth(3); - } - - llassert(idp->getIndex() < sTimerColors.size()); - const F32 * col = sTimerColors[idp->getIndex()].mV;// ft_display_table[idx].color->mV; - - F32 alpha = 1.f; - bool is_hover_timer = true; - - if (mHoverID != NULL && - mHoverID != idp) - { //fade out non-highlighted timers - if (idp->getParent() != mHoverID) - { - alpha = alpha_interp; - is_hover_timer = false; - } - } - - gGL.color4f(col[0], col[1], col[2], alpha); - gGL.begin(LLRender::TRIANGLE_STRIP); - F32 call_scale_factor = (F32)mGraphRect.getHeight() / (F32)max_calls; - F32 time_scale_factor = (F32)mGraphRect.getHeight() / max_time.value(); - F32 hz_scale_factor = (F32) mGraphRect.getHeight() / (1.f / max_time.value()); - - for (U32 j = static_cast(mRecording.getNumRecordedPeriods()); - j > 0; - j--) - { - LLTrace::Recording& recording = mRecording.getPrevRecording(j); - F32Seconds time = llmax(recording.getSum(*idp), F64Seconds(0.000001)); - U32 calls = recording.getSum(idp->callCount()); - - if (is_hover_timer) - { - //normalize to highlighted timer - cur_max = llmax(cur_max, time); - cur_max_calls = llmax(cur_max_calls, calls); - } - F32 x = mGraphRect.mRight - j * (F32)(mGraphRect.getWidth())/(mRecording.getNumRecordedPeriods()-1); - F32 y; - switch(mDisplayType) -{ - case DISPLAY_TIME: - y = mGraphRect.mBottom + time.value() * time_scale_factor; - break; - case DISPLAY_CALLS: - y = mGraphRect.mBottom + (F32)calls * call_scale_factor; - break; - case DISPLAY_HZ: - y = mGraphRect.mBottom + (1.f / time.value()) * hz_scale_factor; - break; - } - gGL.vertex2f(x,y); - gGL.vertex2f(x,(GLfloat)mGraphRect.mBottom); - } - gGL.end(); - - if (mHoverID == idp) - { - gGL.setLineWidth(1.f); - } - - if (idp->getTreeNode().mCollapsed) - { - //skip hidden timers - it.skipDescendants(); - } - } - - //interpolate towards new maximum - max_time = (F32Seconds)lerp(max_time.value(), cur_max.value(), LLSmoothInterpolation::getInterpolant(0.1f)); - if (llabs((max_time - cur_max).value()) <= 1) - { - max_time = llmax(F32Microseconds(1.f), F32Microseconds(cur_max)); - } - - max_calls = ll_round(lerp((F32)max_calls, (F32) cur_max_calls, LLSmoothInterpolation::getInterpolant(0.1f))); - if (llabs((S32)(max_calls - cur_max_calls)) <= 1) - { - max_calls = cur_max_calls; - } - - // TODO: make sure alpha is correct in DisplayHz mode - F32 alpha_target = (max_time > cur_max) - ? llmin(max_time / cur_max - 1.f,1.f) - : llmin(cur_max/ max_time - 1.f,1.f); - alpha_interp = lerp(alpha_interp, alpha_target, LLSmoothInterpolation::getInterpolant(0.1f)); - - if (mHoverID != NULL) - { - S32 x = (mGraphRect.mRight + mGraphRect.mLeft)/2; - S32 y = mGraphRect.mBottom + 8; - - LLFontGL::getFontMonospace()->renderUTF8( - mHoverID->getName(), - 0, - x, y, - LLColor4::white, - LLFontGL::LEFT, LLFontGL::BOTTOM); - } - - //display y-axis range - std::string axis_label; - switch(mDisplayType) - { - case DISPLAY_TIME: - axis_label = llformat("%4.2f ms", F32Milliseconds(max_time).value()); - break; - case DISPLAY_CALLS: - axis_label = llformat("%d calls", (int)max_calls); - break; - case DISPLAY_HZ: - axis_label = llformat("%4.2f Hz", max_time.value() ? 1.f / max_time.value() : 0.f); - break; - } - - LLFontGL* font = LLFontGL::getFontMonospace(); - S32 x = mGraphRect.mRight - font->getWidth(axis_label)-5; - S32 y = mGraphRect.mTop - font->getLineHeight();; - - font->renderUTF8(axis_label, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -} - -void LLFastTimerView::drawLegend() -{ - // draw legend - S32 dx; - S32 x = mLegendRect.mLeft; - S32 y = mLegendRect.mTop; - const S32 TEXT_HEIGHT = (S32)LLFontGL::getFontMonospace()->getLineHeight(); - - { - LLLocalClipRect clip(mLegendRect); - S32 cur_line = 0; - S32 scroll_offset = 0; // element's y offset from top of the inner scroll's rect - ft_display_idx.clear(); - std::map display_line; - for (LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - BlockTimerStatHandle* idp = (*it); - // Needed to figure out offsets and parenting - display_line[idp] = cur_line; - cur_line++; - if (scroll_offset < mScrollBar->getDocPos()) - { - // only offset for visible items - scroll_offset += TEXT_HEIGHT + 2; - if (idp->getTreeNode().mCollapsed) - { - it.skipDescendants(); - } - continue; - } - - // used for mouse clicks - ft_display_idx.push_back(idp); - - // Actual draw, first bar (square), then text - x = MARGIN; - - LLRect bar_rect(x, y, x + TEXT_HEIGHT, y - TEXT_HEIGHT); - S32 scale_offset = 0; - if (idp == mHoverID) - { - scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f); - } - bar_rect.stretch(scale_offset); - llassert(idp->getIndex() < sTimerColors.size()); - gl_rect_2d(bar_rect, sTimerColors[idp->getIndex()]); - - F32Milliseconds ms(0); - S32 calls = 0; - if (mHoverBarIndex > 0 && mHoverID) - { - S32 hidx = mScrollIndex + mHoverBarIndex; - ms = mRecording.getPrevRecording(hidx).getSum(*idp); - calls = mRecording.getPrevRecording(hidx).getSum(idp->callCount()); - } - else - { - ms = F64Seconds(mRecording.getPeriodMean(*idp, RUNNING_AVERAGE_WIDTH)); - calls = (S32)mRecording.getPeriodMean(idp->callCount(), RUNNING_AVERAGE_WIDTH); - } - - std::string timer_label; - switch(mDisplayType) - { - case DISPLAY_TIME: - timer_label = llformat("%s [%.1f]",idp->getName().c_str(),ms.value()); - break; - case DISPLAY_CALLS: - timer_label = llformat("%s (%d)",idp->getName().c_str(),calls); - break; - case DISPLAY_HZ: - timer_label = llformat("%.1f", ms.value() ? (1.f / ms.value()) : 0.f); - break; - } - dx = (TEXT_HEIGHT+4) + get_depth(idp)*8; - - LLColor4 color = LLColor4::white; - if (get_depth(idp) > 0) - { - S32 line_start_y = bar_rect.getCenterY(); - S32 line_end_y = line_start_y + ((TEXT_HEIGHT + 2) * (cur_line - display_line[idp->getParent()])) - TEXT_HEIGHT; - gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color); - S32 line_x = x + (TEXT_HEIGHT + 4) + ((get_depth(idp) - 1) * 8); - gl_line_2d(line_x, line_start_y, line_x, line_end_y, color); - if (idp->getTreeNode().mCollapsed && !idp->getChildren().empty()) - { - gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color); - } - } - - x += dx; - bool is_child_of_hover_item = (idp == mHoverID); - BlockTimerStatHandle* next_parent = idp->getParent(); - while(!is_child_of_hover_item && next_parent) - { - is_child_of_hover_item = (mHoverID == next_parent); - if (next_parent->getParent() == next_parent) break; - next_parent = next_parent->getParent(); - } - - LLFontGL::getFontMonospace()->renderUTF8(timer_label, 0, - x, y, - color, - LLFontGL::LEFT, LLFontGL::TOP, - is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL); - - y -= (TEXT_HEIGHT + 2); - - scroll_offset += TEXT_HEIGHT + 2; - if (idp->getTreeNode().mCollapsed) - { - it.skipDescendants(); - } - } - // Recalculate scroll size - mScrollBar->setDocSize(scroll_offset - mLegendRect.getHeight()); - } -} - -void LLFastTimerView::generateUniqueColors() -{ - // generate unique colors - { - sTimerColors.resize(LLTrace::BlockTimerStatHandle::getNumIndices()); - sTimerColors[FTM_FRAME.getIndex()] = LLColor4::grey; - - F32 hue = 0.f; - - for (LLTrace::block_timer_tree_df_iterator_t it = LLTrace::begin_block_timer_tree_df(FTM_FRAME); - it != LLTrace::end_block_timer_tree_df(); - ++it) - { - BlockTimerStatHandle* idp = (*it); - - const F32 HUE_INCREMENT = 0.23f; - hue = fmodf(hue + HUE_INCREMENT, 1.f); - // saturation increases with depth - F32 saturation = clamp_rescale((F32)get_depth(idp), 0.f, 3.f, 0.f, 1.f); - // lightness alternates with depth - F32 lightness = get_depth(idp) % 2 ? 0.5f : 0.6f; - - LLColor4 child_color; - child_color.setHSL(hue, saturation, lightness); - - llassert(idp->getIndex() < sTimerColors.size()); - sTimerColors[idp->getIndex()] = child_color; - } - } -} - -void LLFastTimerView::drawHelp( S32 y ) -{ - // Draw some help - const S32 texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); - - y -= (texth + 2); - y -= (texth + 2); - - LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected]"), - 0, MARGIN, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -} - -void LLFastTimerView::drawTicks() -{ - // Draw MS ticks - { - U32Milliseconds ms = mTotalTimeDisplay; - std::string tick_label; - S32 x; - S32 barw = mBarRect.getWidth(); - - tick_label = llformat("%.1f ms |", (F32)ms.value()*.25f); - x = mBarRect.mLeft + barw/4 - LLFontGL::getFontMonospace()->getWidth(tick_label); - LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - tick_label = llformat("%.1f ms |", (F32)ms.value()*.50f); - x = mBarRect.mLeft + barw/2 - LLFontGL::getFontMonospace()->getWidth(tick_label); - LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - tick_label = llformat("%.1f ms |", (F32)ms.value()*.75f); - x = mBarRect.mLeft + (barw*3)/4 - LLFontGL::getFontMonospace()->getWidth(tick_label); - LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - - tick_label = llformat( "%d ms |", (U32)ms.value()); - x = mBarRect.mLeft + barw - LLFontGL::getFontMonospace()->getWidth(tick_label); - LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, x, mBarRect.mTop, LLColor4::white, - LLFontGL::LEFT, LLFontGL::TOP); - } -} - -void LLFastTimerView::drawBorders( S32 y, const S32 x_start, S32 bar_height, S32 dy ) -{ - // Draw borders - { - S32 by = y + 6 + (S32)LLFontGL::getFontMonospace()->getLineHeight(); - - //heading - gl_rect_2d(x_start-5, by, getRect().getWidth()-5, y+5, LLColor4::grey, false); - - //tree view - gl_rect_2d(5, by, x_start-10, 5, LLColor4::grey, false); - - by = y + 5; - //average bar - gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-5, LLColor4::grey, false); - - by -= bar_height*2+dy; - - //current frame bar - gl_rect_2d(x_start-5, by, getRect().getWidth()-5, by-bar_height-dy-2, LLColor4::grey, false); - - by -= bar_height+dy+1; - - //history bars - gl_rect_2d(x_start-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-bar_height-dy-2, LLColor4::grey, false); - - by = LINE_GRAPH_HEIGHT-dy; - - //line graph - //mGraphRect = LLRect(x_start-5, by, getRect().getWidth()-5, 5); - - gl_rect_2d(mGraphRect, false); - } -} - -void LLFastTimerView::updateTotalTime() -{ - switch(mDisplayMode) - { - case 0: - mTotalTimeDisplay = mRecording.getPeriodMean(FTM_FRAME, RUNNING_AVERAGE_WIDTH)*2; - break; - case 1: - mTotalTimeDisplay = mRecording.getPeriodMax(FTM_FRAME); - break; - case 2: - // Calculate the max total ticks for the current history - mTotalTimeDisplay = mRecording.getPeriodMax(FTM_FRAME, 20); - break; - default: - mTotalTimeDisplay = F64Milliseconds(100); - break; - } - - mTotalTimeDisplay = LLUnits::Milliseconds::fromValue(llceil((F32)mTotalTimeDisplay.valueInUnits() / 20.f) * 20.f); -} - -void LLFastTimerView::drawBars() -{ - LL_PROFILE_ZONE_SCOPED; - LLLocalClipRect clip(mBarRect); - - S32 bar_height = mBarRect.getHeight() / (MAX_VISIBLE_HISTORY + 2); - const S32 vpad = llmax(1, bar_height / 4); // spacing between bars - bar_height -= vpad; - - updateTotalTime(); - if (mTotalTimeDisplay <= (F32Seconds)0.0) return; - - drawTicks(); - const S32 bars_top = mBarRect.mTop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4); - drawBorders(bars_top, mBarRect.mLeft, bar_height, vpad); - - // Draw bars for each history entry - // Special: 0 = show running average - LLPointer bar_image = LLUI::getUIImage("Rounded_Square"); - - const S32 image_width = bar_image->getTextureWidth(); - const S32 image_height = bar_image->getTextureHeight(); - - gGL.getTexUnit(0)->bind(bar_image->getImage()); - { - const S32 histmax = (S32)mRecording.getNumRecordedPeriods(); - - // update widths - if (!mPauseHistory) - { - U32 bar_index = 0; - if (!mAverageTimerRow.mBars) - { - mAverageTimerRow.mBars = new TimerBar[LLTrace::BlockTimerStatHandle::instance_tracker_t::instanceCount()]; - } - updateTimerBarWidths(&FTM_FRAME, mAverageTimerRow, -1, bar_index); - updateTimerBarOffsets(&FTM_FRAME, mAverageTimerRow); - - for (S32 history_index = 1; history_index <= histmax; history_index++) - { - llassert(history_index <= mTimerBarRows.size()); - TimerBarRow& row = mTimerBarRows[history_index - 1]; - bar_index = 0; - if (!row.mBars) - { - row.mBars = new TimerBar[LLTrace::BlockTimerStatHandle::instance_tracker_t::instanceCount()]; - updateTimerBarWidths(&FTM_FRAME, row, history_index, bar_index); - updateTimerBarOffsets(&FTM_FRAME, row); - } - } - } - - // draw bars - LLRect frame_bar_rect; - frame_bar_rect.setLeftTopAndSize(mBarRect.mLeft, - bars_top, - (S32)ll_round((mAverageTimerRow.mBars[0].mTotalTime / mTotalTimeDisplay) * mBarRect.getWidth()), - bar_height); - mAverageTimerRow.mTop = frame_bar_rect.mTop; - mAverageTimerRow.mBottom = frame_bar_rect.mBottom; - drawBar(frame_bar_rect, mAverageTimerRow, image_width, image_height); - frame_bar_rect.translate(0, -(bar_height + vpad + bar_height)); - - for(S32 bar_index = mScrollIndex; bar_index < llmin(histmax, mScrollIndex + MAX_VISIBLE_HISTORY); ++bar_index) - { - llassert(bar_index < mTimerBarRows.size()); - TimerBarRow& row = mTimerBarRows[bar_index]; - row.mTop = frame_bar_rect.mTop; - row.mBottom = frame_bar_rect.mBottom; - frame_bar_rect.mRight = frame_bar_rect.mLeft - + (S32)ll_round((row.mBars[0].mTotalTime / mTotalTimeDisplay) * mBarRect.getWidth()); - drawBar(frame_bar_rect, row, image_width, image_height); - - frame_bar_rect.translate(0, -(bar_height + vpad)); - } - - } - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -} - -F32Seconds LLFastTimerView::updateTimerBarWidths(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 history_index, U32& bar_index) -{ - LL_PROFILE_ZONE_SCOPED; - const F32Seconds self_time = history_index == -1 - ? mRecording.getPeriodMean(time_block->selfTime(), RUNNING_AVERAGE_WIDTH) - : mRecording.getPrevRecording(history_index).getSum(time_block->selfTime()); - - F32Seconds full_time = self_time; - - // reserve a spot for this bar to be rendered before its children - // even though we don't know its size yet - TimerBar& timer_bar = row.mBars[bar_index]; - bar_index++; - - for (BlockTimerStatHandle::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); it != end_it; ++it) - { - full_time += updateTimerBarWidths(*it, row, history_index, bar_index); - } - - timer_bar.mTotalTime = full_time; - timer_bar.mSelfTime = self_time; - timer_bar.mTimeBlock = time_block; - - return full_time; -} - -S32 LLFastTimerView::updateTimerBarOffsets(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 timer_bar_index) -{ - LL_PROFILE_ZONE_SCOPED; - - TimerBar& timer_bar = row.mBars[timer_bar_index]; - const F32Seconds bar_time = timer_bar.mTotalTime - timer_bar.mSelfTime; - timer_bar.mChildrenStart = timer_bar.mSelfStart + timer_bar.mSelfTime / 2; - timer_bar.mChildrenEnd = timer_bar.mChildrenStart + timer_bar.mTotalTime - timer_bar.mSelfTime; - - if (timer_bar_index == 0) - { - timer_bar.mSelfStart = F32Seconds(0.f); - timer_bar.mSelfEnd = bar_time; - } - - //now loop through children and figure out portion of bar image covered by each bar, now that we know the - //sum of all children - F32 bar_fraction_start = 0.f; - TimerBar* last_child_timer_bar = NULL; - - bool first_child = true; - for (BlockTimerStatHandle::child_iter it = time_block->beginChildren(), end_it = time_block->endChildren(); - it != end_it; - ++it) - { - timer_bar_index++; - - TimerBar& child_timer_bar = row.mBars[timer_bar_index]; - BlockTimerStatHandle* child_time_block = *it; - - if (last_child_timer_bar) - { - last_child_timer_bar->mLastChild = false; - } - child_timer_bar.mLastChild = true; - last_child_timer_bar = &child_timer_bar; - - child_timer_bar.mFirstChild = first_child; - if (first_child) - { - first_child = false; - } - - child_timer_bar.mStartFraction = bar_fraction_start; - child_timer_bar.mEndFraction = bar_time > (S32Seconds)0 - ? bar_fraction_start + child_timer_bar.mTotalTime / bar_time - : 1.f; - child_timer_bar.mSelfStart = timer_bar.mChildrenStart - + child_timer_bar.mStartFraction - * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart); - child_timer_bar.mSelfEnd = timer_bar.mChildrenStart - + child_timer_bar.mEndFraction - * (timer_bar.mChildrenEnd - timer_bar.mChildrenStart); - - timer_bar_index = updateTimerBarOffsets(child_time_block, row, timer_bar_index); - - bar_fraction_start = child_timer_bar.mEndFraction; - } - return timer_bar_index; -} - -S32 LLFastTimerView::drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered, bool visible, S32 bar_index) -{ - LL_PROFILE_ZONE_SCOPED; - TimerBar& timer_bar = row.mBars[bar_index]; - LLTrace::BlockTimerStatHandle* time_block = timer_bar.mTimeBlock; - - hovered |= mHoverID == time_block; - - // animate scale of bar when hovering over that particular timer - if (visible && (F32)bar_rect.getWidth() * (timer_bar.mEndFraction - timer_bar.mStartFraction) > 2.f) - { - LLRect render_rect(bar_rect); - S32 scale_offset = 0; - if (mHoverID == time_block) - { - scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f); - render_rect.mTop += scale_offset; - render_rect.mBottom -= scale_offset; - } - - llassert(time_block->getIndex() < sTimerColors.size()); - LLColor4 color = sTimerColors[time_block->getIndex()]; - if (!hovered) color = lerp(color, LLColor4::grey, 0.2f); - gGL.color4fv(color.mV); - gl_segmented_rect_2d_fragment_tex(render_rect, - image_width, image_height, - 16, - timer_bar.mStartFraction, timer_bar.mEndFraction); - } - - LLRect children_rect; - children_rect.mLeft = (S32)ll_round(timer_bar.mChildrenStart / mTotalTimeDisplay * (F32)mBarRect.getWidth()) + mBarRect.mLeft; - children_rect.mRight = (S32)ll_round(timer_bar.mChildrenEnd / mTotalTimeDisplay * (F32)mBarRect.getWidth()) + mBarRect.mLeft; - - if (bar_rect.getHeight() > MIN_BAR_HEIGHT) - { - // shrink as we go down a level - children_rect.mTop = bar_rect.mTop - 1; - children_rect.mBottom = bar_rect.mBottom + 1; - } - else - { - children_rect.mTop = bar_rect.mTop; - children_rect.mBottom = bar_rect.mBottom; - } - - bool children_visible = visible && !time_block->getTreeNode().mCollapsed; - - bar_index++; - const auto num_bars = LLTrace::BlockTimerStatHandle::instance_tracker_t::instanceCount(); - if (bar_index < num_bars && row.mBars[bar_index].mFirstChild) - { - bool is_last = false; - do - { - is_last = row.mBars[bar_index].mLastChild; - bar_index = drawBar(children_rect, row, image_width, image_height, hovered, children_visible, bar_index); - } - while(!is_last && bar_index < num_bars); - } - - return bar_index; -} diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h deleted file mode 100644 index 2950457c2bf..00000000000 --- a/indra/newview/llfasttimerview.h +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @file llfasttimerview.h - * @brief LLFastTimerView class definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFASTTIMERVIEW_H -#define LL_LLFASTTIMERVIEW_H - -#include "llfloater.h" -#include "llfasttimer.h" -#include "llunits.h" -#include "lltracerecording.h" -#include - -class LLScrollbar; - -class LLFastTimerView : public LLFloater -{ -public: - LLFastTimerView(const LLSD&); - ~LLFastTimerView(); - bool postBuild(); - - static bool sAnalyzePerformance; - - static void outputAllMetrics(); - static void doAnalysis(std::string baseline, std::string target, std::string output); - -private: - static void doAnalysisDefault(std::string baseline, std::string target, std::string output) ; - static LLSD analyzePerformanceLogDefault(std::istream& is) ; - static void exportCharts(const std::string& base, const std::string& target); - void onPause(); - -public: - - virtual bool handleMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleDoubleClick(S32 x, S32 y, MASK mask); - virtual bool handleRightMouseDown(S32 x, S32 y, MASK mask); - virtual bool handleMouseUp(S32 x, S32 y, MASK mask); - virtual bool handleHover(S32 x, S32 y, MASK mask); - virtual bool handleToolTip(S32 x, S32 y, MASK mask); - virtual bool handleScrollWheel(S32 x, S32 y, LLScrollDelta delta); - virtual void draw(); - virtual void onOpen(const LLSD& key); - virtual void onClose(bool app_quitting); - LLTrace::BlockTimerStatHandle* getLegendID(S32 y); - -private: - void drawTicks(); - void drawLineGraph(); - void drawLegend(); - void drawHelp(S32 y); - void drawBorders( S32 y, const S32 x_start, S32 barh, S32 dy); - void drawBars(); - - void printLineStats(); - void generateUniqueColors(); - void updateTotalTime(); - - struct TimerBar - { - TimerBar() - : mTotalTime(0), - mSelfTime(0), - mStartFraction(0.f), - mEndFraction(1.f), - mFirstChild(false), - mLastChild(false) - {} - F32Seconds mTotalTime, - mSelfTime, - mChildrenStart, - mChildrenEnd, - mSelfStart, - mSelfEnd; - LLTrace::BlockTimerStatHandle* mTimeBlock; - bool mVisible, - mFirstChild, - mLastChild; - F32 mStartFraction, - mEndFraction; - }; - - struct TimerBarRow - { - TimerBarRow() - : mBottom(0), - mTop(0), - mBars(NULL) - {} - S32 mBottom, - mTop; - TimerBar* mBars; - }; - - F32Seconds updateTimerBarWidths(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 history_index, U32& bar_index); - S32 updateTimerBarOffsets(LLTrace::BlockTimerStatHandle* time_block, TimerBarRow& row, S32 timer_bar_index = 0); - S32 drawBar(LLRect bar_rect, TimerBarRow& row, S32 image_width, S32 image_height, bool hovered = false, bool visible = true, S32 bar_index = 0); - void setPauseState(bool pause_state); - - std::deque mTimerBarRows; - TimerBarRow mAverageTimerRow; - - enum EDisplayType - { - DISPLAY_TIME, - DISPLAY_CALLS, - DISPLAY_HZ - } mDisplayType; - bool mPauseHistory; - F64Seconds mAllTimeMax, - mTotalTimeDisplay; - S32 mScrollIndex, - mHoverBarIndex, - mStatsIndex; - S32 mDisplayMode; - LLTrace::BlockTimerStatHandle* mHoverID; - LLTrace::BlockTimerStatHandle* mHoverTimer; - LLRect mToolTipRect, - mGraphRect, - mBarRect, - mLegendRect; - LLFrameTimer mHighlightTimer; - LLTrace::PeriodicRecording mRecording; - - LLScrollbar* mScrollBar; -}; - -#endif diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp index 0f29cbbe3a3..11b32667666 100644 --- a/indra/newview/llfilteredwearablelist.cpp +++ b/indra/newview/llfilteredwearablelist.cpp @@ -92,11 +92,9 @@ void LLFilteredWearableListManager::populateIfNeeded() } } -LLTrace::BlockTimerStatHandle FTM_MANAGER_LIST_POPULATION("Manager List Population"); - void LLFilteredWearableListManager::populateList() { - LL_RECORD_BLOCK_TIME(FTM_MANAGER_LIST_POPULATION); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; LLInventoryModel::cat_array_t cat_array; LLInventoryModel::item_array_t item_array; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 3392669f9a4..419e2af94f9 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -69,7 +69,6 @@ #include "lldxhardware.h" #endif -extern LLMemoryInfo gSysMemory; extern U32 gPacketsIn; ///---------------------------------------------------------------------------- diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index a29bad6f8a2..f8ce9f64430 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -713,10 +713,9 @@ void LLFloaterIMSessionTab::updateUsedEmojis(LLWStringView text) } } -static LLTrace::BlockTimerStatHandle FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT("Build Conversation View"); void LLFloaterIMSessionTab::buildConversationViewParticipant() { - LL_RECORD_BLOCK_TIME(FTM_BUILD_CONVERSATION_VIEW_PARTICIPANT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // Clear the widget list since we are rebuilding afresh from the model conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin(); while (widget_it != mConversationsWidgets.end()) diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index 1377526f695..edaf4f3e374 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -141,7 +141,7 @@ void LLFloaterLagMeter::draw() void LLFloaterLagMeter::determineClient() { - F32Milliseconds client_frame_time = LLTrace::get_frame_recording().getPeriodMean(LLStatViewer::FRAME_STACKTIME); + F32Milliseconds client_frame_time = LLTrace::get_frame_recording().getPeriodMean(LLStatViewer::FRAMETIME); bool find_cause = false; if (!gFocusMgr.getAppHasFocus()) @@ -198,7 +198,7 @@ void LLFloaterLagMeter::determineNetwork() // particular if the frame rate is low, because a low frame // rate is a sure recipe for bad ping times right now until // the network handlers are de-synched from the rendering. - F32Milliseconds client_frame_time = frame_recording.getPeriodMean(LLStatViewer::FRAME_STACKTIME); + F32Milliseconds client_frame_time = frame_recording.getPeriodMean(LLStatViewer::FRAMETIME); // Todo: account for LLPacketRing dropped packets? viewer drops those when it can't keep up if(packet_loss >= mNetworkPacketLossCritical) diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp index a0621bb0157..f851d2edc91 100644 --- a/indra/newview/llfolderviewmodelinventory.cpp +++ b/indra/newview/llfolderviewmodelinventory.cpp @@ -35,7 +35,6 @@ // // class LLFolderViewModelInventory // -static LLTrace::BlockTimerStatHandle FTM_INVENTORY_SORT("Inventory Sort"); bool LLFolderViewModelInventory::startDrag(std::vector& items) { @@ -64,7 +63,7 @@ bool LLFolderViewModelInventory::startDrag(std::vector& void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder ) { - LL_RECORD_BLOCK_TIME(FTM_INVENTORY_SORT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; if (!folder->areChildrenInited() || !needsSort(folder->getViewModelItem())) return; diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 871c119c965..957d5c31886 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -807,6 +807,8 @@ struct IsGesturePlaying void LLGestureMgr::update() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER; + S32 i; for (i = 0; i < (S32)mPlaying.size(); ++i) { diff --git a/indra/newview/llhudmanager.cpp b/indra/newview/llhudmanager.cpp index 0005682f8fd..91e6e96701e 100644 --- a/indra/newview/llhudmanager.cpp +++ b/indra/newview/llhudmanager.cpp @@ -44,14 +44,11 @@ LLHUDManager::LLHUDManager() LLHUDManager::~LLHUDManager() { - mHUDEffects.clear(); } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_HUD_EFFECTS("Update Hud Effects"); - void LLHUDManager::updateEffects() { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_HUD_EFFECTS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; S32 i; for (i = 0; i < mHUDEffects.size(); i++) { @@ -95,6 +92,12 @@ void LLHUDManager::sendEffects() } } +//static +void LLHUDManager::shutdownClass() +{ + getInstance()->mHUDEffects.clear(); +} + void LLHUDManager::cleanupEffects() { S32 i = 0; diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h index 5c3852d5d40..efc93b356a0 100644 --- a/indra/newview/llhudmanager.h +++ b/indra/newview/llhudmanager.h @@ -34,18 +34,20 @@ class LLHUDEffect; class LLMessageSystem; -class LLHUDManager : public LLSimpleton +class LLHUDManager : public LLSingleton { -public: - LLHUDManager(); + LLSINGLETON(LLHUDManager); ~LLHUDManager(); +public: LLHUDEffect *createViewerEffect(const U8 type, bool send_to_sim = true, bool originated_here = true); void updateEffects(); void sendEffects(); void cleanupEffects(); + static void shutdownClass(); + static void processViewerEffect(LLMessageSystem *mesgsys, void **user_data); protected: diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index a489d6d32cc..81bab08888e 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -255,12 +255,10 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type) return hud_objectp; } -static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("Update Hud"); - // static void LLHUDObject::updateAll() { - LL_RECORD_BLOCK_TIME(FTM_HUD_UPDATE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; LLHUDText::updateAll(); LLHUDIcon::updateAll(); LLHUDNameTag::updateAll(); diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index f36663d5110..94b8c4bebf7 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -36,6 +36,20 @@ #include "llwearabletype.h" #include "llinventorysettings.h" +struct IconEntry : public LLDictionaryEntry +{ + IconEntry(const std::string &item_name) + : + LLDictionaryEntry(item_name) + {} +}; + +class LLIconDictionary : public LLSingleton, + public LLDictionary +{ + LLSINGLETON(LLIconDictionary); +}; + typedef LLPointer LLUIImagePtr; LLIconDictionary::LLIconDictionary() diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index 0d177b59b55..32e2d8b29d1 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -31,17 +31,6 @@ #include "llassettype.h" #include "llinventorytype.h" -struct IconEntry : public LLDictionaryEntry -{ - IconEntry(const std::string& item_name) : LLDictionaryEntry(item_name) {} -}; - -class LLIconDictionary : public LLSimpleton, public LLDictionary -{ -public: - LLIconDictionary(); -}; - class LLInventoryIcon { public: diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index 82eefb50acf..ebf87f1c716 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -734,11 +734,9 @@ void LLInventoryModelBackgroundFetch::onAISFolderCalback(const LLUUID& request_i } } -static LLTrace::BlockTimerStatHandle FTM_BULK_FETCH("Bulk Fetch"); - void LLInventoryModelBackgroundFetch::bulkFetchViaAis() { - LL_RECORD_BLOCK_TIME(FTM_BULK_FETCH); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. if (gDisconnected) { @@ -1054,7 +1052,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis(const FetchQueueInfo& fetc // Bundle up a bunch of requests to send all at once. void LLInventoryModelBackgroundFetch::bulkFetch() { - LL_RECORD_BLOCK_TIME(FTM_BULK_FETCH); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. //If there are items in mFetchQueue, we want to check the time since the last bulkFetch was //sent. If it exceeds our retry time, go ahead and fire off another batch. diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h index 596e7cdce30..e4f555da748 100644 --- a/indra/newview/llmaterialmgr.h +++ b/indra/newview/llmaterialmgr.h @@ -78,12 +78,12 @@ inline std::size_t hash_value(TEMaterialPair const& id) return seed; } -class LLMaterialMgr : public LLSimpleton +class LLMaterialMgr : public LLSingleton { -public: - LLMaterialMgr(); + LLSINGLETON(LLMaterialMgr); virtual ~LLMaterialMgr(); +public: typedef std::map material_map_t; typedef boost::signals2::signal get_callback_t; diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 8cc1d0cee07..b7f46a1a573 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -185,10 +185,12 @@ LLMuteList::LLMuteList() : //----------------------------------------------------------------------------- LLMuteList::~LLMuteList() { - if (LLAvatarNameCache::instanceExists()) - { - LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(nullptr); - } + +} + +void LLMuteList::cleanupSingleton() +{ + LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(nullptr); } // static diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h index f8a763583a3..a373600dee2 100644 --- a/indra/newview/llmutelist.h +++ b/indra/newview/llmutelist.h @@ -74,11 +74,11 @@ class LLMute U32 mFlags; // flags pertaining to this mute entry }; -class LLMuteList : public LLSimpleton +class LLMuteList : public LLSingleton { -public: - LLMuteList(); + LLSINGLETON(LLMuteList); ~LLMuteList(); + /*virtual*/ void cleanupSingleton() override; enum EMuteListState { @@ -87,7 +87,7 @@ class LLMuteList : public LLSimpleton ML_LOADED, ML_FAILED, }; - +public: // reasons for auto-unmuting a resident enum EAutoReason { diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h index ba73f7ff608..72fe2a79751 100644 --- a/indra/newview/llpersistentnotificationstorage.h +++ b/indra/newview/llpersistentnotificationstorage.h @@ -43,12 +43,12 @@ class LLSD; // be a) serializable(implement LLNotificationResponderInterface), // b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp). -class LLPersistentNotificationStorage : public LLSimpleton, public LLNotificationStorage +class LLPersistentNotificationStorage : public LLParamSingleton, public LLNotificationStorage { + LLSINGLETON(LLPersistentNotificationStorage); + ~LLPersistentNotificationStorage(); LOG_CLASS(LLPersistentNotificationStorage); public: - LLPersistentNotificationStorage(); - ~LLPersistentNotificationStorage(); void saveNotifications(); void loadNotifications(); diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index 742ab9cefe2..c2d79aa6141 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -37,11 +37,6 @@ LLSceneView* gSceneView = NULL; -//borrow this helper function from llfasttimerview.cpp -template -void removeOutliers(std::vector& data, F32 k); - - LLSceneView::LLSceneView(const LLRect& rect) : LLFloater(LLSD()) { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index f0729376ae8..bc3e6e8806b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -195,7 +195,6 @@ #include "llxfermanager.h" #include "pipeline.h" #include "llappviewer.h" -#include "llfasttimerview.h" #include "llfloatermap.h" #include "llweb.h" #include "llvoiceclient.h" @@ -1134,8 +1133,8 @@ bool idle_startup() { // check existance since this part of code can be reached // twice due to login failures - LLPersistentNotificationStorage::createInstance(); - LLDoNotDisturbNotificationStorage::createInstance(); + LLPersistentNotificationStorage::initParamSingleton(); + LLDoNotDisturbNotificationStorage::initParamSingleton(); } else { @@ -3412,7 +3411,7 @@ void LLStartUp::multimediaInit() set_startup_status(0.42f, msg.c_str(), gAgent.mMOTD.c_str()); do_startup_frame(); - ALStreamInfo::createInstance(); + ALStreamInfo::getInstance(); } void LLStartUp::fontInit() diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 646223d15a4..c8037489289 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -73,9 +73,6 @@ LLTrace::SampleStatHandle LLTextureFetch::sTexDecodeLatency("texture LLTrace::SampleStatHandle LLTextureFetch::sCacheWriteLatency("texture_write_latency"); LLTrace::SampleStatHandle LLTextureFetch::sTexFetchLatency("texture_fetch_latency"); -LLTextureFetchTester* LLTextureFetch::sTesterp = NULL ; -const std::string sTesterName("TextureFetchTester"); - ////////////////////////////////////////////////////////////////////////////// // // Introduction @@ -2476,17 +2473,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mod mHttpHighWater = HTTP_NONPIPE_REQUESTS_HIGH_WATER; mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER; mHttpSemaphore = 0; - - // If that test log has ben requested but not yet created, create it - if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) - { - sTesterp = new LLTextureFetchTester() ; - if (!sTesterp->isValid()) - { - delete sTesterp; - sTesterp = NULL; - } - } } LLTextureFetch::~LLTextureFetch() @@ -2831,17 +2817,11 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level, S3 sample(sCacheReadLatency, cache_read_time); sample(sCacheWriteLatency, cache_write_time); - static LLCachedControl min_time_to_log(gSavedSettings, "TextureFetchMinTimeToLog", 2.f); - if (fetch_time > min_time_to_log) - { - //LL_INFOS() << "fetch_time: " << fetch_time << " cache_read_time: " << cache_read_time << " decode_time: " << decode_time << " cache_write_time: " << cache_write_time << LL_ENDL; - - LLTextureFetchTester* tester = (LLTextureFetchTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->updateStats(logged_state_timers, fetch_time, skipped_states_time, file_size) ; - } - } + //static LLCachedControl min_time_to_log(gSavedSettings, "TextureFetchMinTimeToLog", 2.f); + //if (fetch_time > min_time_to_log) + //{ + // LL_INFOS() << "fetch_time: " << fetch_time << " cache_read_time: " << cache_read_time << " decode_time: " << decode_time << " cache_write_time: " << cache_write_time << LL_ENDL; + //} } else { @@ -3696,41 +3676,3 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics) } } // end of anonymous namespace - -LLTextureFetchTester::LLTextureFetchTester() : LLMetricPerformanceTesterBasic(sTesterName) -{ - mTextureFetchTime = 0; - mSkippedStatesTime = 0; - mFileSize = 0; -} - -LLTextureFetchTester::~LLTextureFetchTester() -{ - outputTestResults(); - LLTextureFetch::sTesterp = NULL; -} - -//virtual -void LLTextureFetchTester::outputTestRecord(LLSD *sd) -{ - std::string currentLabel = getCurrentLabelName(); - - (*sd)[currentLabel]["Texture Fetch Time"] = (LLSD::Real)mTextureFetchTime; - (*sd)[currentLabel]["File Size"] = (LLSD::Integer)mFileSize; - (*sd)[currentLabel]["Skipped States Time"] = (LLSD::String)llformat("%.6f", mSkippedStatesTime); - - for(auto i : LOGGED_STATES) - { - (*sd)[currentLabel][sStateDescs[i]] = mStateTimersMap[i]; - } -} - -void LLTextureFetchTester::updateStats(const std::map state_timers, const F32 fetch_time, const F32 skipped_states_time, const S32 file_size) -{ - mTextureFetchTime = fetch_time; - mStateTimersMap = state_timers; - mFileSize = file_size; - mSkippedStatesTime = skipped_states_time; - outputTestResults(); -} - diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 6118eeded87..d8b3a73a6e5 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -49,7 +49,6 @@ class LLImageDecodeThread; class LLHost; class LLViewerAssetStats; class LLTextureCache; -class LLTextureFetchTester; // Interface class @@ -405,8 +404,6 @@ class LLTextureFetch : public LLWorkerThread INVALID_SOURCE }; - static LLTextureFetchTester* sTesterp; - private: e_tex_source mFetchSource; e_tex_source mOriginFetchSource; @@ -420,27 +417,5 @@ class LLTextureFetch : public LLWorkerThread bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;} }; -//debug use -class LLViewerFetchedTexture; - -class LLTextureFetchTester : public LLMetricPerformanceTesterBasic -{ -public: - LLTextureFetchTester(); - ~LLTextureFetchTester(); - - void updateStats(const std::map states_timers, const F32 fetch_time, const F32 other_states_time, const S32 file_size); - -protected: - /*virtual*/ void outputTestRecord(LLSD* sd); - -private: - - F32 mTextureFetchTime; - F32 mSkippedStatesTime; - S32 mFileSize; - - std::map mStateTimersMap; -}; #endif // LL_LLTEXTUREFETCH_H diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h index 752e75a085e..f94cb3cf844 100644 --- a/indra/newview/lltoolcomp.h +++ b/indra/newview/lltoolcomp.h @@ -102,11 +102,11 @@ class LLToolComposite : public LLTool //----------------------------------------------------------------------- // LLToolCompTranslate -class LLToolCompInspect : public LLToolComposite, public LLSimpleton +class LLToolCompInspect : public LLToolComposite, public LLSingleton { -public: - LLToolCompInspect(); + LLSINGLETON(LLToolCompInspect); virtual ~LLToolCompInspect(); +public: // Overridden from LLToolComposite virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; @@ -127,11 +127,11 @@ class LLToolCompInspect : public LLToolComposite, public LLSimpleton +class LLToolCompTranslate : public LLToolComposite, public LLSingleton { -public: - LLToolCompTranslate(); + LLSINGLETON(LLToolCompTranslate); virtual ~LLToolCompTranslate(); +public: // Overridden from LLToolComposite virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; @@ -148,11 +148,11 @@ class LLToolCompTranslate : public LLToolComposite, public LLSimpleton +class LLToolCompScale : public LLToolComposite, public LLSingleton { -public: - LLToolCompScale(); + LLSINGLETON(LLToolCompScale); virtual ~LLToolCompScale(); +public: // Overridden from LLToolComposite virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; @@ -173,11 +173,11 @@ class LLToolCompScale : public LLToolComposite, public LLSimpleton +class LLToolCompRotate : public LLToolComposite, public LLSingleton { -public: - LLToolCompRotate(); + LLSINGLETON(LLToolCompRotate); virtual ~LLToolCompRotate(); +public: // Overridden from LLToolComposite virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; @@ -196,11 +196,11 @@ class LLToolCompRotate : public LLToolComposite, public LLSimpleton +class LLToolCompCreate : public LLToolComposite, public LLSingleton { -public: - LLToolCompCreate(); + LLSINGLETON(LLToolCompCreate); virtual ~LLToolCompCreate(); +public: // Overridden from LLToolComposite virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; @@ -221,11 +221,11 @@ class LLToolGun; class LLToolGrabBase; class LLToolSelect; -class LLToolCompGun : public LLToolComposite, public LLSimpleton +class LLToolCompGun : public LLToolComposite, public LLSingleton { -public: - LLToolCompGun(); + LLSINGLETON(LLToolCompGun); virtual ~LLToolCompGun(); +public: void draw() override; diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index d6ceb01f195..ad6402c4add 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -41,11 +41,10 @@ class LLViewerRegion; class LLVOAvatar; class LLPickInfo; -class LLToolDragAndDrop : public LLTool, public LLSimpleton +class LLToolDragAndDrop : public LLTool, public LLSingleton { + LLSINGLETON(LLToolDragAndDrop); public: - LLToolDragAndDrop(); - typedef boost::signals2::signal enddrag_signal_t; // overridden from LLTool diff --git a/indra/newview/lltoolface.h b/indra/newview/lltoolface.h index 4320b157655..18d42da1e1e 100644 --- a/indra/newview/lltoolface.h +++ b/indra/newview/lltoolface.h @@ -33,11 +33,11 @@ class LLViewerObject; class LLPickInfo; class LLToolFace -: public LLTool, public LLSimpleton +: public LLTool, public LLSingleton { -public: - LLToolFace(); + LLSINGLETON(LLToolFace); virtual ~LLToolFace(); +public: virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; virtual bool handleDoubleClick(S32 x, S32 y, MASK mask) override; diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h index 963f7abbcfe..8541fcaa332 100644 --- a/indra/newview/lltoolfocus.h +++ b/indra/newview/lltoolfocus.h @@ -32,11 +32,11 @@ class LLPickInfo; class LLToolCamera -: public LLTool, public LLSimpleton +: public LLTool, public LLSingleton { -public: - LLToolCamera(); + LLSINGLETON(LLToolCamera); virtual ~LLToolCamera(); +public: virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; virtual bool handleMouseUp(S32 x, S32 y, MASK mask) override; diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h index 43f852b5779..7806cbc24f8 100644 --- a/indra/newview/lltoolgrab.h +++ b/indra/newview/lltoolgrab.h @@ -147,10 +147,9 @@ class LLToolGrabBase : public LLTool }; /// This is the LLSingleton instance of LLToolGrab. -class LLToolGrab : public LLToolGrabBase, public LLSimpleton +class LLToolGrab : public LLToolGrabBase, public LLSingleton { -public: - LLToolGrab() = default; + LLSINGLETON_EMPTY_CTOR(LLToolGrab); }; extern bool gGrabBtnVertical; diff --git a/indra/newview/lltoolindividual.h b/indra/newview/lltoolindividual.h index 94f2797c24a..baf687d183d 100644 --- a/indra/newview/lltoolindividual.h +++ b/indra/newview/lltoolindividual.h @@ -37,11 +37,11 @@ class LLPickInfo; // A tool to select individual objects rather than linked sets. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLToolIndividual : public LLTool, public LLSimpleton +class LLToolIndividual : public LLTool, public LLSingleton { -public: - LLToolIndividual(); + LLSINGLETON(LLToolIndividual); virtual ~LLToolIndividual(); +public: virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; virtual bool handleDoubleClick(S32 x, S32 y, MASK mask) override; diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h index 135255bb25b..2ba4b8c8091 100644 --- a/indra/newview/lltoolmgr.h +++ b/indra/newview/lltoolmgr.h @@ -40,11 +40,11 @@ const MASK MASK_ORBIT = MASK_CONTROL; const MASK MASK_PAN = MASK_CONTROL | MASK_SHIFT; const MASK MASK_COPY = MASK_SHIFT; -class LLToolMgr : public LLSimpleton +class LLToolMgr : public LLSingleton { -public: - LLToolMgr(); + LLSINGLETON(LLToolMgr); ~LLToolMgr(); +public: // Must be called after gSavedSettings set up. void initTools(); diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index a83fa7cfbd3..a9c09280087 100644 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -35,11 +35,11 @@ class LLViewerObject; class LLObjectSelection; -class LLToolPie : public LLTool, public LLSimpleton +class LLToolPie : public LLTool, public LLSingleton { + LLSINGLETON(LLToolPie); LOG_CLASS(LLToolPie); public: - LLToolPie(); // Virtual functions inherited from LLMouseHandler virtual bool handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, bool down) override; diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h index e30482d64cb..b3e91fd8191 100644 --- a/indra/newview/lltoolpipette.h +++ b/indra/newview/lltoolpipette.h @@ -40,12 +40,12 @@ class LLViewerObject; class LLPickInfo; class LLToolPipette -: public LLTool, public LLSimpleton +: public LLTool, public LLSingleton { -public: - LLToolPipette(); + LLSINGLETON(LLToolPipette); virtual ~LLToolPipette(); +public: virtual bool handleMouseDown(S32 x, S32 y, MASK mask) override; virtual bool handleMouseUp(S32 x, S32 y, MASK mask) override; virtual bool handleHover(S32 x, S32 y, MASK mask) override; diff --git a/indra/newview/lltoolselectland.h b/indra/newview/lltoolselectland.h index 10c39ca122d..15672aa7d4e 100644 --- a/indra/newview/lltoolselectland.h +++ b/indra/newview/lltoolselectland.h @@ -33,12 +33,12 @@ class LLParcelSelection; class LLToolSelectLand -: public LLTool, public LLSimpleton +: public LLTool, public LLSingleton { -public: - LLToolSelectLand(); + LLSINGLETON(LLToolSelectLand); virtual ~LLToolSelectLand(); +public: /*virtual*/ bool handleMouseDown(S32 x, S32 y, MASK mask) override; /*virtual*/ bool handleDoubleClick(S32 x, S32 y, MASK mask) override; /*virtual*/ bool handleMouseUp(S32 x, S32 y, MASK mask) override; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 42643fc2c94..e4b68b67334 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -54,7 +54,6 @@ #include "llcommandhandler.h" #include "llcompilequeue.h" -#include "llfasttimerview.h" #include "llfloater360capture.h" #include "llfloaterabout.h" #include "llfloateraddpaymentmethod.h" @@ -272,7 +271,6 @@ class LLFloaterOpenHandler : public LLCommandHandler { const std::list blacklist_untrusted = { "360capture", - "block_timers", "add_payment_method", "appearance", "associate_listing", @@ -359,7 +357,6 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterAboutUtil::registerFloater(); LLFloaterReg::add("360capture", "floater_360capture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("block_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("add_payment_method", "floater_add_payment_method.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 8e9a2dfd2ee..d151f1fb75c 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -34,6 +34,80 @@ extern LLControlGroup gSavedSettings; +static const std::string empty_string; + +struct ViewerFolderEntry : public LLDictionaryEntry +{ + // Constructor for non-ensembles + ViewerFolderEntry(const std::string &new_category_name, // default name when creating a new category of this type + const std::string &icon_name_open, // name of the folder icon + const std::string &icon_name_closed, + bool is_quiet, // folder doesn't need a UI update when changed + bool hide_if_empty, // folder not shown if empty + const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank + ) + : + LLDictionaryEntry(dictionary_name), + mNewCategoryName(new_category_name), + mIconNameOpen(icon_name_open), + mIconNameClosed(icon_name_closed), + mIsQuiet(is_quiet), + mHideIfEmpty(hide_if_empty) + { + mAllowedNames.clear(); + } + + // Constructor for ensembles + ViewerFolderEntry(const std::string &xui_name, // name of the xui menu item + const std::string &new_category_name, // default name when creating a new category of this type + const std::string &icon_name, // name of the folder icon + const std::string allowed_names // allowed item typenames for this folder type + ) + : + LLDictionaryEntry(xui_name), + /* Just use default icons until we actually support ensembles + mIconNameOpen(icon_name), + mIconNameClosed(icon_name), + */ + mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"), + mNewCategoryName(new_category_name), + mIsQuiet(false), + mHideIfEmpty(false) + { + const std::string delims (","); + LLStringUtilBase::getTokens(allowed_names, mAllowedNames, delims); + } + + bool getIsAllowedName(const std::string &name) const + { + if (mAllowedNames.empty()) + return false; + for (name_vec_t::const_iterator iter = mAllowedNames.begin(); + iter != mAllowedNames.end(); + iter++) + { + if (name == (*iter)) + return true; + } + return false; + } + const std::string mIconNameOpen; + const std::string mIconNameClosed; + const std::string mNewCategoryName; + typedef std::vector name_vec_t; + name_vec_t mAllowedNames; + bool mIsQuiet; + bool mHideIfEmpty; +}; + +class LLViewerFolderDictionary : public LLSingleton, + public LLDictionary +{ + LLSINGLETON(LLViewerFolderDictionary); +protected: + bool initEnsemblesFromFile(); // Reads in ensemble information from foldertypes.xml +}; + LLViewerFolderDictionary::LLViewerFolderDictionary() { // NEW CATEGORY NAME FOLDER OPEN FOLDER CLOSED QUIET? HIDE IF EMPTY? diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h index 169574144bf..f25c1113a39 100644 --- a/indra/newview/llviewerfoldertype.h +++ b/indra/newview/llviewerfoldertype.h @@ -29,8 +29,6 @@ #include #include "llfoldertype.h" -#include "lldictionary.h" -#include "llsingleton.h" // This class is similar to llfoldertype, but contains methods // only used by the viewer. This also handles ensembles. @@ -53,77 +51,4 @@ class LLViewerFolderType : public LLFolderType ~LLViewerFolderType() {} }; -struct ViewerFolderEntry : public LLDictionaryEntry -{ - // Constructor for non-ensembles - ViewerFolderEntry(const std::string &new_category_name, // default name when creating a new category of this type - const std::string &icon_name_open, // name of the folder icon - const std::string &icon_name_closed, - bool is_quiet, // folder doesn't need a UI update when changed - bool hide_if_empty, // folder not shown if empty - const std::string &dictionary_name = {} // no reverse lookup needed on non-ensembles, so in most cases just leave this blank - ) - : - LLDictionaryEntry(dictionary_name), - mNewCategoryName(new_category_name), - mIconNameOpen(icon_name_open), - mIconNameClosed(icon_name_closed), - mIsQuiet(is_quiet), - mHideIfEmpty(hide_if_empty) - { - mAllowedNames.clear(); - } - - // Constructor for ensembles - ViewerFolderEntry(const std::string &xui_name, // name of the xui menu item - const std::string &new_category_name, // default name when creating a new category of this type - const std::string &icon_name, // name of the folder icon - const std::string allowed_names // allowed item typenames for this folder type - ) - : - LLDictionaryEntry(xui_name), - /* Just use default icons until we actually support ensembles - mIconNameOpen(icon_name), - mIconNameClosed(icon_name), - */ - mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"), - mNewCategoryName(new_category_name), - mIsQuiet(false), - mHideIfEmpty(false) - { - const std::string delims (","); - LLStringUtilBase::getTokens(allowed_names, mAllowedNames, delims); - } - - bool getIsAllowedName(const std::string &name) const - { - if (mAllowedNames.empty()) - return false; - for (name_vec_t::const_iterator iter = mAllowedNames.begin(); - iter != mAllowedNames.end(); - iter++) - { - if (name == (*iter)) - return true; - } - return false; - } - const std::string mIconNameOpen; - const std::string mIconNameClosed; - const std::string mNewCategoryName; - typedef std::vector name_vec_t; - name_vec_t mAllowedNames; - bool mIsQuiet; - bool mHideIfEmpty; -}; - -class LLViewerFolderDictionary : public LLSimpleton, - public LLDictionary -{ -public: - LLViewerFolderDictionary(); -protected: - bool initEnsemblesFromFile(); // Reads in ensemble information from foldertypes.xml -}; - #endif // LL_LLVIEWERFOLDERTYPE_H diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index c662b2d4c7c..c989615653c 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -46,14 +46,13 @@ typedef enum e_joystick_driver_state JDS_INITIALIZING } EJoystickDriverState; -class LLViewerJoystick : public LLSimpleton +class LLViewerJoystick : public LLSingleton { + LLSINGLETON(LLViewerJoystick); + virtual ~LLViewerJoystick(); LOG_CLASS(LLViewerJoystick); public: - LLViewerJoystick(); - ~LLViewerJoystick(); - void init(bool autoenable); void initDevice(LLSD &guid); bool initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index b6c7ea3cb0f..381b1fa498c 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -218,6 +218,23 @@ mAnyMediaShowing(false), mAnyMediaPlaying(false), mMaxIntances(MAX_MEDIA_INSTANCES_DEFAULT), mSpareBrowserMediaSource(NULL) +{ +} + +LLViewerMedia::~LLViewerMedia() +{ + gIdleCallbacks.deleteFunction(LLViewerMedia::onIdle, NULL); + mTeleportFinishConnection.disconnect(); + mMaxInstancesConnection.disconnect(); + if (mSpareBrowserMediaSource != NULL) + { + delete mSpareBrowserMediaSource; + mSpareBrowserMediaSource = NULL; + } +} + +// static +void LLViewerMedia::initSingleton() { gIdleCallbacks.addFunction(LLViewerMedia::onIdle, NULL); mTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> @@ -238,18 +255,6 @@ mSpareBrowserMediaSource(NULL) } } -LLViewerMedia::~LLViewerMedia() -{ - gIdleCallbacks.deleteFunction(LLViewerMedia::onIdle, NULL); - mTeleportFinishConnection.disconnect(); - mMaxInstancesConnection.disconnect(); - if (mSpareBrowserMediaSource != NULL) - { - delete mSpareBrowserMediaSource; - mSpareBrowserMediaSource = NULL; - } -} - void LLViewerMedia::setMaxInstances(S32 max_instances) { const F32Gigabytes MIN_PHYSICAL_MEMORY(8); @@ -633,15 +638,6 @@ static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMedi } } -static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE("Update Media"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_SPARE_IDLE("Spare Idle"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_INTEREST("Update/Interest"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_UPDATE_VOLUME("Update/Volume"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT("Media Sort"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_SORT2("Media Sort 2"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc"); - - ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMedia::onIdle(void *dummy_arg) { @@ -2181,7 +2177,7 @@ void LLViewerMediaImpl::setMute(bool mute) ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::updateVolume() { - LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE_VOLUME); + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; if(mMediaSource) { // always scale the volume by the global media volume @@ -2916,11 +2912,6 @@ bool LLViewerMediaImpl::canNavigateBack() } ////////////////////////////////////////////////////////////////////////////////////////// -static LLTrace::BlockTimerStatHandle FTM_MEDIA_DO_UPDATE("Do Update"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_GET_DATA("Get Data"); -static LLTrace::BlockTimerStatHandle FTM_MEDIA_SET_SUBIMAGE("Set Subimage"); - - void LLViewerMediaImpl::update() { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_DO_UPDATE); @@ -3775,8 +3766,6 @@ bool LLViewerMediaImpl::isUpdated() return mIsUpdated ; } -static LLTrace::BlockTimerStatHandle FTM_MEDIA_CALCULATE_INTEREST("Calculate Interest"); - void LLViewerMediaImpl::calculateInterest() { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST); diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index f69248fbbbb..a3cb9ec93e7 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -71,14 +71,14 @@ class LLViewerMediaEventEmitter class LLViewerMediaImpl; class LLMediaCtrl; -class LLViewerMedia: public LLSimpleton +class LLViewerMedia: public LLSingleton { + LLSINGLETON(LLViewerMedia); + ~LLViewerMedia(); + void initSingleton() override; LOG_CLASS(LLViewerMedia); public: - LLViewerMedia(); - ~LLViewerMedia(); - // String to get/set media autoplay in gSavedSettings static const char* AUTO_PLAY_MEDIA_SETTING; static const char* SHOW_MEDIA_ON_OTHERS_SETTING; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 170273c6e92..65880c511c8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -754,10 +754,6 @@ class LLAdvancedToggleConsole : public view_listener_t { toggle_visibility(gDebugView->mDebugConsolep); } - else if ("fast timers" == console_type) - { - LLFloaterReg::toggleInstance("block_timers"); - } else if ("scene view" == console_type) { toggle_visibility(gSceneView); @@ -784,10 +780,6 @@ class LLAdvancedCheckConsole : public view_listener_t { new_value = get_visibility(gDebugView->mDebugConsolep); } - else if ("fast timers" == console_type) - { - new_value = LLFloaterReg::instanceVisible("block_timers"); - } else if ("scene view" == console_type) { new_value = get_visibility(gSceneView); @@ -9244,11 +9236,6 @@ void handle_dump_avatar_local_textures() gAgentAvatarp->dumpLocalTextures(); } -void handle_dump_timers() -{ - LLTrace::BlockTimer::dumpCurTimes(); -} - void handle_debug_avatar_textures() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject(); @@ -10606,7 +10593,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest"); view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr"); view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory"); - commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) ); commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) ); view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo"); view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo"); diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index a5398f22fba..0937425a188 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -57,14 +57,13 @@ class LLInvalidGridName * This class maintains the currently selected grid, and provides short * form accessors for each of the properties of the selected grid. **/ -class LLGridManager : public LLSimpleton +class LLGridManager : public LLSingleton { -public: - /// Instantiate the grid manager, load default grids, selects the default grid - LLGridManager(); + LLSINGLETON(LLGridManager); ~LLGridManager(); + public: /* ================================================================ * @name Initialization and Configuration * @{ diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 0017af79932..01303bc1f19 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -295,8 +295,6 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp, } } -static LLTrace::BlockTimerStatHandle FTM_PROCESS_OBJECTS("Process Objects"); - LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* entry, LLViewerRegion* regionp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; @@ -405,7 +403,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, const EObjectUpdateType update_type, bool compressed) { - LL_RECORD_BLOCK_TIME(FTM_PROCESS_OBJECTS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; LLViewerObject *objectp; S32 num_objects; @@ -803,6 +801,8 @@ void LLViewerObjectList::setAllObjectDefaultTextures(U32 nChannel, bool fShowDef void LLViewerObjectList::updateApparentAngles(LLAgent &agent) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + S32 i; LLViewerObject *objectp; diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h index 304c84b6287..c48c438ad04 100644 --- a/indra/newview/llviewerparcelmgr.h +++ b/indra/newview/llviewerparcelmgr.h @@ -74,12 +74,12 @@ class LLParcelObserver virtual void changed() = 0; }; -class LLViewerParcelMgr : public LLSimpleton +class LLViewerParcelMgr : public LLSingleton { -public: - LLViewerParcelMgr(); + LLSINGLETON(LLViewerParcelMgr); ~LLViewerParcelMgr(); +public: typedef std::function teleport_finished_callback_t; typedef boost::signals2::signal teleport_finished_signal_t; typedef std::function teleport_failed_callback_t; diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp index 1be62cafecc..c666663fd34 100644 --- a/indra/newview/llviewerpartsim.cpp +++ b/indra/newview/llviewerpartsim.cpp @@ -656,10 +656,10 @@ void LLViewerPartSim::shift(const LLVector3 &offset) } } -static LLTrace::BlockTimerStatHandle FTM_SIMULATE_PARTICLES("Simulate Particles"); - void LLViewerPartSim::updateSimulation() { + LL_PROFILE_ZONE_SCOPED; + static LLFrameTimer update_timer; const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f); @@ -669,8 +669,6 @@ void LLViewerPartSim::updateSimulation() return; } - LL_RECORD_BLOCK_TIME(FTM_SIMULATE_PARTICLES); - // Start at a random particle system so the same // particle system doesn't always get first pick at the // particles. Theoretically we'd want to do this in distance diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h index 506978f56cc..cf3843bd667 100644 --- a/indra/newview/llviewerpartsim.h +++ b/indra/newview/llviewerpartsim.h @@ -133,11 +133,10 @@ class LLViewerPartGroup LLViewerRegion *mRegionp; }; -class LLViewerPartSim : public LLSimpleton +class LLViewerPartSim : public LLSingleton { + LLSINGLETON(LLViewerPartSim); public: - LLViewerPartSim(); - void destroyClass(); typedef std::vector group_list_t; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 27c1482e34c..7de74ab19f2 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -718,9 +718,6 @@ void LLViewerRegion::initStats() mAlive = false; // can become false if circuit disconnects } -static LLTrace::BlockTimerStatHandle FTM_CLEANUP_REGION_OBJECTS("Cleanup Region Objects"); -static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache"); - LLViewerRegion::~LLViewerRegion() { LL_PROFILE_ZONE_SCOPED; @@ -737,7 +734,6 @@ LLViewerRegion::~LLViewerRegion() LLViewerPartSim::getInstance()->cleanupRegion(this); { - LL_RECORD_BLOCK_TIME(FTM_CLEANUP_REGION_OBJECTS); gObjectList.killObjects(this); } @@ -751,7 +747,6 @@ LLViewerRegion::~LLViewerRegion() std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); { - LL_RECORD_BLOCK_TIME(FTM_SAVE_REGION_CACHE); saveObjectCache(); } @@ -807,6 +802,7 @@ void LLViewerRegion::loadObjectCache() void LLViewerRegion::saveObjectCache() { + LL_PROFILE_ZONE_SCOPED; if (!mCacheLoaded) { return; diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 3929aee80a2..f7352c40076 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -50,7 +50,6 @@ #include "llversioninfo.h" #include "llfloatertools.h" #include "lldebugview.h" -#include "llfasttimerview.h" #include "llviewerregion.h" #include "llvoavatar.h" #include "llvoavatarself.h" @@ -240,7 +239,6 @@ LLTrace::EventStatHandle > AGENT_POSITION_SNAP("age LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"); LLTrace::EventStatHandle REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"), - FRAME_STACKTIME("framestacktime", "FRAME_SECS"), UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"), NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"), IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"), @@ -489,8 +487,6 @@ void update_statistics() typedef LLTrace::StatType::instance_tracker_t stat_type_t; - record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Frame"))); - if (gAgent.getRegion() && isAgentAvatarValid()) { LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 8ec0dd00247..d76aa00e1b7 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -215,8 +215,21 @@ extern LLTrace::EventStatHandle > AGENT_POSITION_SN extern LLTrace::EventStatHandle<> LOADING_WEARABLES_LONG_DELAY; +extern LLTrace::SampleStatHandle FRAMETIME_JITTER, + FRAMETIME, + FRAMETIME_JITTER_99TH, + FRAMETIME_JITTER_95TH, + FRAMETIME_99TH, + FRAMETIME_95TH, + FRAMETIME_JITTER_CUMULATIVE, + FRAMETIME_JITTER_STDDEV, + FRAMETIME_STDDEV; + +extern LLTrace::SampleStatHandle FRAMETIME_JITTER_EVENTS, + FRAMETIME_JITTER_EVENTS_PER_MINUTE, + FRAMETIME_JITTER_EVENTS_LAST_MINUTE; + extern LLTrace::EventStatHandle REGION_CROSSING_TIME, - FRAME_STACKTIME, UPDATE_STACKTIME, NETWORK_STACKTIME, IMAGE_STACKTIME, diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index f7baafbdd1d..cff181525ab 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -80,11 +80,8 @@ LLPointer LLViewerFetchedTexture::sDefaultIrradiancePBRp LLPointer LLViewerFetchedTexture::sDefaultDiffuseImagep = NULL; // [/SL:KB] LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap; -LLTexturePipelineTester* LLViewerTextureManager::sTesterp = nullptr; F32 LLViewerFetchedTexture::sMaxVirtualSize = 8192.f*8192.f; -const std::string sTesterName("TextureTester"); - S32 LLViewerTexture::sImageCount = 0; S32 LLViewerTexture::sRawCount = 0; S32 LLViewerTexture::sAuxCount = 0; @@ -439,16 +436,6 @@ void LLViewerTextureManager::init() // Create a texture manager bridge. gTextureManagerBridgep = new LLViewerTextureManagerBridge; - - if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName)) - { - sTesterp = new LLTexturePipelineTester(); - if (!sTesterp->isValid()) - { - delete sTesterp; - sTesterp = NULL; - } - } } void LLViewerTextureManager::cleanup() @@ -488,12 +475,6 @@ void LLViewerTexture::updateClass() LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; sCurrentTime = gFrameTimeSeconds; - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->update(); - } - LLViewerMediaTexture::updateClass(); // This is a divisor used to determine how much VRAM from our overall VRAM budget to use. // This is **cumulative** on whatever the detected or manually set VRAM budget is. @@ -862,11 +843,6 @@ bool LLViewerTexture::bindDefaultImage(S32 stage) } stop_glerror(); - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->updateGrayTextureBinding(); - } return res; } @@ -1067,16 +1043,6 @@ bool LLViewerTexture::isLargeImage() return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize; } -//virtual -void LLViewerTexture::updateBindStatsForTester() -{ - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - tester->updateTextureBindingStats(this); - } -} - //---------------------------------------------------------------------------------------------- //end of LLViewerTexture //---------------------------------------------------------------------------------------------- @@ -1907,12 +1873,7 @@ bool LLViewerFetchedTexture::processFetchResults(S32& desired_discard, S32 curre if (mRawImage.notNull()) { LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image"); - LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName); - if (tester) - { - mIsFetched = true; - tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)); - } + mIsFetched = true; mRawDiscardLevel = fetch_discard; if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) @@ -3805,397 +3766,3 @@ F32 LLViewerMediaTexture::getMaxVirtualSize() //---------------------------------------------------------------------------------------------- //end of LLViewerMediaTexture //---------------------------------------------------------------------------------------------- - -//---------------------------------------------------------------------------------------------- -//start of LLTexturePipelineTester -//---------------------------------------------------------------------------------------------- -LLTexturePipelineTester::LLTexturePipelineTester() : LLMetricPerformanceTesterWithSession(sTesterName) -{ - addMetric("TotalBytesLoaded"); - addMetric("TotalBytesLoadedFromCache"); - addMetric("TotalBytesLoadedForLargeImage"); - addMetric("TotalBytesLoadedForSculpties"); - addMetric("StartFetchingTime"); - addMetric("TotalGrayTime"); - addMetric("TotalStablizingTime"); - addMetric("StartTimeLoadingSculpties"); - addMetric("EndTimeLoadingSculpties"); - - addMetric("Time"); - addMetric("TotalBytesBound"); - addMetric("TotalBytesBoundForLargeImage"); - addMetric("PercentageBytesBound"); - - mTotalBytesLoaded = (S32Bytes)0; - mTotalBytesLoadedFromCache = (S32Bytes)0; - mTotalBytesLoadedForLargeImage = (S32Bytes)0; - mTotalBytesLoadedForSculpties = (S32Bytes)0; - - reset(); -} - -LLTexturePipelineTester::~LLTexturePipelineTester() -{ - LLViewerTextureManager::sTesterp = NULL; -} - -void LLTexturePipelineTester::update() -{ - mLastTotalBytesUsed = mTotalBytesUsed; - mLastTotalBytesUsedForLargeImage = mTotalBytesUsedForLargeImage; - mTotalBytesUsed = (S32Bytes)0; - mTotalBytesUsedForLargeImage = (S32Bytes)0; - - if(LLAppViewer::getTextureFetch()->getNumRequests() > 0) //fetching list is not empty - { - if(mPause) - { - //start a new fetching session - reset(); - mStartFetchingTime = LLImageGL::sLastFrameTime; - mPause = false; - } - - //update total gray time - if(mUsingDefaultTexture) - { - mUsingDefaultTexture = false; - mTotalGrayTime = LLImageGL::sLastFrameTime - mStartFetchingTime; - } - - //update the stablizing timer. - updateStablizingTime(); - - outputTestResults(); - } - else if(!mPause) - { - //stop the current fetching session - mPause = true; - outputTestResults(); - reset(); - } -} - -void LLTexturePipelineTester::reset() -{ - mPause = true; - - mUsingDefaultTexture = false; - mStartStablizingTime = 0.0f; - mEndStablizingTime = 0.0f; - - mTotalBytesUsed = (S32Bytes)0; - mTotalBytesUsedForLargeImage = (S32Bytes)0; - mLastTotalBytesUsed = (S32Bytes)0; - mLastTotalBytesUsedForLargeImage = (S32Bytes)0; - - mStartFetchingTime = 0.0f; - - mTotalGrayTime = 0.0f; - mTotalStablizingTime = 0.0f; - - mStartTimeLoadingSculpties = 1.0f; - mEndTimeLoadingSculpties = 0.0f; -} - -//virtual -void LLTexturePipelineTester::outputTestRecord(LLSD *sd) -{ - std::string currentLabel = getCurrentLabelName(); - (*sd)[currentLabel]["TotalBytesLoaded"] = (LLSD::Integer)mTotalBytesLoaded.value(); - (*sd)[currentLabel]["TotalBytesLoadedFromCache"] = (LLSD::Integer)mTotalBytesLoadedFromCache.value(); - (*sd)[currentLabel]["TotalBytesLoadedForLargeImage"] = (LLSD::Integer)mTotalBytesLoadedForLargeImage.value(); - (*sd)[currentLabel]["TotalBytesLoadedForSculpties"] = (LLSD::Integer)mTotalBytesLoadedForSculpties.value(); - - (*sd)[currentLabel]["StartFetchingTime"] = (LLSD::Real)mStartFetchingTime; - (*sd)[currentLabel]["TotalGrayTime"] = (LLSD::Real)mTotalGrayTime; - (*sd)[currentLabel]["TotalStablizingTime"] = (LLSD::Real)mTotalStablizingTime; - - (*sd)[currentLabel]["StartTimeLoadingSculpties"] = (LLSD::Real)mStartTimeLoadingSculpties; - (*sd)[currentLabel]["EndTimeLoadingSculpties"] = (LLSD::Real)mEndTimeLoadingSculpties; - - (*sd)[currentLabel]["Time"] = LLImageGL::sLastFrameTime; - (*sd)[currentLabel]["TotalBytesBound"] = (LLSD::Integer)mLastTotalBytesUsed.value(); - (*sd)[currentLabel]["TotalBytesBoundForLargeImage"] = (LLSD::Integer)mLastTotalBytesUsedForLargeImage.value(); - (*sd)[currentLabel]["PercentageBytesBound"] = (LLSD::Real)(100.f * mLastTotalBytesUsed / mTotalBytesLoaded); -} - -void LLTexturePipelineTester::updateTextureBindingStats(const LLViewerTexture* imagep) -{ - U32Bytes mem_size = imagep->getTextureMemory(); - mTotalBytesUsed += mem_size; - - if(MIN_LARGE_IMAGE_AREA <= (U32)(mem_size.value() / (U32)imagep->getComponents())) - { - mTotalBytesUsedForLargeImage += mem_size; - } -} - -void LLTexturePipelineTester::updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, bool from_cache) -{ - U32Bytes data_size = (U32Bytes)raw_imagep->getDataSize(); - mTotalBytesLoaded += data_size; - - if(from_cache) - { - mTotalBytesLoadedFromCache += data_size; - } - - if(MIN_LARGE_IMAGE_AREA <= (U32)(data_size.value() / (U32)raw_imagep->getComponents())) - { - mTotalBytesLoadedForLargeImage += data_size; - } - - if(imagep->forSculpt()) - { - mTotalBytesLoadedForSculpties += data_size; - - if(mStartTimeLoadingSculpties > mEndTimeLoadingSculpties) - { - mStartTimeLoadingSculpties = LLImageGL::sLastFrameTime; - } - mEndTimeLoadingSculpties = LLImageGL::sLastFrameTime; - } -} - -void LLTexturePipelineTester::updateGrayTextureBinding() -{ - mUsingDefaultTexture = true; -} - -void LLTexturePipelineTester::setStablizingTime() -{ - if(mStartStablizingTime <= mStartFetchingTime) - { - mStartStablizingTime = LLImageGL::sLastFrameTime; - } - mEndStablizingTime = LLImageGL::sLastFrameTime; -} - -void LLTexturePipelineTester::updateStablizingTime() -{ - if(mStartStablizingTime > mStartFetchingTime) - { - F32 t = mEndStablizingTime - mStartStablizingTime; - - if(t > F_ALMOST_ZERO && (t - mTotalStablizingTime) < F_ALMOST_ZERO) - { - //already stablized - mTotalStablizingTime = LLImageGL::sLastFrameTime - mStartStablizingTime; - - //cancel the timer - mStartStablizingTime = 0.f; - mEndStablizingTime = 0.f; - } - else - { - mTotalStablizingTime = t; - } - } - mTotalStablizingTime = 0.f; -} - -//virtual -void LLTexturePipelineTester::compareTestSessions(llofstream* os) -{ - LLTexturePipelineTester::LLTextureTestSession* base_sessionp = dynamic_cast(mBaseSessionp); - LLTexturePipelineTester::LLTextureTestSession* current_sessionp = dynamic_cast(mCurrentSessionp); - if(!base_sessionp || !current_sessionp) - { - LL_ERRS() << "type of test session does not match!" << LL_ENDL; - } - - //compare and output the comparison - *os << llformat("%s\n", getTesterName().c_str()); - *os << llformat("AggregateResults\n"); - - compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime); - compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime); - compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties); - compareTestResults(os, "TotalTimeLoadingSculpties", base_sessionp->mTotalTimeLoadingSculpties, current_sessionp->mTotalTimeLoadingSculpties); - - compareTestResults(os, "TotalBytesLoaded", base_sessionp->mTotalBytesLoaded, current_sessionp->mTotalBytesLoaded); - compareTestResults(os, "TotalBytesLoadedFromCache", base_sessionp->mTotalBytesLoadedFromCache, current_sessionp->mTotalBytesLoadedFromCache); - compareTestResults(os, "TotalBytesLoadedForLargeImage", base_sessionp->mTotalBytesLoadedForLargeImage, current_sessionp->mTotalBytesLoadedForLargeImage); - compareTestResults(os, "TotalBytesLoadedForSculpties", base_sessionp->mTotalBytesLoadedForSculpties, current_sessionp->mTotalBytesLoadedForSculpties); - - *os << llformat("InstantResults\n"); - S32 size = llmin(base_sessionp->mInstantPerformanceListCounter, current_sessionp->mInstantPerformanceListCounter); - for(S32 i = 0; i < size; i++) - { - *os << llformat("Time(B-T)-%.4f-%.4f\n", base_sessionp->mInstantPerformanceList[i].mTime, current_sessionp->mInstantPerformanceList[i].mTime); - - compareTestResults(os, "AverageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond, - current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); - - compareTestResults(os, "AverageBytesUsedForLargeImagePerSecond", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond, - current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); - - compareTestResults(os, "AveragePercentageBytesUsedPerSecond", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond, - current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); - } - - if(size < base_sessionp->mInstantPerformanceListCounter) - { - for(S32 i = size; i < base_sessionp->mInstantPerformanceListCounter; i++) - { - *os << llformat("Time(B-T)-%.4f- \n", base_sessionp->mInstantPerformanceList[i].mTime); - - *os << llformat(", AverageBytesUsedPerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); - *os << llformat(", AverageBytesUsedForLargeImagePerSecond, %d, N/A \n", base_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); - *os << llformat(", AveragePercentageBytesUsedPerSecond, %.4f, N/A \n", base_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); - } - } - else if(size < current_sessionp->mInstantPerformanceListCounter) - { - for(S32 i = size; i < current_sessionp->mInstantPerformanceListCounter; i++) - { - *os << llformat("Time(B-T)- -%.4f\n", current_sessionp->mInstantPerformanceList[i].mTime); - - *os << llformat(", AverageBytesUsedPerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedPerSecond); - *os << llformat(", AverageBytesUsedForLargeImagePerSecond, N/A, %d\n", current_sessionp->mInstantPerformanceList[i].mAverageBytesUsedForLargeImagePerSecond); - *os << llformat(", AveragePercentageBytesUsedPerSecond, N/A, %.4f\n", current_sessionp->mInstantPerformanceList[i].mAveragePercentageBytesUsedPerSecond); - } - } -} - -//virtual -LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::loadTestSession(LLSD* log) -{ - LLTexturePipelineTester::LLTextureTestSession* sessionp = new LLTexturePipelineTester::LLTextureTestSession(); - if(!sessionp) - { - return NULL; - } - - F32 total_gray_time = 0.f; - F32 total_stablizing_time = 0.f; - F32 total_loading_sculpties_time = 0.f; - - F32 start_fetching_time = -1.f; - F32 start_fetching_sculpties_time = 0.f; - - F32 last_time = 0.0f; - S32 frame_count = 0; - - sessionp->mInstantPerformanceListCounter = 0; - sessionp->mInstantPerformanceList.resize(128); - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f; - - //load a session - std::string currentLabel = getCurrentLabelName(); - bool in_log = (*log).has(currentLabel); - while (in_log) - { - LLSD::String label = currentLabel; - - if(sessionp->mInstantPerformanceListCounter >= (S32)sessionp->mInstantPerformanceList.size()) - { - sessionp->mInstantPerformanceList.resize(sessionp->mInstantPerformanceListCounter + 128); - } - - //time - F32 start_time = (F32)(*log)[label]["StartFetchingTime"].asReal(); - F32 cur_time = (F32)(*log)[label]["Time"].asReal(); - if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while - { - sessionp->mTotalGrayTime += total_gray_time; - sessionp->mTotalStablizingTime += total_stablizing_time; - - sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time; - sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; - - start_fetching_time = start_time; - total_gray_time = 0.f; - total_stablizing_time = 0.f; - total_loading_sculpties_time = 0.f; - } - else - { - total_gray_time = (F32)(*log)[label]["TotalGrayTime"].asReal(); - total_stablizing_time = (F32)(*log)[label]["TotalStablizingTime"].asReal(); - - total_loading_sculpties_time = (F32)(*log)[label]["EndTimeLoadingSculpties"].asReal() - (F32)(*log)[label]["StartTimeLoadingSculpties"].asReal(); - if(start_fetching_sculpties_time < 0.f && total_loading_sculpties_time > 0.f) - { - start_fetching_sculpties_time = (F32)(*log)[label]["StartTimeLoadingSculpties"].asReal(); - } - } - - //total loaded bytes - sessionp->mTotalBytesLoaded = (*log)[label]["TotalBytesLoaded"].asInteger(); - sessionp->mTotalBytesLoadedFromCache = (*log)[label]["TotalBytesLoadedFromCache"].asInteger(); - sessionp->mTotalBytesLoadedForLargeImage = (*log)[label]["TotalBytesLoadedForLargeImage"].asInteger(); - sessionp->mTotalBytesLoadedForSculpties = (*log)[label]["TotalBytesLoadedForSculpties"].asInteger(); - - //instant metrics - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond += - (*log)[label]["TotalBytesBound"].asInteger(); - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond += - (*log)[label]["TotalBytesBoundForLargeImage"].asInteger(); - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond += - (F32)(*log)[label]["PercentageBytesBound"].asReal(); - frame_count++; - if(cur_time - last_time >= 1.0f) - { - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond /= frame_count; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond /= frame_count; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond /= frame_count; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = last_time; - - frame_count = 0; - last_time = cur_time; - sessionp->mInstantPerformanceListCounter++; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedPerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAverageBytesUsedForLargeImagePerSecond = 0; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mAveragePercentageBytesUsedPerSecond = 0.f; - sessionp->mInstantPerformanceList[sessionp->mInstantPerformanceListCounter].mTime = 0.f; - } - // Next label - incrementCurrentCount(); - currentLabel = getCurrentLabelName(); - in_log = (*log).has(currentLabel); - } - - sessionp->mTotalGrayTime += total_gray_time; - sessionp->mTotalStablizingTime += total_stablizing_time; - - if(sessionp->mStartTimeLoadingSculpties < 0.f) - { - sessionp->mStartTimeLoadingSculpties = start_fetching_sculpties_time; - } - sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time; - - return sessionp; -} - -LLTexturePipelineTester::LLTextureTestSession::LLTextureTestSession() -{ - reset(); -} -LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession() -{ -} -void LLTexturePipelineTester::LLTextureTestSession::reset() -{ - mTotalGrayTime = 0.0f; - mTotalStablizingTime = 0.0f; - - mStartTimeLoadingSculpties = 0.0f; - mTotalTimeLoadingSculpties = 0.0f; - - mTotalBytesLoaded = 0; - mTotalBytesLoadedFromCache = 0; - mTotalBytesLoadedForLargeImage = 0; - mTotalBytesLoadedForSculpties = 0; - - mInstantPerformanceListCounter = 0; -} -//---------------------------------------------------------------------------------------------- -//end of LLTexturePipelineTester -//---------------------------------------------------------------------------------------------- - diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 7360e21f9fd..9c1b490ed50 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -34,7 +34,6 @@ #include "llhost.h" #include "llgltypes.h" #include "llrender.h" -#include "llmetricperformancetester.h" #include "httpcommon.h" #include "workqueue.h" #include "gltf/common.h" @@ -49,8 +48,6 @@ class LLViewerObject; class LLViewerTexture; class LLViewerFetchedTexture ; class LLViewerMediaTexture ; -class LLTexturePipelineTester ; - typedef void (*loaded_callback_func)( bool success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, bool final, void* userdata ); @@ -171,8 +168,6 @@ class LLViewerTexture : public LLGLTexture bool hasParcelMedia() const { return mParcelMedia != NULL;} LLViewerMediaTexture* getParcelMedia() const { return mParcelMedia;} - /*virtual*/ void updateBindStatsForTester() ; - protected: void cleanup() ; void init(bool firstinit) ; @@ -624,9 +619,6 @@ class LLViewerTextureManager LLViewerTextureManager(){} public: - //texture pipeline tester - static LLTexturePipelineTester* sTesterp ; - //returns NULL if tex is not a LLViewerFetchedTexture nor derived from LLViewerFetchedTexture. static LLViewerFetchedTexture* staticCastToFetchedTexture(LLTexture* tex, bool report_error = false) ; @@ -695,98 +687,5 @@ class LLViewerTextureManager static void init() ; static void cleanup() ; }; -// -//this class is used for test/debug only -//it tracks the activities of the texture pipeline -//records them, and outputs them to log files -// -class LLTexturePipelineTester : public LLMetricPerformanceTesterWithSession -{ - enum - { - MIN_LARGE_IMAGE_AREA = 262144 //512 * 512 - }; -public: - LLTexturePipelineTester() ; - ~LLTexturePipelineTester() ; - - void update(); - void updateTextureBindingStats(const LLViewerTexture* imagep) ; - void updateTextureLoadingStats(const LLViewerFetchedTexture* imagep, const LLImageRaw* raw_imagep, bool from_cache) ; - void updateGrayTextureBinding() ; - void setStablizingTime() ; - -private: - void reset() ; - void updateStablizingTime() ; - - /*virtual*/ void outputTestRecord(LLSD* sd) ; - -private: - bool mPause ; -private: - bool mUsingDefaultTexture; //if set, some textures are still gray. - - U32Bytes mTotalBytesUsed ; //total bytes of textures bound/used for the current frame. - U32Bytes mTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the current frame for images larger than 256 * 256. - U32Bytes mLastTotalBytesUsed ; //total bytes of textures bound/used for the previous frame. - U32Bytes mLastTotalBytesUsedForLargeImage ; //total bytes of textures bound/used for the previous frame for images larger than 256 * 256. - - // - //data size - // - U32Bytes mTotalBytesLoaded ; //total bytes fetched by texture pipeline - U32Bytes mTotalBytesLoadedFromCache ; //total bytes fetched by texture pipeline from local cache - U32Bytes mTotalBytesLoadedForLargeImage ; //total bytes fetched by texture pipeline for images larger than 256 * 256. - U32Bytes mTotalBytesLoadedForSculpties ; //total bytes fetched by texture pipeline for sculpties - - // - //time - //NOTE: the error tolerances of the following timers is one frame time. - // - F32 mStartFetchingTime ; - F32 mTotalGrayTime ; //total loading time when no gray textures. - F32 mTotalStablizingTime ; //total stablizing time when texture memory overflows - F32 mStartTimeLoadingSculpties ; //the start moment of loading sculpty images. - F32 mEndTimeLoadingSculpties ; //the end moment of loading sculpty images. - F32 mStartStablizingTime ; - F32 mEndStablizingTime ; - -private: - // - //The following members are used for performance analyzing - // - class LLTextureTestSession : public LLTestSession - { - public: - LLTextureTestSession() ; - /*virtual*/ ~LLTextureTestSession() ; - - void reset() ; - - F32 mTotalGrayTime ; - F32 mTotalStablizingTime ; - F32 mStartTimeLoadingSculpties ; - F32 mTotalTimeLoadingSculpties ; - - S32 mTotalBytesLoaded ; - S32 mTotalBytesLoadedFromCache ; - S32 mTotalBytesLoadedForLargeImage ; - S32 mTotalBytesLoadedForSculpties ; - - typedef struct _texture_instant_preformance_t - { - S32 mAverageBytesUsedPerSecond ; - S32 mAverageBytesUsedForLargeImagePerSecond ; - F32 mAveragePercentageBytesUsedPerSecond ; - F32 mTime ; - }texture_instant_preformance_t ; - std::vector mInstantPerformanceList ; - S32 mInstantPerformanceListCounter ; - }; - - /*virtual*/ LLMetricPerformanceTesterWithSession::LLTestSession* loadTestSession(LLSD* log) ; - /*virtual*/ void compareTestSessions(llofstream* os) ; -}; #endif diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 7677178d01b..62062de7550 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -417,8 +417,6 @@ void normalized_float_to_string(const float x, char *out_str) // LLDebugText // -static LLTrace::BlockTimerStatHandle FTM_DISPLAY_DEBUG_TEXT("Display Debug Text"); - class LLDebugText { private: @@ -962,7 +960,7 @@ class LLDebugText void draw() { - LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT); + LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; // Camera matrix text is hard to see again a white background // Add a dark background underneath the matrices for readability (contrast) @@ -4364,10 +4362,9 @@ void LLViewerWindow::updateKeyboardFocus() } } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_WORLD_VIEW("Update World View"); void LLViewerWindow::updateWorldViewRect(bool use_full_window) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_WORLD_VIEW); + LL_PROFILE_ZONE_SCOPED; // start off using whole window to render world LLRect new_world_rect = mWindowRectRaw; @@ -6430,11 +6427,9 @@ void LLViewerWindow::requestResolutionUpdate() mResDirty = true; } -static LLTrace::BlockTimerStatHandle FTM_WINDOW_CHECK_SETTINGS("Window Settings"); - void LLViewerWindow::checkSettings() { - LL_RECORD_BLOCK_TIME(FTM_WINDOW_CHECK_SETTINGS); + LL_PROFILE_ZONE_SCOPED; if (mStatesDirty) { gGL.refreshState(); diff --git a/indra/newview/llvlmanager.cpp b/indra/newview/llvlmanager.cpp index f4c2c27cee2..07c9b548a53 100644 --- a/indra/newview/llvlmanager.cpp +++ b/indra/newview/llvlmanager.cpp @@ -80,6 +80,8 @@ void LLVLManager::addLayerData(LLVLData *vl_datap, const S32Bytes mesg_size) void LLVLManager::unpackData(const S32 num_packets) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + static LLFrameTimer decode_timer; S32 i; diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index f5bd9198d34..c7bd4625f8d 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -247,10 +247,9 @@ class LLVOCachePartition : public LLViewerOctreePartition // //Note: LLVOCache is not thread-safe // -class LLVOCache : public LLSimpleton +class LLVOCache : public LLParamSingleton { -public: - LLVOCache(bool read_only); + LLSINGLETON(LLVOCache, bool read_only); ~LLVOCache() ; private: diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index b4f2dca5a98..3ca3081340d 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -403,11 +403,9 @@ LLDrawable* LLVOGrass::createDrawable(LLPipeline *pipeline) return mDrawable; } -static LLTrace::BlockTimerStatHandle FTM_UPDATE_GRASS("Update Grass"); - bool LLVOGrass::updateGeometry(LLDrawable *drawable) { - LL_RECORD_BLOCK_TIME(FTM_UPDATE_GRASS); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; dirtySpatialGroup(); diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index eb653b323fc..135a7331cb4 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -167,7 +167,6 @@ void LLVoiceClient::init(LLPumpIO *pump) // Initialize all of the voice modules m_servicePump = pump; #ifndef DISABLE_WEBRTC - LLWebRTCVoiceClient::createInstance(); LLWebRTCVoiceClient::getInstance()->init(pump); #endif } diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index b2d997337ab..70bce055f9b 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -342,13 +342,13 @@ class LLVoiceEffectInterface }; -class LLVoiceClient: public LLSimpleton +class LLVoiceClient: public LLParamSingleton { + LLSINGLETON(LLVoiceClient, LLPumpIO *pump); LOG_CLASS(LLVoiceClient); -public: - LLVoiceClient(LLPumpIO* pump); ~LLVoiceClient(); +public: typedef boost::signals2::signal micro_changed_signal_t; micro_changed_signal_t mMicroChangedSignal; diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index db1852cdcd9..7dea89d286f 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -281,6 +281,10 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() : //--------------------------------------------------- LLWebRTCVoiceClient::~LLWebRTCVoiceClient() +{ +} + +void LLWebRTCVoiceClient::cleanupSingleton() { if (mAvatarNameCacheConnection.connected()) { diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index 9e838fc44c4..8a15ba54b42 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -56,18 +56,18 @@ typedef std::shared_ptr connectionPtr_t; extern const std::string WEBRTC_VOICE_SERVER_TYPE; -class LLWebRTCVoiceClient : public LLSimpleton, +class LLWebRTCVoiceClient : public LLSingleton, virtual public LLVoiceModuleInterface, public llwebrtc::LLWebRTCDevicesObserver, public LLMuteListObserver, public llwebrtc::LLWebRTCLogCallback { + LLSINGLETON(LLWebRTCVoiceClient); LOG_CLASS(LLWebRTCVoiceClient); - -public: - LLWebRTCVoiceClient(); virtual ~LLWebRTCVoiceClient(); +public: + void cleanupSingleton() override; /// @name LLVoiceModuleInterface virtual implementations /// @see LLVoiceModuleInterface //@{ diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 78d711e369a..6cda8f5709e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1393,11 +1393,6 @@ void LLVOVolume::sculpt() sculpt_width = 0; sculpt_height = 0; sculpt_data = NULL ; - - if(LLViewerTextureManager::sTesterp) - { - LLViewerTextureManager::sTesterp->updateGrayTextureBinding(); - } } else { @@ -1408,11 +1403,6 @@ void LLVOVolume::sculpt() sculpt_components = raw_image->getComponents(); sculpt_data = raw_image->getData(); - - if(LLViewerTextureManager::sTesterp) - { - mSculptTexture->updateBindStatsForTester() ; - } } getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level, mSculptTexture->isMissingAsset()); diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h index e2a415abe71..8378b5e447e 100644 --- a/indra/newview/llworldmap.h +++ b/indra/newview/llworldmap.h @@ -182,12 +182,12 @@ const S32 MAP_MAX_SIZE = 2048; const S32 MAP_BLOCK_SIZE = 4; const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE); -class LLWorldMap : public LLSimpleton +class LLWorldMap : public LLSingleton { -public: - LLWorldMap(); + LLSINGLETON(LLWorldMap); ~LLWorldMap(); +public: // Clear all: list of region info, tiles, blocks and items void reset(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b335217b0ee..af6fb3283ef 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -266,40 +266,6 @@ bool gDebugPipeline = false; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; -LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY("Render Geometry"); -LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS("Grass"); -LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE("Invisible"); -LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY("Shiny"); -LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE("Simple"); -LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN("Terrain"); -LLTrace::BlockTimerStatHandle FTM_RENDER_TREES("Trees"); -LLTrace::BlockTimerStatHandle FTM_RENDER_UI("UI"); -LLTrace::BlockTimerStatHandle FTM_RENDER_WATER("Water"); -LLTrace::BlockTimerStatHandle FTM_RENDER_WL_SKY("Windlight Sky"); -LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA("Alpha Objects"); -LLTrace::BlockTimerStatHandle FTM_RENDER_CHARACTERS("Avatars"); -LLTrace::BlockTimerStatHandle FTM_RENDER_BUMP("Bump"); -LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS("Render Materials"); -LLTrace::BlockTimerStatHandle FTM_RENDER_FULLBRIGHT("Fullbright"); -LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW("Glow"); -LLTrace::BlockTimerStatHandle FTM_GEO_UPDATE("Geo Update"); -LLTrace::BlockTimerStatHandle FTM_POOLRENDER("RenderPool"); -LLTrace::BlockTimerStatHandle FTM_POOLS("Pools"); -LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)"); -LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLS("Pools (Deferred)"); -LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)"); -LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLS("Pools (Post)"); -LLTrace::BlockTimerStatHandle FTM_STATESORT("Sort Draw State"); -LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline"); -LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy"); -LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading"); - -LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD("HUD"); -LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D("3D"); -LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D("2D"); - -static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables"); - static LLStaticHashedString sTint("tint"); static LLStaticHashedString sAmbiance("ambiance"); static LLStaticHashedString sAlphaScale("alpha_scale"); @@ -2775,8 +2741,6 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& return res; } -static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); - // static bool LLPipeline::isWaterClip() { @@ -3128,10 +3092,8 @@ void LLPipeline::rebuildPriorityGroups() void LLPipeline::updateGeom(F32 max_dtime) { - LLTimer update_timer; - LLPointer drawablep; + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE); if (gCubeSnapshot) { return; @@ -7237,8 +7199,6 @@ void LLPipeline::bindScreenToTexture() } -static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); - void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex) { dst->bindTarget(); @@ -8818,15 +8778,15 @@ void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst) void LLPipeline::renderFinalize() { + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + LL_PROFILE_GPU_ZONE("renderFinalize"); + llassert(!gCubeSnapshot); LLVertexBuffer::unbind(); LLGLState::checkStates(); assertInitialized(); - LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); - LL_PROFILE_GPU_ZONE("renderFinalize"); - gGL.color4f(1, 1, 1, 1); LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -10333,17 +10293,6 @@ glm::mat4 look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) return glm::make_mat4(ret); } -static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_GEOM("Shadow Geom"); - -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_MASKED("Alpha Masked"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_BLEND("Alpha Blend"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass"); -static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked"); - void LLPipeline::renderShadow(const glm::mat4& view, const glm::mat4& proj, LLCamera& shadow_cam, LLCullResult& result, bool depth_clamp, bool do_cull) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER); @@ -10803,9 +10752,6 @@ LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i) return &mSpotShadow[i]; } -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); -static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render"); - // helper class for disabling occlusion culling for the current stack frame class LLDisableOcclusionCulling { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index f7cc8dd10c3..ad58b799018 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -68,31 +68,6 @@ bool LLRayAABB(const LLVector3 ¢er, const LLVector3 &size, const LLVector3& bool setup_hud_matrices(); // use whole screen to render hud bool setup_hud_matrices(const LLRect& screen_region); // specify portion of screen (in pixels) to render hud attachments from (for picking) - -extern LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_TREES; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_WATER; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_WL_SKY; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_CHARACTERS; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_BUMP; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_FULLBRIGHT; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW; -extern LLTrace::BlockTimerStatHandle FTM_STATESORT; -extern LLTrace::BlockTimerStatHandle FTM_PIPELINE; -extern LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY; - -extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D; -extern LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D; - class LLPipeline { public: diff --git a/indra/newview/rlveffects.cpp b/indra/newview/rlveffects.cpp index 90896f5b20f..63be4561de2 100644 --- a/indra/newview/rlveffects.cpp +++ b/indra/newview/rlveffects.cpp @@ -374,11 +374,9 @@ void RlvSphereEffect::renderPass(LLGLSLShader* pShader, const LLShaderEffectPara } } -LLTrace::BlockTimerStatHandle FTM_RLV_EFFECT_SPHERE("Post-process (RLVa sphere)"); - void RlvSphereEffect::run(const LLVisualEffectParams* pParams) { - LL_RECORD_BLOCK_TIME(FTM_RLV_EFFECT_SPHERE); + LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; if (gRlvSphereProgram.isComplete()) { LLGLDepthTest depth(GL_FALSE, GL_FALSE); diff --git a/indra/newview/rlvhelper.h b/indra/newview/rlvhelper.h index 316f50190fd..920dd50ed91 100644 --- a/indra/newview/rlvhelper.h +++ b/indra/newview/rlvhelper.h @@ -98,14 +98,14 @@ class RlvBehaviourInfo // RlvBehaviourDictionary and related classes // -class RlvBehaviourDictionary : public LLSimpleton +class RlvBehaviourDictionary : public LLSingleton { friend class RlvFloaterBehaviours; -public: - RlvBehaviourDictionary(); + LLSINGLETON(RlvBehaviourDictionary); +protected: ~RlvBehaviourDictionary(); - +public: void addEntry(const RlvBehaviourInfo* pBhvrEntry); void addModifier(ERlvBehaviour eBhvr, ERlvBehaviourModifier eModifier, RlvBehaviourModifier* pModifierEntry); void addModifier(const RlvBehaviourInfo* pBhvrEntry, ERlvBehaviourModifier eModifier, RlvBehaviourModifier* pModifierEntry); diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml index 3bdcb759a2f..f375a9f9704 100644 --- a/indra/newview/skins/default/xui/da/menu_viewer.xml +++ b/indra/newview/skins/default/xui/da/menu_viewer.xml @@ -204,7 +204,6 @@ - diff --git a/indra/newview/skins/default/xui/de/floater_fast_timers.xml b/indra/newview/skins/default/xui/de/floater_fast_timers.xml deleted file mode 100644 index 4b5383c64d4..00000000000 --- a/indra/newview/skins/default/xui/de/floater_fast_timers.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - Pause - - - Rennen - - - - - - - - - - - - -