diff options
Diffstat (limited to 'indra')
89 files changed, 1542 insertions, 2824 deletions
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index a6f69a09e9..543075db5b 100644..100755 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -201,6 +201,15 @@ FUNCTION(LL_ADD_INTEGRATION_TEST endif(TEST_DEBUG) ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files}) SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}") + if (WINDOWS) + set_target_properties(INTEGRATION_TEST_${testname} + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" + LINK_FLAGS_RELEASE "" + ) + endif(WINDOWS) + if(STANDALONE) SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}") endif(STANDALONE) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 17e211cb99..d4694ad37a 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -24,7 +24,7 @@ endif (LINUX) add_definitions(${TCMALLOC_FLAG}) -set(LLCOMMON_LINK_SHARED ON CACHE BOOL "Build the llcommon target as a shared library.") +set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a shared library.") if(LLCOMMON_LINK_SHARED) add_definitions(-DLL_COMMON_LINK_SHARED=1) endif(LLCOMMON_LINK_SHARED) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 346ea360f1..87fffec0c3 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -53,7 +53,7 @@ set(llcommon_SOURCE_FILES lleventfilter.cpp llevents.cpp lleventtimer.cpp - llfasttimer_class.cpp + llfasttimer.cpp llfile.cpp llfindlocale.cpp llfixedbuffer.cpp @@ -166,7 +166,6 @@ set(llcommon_HEADER_FILES lleventemitter.h llextendedstatus.h llfasttimer.h - llfasttimer_class.h llfile.h llfindlocale.h llfixedbuffer.h diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer.cpp index 463f558c2c..6970c29092 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -1,5 +1,5 @@ /** - * @file llfasttimer_class.cpp + * @file llfasttimer.cpp * @brief Implementation of the fast timer. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ @@ -64,19 +64,12 @@ BOOL LLFastTimer::sMetricLog = FALSE; LLMutex* LLFastTimer::sLogLock = NULL; std::queue<LLSD> LLFastTimer::sLogQueue; -#define USE_RDTSC 0 - #if LL_LINUX || LL_SOLARIS U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution #else U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution #endif -std::vector<LLFastTimer::FrameState>* LLFastTimer::sTimerInfos = NULL; -U64 LLFastTimer::sTimerCycles = 0; -U32 LLFastTimer::sTimerCalls = 0; - - // FIXME: move these declarations to the relevant modules // helper functions @@ -109,52 +102,35 @@ static timer_tree_dfs_iterator_t end_timer_tree() return timer_tree_dfs_iterator_t(); } - - // factory class that creates NamedTimers via static DeclareTimer objects class NamedTimerFactory : public LLSingleton<NamedTimerFactory> { public: NamedTimerFactory() - : mActiveTimerRoot(NULL), - mTimerRoot(NULL), - mAppTimer(NULL), - mRootFrameState(NULL) + : mTimerRoot(NULL) {} /*virtual */ void initSingleton() { mTimerRoot = new LLFastTimer::NamedTimer("root"); - - mActiveTimerRoot = new LLFastTimer::NamedTimer("Frame"); - mActiveTimerRoot->setCollapsed(false); - - mRootFrameState = new LLFastTimer::FrameState(mActiveTimerRoot); - mRootFrameState->mParent = &mTimerRoot->getFrameState(); - mActiveTimerRoot->setParent(mTimerRoot); - - mAppTimer = new LLFastTimer(mRootFrameState); + mRootFrameState.setNamedTimer(mTimerRoot); + mTimerRoot->setFrameState(&mRootFrameState); + mTimerRoot->mParent = mTimerRoot; + mTimerRoot->setCollapsed(false); + mRootFrameState.mParent = &mRootFrameState; } ~NamedTimerFactory() { std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer()); - delete mAppTimer; - delete mActiveTimerRoot; delete mTimerRoot; - delete mRootFrameState; } - LLFastTimer::NamedTimer& createNamedTimer(const std::string& name) + LLFastTimer::NamedTimer& createNamedTimer(const std::string& name, LLFastTimer::FrameState* state) { - timer_map_t::iterator found_it = mTimers.find(name); - if (found_it != mTimers.end()) - { - return *found_it->second; - } - LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name); + timer->setFrameState(state); timer->setParent(mTimerRoot); mTimers.insert(std::make_pair(name, timer)); @@ -171,12 +147,9 @@ public: return NULL; } - LLFastTimer::NamedTimer* getActiveRootTimer() { return mActiveTimerRoot; } LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; } - const LLFastTimer* getAppTimer() { return mAppTimer; } - LLFastTimer::FrameState& getRootFrameState() { return *mRootFrameState; } - typedef std::map<std::string, LLFastTimer::NamedTimer*> timer_map_t; + typedef std::multimap<std::string, LLFastTimer::NamedTimer*> timer_map_t; timer_map_t::iterator beginTimers() { return mTimers.begin(); } timer_map_t::iterator endTimers() { return mTimers.end(); } S32 timerCount() { return mTimers.size(); } @@ -184,55 +157,19 @@ public: private: timer_map_t mTimers; - LLFastTimer::NamedTimer* mActiveTimerRoot; LLFastTimer::NamedTimer* mTimerRoot; - LLFastTimer* mAppTimer; - LLFastTimer::FrameState* mRootFrameState; + LLFastTimer::FrameState mRootFrameState; }; -void update_cached_pointers_if_changed() -{ - // detect when elements have moved and update cached pointers - static LLFastTimer::FrameState* sFirstTimerAddress = NULL; - if (&*(LLFastTimer::getFrameStateList().begin()) != sFirstTimerAddress) - { - LLFastTimer::DeclareTimer::updateCachedPointers(); - } - sFirstTimerAddress = &*(LLFastTimer::getFrameStateList().begin()); -} - LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open ) -: mTimer(NamedTimerFactory::instance().createNamedTimer(name)) +: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState)) { mTimer.setCollapsed(!open); - mFrameState = &mTimer.getFrameState(); - update_cached_pointers_if_changed(); } LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name) -: mTimer(NamedTimerFactory::instance().createNamedTimer(name)) -{ - mFrameState = &mTimer.getFrameState(); - update_cached_pointers_if_changed(); -} - -// static -void LLFastTimer::DeclareTimer::updateCachedPointers() +: mTimer(NamedTimerFactory::instance().createNamedTimer(name, &mFrameState)) { - // propagate frame state pointers to timer declarations - for (instance_iter it = beginInstances(); it != endInstances(); ++it) - { - // update cached pointer - it->mFrameState = &it->mTimer.getFrameState(); - } - - // also update frame states of timers on stack - LLFastTimer* cur_timerp = LLFastTimer::sCurTimerData.mCurTimer; - while(cur_timerp->mLastTimerData.mCurTimer != cur_timerp) - { - cur_timerp->mFrameState = &cur_timerp->mFrameState->mTimer->getFrameState(); - cur_timerp = cur_timerp->mLastTimerData.mCurTimer; - } } //static @@ -244,7 +181,7 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer #else // windows or x86-mac or x86-linux or x86-solaris U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer { -#if USE_RDTSC || !LL_WINDOWS +#if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS //getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0); @@ -265,14 +202,13 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer } #endif -LLFastTimer::FrameState::FrameState(LLFastTimer::NamedTimer* timerp) +LLFastTimer::FrameState::FrameState() : mActiveCount(0), mCalls(0), mSelfTimeCounter(0), mParent(NULL), mLastCaller(NULL), - mMoveUpTree(false), - mTimer(timerp) + mMoveUpTree(false) {} @@ -283,12 +219,9 @@ LLFastTimer::NamedTimer::NamedTimer(const std::string& name) mTotalTimeCounter(0), mCountAverage(0), mCallAverage(0), - mNeedsSorting(false) + mNeedsSorting(false), + mFrameState(NULL) { - info_list_t& frame_state_list = getFrameStateList(); - mFrameStateIndex = frame_state_list.size(); - getFrameStateList().push_back(FrameState(this)); - mCountHistory = new U32[HISTORY_NUM]; memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM); mCallHistory = new U32[HISTORY_NUM]; @@ -355,6 +288,7 @@ S32 LLFastTimer::NamedTimer::getDepth() while(timerp) { depth++; + if (timerp->getParent() == timerp) break; timerp = timerp->mParent; } return depth; @@ -369,15 +303,6 @@ void LLFastTimer::NamedTimer::processTimes() accumulateTimings(); } -// sort timer info structs by depth first traversal order -struct SortTimersDFS -{ - bool operator()(const LLFastTimer::FrameState& i1, const LLFastTimer::FrameState& i2) - { - return i1.mTimer->getFrameStateIndex() < i2.mTimer->getFrameStateIndex(); - } -}; - // sort child timers by name struct SortTimerByName { @@ -425,8 +350,8 @@ void LLFastTimer::NamedTimer::buildHierarchy() { // since ancestors have already been visited, reparenting won't affect tree traversal //step up tree, bringing our descendants with us - //llinfos << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << - // " to child of " << timerp->getParent()->getParent()->getName() << llendl; + LL_DEBUGS("FastTimers") << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() << + " to child of " << timerp->getParent()->getParent()->getName() << LL_ENDL; timerp->setParent(timerp->getParent()->getParent()); timerp->getFrameState().mMoveUpTree = false; @@ -458,7 +383,7 @@ void LLFastTimer::NamedTimer::accumulateTimings() LLFastTimer* cur_timer = sCurTimerData.mCurTimer; // root defined by parent pointing to self CurTimerData* cur_data = &sCurTimerData; - while(cur_timer->mLastTimerData.mCurTimer != cur_timer) + while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer) { U32 cumulative_time_delta = cur_time - cur_timer->mStartTime; U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime; @@ -473,7 +398,7 @@ void LLFastTimer::NamedTimer::accumulateTimings() } // traverse tree in DFS post order, or bottom up - for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getActiveRootTimer()); + for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer()); it != end_timer_tree_bottom_up(); ++it) { @@ -507,12 +432,12 @@ void LLFastTimer::NamedTimer::resetFrame() static S32 call_count = 0; if (call_count % 100 == 0) { - llinfos << "countsPerSecond (32 bit): " << countsPerSecond() << llendl; - llinfos << "get_clock_count (64 bit): " << get_clock_count() << llendl; - llinfos << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << llendl; - llinfos << "getCPUClockCount32() " << getCPUClockCount32() << llendl; - llinfos << "getCPUClockCount64() " << getCPUClockCount64() << llendl; - llinfos << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << llendl; + LL_DEBUGS("FastTimers") << "countsPerSecond (32 bit): " << countsPerSecond() << LL_ENDL; + LL_DEBUGS("FastTimers") << "get_clock_count (64 bit): " << get_clock_count() << llendl; + LL_DEBUGS("FastTimers") << "LLProcessorInfo().getCPUFrequency() " << LLProcessorInfo().getCPUFrequency() << LL_ENDL; + LL_DEBUGS("FastTimers") << "getCPUClockCount32() " << getCPUClockCount32() << LL_ENDL; + LL_DEBUGS("FastTimers") << "getCPUClockCount64() " << getCPUClockCount64() << LL_ENDL; + LL_DEBUGS("FastTimers") << "elapsed sec " << ((F64)getCPUClockCount64())/((F64)LLProcessorInfo().getCPUFrequency()*1000000.0) << LL_ENDL; } call_count++; @@ -544,48 +469,22 @@ void LLFastTimer::NamedTimer::resetFrame() } } - - // tag timers by position in depth first traversal of tree - S32 index = 0; - for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer()); - it != end_timer_tree(); - ++it) - { - NamedTimer* timerp = (*it); - - timerp->mFrameStateIndex = index; - index++; - - llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size()); - } - - // sort timers by DFS traversal order to improve cache coherency - std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS()); - - // update pointers into framestatelist now that we've sorted it - DeclareTimer::updateCachedPointers(); - // reset for next frame + for (instance_iter it = beginInstances(); it != endInstances(); ++it) { - for (instance_iter it = beginInstances(); it != endInstances(); ++it) - { - NamedTimer& timer = *it; + NamedTimer& timer = *it; - FrameState& info = timer.getFrameState(); - info.mSelfTimeCounter = 0; - info.mCalls = 0; - info.mLastCaller = NULL; - info.mMoveUpTree = false; - // update parent pointer in timer state struct - if (timer.mParent) - { - info.mParent = &timer.mParent->getFrameState(); - } + FrameState& info = timer.getFrameState(); + info.mSelfTimeCounter = 0; + info.mCalls = 0; + info.mLastCaller = NULL; + info.mMoveUpTree = false; + // update parent pointer in timer state struct + if (timer.mParent) + { + info.mParent = &timer.mParent->getFrameState(); } } - - //sTimerCycles = 0; - //sTimerCalls = 0; } //static @@ -600,7 +499,7 @@ void LLFastTimer::NamedTimer::reset() // root defined by parent pointing to self CurTimerData* cur_data = &sCurTimerData; LLFastTimer* cur_timer = cur_data->mCurTimer; - while(cur_timer->mLastTimerData.mCurTimer != cur_timer) + while(cur_timer && cur_timer->mLastTimerData.mCurTimer != cur_timer) { cur_timer->mStartTime = cur_time; cur_data->mChildTime = 0; @@ -630,17 +529,6 @@ void LLFastTimer::NamedTimer::reset() sCurFrameIndex = 0; } -//static -LLFastTimer::info_list_t& LLFastTimer::getFrameStateList() -{ - if (!sTimerInfos) - { - sTimerInfos = new info_list_t(); - } - return *sTimerInfos; -} - - U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const { S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM; @@ -655,18 +543,7 @@ U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const { - llassert_always(mFrameStateIndex >= 0); - if (this == NamedTimerFactory::instance().getActiveRootTimer()) - { - return NamedTimerFactory::instance().getRootFrameState(); - } - return getFrameStateList()[mFrameStateIndex]; -} - -// static -LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer() -{ - return *NamedTimerFactory::instance().getActiveRootTimer(); + return *mFrameState; } std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren() @@ -777,145 +654,3 @@ LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state) } -////////////////////////////////////////////////////////////////////////////// -// -// Important note: These implementations must be FAST! -// - - -#if LL_WINDOWS -// -// Windows implementation of CPU clock -// - -// -// NOTE: put back in when we aren't using platform sdk anymore -// -// because MS has different signatures for these functions in winnt.h -// need to rename them to avoid conflicts -//#define _interlockedbittestandset _renamed_interlockedbittestandset -//#define _interlockedbittestandreset _renamed_interlockedbittestandreset -//#include <intrin.h> -//#undef _interlockedbittestandset -//#undef _interlockedbittestandreset - -//inline U32 LLFastTimer::getCPUClockCount32() -//{ -// U64 time_stamp = __rdtsc(); -// return (U32)(time_stamp >> 8); -//} -// -//// return full timer value, *not* shifted by 8 bits -//inline U64 LLFastTimer::getCPUClockCount64() -//{ -// return __rdtsc(); -//} - -// shift off lower 8 bits for lower resolution but longer term timing -// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing -#if USE_RDTSC -U32 LLFastTimer::getCPUClockCount32() -{ - U32 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - shr eax,8 - shl edx,24 - or eax, edx - mov dword ptr [ret_val], eax - } - return ret_val; -} - -// return full timer value, *not* shifted by 8 bits -U64 LLFastTimer::getCPUClockCount64() -{ - U64 ret_val; - __asm - { - _emit 0x0f - _emit 0x31 - mov eax,eax - mov edx,edx - mov dword ptr [ret_val+4], edx - mov dword ptr [ret_val], eax - } - return ret_val; -} - -std::string LLFastTimer::sClockType = "rdtsc"; - -#else -//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp -// These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures. -U32 LLFastTimer::getCPUClockCount32() -{ - return (U32)(get_clock_count()>>8); -} - -U64 LLFastTimer::getCPUClockCount64() -{ - return get_clock_count(); -} - -std::string LLFastTimer::sClockType = "QueryPerformanceCounter"; -#endif - -#endif - - -#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) -// -// Linux and Solaris implementation of CPU clock - non-x86. -// This is accurate but SLOW! Only use out of desperation. -// -// Try to use the MONOTONIC clock if available, this is a constant time counter -// with nanosecond resolution (but not necessarily accuracy) and attempts are -// made to synchronize this value between cores at kernel start. It should not -// be affected by CPU frequency. If not available use the REALTIME clock, but -// this may be affected by NTP adjustments or other user activity affecting -// the system time. -U64 LLFastTimer::getCPUClockCount64() -{ - struct timespec tp; - -#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time? - if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME -#endif - clock_gettime(CLOCK_REALTIME,&tp); - - return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec; -} - -U32 LLFastTimer::getCPUClockCount32() -{ - return (U32)(LLFastTimer::getCPUClockCount64() >> 8); -} - -std::string LLFastTimer::sClockType = "clock_gettime"; - -#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) - - -#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) -// -// Mac+Linux+Solaris FAST x86 implementation of CPU clock -U32 LLFastTimer::getCPUClockCount32() -{ - U64 x; - __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return (U32)(x >> 8); -} - -U64 LLFastTimer::getCPUClockCount64() -{ - U64 x; - __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); - return x; -} - -std::string LLFastTimer::sClockType = "rdtsc"; -#endif - diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index 2b25f2fabb..e42e549df5 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -1,6 +1,6 @@ /** * @file llfasttimer.h - * @brief Inline implementations of fast timers. + * @brief Declaration of a fast timer. * * $LicenseInfo:firstyear=2004&license=viewerlgpl$ * Second Life Viewer Source Code @@ -27,9 +27,363 @@ #ifndef LL_FASTTIMER_H #define LL_FASTTIMER_H -// Implementation of getCPUClockCount32() and getCPUClockCount64 are now in llfastertimer_class.cpp. +#include "llinstancetracker.h" -// pull in the actual class definition -#include "llfasttimer_class.h" +#define FAST_TIMER_ON 1 +#define DEBUG_FAST_TIMER_THREADS 1 + +class LLMutex; + +#include <queue> +#include "llsd.h" + +#define LL_FASTTIMER_USE_RDTSC 1 + + +LL_COMMON_API void assert_main_thread(); + +class LL_COMMON_API LLFastTimer +{ +public: + class NamedTimer; + + struct LL_COMMON_API FrameState + { + FrameState(); + void setNamedTimer(NamedTimer* timerp) { mTimer = timerp; } + + U32 mSelfTimeCounter; + U32 mCalls; + FrameState* mParent; // info for caller timer + FrameState* mLastCaller; // used to bootstrap tree construction + NamedTimer* mTimer; + U16 mActiveCount; // number of timers with this ID active on stack + bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame + }; + + // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances + class LL_COMMON_API NamedTimer + : public LLInstanceTracker<NamedTimer> + { + friend class DeclareTimer; + public: + ~NamedTimer(); + + enum { HISTORY_NUM = 300 }; + + const std::string& getName() const { return mName; } + NamedTimer* getParent() const { return mParent; } + void setParent(NamedTimer* parent); + S32 getDepth(); + std::string getToolTip(S32 history_index = -1); + + typedef std::vector<NamedTimer*>::const_iterator child_const_iter; + child_const_iter beginChildren(); + child_const_iter endChildren(); + std::vector<NamedTimer*>& getChildren(); + + void setCollapsed(bool collapsed) { mCollapsed = collapsed; } + bool getCollapsed() const { return mCollapsed; } + + U32 getCountAverage() const { return mCountAverage; } + U32 getCallAverage() const { return mCallAverage; } + + U32 getHistoricalCount(S32 history_index = 0) const; + U32 getHistoricalCalls(S32 history_index = 0) const; + + void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); } + FrameState& getFrameState() const; + + private: + friend class LLFastTimer; + friend class NamedTimerFactory; + + // + // methods + // + NamedTimer(const std::string& name); + // recursive call to gather total time from children + static void accumulateTimings(); + + // updates cumulative times and hierarchy, + // can be called multiple times in a frame, at any point + static void processTimes(); + + static void buildHierarchy(); + static void resetFrame(); + static void reset(); + + // + // members + // + FrameState* mFrameState; + + std::string mName; + + U32 mTotalTimeCounter; + + U32 mCountAverage; + U32 mCallAverage; + + U32* mCountHistory; + U32* mCallHistory; + + // tree structure + NamedTimer* mParent; // NamedTimer of caller(parent) + std::vector<NamedTimer*> mChildren; + bool mCollapsed; // don't show children + bool mNeedsSorting; // sort children whenever child added + }; + + // used to statically declare a new named timer + class LL_COMMON_API DeclareTimer + : public LLInstanceTracker<DeclareTimer> + { + friend class LLFastTimer; + public: + DeclareTimer(const std::string& name, bool open); + DeclareTimer(const std::string& name); + + NamedTimer& getNamedTimer() { return mTimer; } + + private: + FrameState mFrameState; + NamedTimer& mTimer; + }; + +public: + LLFastTimer(LLFastTimer::FrameState* state); + + LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) + : mFrameState(&timer.mFrameState) + { +#if FAST_TIMER_ON + LLFastTimer::FrameState* frame_state = mFrameState; + mStartTime = getCPUClockCount32(); + + frame_state->mActiveCount++; + frame_state->mCalls++; + // keep current parent as long as it is active when we are + frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); + + LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; + mLastTimerData = *cur_timer_data; + cur_timer_data->mCurTimer = this; + cur_timer_data->mFrameState = frame_state; + cur_timer_data->mChildTime = 0; +#endif +#if DEBUG_FAST_TIMER_THREADS +#if !LL_RELEASE + assert_main_thread(); +#endif +#endif + } + + LL_FORCE_INLINE ~LLFastTimer() + { +#if FAST_TIMER_ON + LLFastTimer::FrameState* frame_state = mFrameState; + U32 total_time = getCPUClockCount32() - mStartTime; + + frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; + frame_state->mActiveCount--; + + // store last caller to bootstrap tree creation + // do this in the destructor in case of recursion to get topmost caller + frame_state->mLastCaller = mLastTimerData.mFrameState; + + // we are only tracking self time, so subtract our total time delta from parents + mLastTimerData.mChildTime += total_time; + + LLFastTimer::sCurTimerData = mLastTimerData; +#endif + } + +public: + static LLMutex* sLogLock; + static std::queue<LLSD> sLogQueue; + static BOOL sLog; + static BOOL sMetricLog; + static std::string sLogName; + static bool sPauseHistory; + static bool sResetHistory; + + // call this once a frame to reset timers + static void nextFrame(); + + // dumps current cumulative frame stats to log + // call nextFrame() to reset timers + static void dumpCurTimes(); + + // call this to reset timer hierarchy, averages, etc. + static void reset(); + + static U64 countsPerSecond(); + static S32 getLastFrameIndex() { return sLastFrameIndex; } + static S32 getCurFrameIndex() { return sCurFrameIndex; } + + static void writeLog(std::ostream& os); + static const NamedTimer* getTimerByName(const std::string& name); + + struct CurTimerData + { + LLFastTimer* mCurTimer; + FrameState* mFrameState; + U32 mChildTime; + }; + static CurTimerData sCurTimerData; + +private: + + + ////////////////////////////////////////////////////////////////////////////// + // + // Important note: These implementations must be FAST! + // + + +#if LL_WINDOWS + // + // Windows implementation of CPU clock + // + + // + // NOTE: put back in when we aren't using platform sdk anymore + // + // because MS has different signatures for these functions in winnt.h + // need to rename them to avoid conflicts + //#define _interlockedbittestandset _renamed_interlockedbittestandset + //#define _interlockedbittestandreset _renamed_interlockedbittestandreset + //#include <intrin.h> + //#undef _interlockedbittestandset + //#undef _interlockedbittestandreset + + //inline U32 LLFastTimer::getCPUClockCount32() + //{ + // U64 time_stamp = __rdtsc(); + // return (U32)(time_stamp >> 8); + //} + // + //// return full timer value, *not* shifted by 8 bits + //inline U64 LLFastTimer::getCPUClockCount64() + //{ + // return __rdtsc(); + //} + + // shift off lower 8 bits for lower resolution but longer term timing + // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing +#if LL_FASTTIMER_USE_RDTSC + static U32 getCPUClockCount32() + { + U32 ret_val; + __asm + { + _emit 0x0f + _emit 0x31 + shr eax,8 + shl edx,24 + or eax, edx + mov dword ptr [ret_val], eax + } + return ret_val; + } + + // return full timer value, *not* shifted by 8 bits + static U64 getCPUClockCount64() + { + U64 ret_val; + __asm + { + _emit 0x0f + _emit 0x31 + mov eax,eax + mov edx,edx + mov dword ptr [ret_val+4], edx + mov dword ptr [ret_val], eax + } + return ret_val; + } + +#else + //LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp + // These use QueryPerformanceCounter, which is arguably fine and also works on AMD architectures. + static U32 getCPUClockCount32() + { + return (U32)(get_clock_count()>>8); + } + + static U64 getCPUClockCount64() + { + return get_clock_count(); + } + +#endif + +#endif + + +#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) + // + // Linux and Solaris implementation of CPU clock - non-x86. + // This is accurate but SLOW! Only use out of desperation. + // + // Try to use the MONOTONIC clock if available, this is a constant time counter + // with nanosecond resolution (but not necessarily accuracy) and attempts are + // made to synchronize this value between cores at kernel start. It should not + // be affected by CPU frequency. If not available use the REALTIME clock, but + // this may be affected by NTP adjustments or other user activity affecting + // the system time. + static U64 getCPUClockCount64() + { + struct timespec tp; + +#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time? + if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME +#endif + clock_gettime(CLOCK_REALTIME,&tp); + + return (tp.tv_sec*sClockResolution)+tp.tv_nsec; + } + + static U32 getCPUClockCount32() + { + return (U32)(getCPUClockCount64() >> 8); + } + +#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__)) + + +#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__)) + // + // Mac+Linux+Solaris FAST x86 implementation of CPU clock + static U32 getCPUClockCount32() + { + U64 x; + __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); + return (U32)(x >> 8); + } + + static U64 getCPUClockCount64() + { + U64 x; + __asm__ volatile (".byte 0x0f, 0x31": "=A"(x)); + return x; + } + +#endif + + static U64 sClockResolution; + + static S32 sCurFrameIndex; + static S32 sLastFrameIndex; + static U64 sLastFrameTime; + + U32 mStartTime; + LLFastTimer::FrameState* mFrameState; + LLFastTimer::CurTimerData mLastTimerData; + +}; + +typedef class LLFastTimer LLFastTimer; #endif // LL_LLFASTTIMER_H diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h deleted file mode 100644 index f481e968a6..0000000000 --- a/indra/llcommon/llfasttimer_class.h +++ /dev/null @@ -1,276 +0,0 @@ -/** - * @file llfasttimer_class.h - * @brief Declaration of a fast timer. - * - * $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_FASTTIMER_CLASS_H -#define LL_FASTTIMER_CLASS_H - -#include "llinstancetracker.h" - -#define FAST_TIMER_ON 1 -#define TIME_FAST_TIMERS 0 -#define DEBUG_FAST_TIMER_THREADS 1 - -class LLMutex; - -#include <queue> -#include "llsd.h" - -LL_COMMON_API void assert_main_thread(); - -class LL_COMMON_API LLFastTimer -{ -public: - class NamedTimer; - - struct LL_COMMON_API FrameState - { - FrameState(NamedTimer* timerp); - - U32 mSelfTimeCounter; - U32 mCalls; - FrameState* mParent; // info for caller timer - FrameState* mLastCaller; // used to bootstrap tree construction - NamedTimer* mTimer; - U16 mActiveCount; // number of timers with this ID active on stack - bool mMoveUpTree; // needs to be moved up the tree of timers at the end of frame - }; - - // stores a "named" timer instance to be reused via multiple LLFastTimer stack instances - class LL_COMMON_API NamedTimer - : public LLInstanceTracker<NamedTimer> - { - friend class DeclareTimer; - public: - ~NamedTimer(); - - enum { HISTORY_NUM = 300 }; - - const std::string& getName() const { return mName; } - NamedTimer* getParent() const { return mParent; } - void setParent(NamedTimer* parent); - S32 getDepth(); - std::string getToolTip(S32 history_index = -1); - - typedef std::vector<NamedTimer*>::const_iterator child_const_iter; - child_const_iter beginChildren(); - child_const_iter endChildren(); - std::vector<NamedTimer*>& getChildren(); - - void setCollapsed(bool collapsed) { mCollapsed = collapsed; } - bool getCollapsed() const { return mCollapsed; } - - U32 getCountAverage() const { return mCountAverage; } - U32 getCallAverage() const { return mCallAverage; } - - U32 getHistoricalCount(S32 history_index = 0) const; - U32 getHistoricalCalls(S32 history_index = 0) const; - - static NamedTimer& getRootNamedTimer(); - - S32 getFrameStateIndex() const { return mFrameStateIndex; } - - FrameState& getFrameState() const; - - private: - friend class LLFastTimer; - friend class NamedTimerFactory; - - // - // methods - // - NamedTimer(const std::string& name); - // recursive call to gather total time from children - static void accumulateTimings(); - - // updates cumulative times and hierarchy, - // can be called multiple times in a frame, at any point - static void processTimes(); - - static void buildHierarchy(); - static void resetFrame(); - static void reset(); - - // - // members - // - S32 mFrameStateIndex; - - std::string mName; - - U32 mTotalTimeCounter; - - U32 mCountAverage; - U32 mCallAverage; - - U32* mCountHistory; - U32* mCallHistory; - - // tree structure - NamedTimer* mParent; // NamedTimer of caller(parent) - std::vector<NamedTimer*> mChildren; - bool mCollapsed; // don't show children - bool mNeedsSorting; // sort children whenever child added - }; - - // used to statically declare a new named timer - class LL_COMMON_API DeclareTimer - : public LLInstanceTracker<DeclareTimer> - { - friend class LLFastTimer; - public: - DeclareTimer(const std::string& name, bool open); - DeclareTimer(const std::string& name); - - static void updateCachedPointers(); - - private: - NamedTimer& mTimer; - FrameState* mFrameState; - }; - -public: - LLFastTimer(LLFastTimer::FrameState* state); - - LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer) - : mFrameState(timer.mFrameState) - { -#if TIME_FAST_TIMERS - U64 timer_start = getCPUClockCount64(); -#endif -#if FAST_TIMER_ON - LLFastTimer::FrameState* frame_state = mFrameState; - mStartTime = getCPUClockCount32(); - - frame_state->mActiveCount++; - frame_state->mCalls++; - // keep current parent as long as it is active when we are - frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0); - - LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData; - mLastTimerData = *cur_timer_data; - cur_timer_data->mCurTimer = this; - cur_timer_data->mFrameState = frame_state; - cur_timer_data->mChildTime = 0; -#endif -#if TIME_FAST_TIMERS - U64 timer_end = getCPUClockCount64(); - sTimerCycles += timer_end - timer_start; -#endif -#if DEBUG_FAST_TIMER_THREADS -#if !LL_RELEASE - assert_main_thread(); -#endif -#endif - } - - LL_FORCE_INLINE ~LLFastTimer() - { -#if TIME_FAST_TIMERS - U64 timer_start = getCPUClockCount64(); -#endif -#if FAST_TIMER_ON - LLFastTimer::FrameState* frame_state = mFrameState; - U32 total_time = getCPUClockCount32() - mStartTime; - - frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime; - frame_state->mActiveCount--; - - // store last caller to bootstrap tree creation - // do this in the destructor in case of recursion to get topmost caller - frame_state->mLastCaller = mLastTimerData.mFrameState; - - // we are only tracking self time, so subtract our total time delta from parents - mLastTimerData.mChildTime += total_time; - - LLFastTimer::sCurTimerData = mLastTimerData; -#endif -#if TIME_FAST_TIMERS - U64 timer_end = getCPUClockCount64(); - sTimerCycles += timer_end - timer_start; - sTimerCalls++; -#endif - } - -public: - static LLMutex* sLogLock; - static std::queue<LLSD> sLogQueue; - static BOOL sLog; - static BOOL sMetricLog; - static std::string sLogName; - static bool sPauseHistory; - static bool sResetHistory; - static U64 sTimerCycles; - static U32 sTimerCalls; - - typedef std::vector<FrameState> info_list_t; - static info_list_t& getFrameStateList(); - - - // call this once a frame to reset timers - static void nextFrame(); - - // dumps current cumulative frame stats to log - // call nextFrame() to reset timers - static void dumpCurTimes(); - - // call this to reset timer hierarchy, averages, etc. - static void reset(); - - static U64 countsPerSecond(); - static S32 getLastFrameIndex() { return sLastFrameIndex; } - static S32 getCurFrameIndex() { return sCurFrameIndex; } - - static void writeLog(std::ostream& os); - static const NamedTimer* getTimerByName(const std::string& name); - - struct CurTimerData - { - LLFastTimer* mCurTimer; - FrameState* mFrameState; - U32 mChildTime; - }; - static CurTimerData sCurTimerData; - static std::string sClockType; - -private: - static U32 getCPUClockCount32(); - static U64 getCPUClockCount64(); - static U64 sClockResolution; - - static S32 sCurFrameIndex; - static S32 sLastFrameIndex; - static U64 sLastFrameTime; - static info_list_t* sTimerInfos; - - U32 mStartTime; - LLFastTimer::FrameState* mFrameState; - LLFastTimer::CurTimerData mLastTimerData; - -}; - -typedef class LLFastTimer LLFastTimer; - -#endif // LL_LLFASTTIMER_CLASS_H diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index 99983a19cb..9a6d1eff5c 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -35,7 +35,7 @@ #include <boost/shared_ptr.hpp> #include "llerror.h" -#include "lltypeinfolookup.h" +#include "llstl.h" namespace LLInitParam { @@ -212,14 +212,6 @@ namespace LLInitParam public: - struct CompareTypeID - { - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } - }; - typedef std::vector<std::pair<std::string, bool> > name_stack_t; typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t; typedef std::vector<std::string> possible_values_t; @@ -228,9 +220,9 @@ namespace LLInitParam typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&); typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t; - typedef LLTypeInfoLookup<parser_read_func_t> parser_read_func_map_t; - typedef LLTypeInfoLookup<parser_write_func_t> parser_write_func_map_t; - typedef LLTypeInfoLookup<parser_inspect_func_t> parser_inspect_func_map_t; + typedef std::map<const std::type_info*, parser_read_func_t> parser_read_func_map_t; + typedef std::map<const std::type_info*, parser_write_func_t> parser_write_func_map_t; + typedef std::map<const std::type_info*, parser_inspect_func_t> parser_inspect_func_map_t; Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map) : mParseSilently(false), diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h index 36d7f7a44c..853c427a13 100644 --- a/indra/llcommon/llregistry.h +++ b/indra/llcommon/llregistry.h @@ -31,30 +31,16 @@ #include <boost/type_traits.hpp> #include "llsingleton.h" -#include "lltypeinfolookup.h" +#include "llstl.h" template <typename T> -class LLRegistryDefaultComparator +struct LLRegistryDefaultComparator { - bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; } -}; - -template <typename KEY, typename VALUE> -struct LLRegistryMapSelector -{ - typedef std::map<KEY, VALUE> type; -}; - -template <typename VALUE> -struct LLRegistryMapSelector<std::type_info*, VALUE> -{ - typedef LLTypeInfoLookup<VALUE> type; -}; - -template <typename VALUE> -struct LLRegistryMapSelector<const std::type_info*, VALUE> -{ - typedef LLTypeInfoLookup<VALUE> type; + bool operator()(const T& lhs, const T& rhs) const + { + using std::less; + return less<T>()(lhs, rhs); + } }; template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> > @@ -72,7 +58,7 @@ public: { friend class LLRegistry<KEY, VALUE, COMPARATOR>; public: - typedef typename LLRegistryMapSelector<KEY, VALUE>::type registry_map_t; + typedef std::map<KEY, VALUE, COMPARATOR> registry_map_t; bool add(ref_const_key_t key, ref_const_value_t value) { diff --git a/indra/llcommon/llstat.cpp b/indra/llcommon/llstat.cpp index 057257057f..3678c8e1c1 100644 --- a/indra/llcommon/llstat.cpp +++ b/indra/llcommon/llstat.cpp @@ -37,849 +37,70 @@ // statics -S32 LLPerfBlock::sStatsFlags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS; // Control what is being recorded -LLPerfBlock::stat_map_t LLPerfBlock::sStatMap; // Map full path string to LLStatTime objects, tracks all active objects -std::string LLPerfBlock::sCurrentStatPath = ""; // Something like "/total_time/physics/physics step" -LLStat::stat_map_t LLStat::sStatList; - -//------------------------------------------------------------------------ -// Live config file to trigger stats logging -static const char STATS_CONFIG_FILE_NAME[] = "/dev/shm/simperf/simperf_proc_config.llsd"; -static const F32 STATS_CONFIG_REFRESH_RATE = 5.0; // seconds - -class LLStatsConfigFile : public LLLiveFile -{ -public: - LLStatsConfigFile() - : LLLiveFile(filename(), STATS_CONFIG_REFRESH_RATE), - mChanged(false), mStatsp(NULL) { } - - static std::string filename(); - -protected: - /* virtual */ bool loadFile(); - -public: - void init(LLPerfStats* statsp); - static LLStatsConfigFile& instance(); - // return the singleton stats config file - - bool mChanged; - -protected: - LLPerfStats* mStatsp; -}; - -std::string LLStatsConfigFile::filename() -{ - return STATS_CONFIG_FILE_NAME; -} - -void LLStatsConfigFile::init(LLPerfStats* statsp) -{ - mStatsp = statsp; -} - -LLStatsConfigFile& LLStatsConfigFile::instance() -{ - static LLStatsConfigFile the_file; - return the_file; -} - - -/* virtual */ -// Load and parse the stats configuration file -bool LLStatsConfigFile::loadFile() -{ - if (!mStatsp) - { - llwarns << "Tries to load performance configure file without initializing LPerfStats" << llendl; - return false; - } - mChanged = true; - - LLSD stats_config; - { - llifstream file(filename().c_str()); - if (file.is_open()) - { - LLSDSerialize::fromXML(stats_config, file); - if (stats_config.isUndefined()) - { - llinfos << "Performance statistics configuration file ill-formed, not recording statistics" << llendl; - mStatsp->setReportPerformanceDuration( 0.f ); - return false; - } - } - else - { // File went away, turn off stats if it was on - if ( mStatsp->frameStatsIsRunning() ) - { - llinfos << "Performance statistics configuration file deleted, not recording statistics" << llendl; - mStatsp->setReportPerformanceDuration( 0.f ); - } - return true; - } - } - - F32 duration = 0.f; - F32 interval = 0.f; - S32 flags = LLPerfBlock::LLSTATS_BASIC_STATS; - - const char * w = "duration"; - if (stats_config.has(w)) - { - duration = (F32)stats_config[w].asReal(); - } - w = "interval"; - if (stats_config.has(w)) - { - interval = (F32)stats_config[w].asReal(); - } - w = "flags"; - if (stats_config.has(w)) - { - flags = (S32)stats_config[w].asInteger(); - if (flags == LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS && - duration > 0) - { // No flags passed in, but have a duration, so reset to basic stats - flags = LLPerfBlock::LLSTATS_BASIC_STATS; - } - } - - mStatsp->setReportPerformanceDuration( duration, flags ); - mStatsp->setReportPerformanceInterval( interval ); - - if ( duration > 0 ) - { - if ( interval == 0.f ) - { - llinfos << "Recording performance stats every frame for " << duration << " sec" << llendl; - } - else - { - llinfos << "Recording performance stats every " << interval << " seconds for " << duration << " seconds" << llendl; - } - } - else - { - llinfos << "Performance stats recording turned off" << llendl; - } - return true; -} - - //------------------------------------------------------------------------ - -LLPerfStats::LLPerfStats(const std::string& process_name, S32 process_pid) : - mFrameStatsFileFailure(FALSE), - mSkipFirstFrameStats(FALSE), - mProcessName(process_name), - mProcessPID(process_pid), - mReportPerformanceStatInterval(1.f), - mReportPerformanceStatEnd(0.0) -{ } - -LLPerfStats::~LLPerfStats() -{ - LLPerfBlock::clearDynamicStats(); - mFrameStatsFile.close(); -} - -void LLPerfStats::init() -{ - // Initialize the stats config file instance. - (void) LLStatsConfigFile::instance().init(this); - (void) LLStatsConfigFile::instance().checkAndReload(); -} - -// Open file for statistics -void LLPerfStats::openPerfStatsFile() -{ - if ( !mFrameStatsFile - && !mFrameStatsFileFailure ) - { - std::string stats_file = llformat("/dev/shm/simperf/%s_proc.%d.llsd", mProcessName.c_str(), mProcessPID); - mFrameStatsFile.close(); - mFrameStatsFile.clear(); - mFrameStatsFile.open(stats_file, llofstream::out); - if ( mFrameStatsFile.fail() ) - { - llinfos << "Error opening statistics log file " << stats_file << llendl; - mFrameStatsFileFailure = TRUE; - } - else - { - LLSD process_info = LLSD::emptyMap(); - process_info["name"] = mProcessName; - process_info["pid"] = (LLSD::Integer) mProcessPID; - process_info["stat_rate"] = (LLSD::Integer) mReportPerformanceStatInterval; - // Add process-specific info. - addProcessHeaderInfo(process_info); - - mFrameStatsFile << LLSDNotationStreamer(process_info) << std::endl; - } - } -} - -// Dump out performance metrics over some time interval -void LLPerfStats::dumpIntervalPerformanceStats() -{ - // Ensure output file is OK - openPerfStatsFile(); - - if ( mFrameStatsFile ) - { - LLSD stats = LLSD::emptyMap(); - - LLStatAccum::TimeScale scale; - if ( getReportPerformanceInterval() == 0.f ) - { - scale = LLStatAccum::SCALE_PER_FRAME; - } - else if ( getReportPerformanceInterval() < 0.5f ) - { - scale = LLStatAccum::SCALE_100MS; - } - else - { - scale = LLStatAccum::SCALE_SECOND; - } - - // Write LLSD into log - stats["utc_time"] = (LLSD::String) LLError::utcTime(); - stats["timestamp"] = U64_to_str((totalTime() / 1000) + (gUTCOffset * 1000)); // milliseconds since epoch - stats["frame_number"] = (LLSD::Integer) LLFrameTimer::getFrameCount(); - - // Add process-specific frame info. - addProcessFrameInfo(stats, scale); - LLPerfBlock::addStatsToLLSDandReset( stats, scale ); - - mFrameStatsFile << LLSDNotationStreamer(stats) << std::endl; - } -} - -// Set length of performance stat recording. -// If turning stats on, caller must provide flags -void LLPerfStats::setReportPerformanceDuration( F32 seconds, S32 flags /* = LLSTATS_NO_OPTIONAL_STATS */ ) -{ - if ( seconds <= 0.f ) - { - mReportPerformanceStatEnd = 0.0; - LLPerfBlock::setStatsFlags(LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS); // Make sure all recording is off - mFrameStatsFile.close(); - LLPerfBlock::clearDynamicStats(); - } - else - { - mReportPerformanceStatEnd = LLFrameTimer::getElapsedSeconds() + ((F64) seconds); - // Clear failure flag to try and create the log file once - mFrameStatsFileFailure = FALSE; - mSkipFirstFrameStats = TRUE; // Skip the first report (at the end of this frame) - LLPerfBlock::setStatsFlags(flags); - } -} - -void LLPerfStats::updatePerFrameStats() -{ - (void) LLStatsConfigFile::instance().checkAndReload(); - static LLFrameTimer performance_stats_timer; - if ( frameStatsIsRunning() ) - { - if ( mReportPerformanceStatInterval == 0 ) - { // Record info every frame - if ( mSkipFirstFrameStats ) - { // Skip the first time - was started this frame - mSkipFirstFrameStats = FALSE; - } - else - { - dumpIntervalPerformanceStats(); - } - } - else - { - performance_stats_timer.setTimerExpirySec( getReportPerformanceInterval() ); - if (performance_stats_timer.checkExpirationAndReset( mReportPerformanceStatInterval )) - { - dumpIntervalPerformanceStats(); - } - } - - if ( LLFrameTimer::getElapsedSeconds() > mReportPerformanceStatEnd ) - { // Reached end of time, clear it to stop reporting - setReportPerformanceDuration(0.f); // Don't set mReportPerformanceStatEnd directly - llinfos << "Recording performance stats completed" << llendl; - } - } -} - - -//------------------------------------------------------------------------ - -U64 LLStatAccum::sScaleTimes[NUM_SCALES] = -{ - USEC_PER_SEC / 10, // 100 millisec - USEC_PER_SEC * 1, // seconds - USEC_PER_SEC * 60, // minutes -#if ENABLE_LONG_TIME_STATS - // enable these when more time scales are desired - USEC_PER_SEC * 60*60, // hours - USEC_PER_SEC * 24*60*60, // days - USEC_PER_SEC * 7*24*60*60, // weeks -#endif -}; - - - -LLStatAccum::LLStatAccum(bool useFrameTimer) - : mUseFrameTimer(useFrameTimer), - mRunning(FALSE), - mLastTime(0), - mLastSampleValue(0.0), - mLastSampleValid(FALSE) -{ -} - -LLStatAccum::~LLStatAccum() -{ -} - - - -void LLStatAccum::reset(U64 when) -{ - mRunning = TRUE; - mLastTime = when; - - for (int i = 0; i < NUM_SCALES; ++i) - { - mBuckets[i].accum = 0.0; - mBuckets[i].endTime = when + sScaleTimes[i]; - mBuckets[i].lastValid = false; - } -} - -void LLStatAccum::sum(F64 value) -{ - sum(value, getCurrentUsecs()); -} - -void LLStatAccum::sum(F64 value, U64 when) -{ - if (!mRunning) - { - reset(when); - return; - } - if (when < mLastTime) - { - // This happens a LOT on some dual core systems. - lldebugs << "LLStatAccum::sum clock has gone backwards from " - << mLastTime << " to " << when << ", resetting" << llendl; - - reset(when); - return; - } - - // how long is this value for - U64 timeSpan = when - mLastTime; - - for (int i = 0; i < NUM_SCALES; ++i) - { - Bucket& bucket = mBuckets[i]; - - if (when < bucket.endTime) - { - bucket.accum += value; - } - else - { - U64 timeScale = sScaleTimes[i]; - - U64 timeLeft = when - bucket.endTime; - // how much time is left after filling this bucket - - if (timeLeft < timeScale) - { - F64 valueLeft = value * timeLeft / timeSpan; - - bucket.lastValid = true; - bucket.lastAccum = bucket.accum + (value - valueLeft); - bucket.accum = valueLeft; - bucket.endTime += timeScale; - } - else - { - U64 timeTail = timeLeft % timeScale; - - bucket.lastValid = true; - bucket.lastAccum = value * timeScale / timeSpan; - bucket.accum = value * timeTail / timeSpan; - bucket.endTime += (timeLeft - timeTail) + timeScale; - } - } - } - - mLastTime = when; -} - - -F32 LLStatAccum::meanValue(TimeScale scale) const -{ - if (!mRunning) - { - return 0.0; - } - if ( scale == SCALE_PER_FRAME ) - { // Per-frame not supported here - scale = SCALE_100MS; - } - - if (scale < 0 || scale >= NUM_SCALES) - { - llwarns << "llStatAccum::meanValue called for unsupported scale: " - << scale << llendl; - return 0.0; - } - - const Bucket& bucket = mBuckets[scale]; - - F64 value = bucket.accum; - U64 timeLeft = bucket.endTime - mLastTime; - U64 scaleTime = sScaleTimes[scale]; - - if (bucket.lastValid) - { - value += bucket.lastAccum * timeLeft / scaleTime; - } - else if (timeLeft < scaleTime) - { - value *= scaleTime / (scaleTime - timeLeft); - } - else - { - value = 0.0; - } - - return (F32)(value / scaleTime); -} - - -U64 LLStatAccum::getCurrentUsecs() const -{ - if (mUseFrameTimer) - { - return LLFrameTimer::getTotalTime(); - } - else - { - return totalTime(); - } -} - - -// ------------------------------------------------------------------------ - -LLStatRate::LLStatRate(bool use_frame_timer) - : LLStatAccum(use_frame_timer) -{ -} - -void LLStatRate::count(U32 value) -{ - sum((F64)value * sScaleTimes[SCALE_SECOND]); -} - - -void LLStatRate::mark() - { - // Effectively the same as count(1), but sets mLastSampleValue - U64 when = getCurrentUsecs(); - - if ( mRunning - && (when > mLastTime) ) - { // Set mLastSampleValue to the time from the last mark() - F64 duration = ((F64)(when - mLastTime)) / sScaleTimes[SCALE_SECOND]; - if ( duration > 0.0 ) - { - mLastSampleValue = 1.0 / duration; - } - else - { - mLastSampleValue = 0.0; - } - } - - sum( (F64) sScaleTimes[SCALE_SECOND], when); - } - - -// ------------------------------------------------------------------------ - - -LLStatMeasure::LLStatMeasure(bool use_frame_timer) - : LLStatAccum(use_frame_timer) -{ -} - -void LLStatMeasure::sample(F64 value) -{ - U64 when = getCurrentUsecs(); - - if (mLastSampleValid) - { - F64 avgValue = (value + mLastSampleValue) / 2.0; - F64 interval = (F64)(when - mLastTime); - - sum(avgValue * interval, when); - } - else - { - reset(when); - } - - mLastSampleValid = TRUE; - mLastSampleValue = value; -} - - -// ------------------------------------------------------------------------ - -LLStatTime::LLStatTime(const std::string & key) - : LLStatAccum(false), - mFrameNumber(LLFrameTimer::getFrameCount()), - mTotalTimeInFrame(0), - mKey(key) -#if LL_DEBUG - , mRunning(FALSE) -#endif -{ -} - -void LLStatTime::start() -{ - // Reset frame accumluation if the frame number has changed - U32 frame_number = LLFrameTimer::getFrameCount(); - if ( frame_number != mFrameNumber ) - { - mFrameNumber = frame_number; - mTotalTimeInFrame = 0; - } - - sum(0.0); - -#if LL_DEBUG - // Shouldn't be running already - llassert( !mRunning ); - mRunning = TRUE; -#endif -} - -void LLStatTime::stop() -{ - U64 end_time = getCurrentUsecs(); - U64 duration = end_time - mLastTime; - sum(F64(duration), end_time); - //llinfos << "mTotalTimeInFrame incremented from " << mTotalTimeInFrame << " to " << (mTotalTimeInFrame + duration) << llendl; - mTotalTimeInFrame += duration; - -#if LL_DEBUG - mRunning = FALSE; -#endif -} - -/* virtual */ F32 LLStatTime::meanValue(TimeScale scale) const -{ - if ( LLStatAccum::SCALE_PER_FRAME == scale ) - { - return (F32)mTotalTimeInFrame; - } - else - { - return LLStatAccum::meanValue(scale); - } -} - - -// ------------------------------------------------------------------------ - - -// Use this constructor for pre-defined LLStatTime objects -LLPerfBlock::LLPerfBlock(LLStatTime* stat ) : mPredefinedStat(stat), mDynamicStat(NULL) -{ - if (mPredefinedStat) - { - // If dynamic stats are turned on, this will create a separate entry in the stat map. - initDynamicStat(mPredefinedStat->mKey); - - // Start predefined stats. These stats are not part of the stat map. - mPredefinedStat->start(); - } -} - -// Use this constructor for normal, optional LLPerfBlock time slices -LLPerfBlock::LLPerfBlock( const char* key ) : mPredefinedStat(NULL), mDynamicStat(NULL) -{ - if ((sStatsFlags & LLSTATS_BASIC_STATS) == 0) - { // These are off unless the base set is enabled - return; - } - - initDynamicStat(key); -} - - -// Use this constructor for dynamically created LLPerfBlock time slices -// that are only enabled by specific control flags -LLPerfBlock::LLPerfBlock( const char* key1, const char* key2, S32 flags ) : mPredefinedStat(NULL), mDynamicStat(NULL) -{ - if ((sStatsFlags & flags) == 0) - { - return; - } - - if (NULL == key2 || strlen(key2) == 0) - { - initDynamicStat(key1); - } - else - { - std::ostringstream key; - key << key1 << "_" << key2; - initDynamicStat(key.str()); - } -} - -// Set up the result data map if dynamic stats are enabled -void LLPerfBlock::initDynamicStat(const std::string& key) -{ - // Early exit if dynamic stats aren't enabled. - if (sStatsFlags == LLSTATS_NO_OPTIONAL_STATS) - return; - - mLastPath = sCurrentStatPath; // Save and restore current path - sCurrentStatPath += "/" + key; // Add key to current path - - // See if the LLStatTime object already exists - stat_map_t::iterator iter = sStatMap.find(sCurrentStatPath); - if ( iter == sStatMap.end() ) - { - // StatEntry object doesn't exist, so create it - mDynamicStat = new StatEntry( key ); - sStatMap[ sCurrentStatPath ] = mDynamicStat; // Set the entry for this path - } - else - { - // Found this path in the map, use the object there - mDynamicStat = (*iter).second; // Get StatEntry for the current path - } - - if (mDynamicStat) - { - mDynamicStat->mStat.start(); - mDynamicStat->mCount++; - } - else - { - llwarns << "Initialized NULL dynamic stat at '" << sCurrentStatPath << "'" << llendl; - sCurrentStatPath = mLastPath; - } -} - - -// Destructor does the time accounting -LLPerfBlock::~LLPerfBlock() -{ - if (mPredefinedStat) mPredefinedStat->stop(); - if (mDynamicStat) - { - mDynamicStat->mStat.stop(); - sCurrentStatPath = mLastPath; // Restore the path in case sStatsEnabled changed during this block - } -} - - -// Clear the map of any dynamic stats. Static routine -void LLPerfBlock::clearDynamicStats() -{ - std::for_each(sStatMap.begin(), sStatMap.end(), DeletePairedPointer()); - sStatMap.clear(); -} - -// static - Extract the stat info into LLSD -void LLPerfBlock::addStatsToLLSDandReset( LLSD & stats, - LLStatAccum::TimeScale scale ) -{ - // If we aren't in per-frame scale, we need to go from second to microsecond. - U32 scale_adjustment = 1; - if (LLStatAccum::SCALE_PER_FRAME != scale) - { - scale_adjustment = USEC_PER_SEC; - } - stat_map_t::iterator iter = sStatMap.begin(); - for ( ; iter != sStatMap.end(); ++iter ) - { // Put the entry into LLSD "/full/path/to/stat/" = microsecond total time - const std::string & stats_full_path = (*iter).first; - - StatEntry * stat = (*iter).second; - if (stat) - { - if (stat->mCount > 0) - { - stats[stats_full_path] = LLSD::emptyMap(); - stats[stats_full_path]["us"] = (LLSD::Integer) (scale_adjustment * stat->mStat.meanValue(scale)); - if (stat->mCount > 1) - { - stats[stats_full_path]["count"] = (LLSD::Integer) stat->mCount; - } - stat->mCount = 0; - } - } - else - { // Shouldn't have a NULL pointer in the map. - llwarns << "Unexpected NULL dynamic stat at '" << stats_full_path << "'" << llendl; - } - } -} - - -// ------------------------------------------------------------------------ - LLTimer LLStat::sTimer; LLFrameTimer LLStat::sFrameTimer; -void LLStat::init() +void LLStat::reset() { - llassert(mNumBins > 0); mNumValues = 0; mLastValue = 0.f; - mLastTime = 0.f; - mCurBin = (mNumBins-1); + delete[] mBins; + mBins = new ValueEntry[mNumBins]; + mCurBin = mNumBins-1; mNextBin = 0; - mBins = new F32[mNumBins]; - mBeginTime = new F64[mNumBins]; - mTime = new F64[mNumBins]; - mDT = new F32[mNumBins]; - for (U32 i = 0; i < mNumBins; i++) - { - mBins[i] = 0.f; - mBeginTime[i] = 0.0; - mTime[i] = 0.0; - mDT[i] = 0.f; - } +} + +LLStat::LLStat(std::string name, S32 num_bins, BOOL use_frame_timer) +: mUseFrameTimer(use_frame_timer), + mNumBins(num_bins), + mName(name), + mBins(NULL) +{ + llassert(mNumBins > 0); + mLastTime = 0.f; + + reset(); if (!mName.empty()) { - stat_map_t::iterator iter = sStatList.find(mName); - if (iter != sStatList.end()) + stat_map_t::iterator iter = getStatList().find(mName); + if (iter != getStatList().end()) llwarns << "LLStat with duplicate name: " << mName << llendl; - sStatList.insert(std::make_pair(mName, this)); + getStatList().insert(std::make_pair(mName, this)); } } -LLStat::LLStat(const U32 num_bins, const BOOL use_frame_timer) - : mUseFrameTimer(use_frame_timer), - mNumBins(num_bins) +LLStat::stat_map_t& LLStat::getStatList() { - init(); + static LLStat::stat_map_t stat_list; + return stat_list; } -LLStat::LLStat(std::string name, U32 num_bins, BOOL use_frame_timer) - : mUseFrameTimer(use_frame_timer), - mNumBins(num_bins), - mName(name) -{ - init(); -} LLStat::~LLStat() { delete[] mBins; - delete[] mBeginTime; - delete[] mTime; - delete[] mDT; if (!mName.empty()) { // handle multiple entries with the same name - stat_map_t::iterator iter = sStatList.find(mName); - while (iter != sStatList.end() && iter->second != this) + stat_map_t::iterator iter = getStatList().find(mName); + while (iter != getStatList().end() && iter->second != this) ++iter; - sStatList.erase(iter); + getStatList().erase(iter); } } -void LLStat::reset() -{ - U32 i; - - mNumValues = 0; - mLastValue = 0.f; - mCurBin = (mNumBins-1); - delete[] mBins; - delete[] mBeginTime; - delete[] mTime; - delete[] mDT; - mBins = new F32[mNumBins]; - mBeginTime = new F64[mNumBins]; - mTime = new F64[mNumBins]; - mDT = new F32[mNumBins]; - for (i = 0; i < mNumBins; i++) - { - mBins[i] = 0.f; - mBeginTime[i] = 0.0; - mTime[i] = 0.0; - mDT[i] = 0.f; - } -} - -void LLStat::setBeginTime(const F64 time) -{ - mBeginTime[mNextBin] = time; -} - -void LLStat::addValueTime(const F64 time, const F32 value) -{ - if (mNumValues < mNumBins) - { - mNumValues++; - } - - // Increment the bin counters. - mCurBin++; - if ((U32)mCurBin == mNumBins) - { - mCurBin = 0; - } - mNextBin++; - if ((U32)mNextBin == mNumBins) - { - mNextBin = 0; - } - - mBins[mCurBin] = value; - mTime[mCurBin] = time; - mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]); - //this value is used to prime the min/max calls - mLastTime = mTime[mCurBin]; - mLastValue = value; - - // Set the begin time for the next stat segment. - mBeginTime[mNextBin] = mTime[mCurBin]; - mTime[mNextBin] = mTime[mCurBin]; - mDT[mNextBin] = 0.f; -} - void LLStat::start() { if (mUseFrameTimer) { - mBeginTime[mNextBin] = sFrameTimer.getElapsedSeconds(); + mBins[mNextBin].mBeginTime = sFrameTimer.getElapsedSeconds(); } else { - mBeginTime[mNextBin] = sTimer.getElapsedTimeF64(); + mBins[mNextBin].mBeginTime = sTimer.getElapsedTimeF64(); } } @@ -892,41 +113,41 @@ void LLStat::addValue(const F32 value) // Increment the bin counters. mCurBin++; - if ((U32)mCurBin == mNumBins) + if (mCurBin >= mNumBins) { mCurBin = 0; } mNextBin++; - if ((U32)mNextBin == mNumBins) + if (mNextBin >= mNumBins) { mNextBin = 0; } - mBins[mCurBin] = value; + mBins[mCurBin].mValue = value; if (mUseFrameTimer) { - mTime[mCurBin] = sFrameTimer.getElapsedSeconds(); + mBins[mCurBin].mTime = sFrameTimer.getElapsedSeconds(); } else { - mTime[mCurBin] = sTimer.getElapsedTimeF64(); + mBins[mCurBin].mTime = sTimer.getElapsedTimeF64(); } - mDT[mCurBin] = (F32)(mTime[mCurBin] - mBeginTime[mCurBin]); + mBins[mCurBin].mDT = (F32)(mBins[mCurBin].mTime - mBins[mCurBin].mBeginTime); //this value is used to prime the min/max calls - mLastTime = mTime[mCurBin]; + mLastTime = mBins[mCurBin].mTime; mLastValue = value; // Set the begin time for the next stat segment. - mBeginTime[mNextBin] = mTime[mCurBin]; - mTime[mNextBin] = mTime[mCurBin]; - mDT[mNextBin] = 0.f; + mBins[mNextBin].mBeginTime = mBins[mCurBin].mTime; + mBins[mNextBin].mTime = mBins[mCurBin].mTime; + mBins[mNextBin].mDT = 0.f; } F32 LLStat::getMax() const { - U32 i; + S32 i; F32 current_max = mLastValue; if (mNumBins == 0) { @@ -937,13 +158,13 @@ F32 LLStat::getMax() const for (i = 0; (i < mNumBins) && (i < mNumValues); i++) { // Skip the bin we're currently filling. - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - if (mBins[i] > current_max) + if (mBins[i].mValue > current_max) { - current_max = mBins[i]; + current_max = mBins[i].mValue; } } } @@ -952,17 +173,17 @@ F32 LLStat::getMax() const F32 LLStat::getMean() const { - U32 i; + S32 i; F32 current_mean = 0.f; - U32 samples = 0; + S32 samples = 0; for (i = 0; (i < mNumBins) && (i < mNumValues); i++) { // Skip the bin we're currently filling. - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - current_mean += mBins[i]; + current_mean += mBins[i].mValue; samples++; } @@ -980,7 +201,7 @@ F32 LLStat::getMean() const F32 LLStat::getMin() const { - U32 i; + S32 i; F32 current_min = mLastValue; if (mNumBins == 0) @@ -992,53 +213,19 @@ F32 LLStat::getMin() const for (i = 0; (i < mNumBins) && (i < mNumValues); i++) { // Skip the bin we're currently filling. - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - if (mBins[i] < current_min) + if (mBins[i].mValue < current_min) { - current_min = mBins[i]; + current_min = mBins[i].mValue; } } } return current_min; } -F32 LLStat::getSum() const -{ - U32 i; - F32 sum = 0.f; - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == (U32)mNextBin) - { - continue; - } - sum += mBins[i]; - } - - return sum; -} - -F32 LLStat::getSumDuration() const -{ - U32 i; - F32 sum = 0.f; - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) - { - // Skip the bin we're currently filling. - if (i == (U32)mNextBin) - { - continue; - } - sum += mDT[i]; - } - - return sum; -} - F32 LLStat::getPrev(S32 age) const { S32 bin; @@ -1054,7 +241,7 @@ F32 LLStat::getPrev(S32 age) const // Bogus for bin we're currently working on. return 0.f; } - return mBins[bin]; + return mBins[bin].mValue; } F32 LLStat::getPrevPerSec(S32 age) const @@ -1072,107 +259,34 @@ F32 LLStat::getPrevPerSec(S32 age) const // Bogus for bin we're currently working on. return 0.f; } - return mBins[bin] / mDT[bin]; -} - -F64 LLStat::getPrevBeginTime(S32 age) const -{ - S32 bin; - bin = mCurBin - age; - - while (bin < 0) - { - bin += mNumBins; - } - - if (bin == mNextBin) - { - // Bogus for bin we're currently working on. - return 0.f; - } - - return mBeginTime[bin]; -} - -F64 LLStat::getPrevTime(S32 age) const -{ - S32 bin; - bin = mCurBin - age; - - while (bin < 0) - { - bin += mNumBins; - } - - if (bin == mNextBin) - { - // Bogus for bin we're currently working on. - return 0.f; - } - - return mTime[bin]; -} - -F32 LLStat::getBin(S32 bin) const -{ - return mBins[bin]; -} - -F32 LLStat::getBinPerSec(S32 bin) const -{ - return mBins[bin] / mDT[bin]; -} - -F64 LLStat::getBinBeginTime(S32 bin) const -{ - return mBeginTime[bin]; -} - -F64 LLStat::getBinTime(S32 bin) const -{ - return mTime[bin]; + return mBins[bin].mValue / mBins[bin].mDT; } F32 LLStat::getCurrent() const { - return mBins[mCurBin]; + return mBins[mCurBin].mValue; } F32 LLStat::getCurrentPerSec() const { - return mBins[mCurBin] / mDT[mCurBin]; -} - -F64 LLStat::getCurrentBeginTime() const -{ - return mBeginTime[mCurBin]; -} - -F64 LLStat::getCurrentTime() const -{ - return mTime[mCurBin]; -} - -F32 LLStat::getCurrentDuration() const -{ - return mDT[mCurBin]; + return mBins[mCurBin].mValue / mBins[mCurBin].mDT; } F32 LLStat::getMeanPerSec() const { - U32 i; + S32 i; F32 value = 0.f; F32 dt = 0.f; for (i = 0; (i < mNumBins) && (i < mNumValues); i++) { // Skip the bin we're currently filling. - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - value += mBins[i]; - dt += mDT[i]; + value += mBins[i].mValue; + dt += mBins[i].mDT; } if (dt > 0.f) @@ -1188,14 +302,14 @@ F32 LLStat::getMeanPerSec() const F32 LLStat::getMeanDuration() const { F32 dur = 0.0f; - U32 count = 0; - for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++) + S32 count = 0; + for (S32 i=0; (i < mNumBins) && (i < mNumValues); i++) { - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - dur += mDT[i]; + dur += mBins[i].mDT; count++; } @@ -1212,46 +326,45 @@ F32 LLStat::getMeanDuration() const F32 LLStat::getMaxPerSec() const { - U32 i; F32 value; if (mNextBin != 0) { - value = mBins[0]/mDT[0]; + value = mBins[0].mValue/mBins[0].mDT; } else if (mNumValues > 0) { - value = mBins[1]/mDT[1]; + value = mBins[1].mValue/mBins[1].mDT; } else { value = 0.f; } - for (i = 0; (i < mNumBins) && (i < mNumValues); i++) + for (S32 i = 0; (i < mNumBins) && (i < mNumValues); i++) { // Skip the bin we're currently filling. - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - value = llmax(value, mBins[i]/mDT[i]); + value = llmax(value, mBins[i].mValue/mBins[i].mDT); } return value; } F32 LLStat::getMinPerSec() const { - U32 i; + S32 i; F32 value; if (mNextBin != 0) { - value = mBins[0]/mDT[0]; + value = mBins[0].mValue/mBins[0].mDT; } else if (mNumValues > 0) { - value = mBins[1]/mDT[1]; + value = mBins[1].mValue/mBins[0].mDT; } else { @@ -1261,25 +374,15 @@ F32 LLStat::getMinPerSec() const for (i = 0; (i < mNumBins) && (i < mNumValues); i++) { // Skip the bin we're currently filling. - if (i == (U32)mNextBin) + if (i == mNextBin) { continue; } - value = llmin(value, mBins[i]/mDT[i]); + value = llmin(value, mBins[i].mValue/mBins[i].mDT); } return value; } -F32 LLStat::getMinDuration() const -{ - F32 dur = 0.0f; - for (U32 i=0; (i < mNumBins) && (i < mNumValues); i++) - { - dur = llmin(dur, mDT[i]); - } - return dur; -} - U32 LLStat::getNumValues() const { return mNumValues; @@ -1290,11 +393,6 @@ S32 LLStat::getNumBins() const return mNumBins; } -S32 LLStat::getCurBin() const -{ - return mCurBin; -} - S32 LLStat::getNextBin() const { return mNextBin; diff --git a/indra/llcommon/llstat.h b/indra/llcommon/llstat.h index b877432e86..38377a010b 100644 --- a/indra/llcommon/llstat.h +++ b/indra/llcommon/llstat.h @@ -27,294 +27,46 @@ #ifndef LL_LLSTAT_H #define LL_LLSTAT_H -#include <deque> #include <map> #include "lltimer.h" #include "llframetimer.h" -#include "llfile.h" class LLSD; -// Set this if longer stats are needed -#define ENABLE_LONG_TIME_STATS 0 - -// -// Accumulates statistics for an arbitrary length of time. -// Does this by maintaining a chain of accumulators, each one -// accumulation the results of the parent. Can scale to arbitrary -// amounts of time with very low memory cost. -// - -class LL_COMMON_API LLStatAccum -{ -protected: - LLStatAccum(bool use_frame_timer); - virtual ~LLStatAccum(); - -public: - enum TimeScale { - SCALE_100MS, - SCALE_SECOND, - SCALE_MINUTE, -#if ENABLE_LONG_TIME_STATS - SCALE_HOUR, - SCALE_DAY, - SCALE_WEEK, -#endif - NUM_SCALES, // Use to size storage arrays - SCALE_PER_FRAME // For latest frame information - should be after NUM_SCALES since this doesn't go into the time buckets - }; - - static U64 sScaleTimes[NUM_SCALES]; - - virtual F32 meanValue(TimeScale scale) const; - // see the subclasses for the specific meaning of value - - F32 meanValueOverLast100ms() const { return meanValue(SCALE_100MS); } - F32 meanValueOverLastSecond() const { return meanValue(SCALE_SECOND); } - F32 meanValueOverLastMinute() const { return meanValue(SCALE_MINUTE); } - - void reset(U64 when); - - void sum(F64 value); - void sum(F64 value, U64 when); - - U64 getCurrentUsecs() const; - // Get current microseconds based on timer type - - BOOL mUseFrameTimer; - BOOL mRunning; - - U64 mLastTime; - - struct Bucket - { - Bucket() : - accum(0.0), - endTime(0), - lastValid(false), - lastAccum(0.0) - {} - - F64 accum; - U64 endTime; - - bool lastValid; - F64 lastAccum; - }; - - Bucket mBuckets[NUM_SCALES]; - - BOOL mLastSampleValid; - F64 mLastSampleValue; -}; - -class LL_COMMON_API LLStatMeasure : public LLStatAccum - // gathers statistics about things that are measured - // ex.: tempature, time dilation -{ -public: - LLStatMeasure(bool use_frame_timer = true); - - void sample(F64); - void sample(S32 v) { sample((F64)v); } - void sample(U32 v) { sample((F64)v); } - void sample(S64 v) { sample((F64)v); } - void sample(U64 v) { sample((F64)v); } -}; - - -class LL_COMMON_API LLStatRate : public LLStatAccum - // gathers statistics about things that can be counted over time - // ex.: LSL instructions executed, messages sent, simulator frames completed - // renders it in terms of rate of thing per second -{ -public: - LLStatRate(bool use_frame_timer = true); - - void count(U32); - // used to note that n items have occured - - void mark(); - // used for counting the rate thorugh a point in the code -}; - - -class LL_COMMON_API LLStatTime : public LLStatAccum - // gathers statistics about time spent in a block of code - // measure average duration per second in the block -{ -public: - LLStatTime( const std::string & key = "undefined" ); - - U32 mFrameNumber; // Current frame number - U64 mTotalTimeInFrame; // Total time (microseconds) accumulated during the last frame - - void setKey( const std::string & key ) { mKey = key; }; - - virtual F32 meanValue(TimeScale scale) const; - -private: - void start(); // Start and stop measuring time block - void stop(); - - std::string mKey; // Tag representing this time block - -#if LL_DEBUG - BOOL mRunning; // TRUE if start() has been called -#endif - - friend class LLPerfBlock; -}; - -// ---------------------------------------------------------------------------- - - -// Use this class on the stack to record statistics about an area of code -class LL_COMMON_API LLPerfBlock -{ -public: - struct StatEntry - { - StatEntry(const std::string& key) : mStat(LLStatTime(key)), mCount(0) {} - LLStatTime mStat; - U32 mCount; - }; - typedef std::map<std::string, StatEntry*> stat_map_t; - - // Use this constructor for pre-defined LLStatTime objects - LLPerfBlock(LLStatTime* stat); - - // Use this constructor for normal, optional LLPerfBlock time slices - LLPerfBlock( const char* key ); - - // Use this constructor for dynamically created LLPerfBlock time slices - // that are only enabled by specific control flags - LLPerfBlock( const char* key1, const char* key2, S32 flags = LLSTATS_BASIC_STATS ); - - ~LLPerfBlock(); - - enum - { // Stats bitfield flags - LLSTATS_NO_OPTIONAL_STATS = 0x00, // No optional stats gathering, just pre-defined LLStatTime objects - LLSTATS_BASIC_STATS = 0x01, // Gather basic optional runtime stats - LLSTATS_SCRIPT_FUNCTIONS = 0x02, // Include LSL function calls - }; - static void setStatsFlags( S32 flags ) { sStatsFlags = flags; }; - static S32 getStatsFlags() { return sStatsFlags; }; - - static void clearDynamicStats(); // Reset maps to clear out dynamic objects - static void addStatsToLLSDandReset( LLSD & stats, // Get current information and clear time bin - LLStatAccum::TimeScale scale ); - -private: - // Initialize dynamically created LLStatTime objects - void initDynamicStat(const std::string& key); - - std::string mLastPath; // Save sCurrentStatPath when this is called - LLStatTime * mPredefinedStat; // LLStatTime object to get data - StatEntry * mDynamicStat; // StatEntryobject to get data - - static S32 sStatsFlags; // Control what is being recorded - static stat_map_t sStatMap; // Map full path string to LLStatTime objects - static std::string sCurrentStatPath; // Something like "frame/physics/physics step" -}; - -// ---------------------------------------------------------------------------- - -class LL_COMMON_API LLPerfStats -{ -public: - LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0); - virtual ~LLPerfStats(); - - virtual void init(); // Reset and start all stat timers - virtual void updatePerFrameStats(); - // Override these function to add process-specific information to the performance log header and per-frame logging. - virtual void addProcessHeaderInfo(LLSD& info) { /* not implemented */ } - virtual void addProcessFrameInfo(LLSD& info, LLStatAccum::TimeScale scale) { /* not implemented */ } - - // High-resolution frame stats - BOOL frameStatsIsRunning() { return (mReportPerformanceStatEnd > 0.); }; - F32 getReportPerformanceInterval() const { return mReportPerformanceStatInterval; }; - void setReportPerformanceInterval( F32 interval ) { mReportPerformanceStatInterval = interval; }; - void setReportPerformanceDuration( F32 seconds, S32 flags = LLPerfBlock::LLSTATS_NO_OPTIONAL_STATS ); - void setProcessName(const std::string& process_name) { mProcessName = process_name; } - void setProcessPID(S32 process_pid) { mProcessPID = process_pid; } - -protected: - void openPerfStatsFile(); // Open file for high resolution metrics logging - void dumpIntervalPerformanceStats(); - - llofstream mFrameStatsFile; // File for per-frame stats - BOOL mFrameStatsFileFailure; // Flag to prevent repeat opening attempts - BOOL mSkipFirstFrameStats; // Flag to skip one (partial) frame report - std::string mProcessName; - S32 mProcessPID; - -private: - F32 mReportPerformanceStatInterval; // Seconds between performance stats - F64 mReportPerformanceStatEnd; // End time (seconds) for performance stats -}; - // ---------------------------------------------------------------------------- class LL_COMMON_API LLStat { private: typedef std::multimap<std::string, LLStat*> stat_map_t; - static stat_map_t sStatList; - void init(); + static stat_map_t& getStatList(); public: - LLStat(U32 num_bins = 32, BOOL use_frame_timer = FALSE); - LLStat(std::string name, U32 num_bins = 32, BOOL use_frame_timer = FALSE); + LLStat(std::string name = std::string(), S32 num_bins = 32, BOOL use_frame_timer = FALSE); ~LLStat(); - void reset(); - void start(); // Start the timer for the current "frame", otherwise uses the time tracked from // the last addValue + void reset(); void addValue(const F32 value = 1.f); // Adds the current value being tracked, and tracks the DT. void addValue(const S32 value) { addValue((F32)value); } void addValue(const U32 value) { addValue((F32)value); } - void setBeginTime(const F64 time); - void addValueTime(const F64 time, const F32 value = 1.f); - - S32 getCurBin() const; S32 getNextBin() const; - F32 getCurrent() const; - F32 getCurrentPerSec() const; - F64 getCurrentBeginTime() const; - F64 getCurrentTime() const; - F32 getCurrentDuration() const; - F32 getPrev(S32 age) const; // Age is how many "addValues" previously - zero is current F32 getPrevPerSec(S32 age) const; // Age is how many "addValues" previously - zero is current - F64 getPrevBeginTime(S32 age) const; - F64 getPrevTime(S32 age) const; - - F32 getBin(S32 bin) const; - F32 getBinPerSec(S32 bin) const; - F64 getBinBeginTime(S32 bin) const; - F64 getBinTime(S32 bin) const; - - F32 getMax() const; - F32 getMaxPerSec() const; + F32 getCurrent() const; + F32 getCurrentPerSec() const; + F32 getMin() const; + F32 getMinPerSec() const; F32 getMean() const; F32 getMeanPerSec() const; F32 getMeanDuration() const; - - F32 getMin() const; - F32 getMinPerSec() const; - F32 getMinDuration() const; - - F32 getSum() const; - F32 getSumDuration() const; + F32 getMax() const; + F32 getMaxPerSec() const; U32 getNumValues() const; S32 getNumBins() const; @@ -326,10 +78,21 @@ private: U32 mNumBins; F32 mLastValue; F64 mLastTime; - F32 *mBins; - F64 *mBeginTime; - F64 *mTime; - F32 *mDT; + + struct ValueEntry + { + ValueEntry() + : mValue(0.f), + mBeginTime(0.0), + mTime(0.0), + mDT(0.f) + {} + F32 mValue; + F64 mBeginTime; + F64 mTime; + F32 mDT; + }; + ValueEntry* mBins; S32 mCurBin; S32 mNextBin; @@ -342,8 +105,8 @@ public: static LLStat* getStat(const std::string& name) { // return the first stat that matches 'name' - stat_map_t::iterator iter = sStatList.find(name); - if (iter != sStatList.end()) + stat_map_t::iterator iter = getStatList().find(name); + if (iter != getStatList().end()) return iter->second; else return NULL; diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index 8ad12c9a03..d3941e1bc9 100644 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -33,6 +33,7 @@ #include <vector> #include <set> #include <deque> +#include <typeinfo> // Use to compare the first element only of a pair // e.g. typedef std::set<std::pair<int, Data*>, compare_pair<int, Data*> > some_pair_set_t; @@ -470,4 +471,54 @@ llbind2nd(const _Operation& __oper, const _Tp& __x) return llbinder2nd<_Operation>(__oper, _Arg2_type(__x)); } +/** + * Compare std::type_info* pointers a la std::less. We break this out as a + * separate function for use in two different std::less specializations. + */ +inline +bool before(const std::type_info* lhs, const std::type_info* rhs) +{ +#if LL_LINUX && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 4)) + // If we're building on Linux with gcc, and it's either gcc 3.x or + // 4.{0,1,2,3}, then we have to use a workaround. Note that we use gcc on + // Mac too, and some people build with gcc on Windows (cygwin or mingw). + // On Linux, different load modules may produce different type_info* + // pointers for the same type. Have to compare name strings to get good + // results. + return strcmp(lhs->name(), rhs->name()) < 0; +#else // not Linux, or gcc 4.4+ + // Just use before(), as we normally would + return lhs->before(*rhs); +#endif +} + +/** + * Specialize std::less<std::type_info*> to use std::type_info::before(). + * See MAINT-1175. It is NEVER a good idea to directly compare std::type_info* + * because, on Linux, you might get different std::type_info* pointers for the + * same type (from different load modules)! + */ +namespace std +{ + template <> + struct less<const std::type_info*>: + public std::binary_function<const std::type_info*, const std::type_info*, bool> + { + bool operator()(const std::type_info* lhs, const std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; + + template <> + struct less<std::type_info*>: + public std::binary_function<std::type_info*, std::type_info*, bool> + { + bool operator()(std::type_info* lhs, std::type_info* rhs) const + { + return before(lhs, rhs); + } + }; +} // std + #endif // LL_LLSTL_H diff --git a/indra/llcommon/lltypeinfolookup.h b/indra/llcommon/lltypeinfolookup.h index 7510cc12ed..0b6862444e 100644 --- a/indra/llcommon/lltypeinfolookup.h +++ b/indra/llcommon/lltypeinfolookup.h @@ -12,10 +12,50 @@ #if ! defined(LL_LLTYPEINFOLOOKUP_H) #define LL_LLTYPEINFOLOOKUP_H -#include "llsortedvector.h" +#include <boost/unordered_map.hpp> +#include <boost/functional/hash.hpp> +#include <boost/optional.hpp> +#include <functional> // std::binary_function #include <typeinfo> /** + * The following helper classes are based on the Boost.Unordered documentation: + * http://www.boost.org/doc/libs/1_45_0/doc/html/unordered/hash_equality.html + */ + +/** + * Compute hash for a string passed as const char* + */ +struct const_char_star_hash: public std::unary_function<const char*, std::size_t> +{ + std::size_t operator()(const char* str) const + { + std::size_t seed = 0; + for ( ; *str; ++str) + { + boost::hash_combine(seed, *str); + } + return seed; + } +}; + +/** + * Compute equality for strings passed as const char* + * + * I (nat) suspect that this is where the default behavior breaks for the + * const char* values returned from std::type_info::name(). If you compare the + * two const char* pointer values, as a naive, unspecialized implementation + * will surely do, they'll compare unequal. + */ +struct const_char_star_equal: public std::binary_function<const char*, const char*, bool> +{ + bool operator()(const char* lhs, const char* rhs) const + { + return strcmp(lhs, rhs) == 0; + } +}; + +/** * LLTypeInfoLookup is specifically designed for use cases for which you might * consider std::map<std::type_info*, VALUE>. We have several such data * structures in the viewer. The trouble with them is that at least on Linux, @@ -23,88 +63,55 @@ * different load modules will produce different std::type_info*. * LLTypeInfoLookup contains a workaround to address this issue. * - * Specifically, when we don't find the passed std::type_info*, - * LLTypeInfoLookup performs a linear search over registered entries to - * compare name() strings. Presuming that this succeeds, we cache the new - * (previously unrecognized) std::type_info* to speed future lookups. - * - * This worst-case fallback search (linear search with string comparison) - * should only happen the first time we look up a given type from a particular - * load module other than the one from which we initially registered types. - * (However, a lookup which wouldn't succeed anyway will always have - * worst-case performance.) This class is probably best used with less than a - * few dozen different types. + * The API deliberately diverges from std::map in several respects: + * * It avoids iterators, not only begin()/end() but also as return values + * from insert() and find(). This bypasses transform_iterator overhead. + * * Since we literally use compile-time types as keys, the essential insert() + * and find() methods accept the key type as a @em template parameter, + * accepting and returning value_type as a normal runtime value. This is to + * permit future optimization (e.g. compile-time type hashing) without + * changing the API. */ template <typename VALUE> class LLTypeInfoLookup { + // Use this for our underlying implementation: lookup by + // std::type_info::name() string. This is one of the rare cases in which I + // dare use const char* directly, rather than std::string, because I'm + // sure that every value returned by std::type_info::name() is static. + // HOWEVER, specify our own hash + equality functors: naively comparing + // distinct const char* values won't work. + typedef boost::unordered_map<const char*, VALUE, + const_char_star_hash, const_char_star_equal> impl_map_type; + public: - typedef LLTypeInfoLookup<VALUE> self; - typedef LLSortedVector<const std::type_info*, VALUE> vector_type; - typedef typename vector_type::key_type key_type; - typedef typename vector_type::mapped_type mapped_type; - typedef typename vector_type::value_type value_type; - typedef typename vector_type::iterator iterator; - typedef typename vector_type::const_iterator const_iterator; + typedef VALUE value_type; LLTypeInfoLookup() {} - iterator begin() { return mVector.begin(); } - iterator end() { return mVector.end(); } - const_iterator begin() const { return mVector.begin(); } - const_iterator end() const { return mVector.end(); } - bool empty() const { return mVector.empty(); } - std::size_t size() const { return mVector.size(); } - - std::pair<iterator, bool> insert(const std::type_info* key, const VALUE& value) - { - return insert(value_type(key, value)); - } - - std::pair<iterator, bool> insert(const value_type& pair) - { - return mVector.insert(pair); - } + bool empty() const { return mMap.empty(); } + std::size_t size() const { return mMap.size(); } - // const find() forwards to non-const find(): this can alter mVector! - const_iterator find(const std::type_info* key) const + template <typename KEY> + bool insert(const value_type& value) { - return const_cast<self*>(this)->find(key); + // Obtain and store the std::type_info::name() string as the key. + // Return just the bool from std::map::insert()'s return pair. + return mMap.insert(typename impl_map_type::value_type(typeid(KEY).name(), value)).second; } - // non-const find() caches previously-unknown type_info* to speed future - // lookups. - iterator find(const std::type_info* key) + template <typename KEY> + boost::optional<value_type> find() const { - iterator found = mVector.find(key); - if (found != mVector.end()) - { - // If LLSortedVector::find() found, great, we're done. - return found; - } - // Here we didn't find the passed type_info*. On Linux, though, even - // for the same type, typeid(sametype) produces a different type_info* - // when used in different load modules. So the fact that we didn't - // find the type_info* we seek doesn't mean this type isn't - // registered. Scan for matching name() string. - for (typename vector_type::iterator ti(mVector.begin()), tend(mVector.end()); - ti != tend; ++ti) - { - if (std::string(ti->first->name()) == key->name()) - { - // This unrecognized 'key' is for the same type as ti->first. - // To speed future lookups, insert a new entry that lets us - // look up ti->second using this same 'key'. - return insert(key, ti->second).first; - } - } - // We simply have never seen a type with this type_info* from any load - // module. - return mVector.end(); + // Use the std::type_info::name() string as the key. + typename impl_map_type::const_iterator found = mMap.find(typeid(KEY).name()); + if (found == mMap.end()) + return boost::optional<value_type>(); + return found->second; } private: - vector_type mVector; + impl_map_type mMap; }; #endif /* ! defined(LL_LLTYPEINFOLOOKUP_H) */ diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp index e0410906fb..0c2d4b823d 100644 --- a/indra/llmessage/llcircuit.cpp +++ b/indra/llmessage/llcircuit.cpp @@ -679,7 +679,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID); mLastPacketGap = 0; - mOutOfOrderRate.count(0); return; } @@ -775,7 +774,6 @@ void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent) } } - mOutOfOrderRate.count(gap); mLastPacketGap = gap; } diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h index d1c400c6a2..430d6358f7 100644 --- a/indra/llmessage/llcircuit.h +++ b/indra/llmessage/llcircuit.h @@ -40,7 +40,6 @@ #include "llpacketack.h" #include "lluuid.h" #include "llthrottle.h" -#include "llstat.h" // // Constants @@ -126,8 +125,6 @@ public: S32 getUnackedPacketCount() const { return mUnackedPacketCount; } S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; } F64 getNextPingSendTime() const { return mNextPingSendTime; } - F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE) - { return mOutOfOrderRate.meanValue(scale); } U32 getLastPacketGap() const { return mLastPacketGap; } LLHost getHost() const { return mHost; } F64 getLastPacketInTime() const { return mLastPacketInTime; } @@ -275,7 +272,6 @@ protected: LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers S32 mCurrentResendCount; // Number of resent packets since last spam - LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in. U32 mLastPacketGap; // Gap in sequence number of last packet. const F32 mHeartbeatInterval; diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 127a2caabe..1236fc8b71 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -41,7 +41,6 @@ #include "llpumpio.h" #include "llsd.h" #include "llsdserialize_xml.h" -#include "llstat.h" #include "llstl.h" #include "lltimer.h" @@ -140,6 +139,11 @@ private: }; static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PIPE("HTTP Pipe"); +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_GET("HTTP Get"); +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_PUT("HTTP Put"); +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_POST("HTTP Post"); +static LLFastTimer::DeclareTimer FTM_PROCESS_HTTP_DELETE("HTTP Delete"); + LLIOPipe::EStatus LLHTTPPipe::process_impl( const LLChannelDescriptors& channels, buffer_ptr_t& buffer, @@ -176,12 +180,12 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( std::string verb = context[CONTEXT_REQUEST][CONTEXT_VERB]; if(verb == HTTP_VERB_GET) { - LLPerfBlock getblock("http_get"); + LLFastTimer _(FTM_PROCESS_HTTP_GET); mNode.get(LLHTTPNode::ResponsePtr(mResponse), context); } else if(verb == HTTP_VERB_PUT) { - LLPerfBlock putblock("http_put"); + LLFastTimer _(FTM_PROCESS_HTTP_PUT); LLSD input; if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) { @@ -197,7 +201,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( } else if(verb == HTTP_VERB_POST) { - LLPerfBlock postblock("http_post"); + LLFastTimer _(FTM_PROCESS_HTTP_POST); LLSD input; if (mNode.getContentType() == LLHTTPNode::CONTENT_TYPE_LLSD) { @@ -213,7 +217,7 @@ LLIOPipe::EStatus LLHTTPPipe::process_impl( } else if(verb == HTTP_VERB_DELETE) { - LLPerfBlock delblock("http_delete"); + LLFastTimer _(FTM_PROCESS_HTTP_DELETE); mNode.del(LLHTTPNode::ResponsePtr(mResponse), context); } else if(verb == HTTP_VERB_OPTIONS) diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h index 16d825d33b..ae8e0087c1 100644 --- a/indra/llmessage/llmessagetemplate.h +++ b/indra/llmessage/llmessagetemplate.h @@ -29,7 +29,6 @@ #include "lldarray.h" #include "message.h" // TODO: babbage: Remove... -#include "llstat.h" #include "llstl.h" class LLMsgVarData @@ -263,6 +262,7 @@ enum EMsgDeprecation MD_DEPRECATED }; + class LLMessageTemplate { public: @@ -364,7 +364,6 @@ public: { if (mHandlerFunc) { - LLPerfBlock msg_cb_time("msg_cb", mName); mHandlerFunc(msgsystem, mUserData); return TRUE; } diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 97db666e6b..0623e99f0a 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -35,7 +35,6 @@ #include "llapr.h" #include "llstl.h" -#include "llstat.h" // These should not be enabled in production, but they can be // intensely useful during development for finding certain kinds of @@ -432,6 +431,7 @@ void LLPumpIO::pump() } static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO"); +static LLFastTimer::DeclareTimer FTM_PUMP_POLL("Pump Poll"); LLPumpIO::current_chain_t LLPumpIO::removeRunningChain(LLPumpIO::current_chain_t& run_chain) { @@ -526,7 +526,7 @@ void LLPumpIO::pump(const S32& poll_timeout) S32 count = 0; S32 client_id = 0; { - LLPerfBlock polltime("pump_poll"); + LLFastTimer _(FTM_PUMP_POLL); apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd); } PUMP_DEBUG; diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 8ca1e685a9..dea746db60 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -1101,17 +1101,26 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user) const LLRect old_rect = getRect(); LLView::handleReshape(new_rect, by_user); - if (by_user && !isMinimized()) + if (by_user && !getHost()) { - storeRectControl(); - mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; - LLRect screen_rect = calcScreenRect(); - mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + static_cast<LLFloaterView*>(getParent())->adjustToFitScreen(this, !isMinimized()); } // if not minimized, adjust all snapped dependents to new shape if (!isMinimized()) { + if (by_user) + { + if (isDocked()) + { + setDocked( false, false); + } + storeRectControl(); + mPositioning = LLFloaterEnums::POSITIONING_RELATIVE; + LLRect screen_rect = calcScreenRect(); + mPosition = LLCoordGL(screen_rect.getCenterX(), screen_rect.getCenterY()).convert(); + } + // gather all snapped dependents for(handle_set_iter_t dependent_it = mDependents.begin(); dependent_it != mDependents.end(); ++dependent_it) @@ -1707,56 +1716,10 @@ void LLFloater::onClickHelp( LLFloater* self ) } } -// static -LLFloater* LLFloater::getClosableFloaterFromFocus() -{ - LLFloater* focused_floater = NULL; - LLInstanceTracker<LLFloater>::instance_iter it = beginInstances(); - LLInstanceTracker<LLFloater>::instance_iter end_it = endInstances(); - for (; it != end_it; ++it) - { - if (it->hasFocus()) - { - LLFloater& floater = *it; - focused_floater = &floater; - break; - } - } - - if (it == endInstances()) - { - // nothing found, return - return NULL; - } - - // The focused floater may not be closable, - // Find and close a parental floater that is closeable, if any. - LLFloater* prev_floater = NULL; - for(LLFloater* floater_to_close = focused_floater; - NULL != floater_to_close; - floater_to_close = gFloaterView->getParentFloater(floater_to_close)) - { - if(floater_to_close->isCloseable()) - { - return floater_to_close; - } - - // If floater has as parent root view - // gFloaterView->getParentFloater(floater_to_close) returns - // the same floater_to_close, so we need to check this. - if (prev_floater == floater_to_close) { - break; - } - prev_floater = floater_to_close; - } - - return NULL; -} - // static -void LLFloater::closeFocusedFloater() +void LLFloater::closeFrontmostFloater() { - LLFloater* floater_to_close = LLFloater::getClosableFloaterFromFocus(); + LLFloater* floater_to_close = gFloaterView->getFrontmostClosableFloater(); if(floater_to_close) { floater_to_close->closeFloater(); @@ -2474,6 +2437,24 @@ void LLFloaterView::highlightFocusedFloater() } } +LLFloater* LLFloaterView::getFrontmostClosableFloater() +{ + child_list_const_iter_t child_it; + LLFloater* frontmost_floater = NULL; + + for ( child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) + { + frontmost_floater = (LLFloater *)(*child_it); + + if (frontmost_floater->isInVisibleChain() && frontmost_floater->isCloseable()) + { + return frontmost_floater; + } + } + + return NULL; +} + void LLFloaterView::unhighlightFocusedFloater() { for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 64d6dcea04..0484ca622b 100644 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -325,12 +325,10 @@ public: virtual void setTornOff(bool torn_off) { mTornOff = torn_off; } - // Return a closeable floater, if any, given the current focus. - static LLFloater* getClosableFloaterFromFocus(); - // Close the floater returned by getClosableFloaterFromFocus() and + // Close the floater returned by getFrontmostClosableFloater() and // handle refocusing. - static void closeFocusedFloater(); + static void closeFrontmostFloater(); // LLNotification::Params contextualNotification(const std::string& name) // { @@ -559,6 +557,7 @@ public: S32 getZOrder(LLFloater* child); void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; } + LLFloater* getFrontmostClosableFloater(); private: void hiddenFloaterClosed(LLFloater* floater); diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index efb9848a90..cd6cc6a75e 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -1764,6 +1764,25 @@ bool LLMenuGL::addChild(LLView* view, S32 tab_group) return false; } +// Used in LLContextMenu and in LLTogleableMenu +// to add an item of context menu branch +bool LLMenuGL::addContextChild(LLView* view, S32 tab_group) +{ + LLContextMenu* context = dynamic_cast<LLContextMenu*>(view); + if (context) + return appendContextSubMenu(context); + + LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view); + if (separator) + return append(separator); + + LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view); + if (item) + return append(item); + + return false; +} + void LLMenuGL::removeChild( LLView* ctrl) { // previously a dynamic_cast with if statement to check validity @@ -2501,6 +2520,30 @@ BOOL LLMenuGL::appendMenu( LLMenuGL* menu ) return success; } +// add a context menu branch +BOOL LLMenuGL::appendContextSubMenu(LLMenuGL *menu) +{ + if (menu == this) + { + llerrs << "Can't attach a context menu to itself" << llendl; + } + + LLContextMenuBranch *item; + LLContextMenuBranch::Params p; + p.name = menu->getName(); + p.label = menu->getLabel(); + p.branch = (LLContextMenu *)menu; + p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); + p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); + p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); + p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); + + item = LLUICtrlFactory::create<LLContextMenuBranch>(p); + LLMenuGL::sMenuContainer->addChild(item->getBranch()); + + return append( item ); +} + void LLMenuGL::setEnabledSubMenus(BOOL enable) { setEnabled(enable); @@ -3725,39 +3768,6 @@ void LLTearOffMenu::closeTearOff() mMenu->setDropShadowed(TRUE); } - -//----------------------------------------------------------------------------- -// class LLContextMenuBranch -// A branch to another context menu -//----------------------------------------------------------------------------- -class LLContextMenuBranch : public LLMenuItemGL -{ -public: - struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params> - { - Mandatory<LLContextMenu*> branch; - }; - - LLContextMenuBranch(const Params&); - - virtual ~LLContextMenuBranch() - {} - - // called to rebuild the draw label - virtual void buildDrawLabel( void ); - - // onCommit() - do the primary funcationality of the menu item. - virtual void onCommit( void ); - - LLContextMenu* getBranch() { return mBranch.get(); } - void setHighlight( BOOL highlight ); - -protected: - void showSubMenu(); - - LLHandle<LLContextMenu> mBranch; -}; - LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) : LLMenuItemGL(p), mBranch( p.branch()->getHandle() ) @@ -4034,44 +4044,8 @@ void LLContextMenu::draw() LLMenuGL::draw(); } -BOOL LLContextMenu::appendContextSubMenu(LLContextMenu *menu) -{ - - if (menu == this) - { - llerrs << "Can't attach a context menu to itself" << llendl; - } - - LLContextMenuBranch *item; - LLContextMenuBranch::Params p; - p.name = menu->getName(); - p.label = menu->getLabel(); - p.branch = menu; - p.enabled_color=LLUIColorTable::instance().getColor("MenuItemEnabledColor"); - p.disabled_color=LLUIColorTable::instance().getColor("MenuItemDisabledColor"); - p.highlight_bg_color=LLUIColorTable::instance().getColor("MenuItemHighlightBgColor"); - p.highlight_fg_color=LLUIColorTable::instance().getColor("MenuItemHighlightFgColor"); - - item = LLUICtrlFactory::create<LLContextMenuBranch>(p); - LLMenuGL::sMenuContainer->addChild(item->getBranch()); - - return append( item ); -} - bool LLContextMenu::addChild(LLView* view, S32 tab_group) { - LLContextMenu* context = dynamic_cast<LLContextMenu*>(view); - if (context) - return appendContextSubMenu(context); - - LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view); - if (separator) - return append(separator); - - LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view); - if (item) - return append(item); - - return false; + return addContextChild(view, tab_group); } diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 67b3e1fbe6..00899020bc 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -519,6 +519,9 @@ public: void resetScrollPositionOnShow(bool reset_scroll_pos) { mResetScrollPositionOnShow = reset_scroll_pos; } bool isScrollPositionOnShowReset() { return mResetScrollPositionOnShow; } + // add a context menu branch + BOOL appendContextSubMenu(LLMenuGL *menu); + protected: void createSpilloverBranch(); void cleanupSpilloverBranch(); @@ -528,6 +531,10 @@ protected: // add a menu - this will create a cascading menu virtual BOOL appendMenu( LLMenuGL* menu ); + // Used in LLContextMenu and in LLTogleableMenu + // to add an item of context menu branch + bool addContextChild(LLView* view, S32 tab_group); + // TODO: create accessor methods for these? typedef std::list< LLMenuItemGL* > item_list_t; item_list_t mItems; @@ -679,8 +686,6 @@ public: virtual bool addChild (LLView* view, S32 tab_group = 0); - BOOL appendContextSubMenu(LLContextMenu *menu); - LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); } LLView* getSpawningView() const { return mSpawningViewHandle.get(); } @@ -694,6 +699,38 @@ protected: }; +//----------------------------------------------------------------------------- +// class LLContextMenuBranch +// A branch to another context menu +//----------------------------------------------------------------------------- +class LLContextMenuBranch : public LLMenuItemGL +{ +public: + struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params> + { + Mandatory<LLContextMenu*> branch; + }; + + LLContextMenuBranch(const Params&); + + virtual ~LLContextMenuBranch() + {} + + // called to rebuild the draw label + virtual void buildDrawLabel( void ); + + // onCommit() - do the primary funcationality of the menu item. + virtual void onCommit( void ); + + LLContextMenu* getBranch() { return mBranch.get(); } + void setHighlight( BOOL highlight ); + +protected: + void showSubMenu(); + + LLHandle<LLContextMenu> mBranch; +}; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Class LLMenuBarGL diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp index 87aeb4d7a7..ba90fa5e0c 100644 --- a/indra/llui/llresizebar.cpp +++ b/indra/llui/llresizebar.cpp @@ -139,13 +139,6 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) if( valid_rect.localPointInRect( screen_x, screen_y ) && mResizingView ) { - // undock floater when user resize it - LLFloater* parent = dynamic_cast<LLFloater*>( getParent()); - if (parent && parent->isDocked()) - { - parent->setDocked( false, false); - } - // Resize the parent LLRect orig_rect = mResizingView->getRect(); LLRect scaled_rect = orig_rect; @@ -219,20 +212,66 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) // update last valid mouse cursor position based on resized view's actual size LLRect new_rect = mResizingView->getRect(); + switch(mSide) { case LEFT: - mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft; + { + S32 actual_delta_x = new_rect.mLeft - orig_rect.mLeft; + if (actual_delta_x != delta_x) + { + // restore everything by left + new_rect.mBottom = orig_rect.mBottom; + new_rect.mTop = orig_rect.mTop; + new_rect.mRight = orig_rect.mRight; + mResizingView->setShape(new_rect, true); + } + mDragLastScreenX += actual_delta_x; + break; + } case RIGHT: + { + S32 actual_delta_x = new_rect.mRight - orig_rect.mRight; + if (actual_delta_x != delta_x) + { + // restore everything by left + new_rect.mBottom = orig_rect.mBottom; + new_rect.mTop = orig_rect.mTop; + new_rect.mLeft = orig_rect.mLeft; + mResizingView->setShape(new_rect, true); + } mDragLastScreenX += new_rect.mRight - orig_rect.mRight; break; + } case TOP: + { + S32 actual_delta_y = new_rect.mTop - orig_rect.mTop; + if (actual_delta_y != delta_y) + { + // restore everything by left + new_rect.mBottom = orig_rect.mBottom; + new_rect.mLeft = orig_rect.mLeft; + new_rect.mRight = orig_rect.mRight; + mResizingView->setShape(new_rect, true); + } mDragLastScreenY += new_rect.mTop - orig_rect.mTop; break; + } case BOTTOM: + { + S32 actual_delta_y = new_rect.mBottom - orig_rect.mBottom; + if (actual_delta_y != delta_y) + { + // restore everything by left + new_rect.mTop = orig_rect.mTop; + new_rect.mLeft = orig_rect.mLeft; + new_rect.mRight = orig_rect.mRight; + mResizingView->setShape(new_rect, true); + } mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom; break; + } default: break; } diff --git a/indra/llui/llresizehandle.cpp b/indra/llui/llresizehandle.cpp index c3a51c36c9..24794305ac 100644 --- a/indra/llui/llresizehandle.cpp +++ b/indra/llui/llresizehandle.cpp @@ -257,23 +257,65 @@ BOOL LLResizeHandle::handleHover(S32 x, S32 y, MASK mask) // update last valid mouse cursor position based on resized view's actual size LLRect new_rect = resizing_view->getRect(); + S32 actual_delta_x = 0; + S32 actual_delta_y = 0; switch(mCorner) { case LEFT_TOP: - mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft; - mDragLastScreenY += new_rect.mTop - orig_rect.mTop; + actual_delta_x = new_rect.mLeft - orig_rect.mLeft; + actual_delta_y = new_rect.mTop - orig_rect.mTop; + if (actual_delta_x != delta_x + || actual_delta_y != delta_y) + { + new_rect.mRight = orig_rect.mRight; + new_rect.mBottom = orig_rect.mBottom; + resizing_view->setShape(new_rect, true); + } + + mDragLastScreenX += actual_delta_x; + mDragLastScreenY += actual_delta_y; break; case LEFT_BOTTOM: - mDragLastScreenX += new_rect.mLeft - orig_rect.mLeft; - mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom; + actual_delta_x = new_rect.mLeft - orig_rect.mLeft; + actual_delta_y = new_rect.mBottom - orig_rect.mBottom; + if (actual_delta_x != delta_x + || actual_delta_y != delta_y) + { + new_rect.mRight = orig_rect.mRight; + new_rect.mTop = orig_rect.mTop; + resizing_view->setShape(new_rect, true); + } + + mDragLastScreenX += actual_delta_x; + mDragLastScreenY += actual_delta_y; break; case RIGHT_TOP: - mDragLastScreenX += new_rect.mRight - orig_rect.mRight; - mDragLastScreenY += new_rect.mTop - orig_rect.mTop; + actual_delta_x = new_rect.mRight - orig_rect.mRight; + actual_delta_y = new_rect.mTop - orig_rect.mTop; + if (actual_delta_x != delta_x + || actual_delta_y != delta_y) + { + new_rect.mLeft = orig_rect.mLeft; + new_rect.mBottom = orig_rect.mBottom; + resizing_view->setShape(new_rect, true); + } + + mDragLastScreenX += actual_delta_x; + mDragLastScreenY += actual_delta_y; break; case RIGHT_BOTTOM: - mDragLastScreenX += new_rect.mRight - orig_rect.mRight; - mDragLastScreenY += new_rect.mBottom- orig_rect.mBottom; + actual_delta_x = new_rect.mRight - orig_rect.mRight; + actual_delta_y = new_rect.mBottom - orig_rect.mBottom; + if (actual_delta_x != delta_x + || actual_delta_y != delta_y) + { + new_rect.mLeft = orig_rect.mLeft; + new_rect.mTop = orig_rect.mTop; + resizing_view->setShape(new_rect, true); + } + + mDragLastScreenX += actual_delta_x; + mDragLastScreenY += actual_delta_y; break; default: break; diff --git a/indra/llui/lltoggleablemenu.cpp b/indra/llui/lltoggleablemenu.cpp index d29260750f..b4c6c6162b 100644 --- a/indra/llui/lltoggleablemenu.cpp +++ b/indra/llui/lltoggleablemenu.cpp @@ -99,3 +99,8 @@ bool LLToggleableMenu::toggleVisibility() return true; } + +bool LLToggleableMenu::addChild(LLView* view, S32 tab_group) +{ + return addContextChild(view, tab_group); +} diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h index 2094bd776f..4717b0d0ba 100644 --- a/indra/llui/lltoggleablemenu.h +++ b/indra/llui/lltoggleablemenu.h @@ -47,6 +47,8 @@ public: virtual void handleVisibilityChange (BOOL curVisibilityIn); + virtual bool addChild (LLView* view, S32 tab_group = 0); + const LLRect& getButtonRect() const { return mButtonRect; } // Converts the given local button rect to a screen rect diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h index d612ad5005..4e54354731 100644 --- a/indra/llui/lluictrlfactory.h +++ b/indra/llui/lluictrlfactory.h @@ -31,18 +31,10 @@ #include "llinitparam.h" #include "llregistry.h" #include "llxuiparser.h" +#include "llstl.h" class LLView; -// sort functor for typeid maps -struct LLCompareTypeID -{ - bool operator()(const std::type_info* lhs, const std::type_info* rhs) const - { - return lhs->before(*rhs); - } -}; - // lookup widget constructor funcs by widget name template <typename DERIVED_TYPE> class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorFunc, DERIVED_TYPE> @@ -71,14 +63,14 @@ protected: // lookup widget name by type class LLWidgetNameRegistry -: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry , LLCompareTypeID> +: public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry> {}; // lookup function for generating empty param block by widget type // this is used for schema generation //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)(); //class LLDefaultParamBlockRegistry -//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry, LLCompareTypeID> +//: public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry> //{}; extern LLFastTimer::DeclareTimer FTM_WIDGET_SETUP; diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 64122bbb6c..92a241857e 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -48,6 +48,6 @@ --> </array> </map> - </array> + </array> </map> </llsd> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9e2c529eb3..f896b1ec64 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -5168,7 +5168,7 @@ <key>Comment</key> <string>Center the focal point of the minimap.</string> <key>Persist</key> - <integer>0</integer> + <integer>1</integer> <key>Type</key> <string>Boolean</string> <key>Value</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 90a6923d8a..a8763aae0c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -727,10 +727,6 @@ bool LLAppViewer::init() mAlloc.setProfilingEnabled(gSavedSettings.getBOOL("MemProfiling")); -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::initClass(); -#endif - // *NOTE:Mani - LLCurl::initClass is not thread safe. // Called before threads are created. LLCurl::initClass(gSavedSettings.getF32("CurlRequestTimeOut"), @@ -797,9 +793,6 @@ bool LLAppViewer::init() ////////////////////////////////////////////////////////////////////////////// // *FIX: The following code isn't grouped into functions yet. - // Statistics / debug timer initialization - init_statistics(); - // // Various introspection concerning the libs we're using - particularly // the libs involved in getting to a full login screen. @@ -1185,6 +1178,8 @@ static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback"); static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot"); static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update"); +LLFastTimer::DeclareTimer FTM_FRAME("Frame", true); + bool LLAppViewer::mainLoop() { mMainloopTimeout = new LLWatchdogTimeout(); @@ -1222,7 +1217,8 @@ bool LLAppViewer::mainLoop() // Handle messages while (!LLApp::isExiting()) { - LLFastTimer::nextFrame(); // Should be outside of any timer instances + LLFastTimer _(FTM_FRAME); + LLFastTimer::nextFrame(); //clear call stack records llclearcallstacks; @@ -1911,10 +1907,6 @@ bool LLAppViewer::cleanup() LLMetricPerformanceTesterBasic::cleanClass() ; -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::cleanupClass(); -#endif - llinfos << "Cleaning up Media and Textures" << llendflush; //Note: @@ -3147,8 +3139,6 @@ void LLAppViewer::writeSystemInfo() LL_INFOS("SystemInfo") << "OS: " << getOSInfo().getOSStringSimple() << LL_ENDL; LL_INFOS("SystemInfo") << "OS info: " << getOSInfo() << LL_ENDL; - LL_INFOS("SystemInfo") << "Timers: " << LLFastTimer::sClockType << LL_ENDL; - writeDebugInfo(); // Save out debug_info.log early, in case of crash. } @@ -4245,7 +4235,6 @@ void LLAppViewer::idle() // of SEND_STATS_PERIOD so that the initial stats report will // be sent immediately. static LLFrameStatsTimer viewer_stats_timer(SEND_STATS_PERIOD); - reset_statistics(); // Update session stats every large chunk of time // *FIX: (???) SAMANTHA @@ -4305,7 +4294,7 @@ void LLAppViewer::idle() idle_afk_check(); // Update statistics for this frame - update_statistics(gFrameCount); + update_statistics(); } //////////////////////////////////////// diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index ae3c795d1e..cdf4426469 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -41,6 +41,9 @@ class LLTextureFetch; class LLWatchdogTimeout; class LLUpdaterService; +extern LLFastTimer::DeclareTimer FTM_FRAME; + + class LLAppViewer : public LLApp { public: diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index a264eae302..1b0b11298c 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1192,7 +1192,7 @@ static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_MIN_MAX("Min/Max"); static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RGB2LUM("RGB to Luminance"); static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_RESCALE("Rescale"); static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_GEN_NORMAL("Generate Normal"); -static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Create"); +static LLFastTimer::DeclareTimer FTM_BUMP_SOURCE_CREATE("Bump Source Create"); // static void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLImageRaw* src, LLUUID& source_asset_id, EBumpEffect bump_code ) diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 9664aa7dbe..4dfb93f1bc 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -95,7 +95,6 @@ LLFastTimerView::LLFastTimerView(const LLSD& key) mHoverBarIndex = -1; FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount(); mPrintStats = -1; - mAverageCyclesPerTimer = 0; } void LLFastTimerView::onPause() @@ -161,7 +160,7 @@ LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y) BOOL LLFastTimerView::handleDoubleClick(S32 x, S32 y, MASK mask) { - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -258,7 +257,7 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask) } S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it, ++i) { @@ -379,12 +378,6 @@ void LLFastTimerView::draw() S32 xleft = margin; S32 ytop = margin; - mAverageCyclesPerTimer = LLFastTimer::sTimerCalls == 0 - ? 0 - : llround(lerp((F32)mAverageCyclesPerTimer, (F32)(LLFastTimer::sTimerCycles / (U64)LLFastTimer::sTimerCalls), 0.1f)); - LLFastTimer::sTimerCycles = 0; - LLFastTimer::sTimerCalls = 0; - // Draw some help { @@ -392,10 +385,6 @@ void LLFastTimerView::draw() y = height - ytop; texth = (S32)LLFontGL::getFontMonospace()->getLineHeight(); -#if TIME_FAST_TIMERS - tdesc = llformat("Cycles per timer call: %d", mAverageCyclesPerTimer); - LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -#else char modedesc[][32] = { "2 x Average ", "Max ", @@ -419,7 +408,6 @@ void LLFastTimerView::draw() LLFontGL::getFontMonospace()->renderUTF8(std::string("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]"), 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP); -#endif y -= (texth + 2); } @@ -431,11 +419,11 @@ void LLFastTimerView::draw() y -= (texth + 2); - sTimerColors[&LLFastTimer::NamedTimer::getRootNamedTimer()] = LLColor4::grey; + sTimerColors[&getFrameTimer()] = LLColor4::grey; F32 hue = 0.f; - for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != timer_tree_iterator_t(); ++it) { @@ -460,7 +448,7 @@ void LLFastTimerView::draw() S32 cur_line = 0; ft_display_idx.clear(); std::map<LLFastTimer::NamedTimer*, S32> display_line; - for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for (timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != timer_tree_iterator_t(); ++it) { @@ -526,6 +514,7 @@ void LLFastTimerView::draw() 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(); } @@ -570,7 +559,7 @@ void LLFastTimerView::draw() U64 totalticks; if (!LLFastTimer::sPauseHistory) { - U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(mScrollIndex); + U64 ticks = getFrameTimer().getHistoricalCount(mScrollIndex); if (LLFastTimer::getCurFrameIndex() >= 10) { @@ -610,7 +599,7 @@ void LLFastTimerView::draw() totalticks = 0; for (S32 j=0; j<histmax; j++) { - U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(j); + U64 ticks = getFrameTimer().getHistoricalCount(j); if (ticks > totalticks) totalticks = ticks; @@ -716,7 +705,7 @@ void LLFastTimerView::draw() LLFastTimer::NamedTimer* prev_id = NULL; S32 i = 0; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it, ++i) { @@ -793,6 +782,7 @@ void LLFastTimerView::draw() 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(); } @@ -879,7 +869,7 @@ void LLFastTimerView::draw() } U64 cur_max = 0; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -980,7 +970,7 @@ void LLFastTimerView::draw() { std::string legend_stat; bool first = true; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -1002,7 +992,7 @@ void LLFastTimerView::draw() std::string timer_stat; first = true; - for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer()); + for(timer_tree_iterator_t it = begin_timer_tree(getFrameTimer()); it != end_timer_tree(); ++it) { @@ -1563,3 +1553,9 @@ void LLFastTimerView::onClickCloseBtn() setVisible(false); } +LLFastTimer::NamedTimer& LLFastTimerView::getFrameTimer() +{ + return FTM_FRAME.getNamedTimer(); +} + + diff --git a/indra/newview/llfasttimerview.h b/indra/newview/llfasttimerview.h index a349e7ad4c..5766cfa0b0 100644 --- a/indra/newview/llfasttimerview.h +++ b/indra/newview/llfasttimerview.h @@ -46,6 +46,7 @@ private: static LLSD analyzePerformanceLogDefault(std::istream& is) ; static void exportCharts(const std::string& base, const std::string& target); void onPause(); + LLFastTimer::NamedTimer& getFrameTimer(); public: @@ -90,7 +91,6 @@ private: S32 mHoverBarIndex; LLFrameTimer mHighlightTimer; S32 mPrintStats; - S32 mAverageCyclesPerTimer; LLRect mGraphRect; }; diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 22c265cb8a..a37e27363f 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -48,7 +48,7 @@ std::vector<LLVolumeImplFlexible*> LLVolumeImplFlexible::sInstanceList; std::vector<S32> LLVolumeImplFlexible::sUpdateDelay; static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild"); -static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update"); +static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Flexible Update"); // LLFlexibleObjectData::pack/unpack now in llprimitive.cpp diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index 21b58d3e3d..c85d048c5a 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -330,6 +330,10 @@ void LLFloaterCamera::onClose(bool app_quitting) //We don't care of camera mode if app is quitting if(app_quitting) return; + // It is necessary to reset mCurrMode to CAMERA_CTRL_MODE_PAN so + // to avoid seeing an empty floater when reopening the control. + if (mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA) + mCurrMode = CAMERA_CTRL_MODE_PAN; // When mCurrMode is in CAMERA_CTRL_MODE_PAN // switchMode won't modify mPrevMode, so force it here. // It is needed to correctly return to previous mode on open, see EXT-2727. diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 05d73c2416..d6ebe44daa 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -172,9 +172,9 @@ void LLFloaterColorPicker::createUI () // void LLFloaterColorPicker::showUI () { + openFloater(getKey()); setVisible ( TRUE ); setFocus ( TRUE ); - openFloater(getKey()); // HACK: if system color picker is required - close the SL one we made and use default system dialog if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index c37798c330..d0c22d25f2 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -33,6 +33,7 @@ #include "llerror.h" #include "llrect.h" #include "llstring.h" +#include "llstat.h" // project includes #include "lluictrlfactory.h" @@ -83,7 +84,8 @@ BOOL LLFloaterJoystick::postBuild() for (U32 i = 0; i < 6; i++) { - mAxisStats[i] = new LLStat(4); + std::string stat_name(llformat("Joystick axis %d", i)); + mAxisStats[i] = new LLStat(stat_name, 4); std::string axisname = llformat("axis%d", i); mAxisStatsBar[i] = getChild<LLStatBar>(axisname); if (mAxisStatsBar[i]) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 55f3d548ec..be743d57d2 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -783,8 +783,9 @@ void LLPanelLandGeneral::refresh() mBtnReleaseLand->setEnabled( can_release ); } - BOOL use_pass = parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();; + BOOL use_pass = parcel->getOwnerID()!= gAgent.getID() && parcel->getParcelFlag(PF_USE_PASS_LIST) && !LLViewerParcelMgr::getInstance()->isCollisionBanned();; mBtnBuyPass->setEnabled(use_pass); + } } diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index a65e9e911a..473e2938be 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -122,16 +122,13 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) LLVector3d pos_global = mMap->viewPosToGlobal(x, y); - // If we're not tracking a beacon already, double-click will set one - if (!LLTracker::isTracking(NULL)) + LLTracker::stopTracking(NULL); + LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance(); + if (world_map) { - LLFloaterWorldMap* world_map = LLFloaterWorldMap::getInstance(); - if (world_map) - { - world_map->trackLocation(pos_global); - } + world_map->trackLocation(pos_global); } - + if (gSavedSettings.getBOOL("DoubleClickTeleport")) { // If DoubleClickTeleport is on, double clicking the minimap will teleport there @@ -249,3 +246,8 @@ void LLFloaterMap::handleZoom(const LLSD& userdata) mMap->setScale(scale); } } + +LLFloaterMap* LLFloaterMap::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map"); +} diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index 8a1b965e62..ff2fb20535 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -39,6 +39,7 @@ class LLFloaterMap : public LLFloater { public: LLFloaterMap(const LLSD& key); + static LLFloaterMap* getInstance(); virtual ~LLFloaterMap(); /*virtual*/ BOOL postBuild(); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index b86c453d61..c067a86104 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3173,6 +3173,7 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH); const LLUUID lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND); + const LLUUID favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE); if (lost_and_found_id == mUUID) { @@ -3186,7 +3187,10 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags) mDisabledItems.push_back(std::string("New Clothes")); mDisabledItems.push_back(std::string("New Body Parts")); } - + if (favorites == mUUID) + { + mDisabledItems.push_back(std::string("New Folder")); + } if(trash_id == mUUID) { // This is the trash. @@ -4624,6 +4628,10 @@ void LLCallingCardBridge::buildContextMenu(LLMenuGL& menu, U32 flags) { disabled_items.push_back(std::string("Share")); } + if ((flags & FIRST_SELECTED_ITEM) == 0) + { + disabled_items.push_back(std::string("Open")); + } addOpenRightClickMenuOption(items); items.push_back(std::string("Properties")); @@ -5590,7 +5598,8 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags) items.push_back(std::string("Wearable Edit")); - if ((flags & FIRST_SELECTED_ITEM) == 0) + bool modifiable = !gAgentWearables.isWearableModifiable(item->getUUID()); + if (((flags & FIRST_SELECTED_ITEM) == 0) || modifiable) { disabled_items.push_back(std::string("Wearable Edit")); } diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index c6df207552..f7567baa2b 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -44,6 +44,7 @@ #include "llinventoryfunctions.h" #include "llinventorymodelbackgroundfetch.h" #include "llsidepanelinventory.h" +#include "lltrans.h" #include "llviewerattachmenu.h" #include "llviewerfoldertype.h" #include "llvoavatarself.h" @@ -973,7 +974,6 @@ bool LLInventoryPanel::beginIMSession() std::set<LLUUID> selected_items = mFolderRoot->getSelectionList(); std::string name; - static int session_num = 1; LLDynamicArray<LLUUID> members; EInstantMessage type = IM_SESSION_CONFERENCE_START; @@ -1053,7 +1053,7 @@ bool LLInventoryPanel::beginIMSession() if (name.empty()) { - name = llformat("Session %d", session_num++); + name = LLTrans::getString("conference-title"); } LLUUID session_id = gIMMgr->addSession(name, type, members[0], members); diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index 11b057eb0d..472c26e22d 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -336,7 +336,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( // ...schedule a callback LLAvatarNameCache::get(id, boost::bind(&LLNameListCtrl::onAvatarNameCache, - this, _1, _2)); + this, _1, _2, item->getHandle())); } break; } @@ -392,7 +392,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id) } void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, - const LLAvatarName& av_name) + const LLAvatarName& av_name, + LLHandle<LLNameListItem> item) { std::string name; if (mShortNames) @@ -400,18 +401,14 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id, else name = av_name.getCompleteName(); - item_list::iterator iter; - for (iter = getItemList().begin(); iter != getItemList().end(); ++iter) + LLNameListItem* list_item = item.get(); + if (list_item && list_item->getUUID() == agent_id) { - LLScrollListItem* item = *iter; - if (item->getUUID() == agent_id) + LLScrollListCell* cell = list_item->getColumn(mNameColumnIndex); + if (cell) { - LLScrollListCell* cell = item->getColumn(mNameColumnIndex); - if (cell) - { - cell->setValue(name); - setNeedsSort(); - } + cell->setValue(name); + setNeedsSort(); } } diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h index 77c21f92e2..ba85e77c65 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -33,6 +33,26 @@ class LLAvatarName; +/** + * LLNameListCtrl item + * + * We don't use LLScrollListItem to be able to override getUUID(), which is needed + * because the name list item value is not simply an UUID but a map (uuid, is_group). + */ +class LLNameListItem : public LLScrollListItem, public LLHandleProvider<LLNameListItem> +{ +public: + LLUUID getUUID() const { return getValue()["uuid"].asUUID(); } +protected: + friend class LLNameListCtrl; + + LLNameListItem( const LLScrollListItem::Params& p ) + : LLScrollListItem(p) + { + } +}; + + class LLNameListCtrl : public LLScrollListCtrl, public LLInstanceTracker<LLNameListCtrl> { @@ -117,7 +137,7 @@ public: /*virtual*/ void mouseOverHighlightNthItem( S32 index ); private: void showInspector(const LLUUID& avatar_id, bool is_group); - void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name); + void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, LLHandle<LLNameListItem> item); private: S32 mNameColumnIndex; @@ -126,24 +146,5 @@ private: bool mShortNames; // display name only, no SLID }; -/** - * LLNameListCtrl item - * - * We don't use LLScrollListItem to be able to override getUUID(), which is needed - * because the name list item value is not simply an UUID but a map (uuid, is_group). - */ -class LLNameListItem : public LLScrollListItem -{ -public: - LLUUID getUUID() const { return getValue()["uuid"].asUUID(); } - -protected: - friend class LLNameListCtrl; - - LLNameListItem( const LLScrollListItem::Params& p ) - : LLScrollListItem(p) - { - } -}; #endif diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index f8f0f7d243..c00dc4bc89 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -203,7 +203,12 @@ BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask ) sendChat(CHAT_TYPE_SHOUT); handled = TRUE; } - + else if (KEY_RETURN == key && mask == MASK_SHIFT) + { + // whisper + sendChat(CHAT_TYPE_WHISPER); + handled = TRUE; + } return handled; } @@ -390,12 +395,6 @@ void LLNearbyChatBar::sendChat( EChatType type ) gAgent.stopTyping(); - // If the user wants to stop chatting on hitting return, lose focus - // and go out of chat mode. - if (gSavedSettings.getBOOL("CloseChatOnReturn")) - { - stopChat(); - } } void LLNearbyChatBar::showNearbyChatPanel(bool show) @@ -446,7 +445,12 @@ void LLNearbyChatBar::onChatBoxCommit() { sendChat(CHAT_TYPE_NORMAL); } - + // If the user wants to stop chatting on hitting return, lose focus + // and go out of chat mode. + if (gSavedSettings.getBOOL("CloseChatOnReturn")) + { + stopChat(); + } gAgent.stopTyping(); } diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index ef5ef2ddc8..c15b6bd0d3 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -117,6 +117,8 @@ public: registrar.add("Gear.Rename", boost::bind(&LLOutfitListGearMenu::onRename, this)); registrar.add("Gear.Delete", boost::bind(&LLOutfitsList::removeSelected, mOutfitList)); registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2)); + registrar.add("Gear.Collapse", boost::bind(&LLOutfitsList::collapse_all_folders, mOutfitList)); + registrar.add("Gear.Expand", boost::bind(&LLOutfitsList::expand_all_folders, mOutfitList)); registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this)); @@ -743,6 +745,34 @@ void LLOutfitsList::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const } } +void LLOutfitsList::collapse_all_folders() +{ + for (outfits_map_t::iterator iter = mOutfitsMap.begin(); + iter != mOutfitsMap.end(); + ++iter) + { + LLAccordionCtrlTab* tab = iter->second; + if(tab && tab->isExpanded()) + { + tab->changeOpenClose(true); + } + } +} + +void LLOutfitsList::expand_all_folders() +{ + for (outfits_map_t::iterator iter = mOutfitsMap.begin(); + iter != mOutfitsMap.end(); + ++iter) + { + LLAccordionCtrlTab* tab = iter->second; + if(tab && !tab->isExpanded()) + { + tab->changeOpenClose(false); + } + } +} + boost::signals2::connection LLOutfitsList::setSelectionChangeCallback(selection_change_callback_t cb) { return mSelectionChangeSignal.connect(cb); diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index a0598737f1..2e3fb3f488 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -108,6 +108,16 @@ public: */ bool hasItemSelected(); + /** + Collapses all outfit accordions. + */ + void collapse_all_folders(); + /** + Expands all outfit accordions. + */ + void expand_all_folders(); + + private: void onOutfitsRemovalConfirmation(const LLSD& notification, const LLSD& response); diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 68a3b6d1cd..d6fccb9705 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -418,12 +418,13 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_ bool LLLandmarksPanel::isLandmarkSelected() const { LLFolderViewItem* current_item = getCurSelectedItem(); - if(current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK) - { - return true; - } + return current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK; +} - return false; +bool LLLandmarksPanel::isFolderSelected() const +{ + LLFolderViewItem* current_item = getCurSelectedItem(); + return current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_CATEGORY; } bool LLLandmarksPanel::isReceivedFolderSelected() const @@ -720,7 +721,7 @@ void LLLandmarksPanel::initListCommandsHandlers() void LLLandmarksPanel::updateListCommands() { bool add_folder_enabled = isActionEnabled("category"); - bool trash_enabled = isActionEnabled("delete"); + bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()); // keep Options & Add Landmark buttons always enabled mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled); diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h index b2f4e92473..4e787317ba 100644 --- a/indra/newview/llpanellandmarks.h +++ b/indra/newview/llpanellandmarks.h @@ -84,6 +84,7 @@ protected: * @return true - if current selected panel is not null and selected item is a landmark */ bool isLandmarkSelected() const; + bool isFolderSelected() const; bool isReceivedFolderSelected() const; void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb); LLFolderViewItem* getCurSelectedItem() const; diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 28cfb5b282..fabb8daa6e 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -1174,6 +1174,8 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata) if (command_name == "share") { + LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem(); + if (!current_item) return FALSE; LLSidepanelInventory* parent = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory"); return parent ? parent->canShare() : FALSE; } diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 6d321d4716..6c2a01fc82 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -366,6 +366,7 @@ void LLPanelPlaces::onOpen(const LLSD& key) if (key.size() != 0) { + isLandmarkEditModeOn = false; std::string key_type = key["type"].asString(); if (key_type == LANDMARK_TAB_INFO_TYPE) { @@ -392,7 +393,6 @@ void LLPanelPlaces::onOpen(const LLSD& key) mPlaceInfoType = key_type; mPosGlobal.setZero(); mItem = NULL; - isLandmarkEditModeOn = false; togglePlaceInfoPanel(TRUE); if (mPlaceInfoType == AGENT_INFO_TYPE) diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index c63d89fc98..0756faf5c0 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -972,6 +972,11 @@ void LLTeleportHistoryPanel::onCollapseAllFolders() mItemContainers.get(n)->setDisplayChildren(false); } mHistoryAccordion->arrange(); + + if (mLastSelectedFlatlList) + { + mLastSelectedFlatlList->resetSelection(); + } } void LLTeleportHistoryPanel::onClearTeleportHistory() diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp index 280cc11179..1830086da2 100644 --- a/indra/newview/llpaneltopinfobar.cpp +++ b/indra/newview/llpaneltopinfobar.cpp @@ -64,9 +64,6 @@ private: LLPanelTopInfoBar::LLPanelTopInfoBar(): mParcelChangedObserver(0) { - LLUICtrl::CommitCallbackRegistry::currentRegistrar() - .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2)); - buildFromFile( "panel_topinfo_bar.xml"); } @@ -132,6 +129,11 @@ void LLPanelTopInfoBar::handleLoginComplete() BOOL LLPanelTopInfoBar::handleRightMouseDown(S32 x, S32 y, MASK mask) { + if(!LLUICtrl::CommitCallbackRegistry::getValue("TopInfoBar.Action")) + { + LLUICtrl::CommitCallbackRegistry::currentRegistrar() + .add("TopInfoBar.Action", boost::bind(&LLPanelTopInfoBar::onContextMenuItemClicked, this, _2)); + } show_topinfobar_context_menu(this, x, y); return TRUE; } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index 853656905c..d909a218e3 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -456,10 +456,10 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name) void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch) { LLFloaterSidePanelContainer::showPanel("appearance", LLSD()); - LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data); if (panel) { + panel->showOutfitsInventoryPanel(); panel->showWearableEditPanel(wearable, disable_camera_switch); } } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 30f796a78e..5083478392 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -55,7 +55,7 @@ #include "llviewershadermgr.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); -static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound"); +static LLFastTimer::DeclareTimer FTM_CULL_REBOUND("Cull Rebound Partition"); const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index d4b7c51441..77d76b99f4 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1393,7 +1393,7 @@ bool idle_startup() display_startup(); //reset statistics - LLViewerStats::getInstance()->resetStats(); + LLViewerStats::instance().resetStats(); display_startup(); // @@ -1922,7 +1922,7 @@ bool idle_startup() llinfos << "gAgentStartLocation : " << gAgentStartLocation << llendl; LLSLURL start_slurl = LLStartUp::getStartSLURL(); LL_DEBUGS("AppInit") << "start slurl "<<start_slurl.asString()<<LL_ENDL; - + if (((start_slurl.getType() == LLSLURL::LOCATION) && (gAgentStartLocation == "url")) || ((start_slurl.getType() == LLSLURL::LAST_LOCATION) && (gAgentStartLocation == "last")) || ((start_slurl.getType() == LLSLURL::HOME_LOCATION) && (gAgentStartLocation == "home"))) @@ -2269,7 +2269,7 @@ bool login_alert_status(const LLSD& notification, const LLSD& response) // break; case 2: // Teleport // Restart the login process, starting at our home locaton - LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); + LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME)); LLStartUp::setStartupState( STATE_LOGIN_CLEANUP ); break; default: @@ -2829,11 +2829,11 @@ void LLStartUp::setStartSLURL(const LLSLURL& slurl) case LLSLURL::HOME_LOCATION: case LLSLURL::LAST_LOCATION: case LLSLURL::LOCATION: - gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_HOME); + gSavedSettings.setString("LoginLocation", LLSLURL::SIM_LOCATION_HOME); LLPanelLogin::onUpdateStartSLURL(slurl); // updates grid if needed - break; + break; default: - break; + break; } } diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index 06bbe62f1b..ec11a23eb8 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -62,8 +62,6 @@ LLColor4U MAX_WATER_COLOR(0, 48, 96, 240); S32 LLSurface::sTextureSize = 256; -S32 LLSurface::sTexelsUpdated = 0; -F32 LLSurface::sTextureUpdateTime = 0.f; // ---------------- LLSurface:: Public Members --------------- diff --git a/indra/newview/llsurface.h b/indra/newview/llsurface.h index 8052fb0d18..9d24bf8771 100644 --- a/indra/newview/llsurface.h +++ b/indra/newview/llsurface.h @@ -169,9 +169,6 @@ public: F32 mDetailTextureScale; // Number of times to repeat detail texture across this surface - static F32 sTextureUpdateTime; - static S32 sTexelsUpdated; - protected: void createSTexture(); void createWaterTexture(); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 2ed7488b85..84d15cca72 100755 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -50,6 +50,7 @@ #include "llviewertexture.h" #include "llviewerregion.h" #include "llviewerstats.h" +#include "llviewerstatsrecorder.h" #include "llviewerassetstats.h" #include "llworld.h" #include "llsdutil.h" @@ -1709,6 +1710,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL; if (data_size > 0) { + LLViewerStatsRecorder::instance().textureFetch(data_size); // *TODO: set the formatted image data here directly to avoid the copy mBuffer = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), data_size); buffer->readAfter(channels.in(), NULL, mBuffer, data_size); @@ -1742,6 +1744,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels, mLoaded = TRUE; setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); + LLViewerStatsRecorder::instance().log(0.2f); return data_size ; } @@ -2645,6 +2648,9 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 return false; } + LLViewerStatsRecorder::instance().textureFetch(data_size); + LLViewerStatsRecorder::instance().log(0.1f); + worker->lockWorkMutex(); // Copy header data into image object @@ -2691,6 +2697,9 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1 return false; } + LLViewerStatsRecorder::instance().textureFetch(data_size); + LLViewerStatsRecorder::instance().log(0.1f); + worker->lockWorkMutex(); res = worker->insertPacket(packet_num, data, data_size); @@ -3239,7 +3248,7 @@ void LLTextureFetchDebugger::startDebug() } //collect statistics - mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime; std::set<LLUUID> fetched_textures; S32 size = mFetchingHistory.size(); @@ -3321,7 +3330,7 @@ void LLTextureFetchDebugger::stopDebug() //unlock the fetcher mFetcher->lockFetcher(false); mFreezeHistory = FALSE; - mTotalFetchingTime = gDebugTimers[0].getElapsedTimeF32(); //reset + mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset } //called in the main thread and when the fetching queue is empty @@ -3634,7 +3643,7 @@ bool LLTextureFetchDebugger::update() case REFETCH_VIS_CACHE: if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { - mRefetchVisCacheTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mRefetchVisCacheTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime; mState = IDLE; mFetcher->lockFetcher(true); } @@ -3642,7 +3651,7 @@ bool LLTextureFetchDebugger::update() case REFETCH_VIS_HTTP: if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { - mRefetchVisHTTPTime = gDebugTimers[0].getElapsedTimeF32() - mTotalFetchingTime; + mRefetchVisHTTPTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime; mState = IDLE; mFetcher->lockFetcher(true); } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index 107e1623b0..dbe46444d2 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -35,6 +35,7 @@ #include "lltextureinfo.h" #include "llapr.h" #include "llimageworker.h" +#include "llstat.h" //#include "lltexturecache.h" class LLViewerTexture; diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 8fef2ed6d1..3f75f8da5e 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -357,6 +357,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal if (mLineEditor) { mLineEditor->selectAll(); + mLineEditor->setFocus(TRUE); } if(mDefaultOption >= 0) { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 705edc27f6..ffeea2f4df 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -217,7 +217,7 @@ static LLFastTimer::DeclareTimer FTM_UPDATE_SKY("Update Sky"); static LLFastTimer::DeclareTimer FTM_UPDATE_TEXTURES("Update Textures"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE("Update Images"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_CLASS("Class"); -static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Bump"); +static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_BUMP("Image Update Bump"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_LIST("List"); static LLFastTimer::DeclareTimer FTM_IMAGE_UPDATE_DELETE("Delete"); static LLFastTimer::DeclareTimer FTM_RESIZE_WINDOW("Resize Window"); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index 1aa9fd8a45..f5d3341c66 100644 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -160,6 +160,11 @@ void agent_push_backward( EKeystate s ) camera_move_backward(s); return; } + else if (gAgentAvatarp->isSitting()) + { + gAgentCamera.changeCameraToThirdPerson(); + return; + } agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 01a54509ef..4ec498dc33 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -341,7 +341,8 @@ LLMenuParcelObserver::~LLMenuParcelObserver() void LLMenuParcelObserver::changed() { - gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL)); + LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(); + gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL) && !(parcel->getOwnerID()== gAgent.getID())); BOOL buyable = enable_buy_land(NULL); gMenuHolder->childSetEnabled("Land Buy", buyable); @@ -1316,22 +1317,6 @@ class LLAdvancedPrintAgentInfo : public view_listener_t } }; - - -//////////////////////////////// -// PRINT TEXTURE MEMORY STATS // -//////////////////////////////// - - -class LLAdvancedPrintTextureMemoryStats : public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - output_statistics(NULL); - return true; - } -}; - ////////////////// // DEBUG CLICKS // ////////////////// @@ -3463,6 +3448,20 @@ bool enable_sitdown_self() return isAgentAvatarValid() && !gAgentAvatarp->isSitting() && !gAgent.getFlying(); } +class LLCheckPanelPeopleTab : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + std::string panel_name = userdata.asString(); + + LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name); + if(panel && panel->isInVisibleChain()) + { + return true; + } + return false; + } +}; // Toggle one of "People" panel tabs in side tray. class LLTogglePanelPeopleTab : public view_listener_t { @@ -3940,6 +3939,7 @@ class LLViewToggleUI : public view_listener_t if (option == 0) // OK { gViewerWindow->setUIVisibility(!gViewerWindow->getUIVisibility()); + LLPanelStandStopFlying::getInstance()->setVisible(gViewerWindow->getUIVisibility()); } } }; @@ -8432,7 +8432,6 @@ void initialize_menus() 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"); - view_listener_t::addMenu(new LLAdvancedPrintTextureMemoryStats(), "Advanced.PrintTextureMemoryStats"); view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks"); view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks"); view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews"); @@ -8551,6 +8550,7 @@ void initialize_menus() // we don't use boost::bind directly to delay side tray construction view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab"); + view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab"); // Avatar pie menu view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute"); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index dc2ea4bd1f..be78603e2d 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -34,6 +34,7 @@ #include "llfilepicker.h" #include "llfloaterreg.h" #include "llbuycurrencyhtml.h" +#include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" #include "llimage.h" @@ -475,7 +476,7 @@ class LLFileEnableCloseWindow : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = NULL != LLFloater::getClosableFloaterFromFocus(); + bool new_value = NULL != gFloaterView->getFrontmostClosableFloater(); return new_value; } }; @@ -484,8 +485,7 @@ class LLFileCloseWindow : public view_listener_t { bool handleEvent(const LLSD& userdata) { - LLFloater::closeFocusedFloater(); - + LLFloater::closeFrontmostFloater(); return true; } }; @@ -494,7 +494,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool open_children = gFloaterView->allChildrenClosed(); + bool open_children = gFloaterView->allChildrenClosed() && !LLFloaterSnapshot::getInstance()->isInVisibleChain(); return !open_children; } }; @@ -505,7 +505,7 @@ class LLFileCloseAllWindows : public view_listener_t { bool app_quitting = false; gFloaterView->closeAllChildren(app_quitting); - + LLFloaterSnapshot::getInstance()->closeFloater(app_quitting); return true; } }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a0ca886c4c..85ea543838 100755 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3007,11 +3007,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - LLNotification::Params params("TeleportOffered"); - params.substitutions = args; - params.payload = payload; - LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); - } + LLNotification::Params params("TeleportOffered"); + params.substitutions = args; + params.payload = payload; + LLPostponedNotification::add<LLPostponedOfferNotification>( params, from_id, false); + } } } @@ -3102,10 +3102,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data) } else { - // do not show a message box, because you're about to be - // teleported. - LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); - } + // do not show a message box, because you're about to be + // teleported. + LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0); + } } break; @@ -4276,7 +4276,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) msg_number += 1; if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) { - //LL_INFOS("Messaging") << " head rot " << head_rotation << LL_ENDL; + //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL; } if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) @@ -4295,7 +4295,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable) { LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL; } - */ +*/ duplicate_count = 0; } @@ -4481,7 +4481,7 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_ gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED); } -static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Objects"); +static LLFastTimer::DeclareTimer FTM_PROCESS_OBJECTS("Process Kill Objects"); void process_kill_object(LLMessageSystem *mesgsys, void **user_data) @@ -5625,14 +5625,14 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg) bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - + if (0 == option) { // set the preference to the maturity of the region we're calling U8 preferredMaturity = static_cast<U8>(notification["payload"]["_region_access"].asInteger()); gSavedSettings.setU32("PreferredMaturity", static_cast<U32>(preferredMaturity)); } - + return false; } @@ -5695,7 +5695,7 @@ bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) gAgent.clearTeleportRequest(); maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); returnValue = true; - + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG() || gAgent.prefersMature()) @@ -5792,7 +5792,7 @@ bool handle_teleport_access_blocked(LLSD& llsdBlock) maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); returnValue = true; } - } + } if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) { @@ -5958,8 +5958,8 @@ void process_alert_core(const std::string& message, BOOL modal) std::string alert_name(message.substr(ALERT_PREFIX.length())); if (!handle_special_alerts(alert_name)) { - LLNotificationsUtil::add(alert_name); - } + LLNotificationsUtil::add(alert_name); + } } else if (message.find(NOTIFY_PREFIX) == 0) { diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 423bcc641d..88bb087742 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -332,6 +332,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U64 region_handle; mesgsys->getU64Fast(_PREHASH_RegionData, _PREHASH_RegionHandle, region_handle); + LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(region_handle); if (!regionp) @@ -343,16 +344,14 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U8 compressed_dpbuffer[2048]; LLDataPackerBinaryBuffer compressed_dp(compressed_dpbuffer, 2048); LLDataPacker *cached_dpp = NULL; - -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(regionp); -#endif + LLViewerStatsRecorder& recorder = LLViewerStatsRecorder::instance(); for (i = 0; i < num_objects; i++) { // timer is unused? LLTimer update_timer; BOOL justCreated = FALSE; + S32 msg_size = 0; if (cached) { @@ -360,6 +359,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, U32 crc; mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, id, i); mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_CRC, crc, i); + msg_size += sizeof(U32) * 2; // Lookup data packer and add this id to cache miss lists if necessary. U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE; @@ -375,9 +375,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, else { // Cache Miss. - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordCacheMissEvent(id, update_type, cache_miss_type); - #endif + recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size); continue; // no data packer, skip this object } @@ -420,6 +418,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, else if (update_type != OUT_FULL) // !compressed, !OUT_FULL ==> OUT_FULL_CACHED only? { mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); + msg_size += sizeof(U32); + getUUIDFromLocal(fullid, local_id, gMessageSystem->getSenderIP(), @@ -434,6 +434,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, { mesgsys->getUUIDFast(_PREHASH_ObjectData, _PREHASH_FullID, fullid, i); mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i); + msg_size += sizeof(LLUUID); + msg_size += sizeof(U32); // llinfos << "Full Update, obj " << local_id << ", global ID" << fullid << "from " << mesgsys->getSender() << llendl; } objectp = findObject(fullid); @@ -479,9 +481,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (update_type == OUT_TERSE_IMPROVED) { // llinfos << "terse update for an unknown object (compressed):" << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } } @@ -493,22 +493,20 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (update_type != OUT_FULL) { //llinfos << "terse update for an unknown object:" << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } mesgsys->getU8Fast(_PREHASH_ObjectData, _PREHASH_PCode, pcode, i); + msg_size += sizeof(U8); + } #ifdef IGNORE_DEAD if (mDeadObjects.find(fullid) != mDeadObjects.end()) { mNumDeadObjectUpdates++; //llinfos << "update for a dead object:" << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } #endif @@ -517,9 +515,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (!objectp) { llinfos << "createObject failure for object: " << fullid << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateFailure(local_id, update_type); - #endif + recorder.objectUpdateFailure(local_id, update_type, msg_size); continue; } justCreated = TRUE; @@ -545,12 +541,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, if (update_type != OUT_TERSE_IMPROVED) // OUT_FULL_COMPRESSED only? { bCached = true; - #if LL_RECORD_VIEWER_STATS LLViewerRegion::eCacheUpdateResult result = objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - LLViewerStatsRecorder::instance()->recordCacheFullUpdate(local_id, update_type, result, objectp); - #else - objectp->mRegionp->cacheFullUpdate(objectp, compressed_dp); - #endif + recorder.cacheFullUpdate(local_id, update_type, result, objectp, msg_size); } } else if (cached) // Cache hit only? @@ -566,16 +558,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, } processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated); } - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->recordObjectUpdateEvent(local_id, update_type, objectp); - #endif + recorder.objectUpdateEvent(local_id, update_type, objectp, msg_size); objectp->setLastUpdateType(update_type); objectp->setLastUpdateCached(bCached); } -#if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); -#endif + recorder.log(0.2f); LLVOAvatar::cullAvatarsByPixelArea(); } @@ -911,12 +899,12 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) static std::vector<LLViewerObject*> idle_list; U32 idle_count = 0; - + static LLFastTimer::DeclareTimer idle_copy("Idle Copy"); { LLFastTimer t(idle_copy); - + for (std::vector<LLPointer<LLViewerObject> >::iterator active_iter = mActiveObjects.begin(); active_iter != mActiveObjects.end(); active_iter++) { @@ -925,9 +913,9 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) { if (idle_count >= idle_list.size()) { - idle_list.push_back( objectp ); - } - else + idle_list.push_back( objectp ); + } + else { idle_list[idle_count] = objectp; } @@ -944,7 +932,7 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world) std::vector<LLViewerObject*>::iterator idle_end = idle_list.begin()+idle_count; if (gSavedSettings.getBOOL("FreezeTime")) - { + { for (std::vector<LLViewerObject*>::iterator iter = idle_list.begin(); iter != idle_end; iter++) @@ -1418,10 +1406,10 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) { mActiveObjects.push_back(objectp); objectp->setListIndex(mActiveObjects.size()-1); - objectp->setOnActiveList(TRUE); - } - else - { + objectp->setOnActiveList(TRUE); + } + else + { llassert(idx < mActiveObjects.size()); llassert(mActiveObjects[idx] == objectp); @@ -1547,13 +1535,13 @@ void LLViewerObjectList::shiftObjects(const LLVector3 &offset) { LLFastTimer t(FTM_PIPELINE_SHIFT); - gPipeline.shiftObjects(offset); + gPipeline.shiftObjects(offset); } { LLFastTimer t(FTM_REGION_SHIFT); - LLWorld::getInstance()->shiftRegions(offset); - } + LLWorld::getInstance()->shiftRegions(offset); +} } void LLViewerObjectList::repartitionObjects() @@ -1900,12 +1888,9 @@ LLViewerObject *LLViewerObjectList::createObjectViewer(const LLPCode pcode, LLVi } -static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object"); - LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRegion *regionp, const LLUUID &uuid, const U32 local_id, const LLHost &sender) { - LLFastTimer t(FTM_CREATE_OBJECT); LLUUID fullid; if (uuid == LLUUID::null) diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index 6c8a827ba3..0316f79973 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -59,8 +59,6 @@ #include "indra_constants.h" #include "llinitparam.h" -//#include "linden_common.h" -//#include "llpreprocessor.h" #include "llallocator.h" #include "llapp.h" #include "llcriticaldamp.h" @@ -77,10 +75,8 @@ #include "llprocessor.h" #include "llrefcount.h" #include "llsafehandle.h" -//#include "llsecondlifeurls.h" #include "llsd.h" #include "llsingleton.h" -#include "llstat.h" #include "llstl.h" #include "llstrider.h" #include "llstring.h" @@ -88,11 +84,8 @@ #include "llthread.h" #include "lltimer.h" #include "lluuidhashmap.h" -//#include "processor.h" #include "stdenums.h" #include "stdtypes.h" -//#include "string_table.h" -//#include "timer.h" #include "timing.h" #include "u64.h" diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 603460daf0..1b344bcd9a 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1342,11 +1342,8 @@ void LLViewerRegion::requestCacheMisses() mCacheDirty = TRUE ; // llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; - #if LL_RECORD_VIEWER_STATS - LLViewerStatsRecorder::instance()->beginObjectUpdateEvents(this); - LLViewerStatsRecorder::instance()->recordRequestCacheMissesEvent(full_count + crc_count); - LLViewerStatsRecorder::instance()->endObjectUpdateEvents(); - #endif + LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count); + LLViewerStatsRecorder::instance().log(0.2f); } void LLViewerRegion::dumpCache() @@ -1547,7 +1544,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("LandResources"); capabilityNames.append("MapLayer"); capabilityNames.append("MapLayerGod"); - capabilityNames.append("MeshUploadFlag"); + capabilityNames.append("MeshUploadFlag"); capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); capabilityNames.append("ObjectNavMeshProperties"); @@ -1587,7 +1584,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("ViewerMetrics"); capabilityNames.append("ViewerStartAuction"); capabilityNames.append("ViewerStats"); - + // Please add new capabilities alphabetically to reduce // merge conflicts. } diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 8fef13a6bc..1d6d5b7e72 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -290,19 +290,19 @@ LLViewerStats::~LLViewerStats() void LLViewerStats::resetStats() { - LLViewerStats::getInstance()->mKBitStat.reset(); - LLViewerStats::getInstance()->mLayersKBitStat.reset(); - LLViewerStats::getInstance()->mObjectKBitStat.reset(); - LLViewerStats::getInstance()->mTextureKBitStat.reset(); - LLViewerStats::getInstance()->mVFSPendingOperations.reset(); - LLViewerStats::getInstance()->mAssetKBitStat.reset(); - LLViewerStats::getInstance()->mPacketsInStat.reset(); - LLViewerStats::getInstance()->mPacketsLostStat.reset(); - LLViewerStats::getInstance()->mPacketsOutStat.reset(); - LLViewerStats::getInstance()->mFPSStat.reset(); - LLViewerStats::getInstance()->mTexturePacketsStat.reset(); - - LLViewerStats::getInstance()->mAgentPositionSnaps.reset(); + LLViewerStats& stats = LLViewerStats::instance(); + stats.mKBitStat.reset(); + stats.mLayersKBitStat.reset(); + stats.mObjectKBitStat.reset(); + stats.mTextureKBitStat.reset(); + stats.mVFSPendingOperations.reset(); + stats.mAssetKBitStat.reset(); + stats.mPacketsInStat.reset(); + stats.mPacketsLostStat.reset(); + stats.mPacketsOutStat.reset(); + stats.mFPSStat.reset(); + stats.mTexturePacketsStat.reset(); + stats.mAgentPositionSnaps.reset(); } @@ -327,55 +327,55 @@ void LLViewerStats::updateFrameStats(const F64 time_diff) { if (mPacketsLostPercentStat.getCurrent() > 5.0) { - incStat(LLViewerStats::ST_LOSS_05_SECONDS, time_diff); + incStat(ST_LOSS_05_SECONDS, time_diff); } if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f) { - incStat(LLViewerStats::ST_SIM_FPS_20_SECONDS, time_diff); + incStat(ST_SIM_FPS_20_SECONDS, time_diff); } if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f) { - incStat(LLViewerStats::ST_PHYS_FPS_20_SECONDS, time_diff); + incStat(ST_PHYS_FPS_20_SECONDS, time_diff); } if (time_diff >= 0.5) { - incStat(LLViewerStats::ST_FPS_2_SECONDS, time_diff); + incStat(ST_FPS_2_SECONDS, time_diff); } if (time_diff >= 0.125) { - incStat(LLViewerStats::ST_FPS_8_SECONDS, time_diff); + incStat(ST_FPS_8_SECONDS, time_diff); } if (time_diff >= 0.1) { - incStat(LLViewerStats::ST_FPS_10_SECONDS, time_diff); + incStat(ST_FPS_10_SECONDS, time_diff); } if (gFrameCount && mLastTimeDiff > 0.0) { // new "stutter" meter - setStat(LLViewerStats::ST_FPS_DROP_50_RATIO, - (getStat(LLViewerStats::ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + + setStat(ST_FPS_DROP_50_RATIO, + (getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount); // old stats that were never really used - setStat(LLViewerStats::ST_FRAMETIME_JITTER, - (getStat(LLViewerStats::ST_FRAMETIME_JITTER) * (gFrameCount - 1) + + setStat(ST_FRAMETIME_JITTER, + (getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) + fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount); F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount; - setStat(LLViewerStats::ST_FRAMETIME_SLEW, - (getStat(LLViewerStats::ST_FRAMETIME_SLEW) * (gFrameCount - 1) + + setStat(ST_FRAMETIME_SLEW, + (getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) + fabs(average_frametime - time_diff) / average_frametime) / gFrameCount); F32 max_bandwidth = gViewerThrottle.getMaxBandwidth(); F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth; - setStat(LLViewerStats::ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); + setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f); - setStat(LLViewerStats::ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); + setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f); } @@ -403,155 +403,8 @@ void LLViewerStats::addToMessage(LLSD &body) const << "; Count = " << mAgentPositionSnaps.getCount() << llendl; } -// static -// const std::string LLViewerStats::statTypeToText(EStatType type) -// { -// if (type >= 0 && type < ST_COUNT) -// { -// return STAT_INFO[type].mName; -// } -// else -// { -// return "Unknown statistic"; -// } -// } - // *NOTE:Mani The following methods used to exist in viewer.cpp // Moving them here, but not merging them into LLViewerStats yet. -void reset_statistics() -{ - if (LLSurface::sTextureUpdateTime) - { - LLSurface::sTexelsUpdated = 0; - LLSurface::sTextureUpdateTime = 0.f; - } -} - - -void output_statistics(void*) -{ - llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl; - llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl; - llinfos << "Num images: " << gTextureList.getNumImages() << llendl; - llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemoryInBytes << llendl; - llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemoryInBytes << llendl; - llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl; - llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl; - llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl; - llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl; - - llinfos << "Memory Usage:" << llendl; - llinfos << "--------------------------------" << llendl; - llinfos << "Pipeline:" << llendl; - llinfos << llendl; - -#if LL_SMARTHEAP - llinfos << "--------------------------------" << llendl; - { - llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl; - - U32 total_pool_size = 0; - U32 total_used_size = 0; - MEM_POOL_INFO pool_info; - MEM_POOL_STATUS pool_status; - U32 pool_num = 0; - for(pool_status = MemPoolFirst( &pool_info, 1 ); - pool_status != MEM_POOL_END; - pool_status = MemPoolNext( &pool_info, 1 ) ) - { - llinfos << "Pool #" << pool_num << llendl; - if( MEM_POOL_OK != pool_status ) - { - llwarns << "Pool not ok" << llendl; - continue; - } - - llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS - << " pageSize " << pool_info.pageSize - << llendl; - - U32 pool_count = MemPoolCount(pool_info.pool); - llinfos << "Blocks " << pool_count << llendl; - - U32 pool_size = MemPoolSize( pool_info.pool ); - if( pool_size == MEM_ERROR_RET ) - { - llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl; - } - else - { - llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl; - } - - total_pool_size += pool_size; - - if( !MemPoolLock( pool_info.pool ) ) - { - llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl; - continue; - } - - U32 used_size = 0; - MEM_POOL_ENTRY entry; - entry.entry = NULL; - while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK ) - { - if( entry.isInUse ) - { - used_size += entry.size; - } - } - - MemPoolUnlock( pool_info.pool ); - - llinfos << "MemPool Used " << used_size/1024 << "K" << llendl; - total_used_size += used_size; - pool_num++; - } - - llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl; - llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl; - - } -#endif - - llinfos << "--------------------------------" << llendl; - llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl; - LLTexLayerStaticImageList::getInstance()->dumpByteCount(); - LLVOAvatarSelf::dumpScratchTextureByteCount(); - LLTexLayerSetBuffer::dumpTotalByteCount(); - LLVOAvatarSelf::dumpTotalLocalTextureByteCount(); - LLTexLayerParamAlpha::dumpCacheByteCount(); - LLVOAvatar::dumpBakedStatus(); - - llinfos << llendl; - - llinfos << "Object counts:" << llendl; - S32 i; - S32 obj_counts[256]; -// S32 app_angles[256]; - for (i = 0; i < 256; i++) - { - obj_counts[i] = 0; - } - for (i = 0; i < gObjectList.getNumObjects(); i++) - { - LLViewerObject *objectp = gObjectList.getObject(i); - if (objectp) - { - obj_counts[objectp->getPCode()]++; - } - } - for (i = 0; i < 256; i++) - { - if (obj_counts[i]) - { - llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl; - } - } -} - - U32 gTotalLandIn = 0, gTotalLandOut = 0; U32 gTotalWaterIn = 0, gTotalWaterOut = 0; @@ -569,20 +422,15 @@ U32 gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] extern U32 gVisCompared; extern U32 gVisTested; -std::map<S32,LLFrameTimer> gDebugTimers; -std::map<S32,std::string> gDebugTimerLabel; +LLFrameTimer gTextureTimer; -void init_statistics() -{ - // Label debug timers - gDebugTimerLabel[0] = "Texture"; -} - -void update_statistics(U32 frame_count) +void update_statistics() { gTotalWorldBytes += gVLManager.getTotalBytes(); gTotalObjectBytes += gObjectBits / 8; + LLViewerStats& stats = LLViewerStats::instance(); + // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) { @@ -599,51 +447,47 @@ void update_statistics(U32 frame_count) LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); } } - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); -#if 0 // 1.9.2 - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment")); -#endif - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); + stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); + stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); + stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); + stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); + + stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); + stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); + stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); + stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); + stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); + stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { - LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay()); + stats.mSimPingStat.addValue(cdp->getPingDelay()); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { - LLViewerStats::getInstance()->mSimPingStat.addValue(10000); + stats.mSimPingStat.addValue(10000); } - LLViewerStats::getInstance()->mFPSStat.addValue(1); + stats.mFPSStat.addValue(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f); - LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f); - LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); - LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + stats.mLayersKBitStat.addValue(layer_bits/1024.f); + stats.mObjectKBitStat.addValue(gObjectBits/1024.f); + stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); + stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { - gDebugTimers[0].pause(); + gTextureTimer.pause(); } else { - gDebugTimers[0].unpause(); + gTextureTimer.unpause(); } { @@ -655,7 +499,7 @@ void update_statistics(U32 frame_count) visible_avatar_frames = 1.f; avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } - LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); + stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); @@ -671,15 +515,14 @@ void update_statistics(U32 frame_count) static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); - LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); + stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); + stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; LLViewerTextureList::sTextureBits = 0; LLViewerTextureList::sTexturePackets = 0; texture_stats_timer.reset(); } } - } class ViewerStatsResponder : public LLHTTPClient::Responder @@ -857,10 +700,7 @@ void send_stats() S32 window_height = gViewerWindow->getWindowHeightRaw(); S32 window_size = (window_width * window_height) / 1024; misc["string_1"] = llformat("%d", window_size); - if (gDebugTimers.find(0) != gDebugTimers.end() && gFrameTimeSeconds > 0) - { - misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gDebugTimers[0].getElapsedTimeF32(), gFrameTimeSeconds); - } + misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds); // misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21 // misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21 @@ -951,13 +791,6 @@ LLSD LLViewerStats::PhaseMap::dumpPhases() const std::string& phase_name = iter->first; result[phase_name]["completed"] = !(iter->second.getStarted()); result[phase_name]["elapsed"] = iter->second.getElapsedTimeF32(); -#if 0 // global stats for each phase seem like overkill here - phase_stats_t::iterator stats_iter = sPhaseStats.find(phase_name); - if (stats_iter != sPhaseStats.end()) - { - result[phase_name]["stats"] = stats_iter->second.getData(); - } -#endif } return result; } diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 554e4d647e..e02a4ccdc7 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -33,92 +33,90 @@ class LLViewerStats : public LLSingleton<LLViewerStats> { public: - LLStat mKBitStat; - LLStat mLayersKBitStat; - LLStat mObjectKBitStat; - LLStat mAssetKBitStat; - LLStat mTextureKBitStat; - LLStat mVFSPendingOperations; - LLStat mObjectsDrawnStat; - LLStat mObjectsCulledStat; - LLStat mObjectsTestedStat; - LLStat mObjectsComparedStat; - LLStat mObjectsOccludedStat; - LLStat mFPSStat; - LLStat mPacketsInStat; - LLStat mPacketsLostStat; - LLStat mPacketsOutStat; - LLStat mPacketsLostPercentStat; - LLStat mTexturePacketsStat; - LLStat mActualInKBitStat; // From the packet ring (when faking a bad connection) - LLStat mActualOutKBitStat; // From the packet ring (when faking a bad connection) - LLStat mTrianglesDrawnStat; + LLStat mKBitStat, + mLayersKBitStat, + mObjectKBitStat, + mAssetKBitStat, + mTextureKBitStat, + mVFSPendingOperations, + mObjectsDrawnStat, + mObjectsCulledStat, + mObjectsTestedStat, + mObjectsComparedStat, + mObjectsOccludedStat, + mFPSStat, + mPacketsInStat, + mPacketsLostStat, + mPacketsOutStat, + mPacketsLostPercentStat, + mTexturePacketsStat, + mActualInKBitStat, // From the packet ring (when faking a bad connection) + mActualOutKBitStat, // From the packet ring (when faking a bad connection) + mTrianglesDrawnStat; // Simulator stats - LLStat mSimTimeDilation; - - LLStat mSimFPS; - LLStat mSimPhysicsFPS; - LLStat mSimAgentUPS; - LLStat mSimScriptEPS; - - LLStat mSimFrameMsec; - LLStat mSimNetMsec; - LLStat mSimSimOtherMsec; - LLStat mSimSimPhysicsMsec; - - LLStat mSimSimPhysicsStepMsec; - LLStat mSimSimPhysicsShapeUpdateMsec; - LLStat mSimSimPhysicsOtherMsec; - - LLStat mSimSimAIStepMsec; - LLStat mSimSimSkippedSilhouetteSteps; - LLStat mSimSimPctSteppedCharacters; - - LLStat mSimAgentMsec; - LLStat mSimImagesMsec; - LLStat mSimScriptMsec; - LLStat mSimSpareMsec; - LLStat mSimSleepMsec; - LLStat mSimPumpIOMsec; - - LLStat mSimMainAgents; - LLStat mSimChildAgents; - LLStat mSimObjects; - LLStat mSimActiveObjects; - LLStat mSimActiveScripts; - LLStat mSimPctScriptsRun; - - LLStat mSimInPPS; - LLStat mSimOutPPS; - LLStat mSimPendingDownloads; - LLStat mSimPendingUploads; - LLStat mSimPendingLocalUploads; - LLStat mSimTotalUnackedBytes; - - LLStat mPhysicsPinnedTasks; - LLStat mPhysicsLODTasks; - LLStat mPhysicsMemoryAllocated; - - LLStat mSimPingStat; - - LLStat mNumImagesStat; - LLStat mNumRawImagesStat; - LLStat mGLTexMemStat; - LLStat mGLBoundMemStat; - LLStat mRawMemStat; - LLStat mFormattedMemStat; - - LLStat mNumObjectsStat; - LLStat mNumActiveObjectsStat; - LLStat mNumNewObjectsStat; - LLStat mNumSizeCulledStat; - LLStat mNumVisCulledStat; + LLStat mSimTimeDilation, + + mSimFPS, + mSimPhysicsFPS, + mSimAgentUPS, + mSimScriptEPS, + + mSimFrameMsec, + mSimNetMsec, + mSimSimOtherMsec, + mSimSimPhysicsMsec, + + mSimSimPhysicsStepMsec, + mSimSimPhysicsShapeUpdateMsec, + mSimSimPhysicsOtherMsec, + mSimSimAIStepMsec, + mSimSimSkippedSilhouetteSteps, + mSimSimPctSteppedCharacters, + + mSimAgentMsec, + mSimImagesMsec, + mSimScriptMsec, + mSimSpareMsec, + mSimSleepMsec, + mSimPumpIOMsec, + + mSimMainAgents, + mSimChildAgents, + mSimObjects, + mSimActiveObjects, + mSimActiveScripts, + mSimPctScriptsRun, + + mSimInPPS, + mSimOutPPS, + mSimPendingDownloads, + mSimPendingUploads, + mSimPendingLocalUploads, + mSimTotalUnackedBytes, + + mPhysicsPinnedTasks, + mPhysicsLODTasks, + mPhysicsMemoryAllocated, + + mSimPingStat, + + mNumImagesStat, + mNumRawImagesStat, + mGLTexMemStat, + mGLBoundMemStat, + mRawMemStat, + mFormattedMemStat, + + mNumObjectsStat, + mNumActiveObjectsStat, + mNumNewObjectsStat, + mNumSizeCulledStat, + mNumVisCulledStat; void resetStats(); public: - // If you change this, please also add a corresponding text label - // in statTypeToText in llviewerstats.cpp + // If you change this, please also add a corresponding text label in llviewerstats.cpp enum EStatType { ST_VERSION = 0, @@ -183,7 +181,6 @@ public: ST_COUNT = 58 }; - LLViewerStats(); ~LLViewerStats(); @@ -310,14 +307,10 @@ private: static const F32 SEND_STATS_PERIOD = 300.0f; // The following are from (older?) statistics code found in appviewer. -void init_statistics(); -void reset_statistics(); -void output_statistics(void*); -void update_statistics(U32 frame_count); +void update_statistics(); void send_stats(); -extern std::map<S32,LLFrameTimer> gDebugTimers; -extern std::map<S32,std::string> gDebugTimerLabel; +extern LLFrameTimer gTextureTimer; extern U32 gTotalTextureBytes; extern U32 gTotalObjectBytes; extern U32 gTotalTextureBytesPerBoostLevel[] ; diff --git a/indra/newview/llviewerstatsrecorder.cpp b/indra/newview/llviewerstatsrecorder.cpp index e9d21b4848..91e485d01b 100644 --- a/indra/newview/llviewerstatsrecorder.cpp +++ b/indra/newview/llviewerstatsrecorder.cpp @@ -27,7 +27,6 @@ #include "llviewerprecompiledheaders.h" #include "llviewerstatsrecorder.h" -#if LL_RECORD_VIEWER_STATS #include "llfile.h" #include "llviewerregion.h" @@ -45,9 +44,8 @@ LLViewerStatsRecorder* LLViewerStatsRecorder::sInstance = NULL; LLViewerStatsRecorder::LLViewerStatsRecorder() : mObjectCacheFile(NULL), mTimer(), - mRegionp(NULL), - mStartTime(0.f), - mProcessingTime(0.f) + mStartTime(0.0), + mLastSnapshotTime(0.0) { if (NULL != sInstance) { @@ -61,112 +59,77 @@ LLViewerStatsRecorder::~LLViewerStatsRecorder() { if (mObjectCacheFile != NULL) { + // last chance snapshot + writeToLog(0.f); LLFile::close(mObjectCacheFile); mObjectCacheFile = NULL; } } -// static -void LLViewerStatsRecorder::initClass() -{ - sInstance = new LLViewerStatsRecorder(); -} - -// static -void LLViewerStatsRecorder::cleanupClass() -{ - delete sInstance; - sInstance = NULL; -} - - -void LLViewerStatsRecorder::initStatsRecorder(LLViewerRegion *regionp) -{ - if (mObjectCacheFile == NULL) - { - mStartTime = LLTimer::getTotalTime(); - mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); - if (mObjectCacheFile) - { // Write column headers - std::ostringstream data_msg; - data_msg << "EventTime, " - << "ProcessingTime, " - << "CacheHits, " - << "CacheFullMisses, " - << "CacheCrcMisses, " - << "FullUpdates, " - << "TerseUpdates, " - << "CacheMissRequests, " - << "CacheMissResponses, " - << "CacheUpdateDupes, " - << "CacheUpdateChanges, " - << "CacheUpdateAdds, " - << "CacheUpdateReplacements, " - << "UpdateFailures" - << "\n"; - - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); - } - } -} - -void LLViewerStatsRecorder::beginObjectUpdateEvents(LLViewerRegion *regionp) -{ - initStatsRecorder(regionp); - mRegionp = regionp; - mProcessingTime = LLTimer::getTotalTime(); - clearStats(); -} - void LLViewerStatsRecorder::clearStats() { mObjectCacheHitCount = 0; + mObjectCacheHitSize = 0; mObjectCacheMissFullCount = 0; + mObjectCacheMissFullSize = 0; mObjectCacheMissCrcCount = 0; + mObjectCacheMissCrcSize = 0; mObjectFullUpdates = 0; + mObjectFullUpdatesSize = 0; mObjectTerseUpdates = 0; + mObjectTerseUpdatesSize = 0; mObjectCacheMissRequests = 0; mObjectCacheMissResponses = 0; + mObjectCacheMissResponsesSize = 0; mObjectCacheUpdateDupes = 0; mObjectCacheUpdateChanges = 0; mObjectCacheUpdateAdds = 0; mObjectCacheUpdateReplacements = 0; mObjectUpdateFailures = 0; + mObjectUpdateFailuresSize = 0; + mTextureFetchSize = 0; } -void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type) +void LLViewerStatsRecorder::recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) { mObjectUpdateFailures++; + mObjectUpdateFailuresSize += msg_size; } -void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type) +void LLViewerStatsRecorder::recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size) { if (LLViewerRegion::CACHE_MISS_TYPE_FULL == cache_miss_type) { mObjectCacheMissFullCount++; + mObjectCacheMissFullSize += msg_size; } else { mObjectCacheMissCrcCount++; + mObjectCacheMissCrcSize += msg_size; } } -void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp) +void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size) { switch (update_type) { case OUT_FULL: mObjectFullUpdates++; + mObjectFullUpdatesSize += msg_size; break; case OUT_TERSE_IMPROVED: mObjectTerseUpdates++; + mObjectTerseUpdatesSize += msg_size; break; case OUT_FULL_COMPRESSED: mObjectCacheMissResponses++; + mObjectCacheMissResponsesSize += msg_size; break; case OUT_FULL_CACHED: mObjectCacheHitCount++; + mObjectCacheHitSize += msg_size; break; default: llwarns << "Unknown update_type" << llendl; @@ -174,7 +137,7 @@ void LLViewerStatsRecorder::recordObjectUpdateEvent(U32 local_id, const EObjectU }; } -void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp) +void LLViewerStatsRecorder::recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size) { switch (update_result) { @@ -201,9 +164,15 @@ void LLViewerStatsRecorder::recordRequestCacheMissesEvent(S32 count) mObjectCacheMissRequests += count; } -void LLViewerStatsRecorder::endObjectUpdateEvents() +void LLViewerStatsRecorder::writeToLog( F32 interval ) { - llinfos << "ILX: " + F64 delta_time = LLTimer::getTotalSeconds() - mLastSnapshotTime; + S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; + + if ( delta_time < interval || total_objects == 0) return; + + mLastSnapshotTime = LLTimer::getTotalSeconds(); + lldebugs << "ILX: " << mObjectCacheHitCount << " hits, " << mObjectCacheMissFullCount << " full misses, " << mObjectCacheMissCrcCount << " crc misses, " @@ -218,41 +187,81 @@ void LLViewerStatsRecorder::endObjectUpdateEvents() << mObjectUpdateFailures << " update failures" << llendl; - S32 total_objects = mObjectCacheHitCount + mObjectCacheMissCrcCount + mObjectCacheMissFullCount + mObjectFullUpdates + mObjectTerseUpdates + mObjectCacheMissRequests + mObjectCacheMissResponses + mObjectCacheUpdateDupes + mObjectCacheUpdateChanges + mObjectCacheUpdateAdds + mObjectCacheUpdateReplacements + mObjectUpdateFailures; - if (mObjectCacheFile != NULL && - total_objects > 0) + if (mObjectCacheFile == NULL) { - std::ostringstream data_msg; - F32 processing32 = (F32) ((LLTimer::getTotalTime() - mProcessingTime) / 1000.0); - - data_msg << getTimeSinceStart() - << ", " << processing32 - << ", " << mObjectCacheHitCount - << ", " << mObjectCacheMissFullCount - << ", " << mObjectCacheMissCrcCount - << ", " << mObjectFullUpdates - << ", " << mObjectTerseUpdates - << ", " << mObjectCacheMissRequests - << ", " << mObjectCacheMissResponses - << ", " << mObjectCacheUpdateDupes - << ", " << mObjectCacheUpdateChanges - << ", " << mObjectCacheUpdateAdds - << ", " << mObjectCacheUpdateReplacements - << ", " << mObjectUpdateFailures - << "\n"; + mStartTime = LLTimer::getTotalSeconds(); + mObjectCacheFile = LLFile::fopen(STATS_FILE_NAME, "wb"); + if (mObjectCacheFile) + { // Write column headers + std::ostringstream data_msg; + data_msg << "EventTime(ms)\t" + << "Cache Hits\t" + << "Cache Full Misses\t" + << "Cache Crc Misses\t" + << "Full Updates\t" + << "Terse Updates\t" + << "Cache Miss Requests\t" + << "Cache Miss Responses\t" + << "Cache Update Dupes\t" + << "Cache Update Changes\t" + << "Cache Update Adds\t" + << "Cache Update Replacements\t" + << "Update Failures\t" + << "Cache Hits bps\t" + << "Cache Full Misses bps\t" + << "Cache Crc Misses bps\t" + << "Full Updates bps\t" + << "Terse Updates bps\t" + << "Cache Miss Responses bps\t" + << "Texture Fetch bps\t" + << "\n"; - fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); + } + else + { + llwarns << "Couldn't open " << STATS_FILE_NAME << " for logging." << llendl; + return; + } } + std::ostringstream data_msg; + + data_msg << getTimeSinceStart() + << "\t " << mObjectCacheHitCount + << "\t" << mObjectCacheMissFullCount + << "\t" << mObjectCacheMissCrcCount + << "\t" << mObjectFullUpdates + << "\t" << mObjectTerseUpdates + << "\t" << mObjectCacheMissRequests + << "\t" << mObjectCacheMissResponses + << "\t" << mObjectCacheUpdateDupes + << "\t" << mObjectCacheUpdateChanges + << "\t" << mObjectCacheUpdateAdds + << "\t" << mObjectCacheUpdateReplacements + << "\t" << mObjectUpdateFailures + << "\t" << (mObjectCacheHitSize * 8 / delta_time) + << "\t" << (mObjectCacheMissFullSize * 8 / delta_time) + << "\t" << (mObjectCacheMissCrcSize * 8 / delta_time) + << "\t" << (mObjectFullUpdatesSize * 8 / delta_time) + << "\t" << (mObjectTerseUpdatesSize * 8 / delta_time) + << "\t" << (mObjectCacheMissResponsesSize * 8 / delta_time) + << "\t" << (mTextureFetchSize * 8 / delta_time) + << "\n"; + + fwrite(data_msg.str().c_str(), 1, data_msg.str().size(), mObjectCacheFile ); clearStats(); } F32 LLViewerStatsRecorder::getTimeSinceStart() { - return (F32) ((LLTimer::getTotalTime() - mStartTime) / 1000.0); + return (F32) (LLTimer::getTotalSeconds() - mStartTime); } -#endif +void LLViewerStatsRecorder::recordTextureFetch( S32 msg_size ) +{ + mTextureFetchSize += msg_size; +} diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h index 612ac380f7..ce6dd63ec5 100644 --- a/indra/newview/llviewerstatsrecorder.h +++ b/indra/newview/llviewerstatsrecorder.h @@ -32,66 +32,114 @@ // for analysis. // This is normally 0. Set to 1 to enable viewer stats recording -#define LL_RECORD_VIEWER_STATS 0 +#define LL_RECORD_VIEWER_STATS 1 -#if LL_RECORD_VIEWER_STATS #include "llframetimer.h" #include "llviewerobject.h" #include "llviewerregion.h" class LLMutex; -class LLViewerRegion; class LLViewerObject; -class LLViewerStatsRecorder +class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder> { public: + LOG_CLASS(LLViewerStatsRecorder); LLViewerStatsRecorder(); ~LLViewerStatsRecorder(); - static void initClass(); - static void cleanupClass(); - static LLViewerStatsRecorder* instance() {return sInstance; } + void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordObjectUpdateFailure(local_id, update_type, msg_size); +#endif + } - void initStatsRecorder(LLViewerRegion *regionp); + void cacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordCacheMissEvent(local_id, update_type, cache_miss_type, msg_size); +#endif + } - void beginObjectUpdateEvents(LLViewerRegion *regionp); - void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type); - void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type); - void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp); - void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp); - void recordRequestCacheMissesEvent(S32 count); - void endObjectUpdateEvents(); + void objectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordObjectUpdateEvent(local_id, update_type, objectp, msg_size); +#endif + } + + void cacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordCacheFullUpdate(local_id, update_type, update_result, objectp, msg_size); +#endif + } + + void requestCacheMissesEvent(S32 count) + { +#if LL_RECORD_VIEWER_STATS + recordRequestCacheMissesEvent(count); +#endif + } + + void textureFetch(S32 msg_size) + { +#if LL_RECORD_VIEWER_STATS + recordTextureFetch(msg_size); +#endif + } + + void log(F32 interval) + { +#if LL_RECORD_VIEWER_STATS + writeToLog(interval); +#endif + } F32 getTimeSinceStart(); private: + void recordObjectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size); + void recordCacheMissEvent(U32 local_id, const EObjectUpdateType update_type, U8 cache_miss_type, S32 msg_size); + void recordObjectUpdateEvent(U32 local_id, const EObjectUpdateType update_type, LLViewerObject * objectp, S32 msg_size); + void recordCacheFullUpdate(U32 local_id, const EObjectUpdateType update_type, LLViewerRegion::eCacheUpdateResult update_result, LLViewerObject* objectp, S32 msg_size); + void recordRequestCacheMissesEvent(S32 count); + void recordTextureFetch(S32 msg_size); + void writeToLog(F32 interval); + static LLViewerStatsRecorder* sInstance; LLFILE * mObjectCacheFile; // File to write data into LLFrameTimer mTimer; - LLViewerRegion* mRegionp; F64 mStartTime; - F64 mProcessingTime; + F64 mLastSnapshotTime; S32 mObjectCacheHitCount; + S32 mObjectCacheHitSize; S32 mObjectCacheMissFullCount; + S32 mObjectCacheMissFullSize; S32 mObjectCacheMissCrcCount; + S32 mObjectCacheMissCrcSize; S32 mObjectFullUpdates; + S32 mObjectFullUpdatesSize; S32 mObjectTerseUpdates; + S32 mObjectTerseUpdatesSize; S32 mObjectCacheMissRequests; S32 mObjectCacheMissResponses; + S32 mObjectCacheMissResponsesSize; S32 mObjectCacheUpdateDupes; S32 mObjectCacheUpdateChanges; S32 mObjectCacheUpdateAdds; S32 mObjectCacheUpdateReplacements; S32 mObjectUpdateFailures; + S32 mObjectUpdateFailuresSize; + S32 mTextureFetchSize; void clearStats(); }; -#endif // LL_RECORD_VIEWER_STATS #endif // LLVIEWERSTATSRECORDER_H diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 99102309a1..122d8f4a96 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1144,6 +1144,14 @@ void LLViewerTextEditor::openEmbeddedTexture( LLInventoryItem* item, llwchar wc { preview->setAuxItem( item ); preview->setNotecardInfo(mNotecardInventoryID, mObjectID); + if (preview->hasString("Title")) + { + LLStringUtil::format_map_t args; + args["[NAME]"] = item->getName(); + LLUIString title = preview->getString("Title", args); + preview->setTitle(title.getString()); + } + preview->getChild<LLUICtrl>("desc")->setValue(item->getDescription()); } } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 4ffc12df2d..80cca9963e 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -67,12 +67,12 @@ void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL; U32 LLViewerTextureList::sTextureBits = 0; U32 LLViewerTextureList::sTexturePackets = 0; S32 LLViewerTextureList::sNumImages = 0; -LLStat LLViewerTextureList::sNumImagesStat(32, TRUE); -LLStat LLViewerTextureList::sNumRawImagesStat(32, TRUE); -LLStat LLViewerTextureList::sGLTexMemStat(32, TRUE); -LLStat LLViewerTextureList::sGLBoundMemStat(32, TRUE); -LLStat LLViewerTextureList::sRawMemStat(32, TRUE); -LLStat LLViewerTextureList::sFormattedMemStat(32, TRUE); +LLStat LLViewerTextureList::sNumImagesStat("Num Images", 32, TRUE); +LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", 32, TRUE); +LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", 32, TRUE); +LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", 32, TRUE); +LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", 32, TRUE); +LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", 32, TRUE); LLViewerTextureList gTextureList; static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images"); @@ -906,14 +906,6 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) } min_count--; } - //if (fetch_count == 0) - //{ - // gDebugTimers[0].pause(); - //} - //else - //{ - // gDebugTimers[0].unpause(); - //} return image_op_timer.getElapsedTimeF32(); } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8d4590e755..6101796559 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -77,6 +77,7 @@ #include "llmediaentry.h" #include "llurldispatcher.h" #include "raytrace.h" +#include "llstat.h" // newview includes #include "llagent.h" @@ -334,27 +335,24 @@ public: if (gSavedSettings.getBOOL("DebugShowTime")) { - const U32 y_inc2 = 15; - for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin(); - iter != gDebugTimers.rend(); ++iter) { - S32 idx = iter->first; - LLFrameTimer& timer = iter->second; + const U32 y_inc2 = 15; + LLFrameTimer& timer = gTextureTimer; F32 time = timer.getElapsedTimeF32(); S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); - std::string label = gDebugTimerLabel[idx]; - if (label.empty()) label = llformat("Debug: %d", idx); - addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2; + addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2; } + { F32 time = gFrameTimeSeconds; S32 hours = (S32)(time / (60*60)); S32 mins = (S32)((time - hours*(60*60)) / 60); S32 secs = (S32)((time - hours*(60*60) - mins*60)); addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc; } + } #if LL_WINDOWS if (gSavedSettings.getBOOL("DebugShowMemory")) @@ -615,7 +613,7 @@ public: addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount, LLMeshRepository::sHTTPRetryCount)); ypos += y_inc; - + addText(xpos, ypos, llformat("%d/%d Mesh LOD Pending/Processing", LLMeshRepository::sLODPending, LLMeshRepository::sLODProcessing)); ypos += y_inc; @@ -1542,7 +1540,8 @@ LLViewerWindow::LLViewerWindow(const Params& p) mResDirty(false), mStatesDirty(false), mCurrResolutionIndex(0), - mProgressView(NULL) + mProgressView(NULL), + mMouseVelocityStat(new LLStat("Mouse Velocity")) { // gKeyboard is still NULL, so it doesn't do LLWindowListener any good to // pass its value right now. Instead, pass it a nullary function that @@ -1931,7 +1930,7 @@ void LLViewerWindow::initWorldUI() panel_ssf_container->addChild(panel_rebake_navmesh); panel_ssf_container->setVisible(TRUE); - + // Load and make the toolbars visible // Note: we need to load the toolbars only *after* the user is logged in and IW if (gToolBarView) @@ -1977,12 +1976,12 @@ void LLViewerWindow::shutdownViews() gMorphView->setVisible(FALSE); } llinfos << "Global views cleaned." << llendl ; - + // DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open // will crump with LL_ERRS. LLModalDialog::shutdownModals(); llinfos << "LLModalDialog shut down." << llendl; - + // destroy the nav bar, not currently part of gViewerWindow // *TODO: Make LLNavigationBar part of gViewerWindow if (LLNavigationBar::instanceExists()) @@ -1990,17 +1989,17 @@ void LLViewerWindow::shutdownViews() delete LLNavigationBar::getInstance(); } llinfos << "LLNavigationBar destroyed." << llendl ; - + // destroy menus after instantiating navbar above, as it needs // access to gMenuHolder cleanup_menus(); llinfos << "menus destroyed." << llendl ; - + // Delete all child views. delete mRootView; mRootView = NULL; llinfos << "RootView deleted." << llendl ; - + // Automatically deleted as children of mRootView. Fix the globals. gStatusBar = NULL; gIMMgr = NULL; @@ -2068,6 +2067,8 @@ LLViewerWindow::~LLViewerWindow() delete mDebugText; mDebugText = NULL; + + delete mMouseVelocityStat; } @@ -3241,7 +3242,7 @@ void LLViewerWindow::updateMouseDelta() mouse_vel.setVec((F32) dx, (F32) dy); } - mMouseVelocityStat.addValue(mouse_vel.magVec()); + mMouseVelocityStat->addValue(mouse_vel.magVec()); } void LLViewerWindow::updateKeyboardFocus() @@ -4266,12 +4267,12 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if (!reset_deferred) { - // if image cropping or need to enlarge the scene, compute a scale_factor - F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; - snapshot_width = (S32)(ratio * image_width) ; - snapshot_height = (S32)(ratio * image_height) ; - scale_factor = llmax(1.0f, 1.0f / ratio) ; - } + // if image cropping or need to enlarge the scene, compute a scale_factor + F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; + snapshot_width = (S32)(ratio * image_width) ; + snapshot_height = (S32)(ratio * image_height) ; + scale_factor = llmax(1.0f, 1.0f / ratio) ; + } } if (show_ui && scale_factor > 1.f) @@ -4473,7 +4474,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei { send_agent_resume(); } - + return ret; } @@ -4765,7 +4766,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) LLViewerDynamicTexture::restoreGL(); LLVOAvatar::restoreGL(); LLVOPartGroup::restoreGL(); - + gResizeScreenTexture = TRUE; gWindowResized = TRUE; @@ -5253,8 +5254,8 @@ void LLPickInfo::getSurfaceInfo() LLFace* facep = objectp->mDrawable->getFace(mObjectFace); if (facep) { - mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); - } + mUVCoords = facep->surfaceToTexture(mSTCoords, mIntersection, mNormal); + } } // and XY coords: diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 6efcaeaf18..5f475fe145 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -41,7 +41,6 @@ #include "llcursortypes.h" #include "llwindowcallbacks.h" #include "lltimer.h" -#include "llstat.h" #include "llmousehandler.h" #include "llhandle.h" #include "llinitparam.h" @@ -50,7 +49,7 @@ #include <boost/signals2.hpp> #include <boost/scoped_ptr.hpp> - +class LLStat; class LLView; class LLViewerObject; class LLUUID; @@ -251,7 +250,7 @@ public: S32 getCurrentMouseDX() const { return mCurrentMouseDelta.mX; } S32 getCurrentMouseDY() const { return mCurrentMouseDelta.mY; } LLCoordGL getCurrentMouseDelta() const { return mCurrentMouseDelta; } - LLStat * getMouseVelocityStat() { return &mMouseVelocityStat; } + LLStat* getMouseVelocityStat() { return mMouseVelocityStat; } BOOL getLeftMouseDown() const { return mLeftMouseDown; } BOOL getMiddleMouseDown() const { return mMiddleMouseDown; } BOOL getRightMouseDown() const { return mRightMouseDown; } @@ -428,7 +427,7 @@ private: LLCoordGL mCurrentMousePoint; // last mouse position in GL coords LLCoordGL mLastMousePoint; // Mouse point at last frame. LLCoordGL mCurrentMouseDelta; //amount mouse moved this frame - LLStat mMouseVelocityStat; + LLStat* mMouseVelocityStat; BOOL mLeftMouseDown; BOOL mMiddleMouseDown; BOOL mRightMouseDown; diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index ec932501e5..abb5153480 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -457,8 +457,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, texturep->createGLTexture(0, raw); } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32(); - LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin); for (S32 i = 0; i < 4; i++) { diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index a33f42cf84..7f17fd3e56 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -301,7 +301,7 @@ void LLVOWLSky::restoreGL() gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE); } -static LLFastTimer::DeclareTimer FTM_GEO_SKY("Sky Geometry"); +static LLFastTimer::DeclareTimer FTM_GEO_SKY("Windlight Sky Geometry"); BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) { diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index a3ccf87cfc..ccc513b80d 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -1320,7 +1320,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - gGL.translatef((F32)x, (F32)y, 0.f); + gGL.translatef((F32)x * LLUI::sGLScaleFactor.mV[VX], (F32)y * LLUI::sGLScaleFactor.mV[VY], 0.f); gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color); gGL.popMatrix(); diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml index 2e29c61cb2..6021ba0a5a 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml @@ -134,16 +134,6 @@ top_delta="-25" name="Pipette" width="28" /> - <check_box - follows="left|bottom" - height="20" - initial_value="true" - label="Live Preview" - layout="topleft" - left="4" - name="apply_immediate_check" - top="262" - width="120" /> <text follows="left|bottom" height="20" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 5204efbf65..436e9f8fed 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2994,7 +2994,7 @@ even though the user gets a free copy. use_ellipses="true" read_only="true" name="media_info" - width="280" /> + width="180" /> <web_browser visible="false" enabled="false" diff --git a/indra/newview/skins/default/xui/en/floater_ui_preview.xml b/indra/newview/skins/default/xui/en/floater_ui_preview.xml index 06d4327293..eb01294831 100644 --- a/indra/newview/skins/default/xui/en/floater_ui_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_ui_preview.xml @@ -5,7 +5,7 @@ height="640" layout="topleft" min_height="230" - min_width="650" + min_width="750" name="gui_preview_tool" help_topic="gui_preview_tool" single_instance="true" diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index fc7272b904..3b8ace6308 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -195,6 +195,20 @@ <menu_item_separator name="sepatator2" /> <menu_item_call + label="Expand all folders" + layout="topleft" + name="expand"> + <on_click + function="Gear.Expand" /> + </menu_item_call> + <menu_item_call + label="Collapse all folders" + layout="topleft" + name="collapse"> + <on_click + function="Gear.Collapse" /> + </menu_item_call> + <menu_item_call label="Rename Outfit" layout="topleft" name="rename"> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 1aa55acf2d..c6d9f9ef8f 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -276,30 +276,39 @@ parameter="gestures" /> </menu_item_check> <menu_item_separator/> - <menu_item_call + <menu_item_check label="Friends" name="My Friends" shortcut="control|shift|F"> - <menu_item_call.on_click + <menu_item_check.on_check + function="SideTray.CheckPanelPeopleTab" + parameter="friends_panel" /> + <menu_item_check.on_click function="SideTray.PanelPeopleTab" parameter="friends_panel" /> - </menu_item_call> - <menu_item_call + </menu_item_check> + <menu_item_check label="Groups" name="My Groups" shortcut="control|shift|G"> - <menu_item_call.on_click + <menu_item_check.on_check + function="SideTray.CheckPanelPeopleTab" + parameter="groups_panel" /> + <menu_item_check.on_click function="SideTray.PanelPeopleTab" parameter="groups_panel" /> - </menu_item_call> - <menu_item_call + </menu_item_check> + <menu_item_check label="Nearby people" name="Active Speakers" shortcut="control|shift|A"> - <menu_item_call.on_click + <menu_item_check.on_check + function="SideTray.CheckPanelPeopleTab" + parameter="nearby_panel" /> + <menu_item_check.on_click function="SideTray.PanelPeopleTab" parameter="nearby_panel" /> - </menu_item_call> + </menu_item_check> <menu_item_call label="Block List" name="Block List"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 13f073a1c2..bfb8d61ca6 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7578,18 +7578,6 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran <notification icon="alertmodal.tga" - name="LivePreviewUnavailable" - type="alert"> - -We cannot display a preview of this texture because it is no-copy and/or no-transfer. - <usetemplate - ignoretext="Warn me that Live Preview mode is not available for no-copy and/or no-transfer textures" - name="okignore" - yestext="OK"/> - </notification> - - <notification - icon="alertmodal.tga" name="ConfirmLeaveCall" type="alert"> Are you sure you want to leave this call? diff --git a/indra/newview/skins/default/xui/en/panel_group_roles.xml b/indra/newview/skins/default/xui/en/panel_group_roles.xml index eea2606125..df91ad8b5e 100644 --- a/indra/newview/skins/default/xui/en/panel_group_roles.xml +++ b/indra/newview/skins/default/xui/en/panel_group_roles.xml @@ -254,7 +254,7 @@ things in this group. There's a broad variety of Abilities. column_padding="0" draw_stripes="true" height="200" - follows="left|top" + follows="left|top|right" layout="topleft" left="0" right="-1" diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml index cdf14572fe..e844a15118 100644 --- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml +++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml @@ -30,7 +30,7 @@ (This page does not pass the specified whitelist) </text> <line_editor - max_length="1024" + max_length_bytes="1024" bottom_delta="-24" enabled="true" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml index e9a787cef0..f1ae14809f 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml @@ -292,6 +292,10 @@ label="Open" name="Open" value="Open" /> + <combo_box.item + label="Zoom" + name="Zoom" + value="Zoom" /> </combo_box> <panel border="false" |