diff options
author | Richard Linden <none@none> | 2012-10-09 18:02:47 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2012-10-09 18:02:47 -0700 |
commit | aff9654c1115b4a74fc3ee8f9ca2c2ffa07f8d73 (patch) | |
tree | 4cbd07cad7b3d912324aee7513fb5462bab9d13b /indra/llcommon | |
parent | 3960fdf9e01619ddfd7903bcdd8d894f432752d0 (diff) |
SH-3275 WIP Update viewer metrics system to be more flexible
added PeriodicRecorder class for frame by frame stats accumulation
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/lltrace.h | 4 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.cpp | 35 | ||||
-rw-r--r-- | indra/llcommon/lltracerecording.h | 247 | ||||
-rw-r--r-- | indra/llcommon/llunit.h | 12 |
4 files changed, 261 insertions, 37 deletions
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index d83ea77363..e655a3582e 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -353,7 +353,7 @@ namespace LLTrace template<typename UNIT_T> void sample(UNIT_T value) { - base_measurement_t::sample(value.get()); + base_measurement_t::sample(value.value()); } }; @@ -386,7 +386,7 @@ namespace LLTrace template<typename UNIT_T> void add(UNIT_T value) { - getPrimaryAccumulator().add(value.get()); + getPrimaryAccumulator().add(value.value()); } }; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index e4cff551f9..7cd6280f03 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -38,7 +38,6 @@ namespace LLTrace Recording::Recording() : mElapsedSeconds(0), - mIsStarted(false), mRates(new AccumulatorBuffer<RateAccumulator<F32> >()), mMeasurements(new AccumulatorBuffer<MeasurementAccumulator<F32> >()), mStackTimers(new AccumulatorBuffer<TimerAccumulator>()) @@ -47,13 +46,7 @@ Recording::Recording() Recording::~Recording() {} -void Recording::start() -{ - reset(); - resume(); -} - -void Recording::reset() +void Recording::handleReset() { mRates.write()->reset(); mMeasurements.write()->reset(); @@ -63,24 +56,22 @@ void Recording::reset() mSamplingTimer.reset(); } -void Recording::resume() +void Recording::handleStart() +{ + mSamplingTimer.reset(); + LLTrace::get_thread_recorder()->activate(this); +} + +void Recording::handleStop() { - if (!mIsStarted) - { - mSamplingTimer.reset(); - LLTrace::get_thread_recorder()->activate(this); - mIsStarted = true; - } + mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); + LLTrace::get_thread_recorder()->deactivate(this); } -void Recording::stop() +void Recording::handleSplitTo(Recording& other) { - if (mIsStarted) - { - mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); - LLTrace::get_thread_recorder()->deactivate(this); - mIsStarted = false; - } + stop(); + other.restart(); } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index f9bc6b61b2..080007ba00 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -33,6 +33,147 @@ #include "llpointer.h" #include "lltimer.h" +template<typename DERIVED> +class LL_COMMON_API LLVCRControlsMixinInterface +{ +public: + virtual ~LLVCRControlsMixinInterface() {} + // trigger data accumulation (without reset) + virtual void handleStart() = 0; + // stop data accumulation, should put object in queryable state + virtual void handleStop() = 0; + // clear accumulated values, can be called while started + virtual void handleReset() = 0; + // atomically stop this object while starting the other + // no data can be missed in between stop and start + virtual void handleSplitTo(DERIVED& other) = 0; +}; + +template<typename DERIVED> +class LL_COMMON_API LLVCRControlsMixin +: private LLVCRControlsMixinInterface<DERIVED> +{ +public: + enum EPlayState + { + STOPPED, + PAUSED, + STARTED + }; + + void start() + { + switch (mPlayState) + { + case STOPPED: + handleReset(); + handleStart(); + break; + case PAUSED: + handleStart(); + break; + case STARTED: + handleReset(); + break; + } + mPlayState = STARTED; + } + + void stop() + { + switch (mPlayState) + { + case STOPPED: + break; + case PAUSED: + handleStop(); + break; + case STARTED: + break; + } + mPlayState = STOPPED; + } + + void pause() + { + switch (mPlayState) + { + case STOPPED: + break; + case PAUSED: + break; + case STARTED: + handleStop(); + break; + } + mPlayState = PAUSED; + } + + void resume() + { + switch (mPlayState) + { + case STOPPED: + handleStart(); + break; + case PAUSED: + handleStart(); + break; + case STARTED: + break; + } + mPlayState = STARTED; + } + + void restart() + { + switch (mPlayState) + { + case STOPPED: + handleReset(); + handleStart(); + break; + case PAUSED: + handleReset(); + handleStart(); + break; + case STARTED: + handleReset(); + break; + } + mPlayState = STARTED; + } + + void reset() + { + handleReset(); + } + + void splitTo(DERIVED& other) + { + onSplitTo(other); + } + + void splitFrom(DERIVED& other) + { + other.onSplitTo(*this); + } + + bool isStarted() { return mPlayState == STARTED; } + bool isPaused() { return mPlayState == PAUSED; } + bool isStopped() { return mPlayState == STOPPED; } + EPlayState getPlayState() { return mPlayState; } + +protected: + + LLVCRControlsMixin() + : mPlayState(STOPPED) + {} + +private: + EPlayState mPlayState; +}; + namespace LLTrace { template<typename T, typename IS_UNIT> class Rate; @@ -43,7 +184,7 @@ namespace LLTrace template<typename T> class MeasurementAccumulator; class TimerAccumulator; - class LL_COMMON_API Recording + class LL_COMMON_API Recording : public LLVCRControlsMixin<Recording> { public: Recording(); @@ -53,16 +194,9 @@ namespace LLTrace void makePrimary(); bool isPrimary(); - void start(); - void stop(); - void resume(); - void mergeSamples(const Recording& other); void mergeDeltas(const Recording& baseline, const Recording& target); - void reset(); - - bool isStarted() { return mIsStarted; } // Rate accessors F32 getSum(const Rate<F32, void>& stat); @@ -89,6 +223,14 @@ namespace LLTrace F64 getSampleTime() { return mElapsedSeconds; } private: + friend class PeriodicRecording; + // implementation for LLVCRControlsMixin + /*virtual*/ void handleStart(); + /*virtual*/ void handleStop(); + /*virtual*/ void handleReset(); + /*virtual*/ void handleSplitTo(Recording& other); + + friend class ThreadRecorder; // returns data for current thread class ThreadRecorder* getThreadRecorder(); @@ -97,14 +239,99 @@ namespace LLTrace LLCopyOnWritePointer<AccumulatorBuffer<MeasurementAccumulator<F32> > > mMeasurements; LLCopyOnWritePointer<AccumulatorBuffer<TimerAccumulator> > mStackTimers; - bool mIsStarted; LLTimer mSamplingTimer; F64 mElapsedSeconds; }; - class LL_COMMON_API PeriodicRecording + class LL_COMMON_API PeriodicRecording + : public LLVCRControlsMixin<PeriodicRecording> { + public: + PeriodicRecording(S32 num_periods) + : mNumPeriods(num_periods), + mCurPeriod(0), + mTotalValid(false), + mRecordingPeriods(new Recording[num_periods]) + { + llassert(mNumPeriods > 0); + } + + ~PeriodicRecording() + { + delete[] mRecordingPeriods; + } + + void nextPeriod() + { + EPlayState play_state = getPlayState(); + getCurRecordingPeriod().stop(); + mCurPeriod = (mCurPeriod + 1) % mNumPeriods; + switch(play_state) + { + case STOPPED: + break; + case PAUSED: + getCurRecordingPeriod().pause(); + break; + case STARTED: + getCurRecordingPeriod().start(); + break; + } + // new period, need to recalculate total + mTotalValid = false; + } + + Recording& getCurRecordingPeriod() + { + return mRecordingPeriods[mCurPeriod]; + } + + const Recording& getCurRecordingPeriod() const + { + return mRecordingPeriods[mCurPeriod]; + } + + Recording& getTotalRecording() + { + if (!mTotalValid) + { + mTotalRecording.reset(); + for (S32 i = (mCurPeriod + 1) % mNumPeriods; i < mCurPeriod; i++) + { + mTotalRecording.mergeSamples(mRecordingPeriods[i]); + } + } + mTotalValid = true; + return mTotalRecording; + } + + private: + // implementation for LLVCRControlsMixin + /*virtual*/ void handleStart() + { + getCurRecordingPeriod().handleStart(); + } + + /*virtual*/ void handleStop() + { + getCurRecordingPeriod().handleStop(); + } + + /*virtual*/ void handleReset() + { + getCurRecordingPeriod().handleReset(); + } + + /*virtual*/ void handleSplitTo(PeriodicRecording& other) + { + getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod()); + } + Recording* mRecordingPeriods; + Recording mTotalRecording; + bool mTotalValid; + S32 mNumPeriods, + mCurPeriod; }; } diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h index 9d78df7cae..52b837fdc3 100644 --- a/indra/llcommon/llunit.h +++ b/indra/llcommon/llunit.h @@ -44,13 +44,19 @@ struct LLUnit : public BASE_UNIT : BASE_UNIT(convertToBase(value)) {} - operator value_t() { return get(); } + operator value_t() { return value(); } - value_t get() const + value_t value() const { return convertToDerived(mValue); } + template<typename CONVERTED_TYPE> + value_t value() const + { + return CONVERTED_TYPE(*this).value(); + } + static value_t convertToBase(value_t derived_value) { return (value_t)((F32)derived_value * DERIVED_UNIT::conversionToBaseFactor()); @@ -84,7 +90,7 @@ struct LLUnit<T, T> return *this; } - value_t get() { return mValue; } + value_t value() { return mValue; } static value_t convertToBase(value_t derived_value) { |