diff options
Diffstat (limited to 'indra')
-rw-r--r-- | indra/llcommon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | indra/llcommon/llapr.h | 2 | ||||
-rw-r--r-- | indra/llcommon/lltrace.cpp | 112 | ||||
-rw-r--r-- | indra/llcommon/lltrace.h | 127 | ||||
-rw-r--r-- | indra/llcommon/lltracesampler.cpp | 103 | ||||
-rw-r--r-- | indra/llcommon/lltracesampler.h | 91 | ||||
-rw-r--r-- | indra/llrender/llglheaders.h | 2 | ||||
-rw-r--r-- | indra/llui/llstatbar.cpp | 79 | ||||
-rw-r--r-- | indra/llui/llstatbar.h | 3 | ||||
-rw-r--r-- | indra/llui/llstatgraph.cpp | 123 | ||||
-rw-r--r-- | indra/llui/llstatgraph.h | 99 | ||||
-rw-r--r-- | indra/newview/llstatusbar.cpp | 33 | ||||
-rwxr-xr-x | indra/newview/llviewerstats.cpp | 38 | ||||
-rwxr-xr-x | indra/newview/llviewerstats.h | 20 | ||||
-rw-r--r-- | indra/newview/llviewertexturelist.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llworld.cpp | 3 |
16 files changed, 553 insertions, 288 deletions
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index f78751601c..e10dbb3e4d 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -101,6 +101,7 @@ set(llcommon_SOURCE_FILES llthreadsafequeue.cpp lltimer.cpp lltrace.cpp + lltracesampler.cpp lluri.cpp lluuid.cpp llworkerthread.cpp @@ -243,6 +244,7 @@ set(llcommon_HEADER_FILES llthreadsafequeue.h lltimer.h lltrace.h + lltracesampler.h lltreeiterators.h lltypeinfolookup.h lluri.h diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 830e0a33fa..4e704998c2 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -39,6 +39,8 @@ #define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <windows.h> + #undef min + #undef max #endif #include <boost/noncopyable.hpp> diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index 2da4363b1d..e487e450a9 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -26,6 +26,7 @@ #include "linden_common.h" #include "lltrace.h" +#include "lltracesampler.h" #include "llthread.h" namespace LLTrace @@ -56,77 +57,6 @@ MasterThreadTrace& getMasterThreadTrace() } /////////////////////////////////////////////////////////////////////// -// Sampler -/////////////////////////////////////////////////////////////////////// - -Sampler::Sampler(ThreadTrace* thread_trace) -: mElapsedSeconds(0), - mIsStarted(false), - mThreadTrace(thread_trace) -{ -} - -Sampler::~Sampler() -{ -} - -void Sampler::start() -{ - reset(); - resume(); -} - -void Sampler::reset() -{ - mF32Stats.reset(); - mS32Stats.reset(); - mStackTimers.reset(); - - mElapsedSeconds = 0.0; - mSamplingTimer.reset(); -} - -void Sampler::resume() -{ - if (!mIsStarted) - { - mSamplingTimer.reset(); - getThreadTrace()->activate(this); - mIsStarted = true; - } -} - -void Sampler::stop() -{ - if (mIsStarted) - { - mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); - getThreadTrace()->deactivate(this); - mIsStarted = false; - } -} - -ThreadTrace* Sampler::getThreadTrace() -{ - return mThreadTrace; -} - -void Sampler::makePrimary() -{ - mF32Stats.makePrimary(); - mS32Stats.makePrimary(); - mStackTimers.makePrimary(); -} - -void Sampler::mergeFrom( const Sampler* other ) -{ - mF32Stats.mergeFrom(other->mF32Stats); - mS32Stats.mergeFrom(other->mS32Stats); - mStackTimers.mergeFrom(other->mStackTimers); -} - - -/////////////////////////////////////////////////////////////////////// // MasterThreadTrace /////////////////////////////////////////////////////////////////////// @@ -148,6 +78,11 @@ ThreadTrace::~ThreadTrace() delete mPrimarySampler; } +Sampler* ThreadTrace::getPrimarySampler() +{ + return mPrimarySampler; +} + void ThreadTrace::activate( Sampler* sampler ) { flushPrimary(); @@ -205,6 +140,34 @@ void SlaveThreadTrace::pushToMaster() mSharedData.copyFrom(mPrimarySampler); } +void SlaveThreadTrace::SharedData::copyFrom( Sampler* source ) +{ + LLMutexLock lock(&mSamplerMutex); + { + mSampler->mergeFrom(source); + } +} + +void SlaveThreadTrace::SharedData::copyTo( Sampler* sink ) +{ + LLMutexLock lock(&mSamplerMutex); + { + sink->mergeFrom(mSampler); + } +} + +SlaveThreadTrace::SharedData::~SharedData() +{ + delete mSampler; +} + +SlaveThreadTrace::SharedData::SharedData( Sampler* sampler ) : mSampler(sampler) +{} + + + + + /////////////////////////////////////////////////////////////////////// // MasterThreadTrace /////////////////////////////////////////////////////////////////////// @@ -217,7 +180,7 @@ void MasterThreadTrace::pullFromSlaveThreads() it != end_it; ++it) { - it->mSlaveTrace->mSharedData.copyTo(it->mSamplerStorage); + (*it)->mSlaveTrace->mSharedData.copyTo((*it)->mSamplerStorage); } } @@ -225,7 +188,7 @@ void MasterThreadTrace::addSlaveThread( class SlaveThreadTrace* child ) { LLMutexLock lock(&mSlaveListMutex); - mSlaveThreadTraces.push_back(SlaveThreadTraceProxy(child, createSampler())); + mSlaveThreadTraces.push_back(new SlaveThreadTraceProxy(child, createSampler())); } void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) @@ -236,7 +199,7 @@ void MasterThreadTrace::removeSlaveThread( class SlaveThreadTrace* child ) it != end_it; ++it) { - if (it->mSlaveTrace == child) + if ((*it)->mSlaveTrace == child) { mSlaveThreadTraces.erase(it); break; @@ -266,5 +229,4 @@ MasterThreadTrace::SlaveThreadTraceProxy::~SlaveThreadTraceProxy() delete mSamplerStorage; } - } diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index a443735e69..c6f920b5e4 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -43,14 +43,16 @@ namespace LLTrace { + class Sampler; + void init(); void cleanup(); - class MasterThreadTrace& getMasterThreadTrace(); + class LL_COMMON_API MasterThreadTrace& getMasterThreadTrace(); // one per thread per type template<typename ACCUMULATOR> - class AccumulatorBuffer + class LL_COMMON_API AccumulatorBuffer { static const U32 DEFAULT_ACCUMULATOR_BUFFER_SIZE = 64; private: @@ -64,6 +66,8 @@ namespace LLTrace public: + // copying an accumulator buffer does not copy the actual contents, but simply initializes the buffer size + // to be identical to the other buffer AccumulatorBuffer(const AccumulatorBuffer& other = getDefaultBuffer()) : mStorageSize(other.mStorageSize), mStorage(new ACCUMULATOR[other.mStorageSize]), @@ -150,28 +154,30 @@ namespace LLTrace template<typename ACCUMULATOR> LLThreadLocalPtr<ACCUMULATOR> AccumulatorBuffer<ACCUMULATOR>::sPrimaryStorage; template<typename ACCUMULATOR> - class Trace + class LL_COMMON_API TraceType { public: - Trace(const std::string& name) + TraceType(const std::string& name) : mName(name) { mAccumulatorIndex = AccumulatorBuffer<ACCUMULATOR>::getDefaultBuffer().reserveSlot(); } - LL_FORCE_INLINE ACCUMULATOR& getAccumulator() + LL_FORCE_INLINE ACCUMULATOR& getPrimaryAccumulator() { return AccumulatorBuffer<ACCUMULATOR>::getPrimaryStorage()[mAccumulatorIndex]; } - private: + ACCUMULATOR& getAccumulator(AccumulatorBuffer<ACCUMULATOR>& buffer) { return buffer[mAccumulatorIndex]; } + + protected: std::string mName; size_t mAccumulatorIndex; }; template<typename T> - class StatAccumulator + class LL_COMMON_API StatAccumulator { public: StatAccumulator() @@ -217,6 +223,11 @@ namespace LLTrace mMax = 0; } + T getSum() { return mSum; } + T getMin() { return mMin; } + T getMax() { return mMax; } + T getMean() { return mSum / (T)mNumSamples; } + private: T mSum, mMin, @@ -226,20 +237,23 @@ namespace LLTrace }; template <typename T> - class Stat : public Trace<StatAccumulator<T> > + class LL_COMMON_API Stat + : public TraceType<StatAccumulator<T> >, + public LLInstanceTracker<Stat<T>, std::string> { public: Stat(const std::string& name) - : Trace(name) + : TraceType(name), + LLInstanceTracker(name) {} void sample(T value) { - getAccumulator().sample(value); + getPrimaryAccumulator().sample(value); } }; - struct TimerAccumulator + struct LL_COMMON_API TimerAccumulator { U32 mTotalTimeCounter, mChildTimeCounter, @@ -267,11 +281,11 @@ namespace LLTrace }; - class BlockTimer : public Trace<TimerAccumulator> + class LL_COMMON_API BlockTimer : public TraceType<TimerAccumulator> { public: BlockTimer(const char* name) - : Trace(name) + : TraceType(name) {} struct Recorder @@ -287,7 +301,7 @@ namespace LLTrace : mLastRecorder(sCurRecorder) { mStartTime = getCPUClockCount32(); - TimerAccumulator* accumulator = &block_timer.getAccumulator(); // get per-thread accumulator + TimerAccumulator* accumulator = &block_timer.getPrimaryAccumulator(); // get per-thread accumulator accumulator->mActiveCount++; accumulator->mCalls++; accumulator->mMoveUpTree |= (accumulator->mParent->mActiveCount == 0); @@ -353,44 +367,7 @@ namespace LLTrace static Recorder::StackEntry sCurRecorder; }; - class Sampler - { - public: - ~Sampler(); - - void makePrimary(); - - void start(); - void stop(); - void resume(); - - void mergeFrom(const Sampler* other); - - void reset(); - - bool isStarted() { return mIsStarted; } - - private: - friend class ThreadTrace; - Sampler(class ThreadTrace* thread_trace); - - // no copy - Sampler(const Sampler& other) {} - // returns data for current thread - class ThreadTrace* getThreadTrace(); - - AccumulatorBuffer<StatAccumulator<F32> > mF32Stats; - AccumulatorBuffer<StatAccumulator<S32> > mS32Stats; - - AccumulatorBuffer<TimerAccumulator> mStackTimers; - - bool mIsStarted; - LLTimer mSamplingTimer; - F64 mElapsedSeconds; - ThreadTrace* mThreadTrace; - }; - - class ThreadTrace + class LL_COMMON_API ThreadTrace { public: ThreadTrace(); @@ -406,13 +383,13 @@ namespace LLTrace virtual void pushToMaster() = 0; - Sampler* getPrimarySampler() { return mPrimarySampler; } + Sampler* getPrimarySampler(); protected: Sampler* mPrimarySampler; std::list<Sampler*> mActiveSamplers; }; - class MasterThreadTrace : public ThreadTrace + class LL_COMMON_API MasterThreadTrace : public ThreadTrace { public: MasterThreadTrace(); @@ -433,14 +410,17 @@ namespace LLTrace ~SlaveThreadTraceProxy(); class SlaveThreadTrace* mSlaveTrace; Sampler* mSamplerStorage; + private: + //no need to copy these and then have to duplicate the storage + SlaveThreadTraceProxy(const SlaveThreadTraceProxy& other) {} }; - typedef std::list<SlaveThreadTraceProxy> slave_thread_trace_list_t; + typedef std::list<SlaveThreadTraceProxy*> slave_thread_trace_list_t; slave_thread_trace_list_t mSlaveThreadTraces; LLMutex mSlaveListMutex; }; - class SlaveThreadTrace : public ThreadTrace + class LL_COMMON_API SlaveThreadTrace : public ThreadTrace { public: SlaveThreadTrace(); @@ -457,31 +437,12 @@ namespace LLTrace { public: explicit - SharedData(Sampler* sampler) - : mSampler(sampler) - { - } + SharedData(Sampler* sampler); - ~SharedData() - { - delete mSampler; - } + ~SharedData(); - void copyFrom(Sampler* source) - { - LLMutexLock lock(&mSamplerMutex); - { - mSampler->mergeFrom(source); - } - } - - void copyTo(Sampler* sink) - { - LLMutexLock lock(&mSamplerMutex); - { - sink->mergeFrom(mSampler); - } - } + void copyFrom(Sampler* source); + void copyTo(Sampler* sink); private: // add a cache line's worth of unused space to avoid any potential of false sharing LLMutex mSamplerMutex; @@ -489,14 +450,6 @@ namespace LLTrace }; SharedData mSharedData; }; - - class TimeInterval - { - public: - void start() {} - void stop() {} - void resume() {} - }; } #endif // LL_LLTRACE_H diff --git a/indra/llcommon/lltracesampler.cpp b/indra/llcommon/lltracesampler.cpp new file mode 100644 index 0000000000..0cf01d7a3a --- /dev/null +++ b/indra/llcommon/lltracesampler.cpp @@ -0,0 +1,103 @@ +/** + * @file lltracesampler.cpp + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "lltracesampler.h" + +namespace LLTrace +{ + +/////////////////////////////////////////////////////////////////////// +// Sampler +/////////////////////////////////////////////////////////////////////// + +Sampler::Sampler(ThreadTrace* thread_trace) +: mElapsedSeconds(0), + mIsStarted(false), + mThreadTrace(thread_trace) +{ +} + +Sampler::~Sampler() +{ +} + +void Sampler::start() +{ + reset(); + resume(); +} + +void Sampler::reset() +{ + mF32Stats.reset(); + mS32Stats.reset(); + mStackTimers.reset(); + + mElapsedSeconds = 0.0; + mSamplingTimer.reset(); +} + +void Sampler::resume() +{ + if (!mIsStarted) + { + mSamplingTimer.reset(); + getThreadTrace()->activate(this); + mIsStarted = true; + } +} + +void Sampler::stop() +{ + if (mIsStarted) + { + mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); + getThreadTrace()->deactivate(this); + mIsStarted = false; + } +} + +ThreadTrace* Sampler::getThreadTrace() +{ + return mThreadTrace; +} + +void Sampler::makePrimary() +{ + mF32Stats.makePrimary(); + mS32Stats.makePrimary(); + mStackTimers.makePrimary(); +} + +void Sampler::mergeFrom( const Sampler* other ) +{ + mF32Stats.mergeFrom(other->mF32Stats); + mS32Stats.mergeFrom(other->mS32Stats); + mStackTimers.mergeFrom(other->mStackTimers); +} + +} diff --git a/indra/llcommon/lltracesampler.h b/indra/llcommon/lltracesampler.h new file mode 100644 index 0000000000..d1ca7fc9bb --- /dev/null +++ b/indra/llcommon/lltracesampler.h @@ -0,0 +1,91 @@ +/** + * @file lltracesampler.h + * @brief Sampling object for collecting runtime statistics originating from lltrace. + * + * $LicenseInfo:firstyear=2001&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2012, 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_LLTRACESAMPLER_H +#define LL_LLTRACESAMPLER_H + +#include "stdtypes.h" +#include "llpreprocessor.h" + +#include "lltrace.h" + +namespace LLTrace +{ + class LL_COMMON_API Sampler + { + public: + ~Sampler(); + + void makePrimary(); + + void start(); + void stop(); + void resume(); + + void mergeFrom(const Sampler* other); + + void reset(); + + bool isStarted() { return mIsStarted; } + + F32 getSum(Stat<F32>& stat) { return stat.getAccumulator(mF32Stats).getSum(); } + F32 getMin(Stat<F32>& stat) { return stat.getAccumulator(mF32Stats).getMin(); } + F32 getMax(Stat<F32>& stat) { return stat.getAccumulator(mF32Stats).getMax(); } + F32 getMean(Stat<F32>& stat) { return stat.getAccumulator(mF32Stats).getMean(); } + + S32 getSum(Stat<S32>& stat) { return stat.getAccumulator(mS32Stats).getSum(); } + S32 getMin(Stat<S32>& stat) { return stat.getAccumulator(mS32Stats).getMin(); } + S32 getMax(Stat<S32>& stat) { return stat.getAccumulator(mS32Stats).getMax(); } + S32 getMean(Stat<S32>& stat) { return stat.getAccumulator(mS32Stats).getMean(); } + + F64 getSampleTime() { return mElapsedSeconds; } + + private: + friend class ThreadTrace; + Sampler(class ThreadTrace* thread_trace); + + // no copy + Sampler(const Sampler& other) {} + // returns data for current thread + class ThreadTrace* getThreadTrace(); + + //TODO: take snapshot at sampler start so we can simplify updates + //AccumulatorBuffer<StatAccumulator<F32> > mF32StatsStart; + //AccumulatorBuffer<StatAccumulator<S32> > mS32StatsStart; + //AccumulatorBuffer<TimerAccumulator> mStackTimersStart; + + AccumulatorBuffer<StatAccumulator<F32> > mF32Stats; + AccumulatorBuffer<StatAccumulator<S32> > mS32Stats; + AccumulatorBuffer<TimerAccumulator> mStackTimers; + + bool mIsStarted; + LLTimer mSamplingTimer; + F64 mElapsedSeconds; + ThreadTrace* mThreadTrace; + }; +} + +#endif // LL_LLTRACESAMPLER_H diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index 509de51f4d..605b424b35 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -543,6 +543,8 @@ extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; #define WIN32_LEAN_AND_MEAN #include <winsock2.h> #include <windows.h> +#undef min +#undef max //---------------------------------------------------------------------------- #include <GL/gl.h> diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index a21d7aa6a1..2d1b582598 100644 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -36,6 +36,7 @@ #include "llstat.h" #include "lluictrlfactory.h" +#include "lltracesampler.h" /////////////////////////////////////////////////////////////////////////////////// @@ -46,6 +47,8 @@ LLStatBar::LLStatBar(const Params& p) mMinBar(p.bar_min), mMaxBar(p.bar_max), mStatp(LLStat::getInstance(p.stat)), + mFloatStatp(LLTrace::Stat<F32>::getInstance(p.stat)), + mIntStatp(LLTrace::Stat<S32>::getInstance(p.stat)), mTickSpacing(p.tick_spacing), mLabelSpacing(p.label_spacing), mPrecision(p.precision), @@ -84,30 +87,66 @@ BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask) void LLStatBar::draw() { - if (!mStatp) + F32 current = 0.f, + min = 0.f, + max = 0.f, + mean = 0.f; + + if (mStatp) { -// llinfos << "No stats for statistics bar!" << llendl; - return; + // Get the values. + if (mPerSec) + { + current = mStatp->getCurrentPerSec(); + min = mStatp->getMinPerSec(); + max = mStatp->getMaxPerSec(); + mean = mStatp->getMeanPerSec(); + } + else + { + current = mStatp->getCurrent(); + min = mStatp->getMin(); + max = mStatp->getMax(); + mean = mStatp->getMean(); + } } - - // Get the values. - F32 current, min, max, mean; - if (mPerSec) + else if (mFloatStatp) { - current = mStatp->getCurrentPerSec(); - min = mStatp->getMinPerSec(); - max = mStatp->getMaxPerSec(); - mean = mStatp->getMeanPerSec(); + LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + if (mPerSec) + { + current = sampler->getSum(*mFloatStatp) / sampler->getSampleTime(); + min = sampler->getMin(*mFloatStatp) / sampler->getSampleTime(); + max = sampler->getMax(*mFloatStatp) / sampler->getSampleTime(); + mean = sampler->getMean(*mFloatStatp) / sampler->getSampleTime(); + } + else + { + current = sampler->getSum(*mFloatStatp); + min = sampler->getMin(*mFloatStatp); + max = sampler->getMax(*mFloatStatp); + mean = sampler->getMean(*mFloatStatp); + } } - else + else if (mIntStatp) { - current = mStatp->getCurrent(); - min = mStatp->getMin(); - max = mStatp->getMax(); - mean = mStatp->getMean(); + LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + if (mPerSec) + { + current = (F32)sampler->getSum(*mIntStatp) / sampler->getSampleTime(); + min = (F32)sampler->getMin(*mIntStatp) / sampler->getSampleTime(); + max = (F32)sampler->getMax(*mIntStatp) / sampler->getSampleTime(); + mean = (F32)sampler->getMean(*mIntStatp) / sampler->getSampleTime(); + } + else + { + current = (F32)sampler->getSum(*mIntStatp); + min = (F32)sampler->getMin(*mIntStatp); + max = (F32)sampler->getMax(*mIntStatp); + mean = (F32)sampler->getMean(*mIntStatp); + } } - if ((mUpdatesPerSec == 0.f) || (mUpdateTimer.getElapsedTimeF32() > 1.f/mUpdatesPerSec) || (mValue == 0.f)) { if (mDisplayMean) @@ -153,7 +192,7 @@ void LLStatBar::draw() LLFontGL::RIGHT, LLFontGL::TOP); value_format = llformat( "%%.%df", mPrecision); - if (mDisplayBar) + if (mDisplayBar && mStatp) { std::string tick_label; @@ -213,9 +252,9 @@ void LLStatBar::draw() right = (S32) ((max - mMinBar) * value_scale); gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); - S32 num_values = mStatp->getNumValues() - 1; if (mDisplayHistory) { + S32 num_values = mStatp->getNumValues() - 1; S32 i; for (i = 0; i < num_values; i++) { @@ -270,7 +309,7 @@ LLRect LLStatBar::getRequiredRect() if (mDisplayBar) { - if (mDisplayHistory) + if (mDisplayHistory && mStatp) { rect.mTop = 35 + mStatp->getNumBins(); } diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 7e636d0aa7..8348290abf 100644 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -29,6 +29,7 @@ #include "llview.h" #include "llframetimer.h" +#include "lltrace.h" class LLStat; @@ -92,6 +93,8 @@ private: BOOL mDisplayMean; // If true, display mean, if false, display current value LLStat* mStatp; + LLTrace::Stat<F32>* mFloatStatp; + LLTrace::Stat<S32>* mIntStatp; LLFrameTimer mUpdateTimer; LLUIString mLabel; diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp index e44887ebf0..19896c4597 100644 --- a/indra/llui/llstatgraph.cpp +++ b/indra/llui/llstatgraph.cpp @@ -35,28 +35,38 @@ #include "llstat.h" #include "llgl.h" #include "llglheaders.h" +#include "lltracesampler.h" //#include "llviewercontrol.h" /////////////////////////////////////////////////////////////////////////////////// -LLStatGraph::LLStatGraph(const LLView::Params& p) -: LLView(p) +LLStatGraph::LLStatGraph(const Params& p) +: LLView(p), + mMin(p.min), + mMax(p.max), + mPerSec(true), + mPrecision(p.precision), + mValue(p.value), + mStatp(p.stat.legacy_stat), + mF32Statp(p.stat.f32_stat), + mS32Statp(p.stat.s32_stat) { - mStatp = NULL; setToolTip(p.name()); - mNumThresholds = 3; - mThresholdColors[0] = LLColor4(0.f, 1.f, 0.f, 1.f); - mThresholdColors[1] = LLColor4(1.f, 1.f, 0.f, 1.f); - mThresholdColors[2] = LLColor4(1.f, 0.f, 0.f, 1.f); - mThresholdColors[3] = LLColor4(1.f, 0.f, 0.f, 1.f); - mThresholds[0] = 50.f; - mThresholds[1] = 75.f; - mThresholds[2] = 100.f; - mMin = 0.f; - mMax = 125.f; - mPerSec = TRUE; - mValue = 0.f; - mPrecision = 0; + + for(LLInitParam::ParamIterator<ThresholdParams>::const_iterator it = p.thresholds.threshold.begin(), end_it = p.thresholds.threshold.end(); + it != end_it; + ++it) + { + mThresholds.push_back(Threshold(it->value(), it->color)); + } + + //mThresholdColors[0] = LLColor4(0.f, 1.f, 0.f, 1.f); + //mThresholdColors[1] = LLColor4(1.f, 1.f, 0.f, 1.f); + //mThresholdColors[2] = LLColor4(1.f, 0.f, 0.f, 1.f); + //mThresholdColors[3] = LLColor4(1.f, 0.f, 0.f, 1.f); + //mThresholds[0] = 50.f; + //mThresholds[1] = 75.f; + //mThresholds[2] = 100.f; } void LLStatGraph::draw() @@ -74,6 +84,33 @@ void LLStatGraph::draw() mValue = mStatp->getMean(); } } + else if (mF32Statp) + { + LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + + if (mPerSec) + { + mValue = sampler->getSum(*mF32Statp) / sampler->getSampleTime(); + } + else + { + mValue = sampler->getSum(*mF32Statp); + } + + } + else if (mS32Statp) + { + LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + + if (mPerSec) + { + mValue = sampler->getSum(*mS32Statp) / sampler->getSampleTime(); + } + else + { + mValue = sampler->getSum(*mS32Statp); + } + } frac = (mValue - mMin) / range; frac = llmax(0.f, frac); frac = llmin(1.f, frac); @@ -91,19 +128,22 @@ void LLStatGraph::draw() LLColor4 color; - S32 i; - for (i = 0; i < mNumThresholds - 1; i++) + //S32 i; + //for (i = 0; i < mNumThresholds - 1; i++) + //{ + // if (mThresholds[i] > mValue) + // { + // break; + // } + //} + + threshold_vec_t::iterator it = std::lower_bound(mThresholds.begin(), mThresholds.end(), Threshold(mValue / mMax, LLUIColor())); + + if (it != mThresholds.begin()) { - if (mThresholds[i] > mValue) - { - break; - } + it--; } - //gl_drop_shadow(0, getRect().getHeight(), getRect().getWidth(), 0, - // LLUIColorTable::instance().getColor("ColorDropShadow"), - // (S32) gSavedSettings.getF32("DropShadowFloater") ); - color = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" ); gGL.color4fv(color.mV); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, TRUE); @@ -111,16 +151,11 @@ void LLStatGraph::draw() gGL.color4fv(LLColor4::black.mV); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, FALSE); - color = mThresholdColors[i]; + color = it->mColor; gGL.color4fv(color.mV); gl_rect_2d(1, llround(frac*getRect().getHeight()), getRect().getWidth() - 1, 0, TRUE); } -void LLStatGraph::setValue(const LLSD& value) -{ - mValue = (F32)value.asReal(); -} - void LLStatGraph::setMin(const F32 min) { mMin = min; @@ -131,27 +166,3 @@ void LLStatGraph::setMax(const F32 max) mMax = max; } -void LLStatGraph::setStat(LLStat *statp) -{ - mStatp = statp; -} - -void LLStatGraph::setLabel(const std::string& label) -{ - mLabel = label; -} - -void LLStatGraph::setUnits(const std::string& units) -{ - mUnits = units; -} - -void LLStatGraph::setPrecision(const S32 precision) -{ - mPrecision = precision; -} - -void LLStatGraph::setThreshold(const S32 i, F32 value) -{ - mThresholds[i] = value; -} diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h index 757525e232..e7de945694 100644 --- a/indra/llui/llstatgraph.h +++ b/indra/llui/llstatgraph.h @@ -30,29 +30,88 @@ #include "llview.h" #include "llframetimer.h" #include "v4color.h" +#include "lltrace.h" class LLStat; class LLStatGraph : public LLView { public: - LLStatGraph(const LLView::Params&); + struct ThresholdParams : public LLInitParam::Block<ThresholdParams> + { + Mandatory<F32> value; + Optional<LLUIColor> color; - virtual void draw(); + ThresholdParams() + : value("value"), + color("color", LLColor4::white) + {} + }; + + struct Thresholds : public LLInitParam::Block<Thresholds> + { + Multiple<ThresholdParams> threshold; + + Thresholds() + : threshold("threshold") + {} + }; + + struct StatParams : public LLInitParam::ChoiceBlock<StatParams> + { + Alternative<LLStat*> legacy_stat; + Alternative<LLTrace::Stat<F32>* > f32_stat; + Alternative<LLTrace::Stat<S32>* > s32_stat; + }; + + struct Params : public LLInitParam::Block<Params, LLView::Params> + { + Mandatory<StatParams> stat; + Optional<std::string> label, + units; + Optional<S32> precision; + Optional<F32> min, + max; + Optional<bool> per_sec; + Optional<F32> value; + + Optional<Thresholds> thresholds; + + Params() + : stat("stat"), + label("label"), + units("units"), + precision("precision", 0), + min("min", 0.f), + max("max", 125.f), + per_sec("per_sec", true), + value("value", 0.f), + thresholds("thresholds") + { + Thresholds _thresholds; + _thresholds.threshold.add(ThresholdParams().value(0.f).color(LLColor4::green)) + .add(ThresholdParams().value(0.33f).color(LLColor4::yellow)) + .add(ThresholdParams().value(0.5f).color(LLColor4::red)) + .add(ThresholdParams().value(0.75f).color(LLColor4::red)); + thresholds = _thresholds; + } + }; + LLStatGraph(const Params&); - void setLabel(const std::string& label); - void setUnits(const std::string& units); - void setPrecision(const S32 precision); - void setStat(LLStat *statp); - void setThreshold(const S32 i, F32 value); void setMin(const F32 min); void setMax(const F32 max); + virtual void draw(); + /*virtual*/ void setValue(const LLSD& value); - LLStat *mStatp; - BOOL mPerSec; private: + LLStat* mStatp; + LLTrace::Stat<F32>* mF32Statp; + LLTrace::Stat<S32>* mS32Statp; + + BOOL mPerSec; + F32 mValue; F32 mMin; @@ -62,9 +121,25 @@ private: std::string mUnits; S32 mPrecision; // Num of digits of precision after dot - S32 mNumThresholds; - F32 mThresholds[4]; - LLColor4 mThresholdColors[4]; + struct Threshold + { + Threshold(F32 value, const LLUIColor& color) + : mValue(value), + mColor(color) + {} + + F32 mValue; + LLUIColor mColor; + bool operator <(const Threshold& other) + { + return mValue < other.mValue; + } + }; + typedef std::vector<Threshold> threshold_vec_t; + threshold_vec_t mThresholds; + //S32 mNumThresholds; + //F32 mThresholds[4]; + //LLColor4 mThresholdColors[4]; }; #endif // LL_LLSTATGRAPH_H diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 4892de9da0..9f499ef4ef 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -198,10 +198,10 @@ BOOL LLStatusBar::postBuild() sgp.rect(r); sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); sgp.mouse_opaque(false); + sgp.stat.f32_stat(&STAT_KBIT); + sgp.units("Kbps"); + sgp.precision(0); mSGBandwidth = LLUICtrlFactory::create<LLStatGraph>(sgp); - mSGBandwidth->setStat(&LLViewerStats::getInstance()->mKBitStat); - mSGBandwidth->setUnits("Kbps"); - mSGBandwidth->setPrecision(0); addChild(mSGBandwidth); x -= SIM_STAT_WIDTH + 2; @@ -212,17 +212,20 @@ BOOL LLStatusBar::postBuild() pgp.rect(r); pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT); pgp.mouse_opaque(false); + pgp.stat.legacy_stat(&LLViewerStats::getInstance()->mPacketsLostPercentStat); + pgp.units("%"); + pgp.min(0.f); + pgp.max(5.f); + pgp.precision(1); + pgp.per_sec(false); + LLStatGraph::Thresholds thresholds; + thresholds.threshold.add(LLStatGraph::ThresholdParams().value(0.1).color(LLColor4::green)) + .add(LLStatGraph::ThresholdParams().value(0.25f).color(LLColor4::yellow)) + .add(LLStatGraph::ThresholdParams().value(0.6f).color(LLColor4::red)); + + pgp.thresholds(thresholds); mSGPacketLoss = LLUICtrlFactory::create<LLStatGraph>(pgp); - mSGPacketLoss->setStat(&LLViewerStats::getInstance()->mPacketsLostPercentStat); - mSGPacketLoss->setUnits("%"); - mSGPacketLoss->setMin(0.f); - mSGPacketLoss->setMax(5.f); - mSGPacketLoss->setThreshold(0, 0.5f); - mSGPacketLoss->setThreshold(1, 1.f); - mSGPacketLoss->setThreshold(2, 3.f); - mSGPacketLoss->setPrecision(1); - mSGPacketLoss->mPerSec = FALSE; addChild(mSGPacketLoss); mPanelVolumePulldown = new LLPanelVolumePulldown(); @@ -252,9 +255,9 @@ void LLStatusBar::refresh() F32 bwtotal = gViewerThrottle.getMaxBandwidth() / 1000.f; mSGBandwidth->setMin(0.f); mSGBandwidth->setMax(bwtotal*1.25f); - mSGBandwidth->setThreshold(0, bwtotal*0.75f); - mSGBandwidth->setThreshold(1, bwtotal); - mSGBandwidth->setThreshold(2, bwtotal); + //mSGBandwidth->setThreshold(0, bwtotal*0.75f); + //mSGBandwidth->setThreshold(1, bwtotal); + //mSGBandwidth->setThreshold(2, bwtotal); } // update clock every 10 seconds diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index da87cc2673..b1aeaef91d 100755 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -62,6 +62,13 @@ #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived +LLTrace::Stat<F32> STAT_KBIT("kbitstat"), + STAT_LAYERS_KBIT("layerskbitstat"), + STAT_OBJECT_KBIT("objectkbitstat"), + STAT_ASSET_KBIT("assetkbitstat"), + STAT_TEXTURE_KBIT("texturekbitstat"); + + class StatAttributes { public: @@ -198,11 +205,6 @@ const StatAttributes STAT_INFO[LLViewerStats::ST_COUNT] = }; LLViewerStats::LLViewerStats() : - mKBitStat("kbitstat"), - mLayersKBitStat("layerskbitstat"), - mObjectKBitStat("objectkbitstat"), - mAssetKBitStat("assetkbitstat"), - mTextureKBitStat("texturekbitstat"), mVFSPendingOperations("vfspendingoperations"), mFPSStat("fpsstat"), mPacketsInStat("packetsinstat"), @@ -261,7 +263,8 @@ LLViewerStats::LLViewerStats() : mNumNewObjectsStat("numnewobjectsstat"), mNumSizeCulledStat("numsizeculledstat"), mNumVisCulledStat("numvisculledstat"), - mLastTimeDiff(0.0) + mLastTimeDiff(0.0), + mSampler(LLThread::getTraceData()->createSampler()) { for (S32 i = 0; i < ST_COUNT; i++) { @@ -274,17 +277,18 @@ LLViewerStats::LLViewerStats() : } mAgentPositionSnaps.reset(); + mSampler->start(); +} + +LLViewerStats::~LLViewerStats() +{ + delete mSampler; } void LLViewerStats::resetStats() { 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(); @@ -463,10 +467,13 @@ void update_statistics() stats.mFPSStat.addValue(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); - stats.mLayersKBitStat.addValue(layer_bits/1024.f); - stats.mObjectKBitStat.addValue(gObjectBits/1024.f); + STAT_LAYERS_KBIT.sample(layer_bits/1024.f); + //stats.mLayersKBitStat.addValue(layer_bits/1024.f); + STAT_OBJECT_KBIT.sample(gObjectBits/1024.f); + //stats.mObjectKBitStat.addValue(gObjectBits/1024.f); stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); - stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + STAT_ASSET_KBIT.sample(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); + //stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) @@ -503,7 +510,8 @@ void update_statistics() static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { - stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); + STAT_TEXTURE_KBIT.sample(LLViewerTextureList::sTextureBits/1024.f); + //stats.mTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; LLViewerTextureList::sTextureBits = 0; diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 0d8f2a45c0..ca70660ce9 100755 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -29,16 +29,18 @@ #include "llstat.h" #include "lltextureinfo.h" +#include "lltracesampler.h" + +extern LLTrace::Stat<F32> STAT_KBIT, + STAT_LAYERS_KBIT, + STAT_OBJECT_KBIT, + STAT_ASSET_KBIT, + STAT_TEXTURE_KBIT; class LLViewerStats : public LLSingleton<LLViewerStats> { public: - LLStat mKBitStat, - mLayersKBitStat, - mObjectKBitStat, - mAssetKBitStat, - mTextureKBitStat, - mVFSPendingOperations, + LLStat mVFSPendingOperations, mFPSStat, mPacketsInStat, mPacketsLostStat, @@ -110,7 +112,9 @@ public: mNumVisCulledStat; void resetStats(); + public: + // If you change this, please also add a corresponding text label in llviewerstats.cpp enum EStatType { @@ -177,6 +181,7 @@ public: }; LLViewerStats(); + ~LLViewerStats(); // all return latest value of given stat F64 getStat(EStatType type) const; @@ -292,8 +297,11 @@ public: static void recordPhaseStat(const std::string& phase_name, F32 value); }; + LLTrace::Sampler* getSampler() { return mSampler; } + private: F64 mStats[ST_COUNT]; + LLTrace::Sampler* mSampler; F64 mLastTimeDiff; // used for time stat updates }; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 17d8e5e4fa..034f8edf24 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -622,7 +622,9 @@ void LLViewerTextureList::updateImages(F32 max_time) } cleared = FALSE; - LLAppViewer::getTextureFetch()->setTextureBandwidth(LLViewerStats::getInstance()->mTextureKBitStat.getMeanPerSec()); + LLTrace::Sampler* sampler = LLThread::getTraceData()->getPrimarySampler(); + + LLAppViewer::getTextureFetch()->setTextureBandwidth(sampler->getMean(STAT_TEXTURE_KBIT) / sampler->getSampleTime()); LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages); LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 43152c9025..97079e0588 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -704,7 +704,8 @@ void LLWorld::updateNetStats() S32 actual_out_bits = gMessageSystem->mPacketRing.getAndResetActualOutBits(); LLViewerStats::getInstance()->mActualInKBitStat.addValue(actual_in_bits/1024.f); LLViewerStats::getInstance()->mActualOutKBitStat.addValue(actual_out_bits/1024.f); - LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); + STAT_KBIT.sample(bits/1024.f); + //LLViewerStats::getInstance()->mKBitStat.addValue(bits/1024.f); LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in); LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out); LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets); |