summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llapr.h2
-rw-r--r--indra/llcommon/lltrace.cpp112
-rw-r--r--indra/llcommon/lltrace.h127
-rw-r--r--indra/llcommon/lltracesampler.cpp103
-rw-r--r--indra/llcommon/lltracesampler.h91
-rw-r--r--indra/llrender/llglheaders.h2
-rw-r--r--indra/llui/llstatbar.cpp79
-rw-r--r--indra/llui/llstatbar.h3
-rw-r--r--indra/llui/llstatgraph.cpp123
-rw-r--r--indra/llui/llstatgraph.h99
-rw-r--r--indra/newview/llstatusbar.cpp33
-rwxr-xr-xindra/newview/llviewerstats.cpp38
-rwxr-xr-xindra/newview/llviewerstats.h20
-rw-r--r--indra/newview/llviewertexturelist.cpp4
-rw-r--r--indra/newview/llworld.cpp3
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);