diff options
90 files changed, 1543 insertions, 2824 deletions
| @@ -349,3 +349,4 @@ ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5  28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release  a8b3eca451a9eaab59987efb0ab1c4217e3f2dcc DRTVWR-182  1f27cdfdc54246484f8afbbe42ce48e954175cbd 3.4.0-beta1 +81f6b745ef27f5915fd07f988fdec9944f2bb73e DRTVWR-186 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" | 
