SH-3275 WIP Update viewer metrics system to be more flexible
cleaned up accumulator merging logic introduced frame recording to LLTrace directly instead of going through LLViewerStats moved consumer code over to frame recording instead of whatever the current active recording wasmaster
parent
b3107e3764
commit
0f58ca02cd
|
|
@ -101,16 +101,6 @@ namespace LLTrace
|
|||
}
|
||||
}
|
||||
|
||||
void addDeltas(const AccumulatorBuffer<ACCUMULATOR>& start, const AccumulatorBuffer<ACCUMULATOR>& finish)
|
||||
{
|
||||
llassert(mNextStorageSlot == start.mNextStorageSlot && mNextStorageSlot == finish.mNextStorageSlot);
|
||||
|
||||
for (size_t i = 0; i < mNextStorageSlot; i++)
|
||||
{
|
||||
mStorage[i].addDeltas(start.mStorage[i], finish.mStorage[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void copyFrom(const AccumulatorBuffer<ACCUMULATOR>& other)
|
||||
{
|
||||
for (size_t i = 0; i < mNextStorageSlot; i++)
|
||||
|
|
@ -203,11 +193,12 @@ namespace LLTrace
|
|||
public:
|
||||
MeasurementAccumulator()
|
||||
: mSum(0),
|
||||
mMin(0),
|
||||
mMax(0),
|
||||
mMin(std::numeric_limits<T>::max()),
|
||||
mMax(std::numeric_limits<T>::min()),
|
||||
mMean(0),
|
||||
mVarianceSum(0),
|
||||
mNumSamples(0)
|
||||
mNumSamples(0),
|
||||
mLastValue(0)
|
||||
{}
|
||||
|
||||
LL_FORCE_INLINE void sample(T value)
|
||||
|
|
@ -251,20 +242,27 @@ namespace LLTrace
|
|||
sd_2 = other.getStandardDeviation();
|
||||
// combine variance (and hence standard deviation) of 2 different sized sample groups using
|
||||
// the following formula: http://www.mrc-bsu.cam.ac.uk/cochrane/handbook/chapter_7/7_7_3_8_combining_groups.htm
|
||||
mVarianceSum = (F32)mNumSamples
|
||||
if (n_1 == 0)
|
||||
{
|
||||
mVarianceSum = other.mVarianceSum;
|
||||
}
|
||||
else if (n_2 == 0)
|
||||
{
|
||||
// don't touch variance
|
||||
// mVarianceSum = mVarianceSum;
|
||||
}
|
||||
else
|
||||
{
|
||||
mVarianceSum = (F32)mNumSamples
|
||||
* ((((n_1 - 1.f) * sd_1 * sd_1)
|
||||
+ ((n_2 - 1.f) * sd_2 * sd_2)
|
||||
+ (((n_1 * n_2) / (n_1 + n_2))
|
||||
* ((m_1 * m_1) + (m_2 * m_2) - (2.f * m_1 * m_2))))
|
||||
/ (n_1 + n_2 - 1.f));
|
||||
}
|
||||
mLastValue = other.mLastValue;
|
||||
}
|
||||
|
||||
void addDeltas(const MeasurementAccumulator<T>& start, const MeasurementAccumulator<T>& finish)
|
||||
{
|
||||
llerrs << "Delta merge invalid for measurement accumulators" << llendl;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
mNumSamples = 0;
|
||||
|
|
@ -313,12 +311,6 @@ namespace LLTrace
|
|||
mNumSamples += other.mNumSamples;
|
||||
}
|
||||
|
||||
void addDeltas(const RateAccumulator<T>& start, const RateAccumulator<T>& finish)
|
||||
{
|
||||
mSum += finish.mSum - start.mSum;
|
||||
mNumSamples += finish.mNumSamples - start.mNumSamples;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
mNumSamples = 0;
|
||||
|
|
@ -464,13 +456,6 @@ namespace LLTrace
|
|||
mCalls += other.mCalls;
|
||||
}
|
||||
|
||||
void addDeltas(const TimerAccumulator& start, const TimerAccumulator& finish)
|
||||
{
|
||||
mTotalTimeCounter += finish.mTotalTimeCounter - start.mTotalTimeCounter;
|
||||
mChildTimeCounter += finish.mChildTimeCounter - start.mChildTimeCounter;
|
||||
mCalls += finish.mCalls - start.mCalls;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
mTotalTimeCounter = 0;
|
||||
|
|
|
|||
|
|
@ -68,16 +68,16 @@ void Recording::handleReset()
|
|||
}
|
||||
|
||||
void Recording::handleStart()
|
||||
{
|
||||
mSamplingTimer.reset();
|
||||
LLTrace::get_thread_recorder()->activate(this);
|
||||
{
|
||||
mSamplingTimer.reset();
|
||||
LLTrace::get_thread_recorder()->activate(this);
|
||||
}
|
||||
|
||||
void Recording::handleStop()
|
||||
{
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
LLTrace::get_thread_recorder()->deactivate(this);
|
||||
}
|
||||
{
|
||||
mElapsedSeconds += mSamplingTimer.getElapsedTimeF64();
|
||||
LLTrace::get_thread_recorder()->deactivate(this);
|
||||
}
|
||||
|
||||
void Recording::handleSplitTo(Recording& other)
|
||||
{
|
||||
|
|
@ -105,10 +105,204 @@ void Recording::mergeRecording( const Recording& other )
|
|||
mStackTimers.write()->addSamples(*other.mStackTimers);
|
||||
}
|
||||
|
||||
void Recording::mergeRecordingDelta(const Recording& baseline, const Recording& target)
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Recording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
PeriodicRecording::PeriodicRecording( S32 num_periods )
|
||||
: mNumPeriods(num_periods),
|
||||
mCurPeriod(0),
|
||||
mTotalValid(false),
|
||||
mRecordingPeriods( new Recording[num_periods])
|
||||
{
|
||||
mRates.write()->addDeltas(*baseline.mRates, *target.mRates);
|
||||
mStackTimers.write()->addDeltas(*baseline.mStackTimers, *target.mStackTimers);
|
||||
llassert(mNumPeriods > 0);
|
||||
}
|
||||
|
||||
PeriodicRecording::~PeriodicRecording()
|
||||
{
|
||||
delete[] mRecordingPeriods;
|
||||
}
|
||||
|
||||
|
||||
void PeriodicRecording::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& PeriodicRecording::getTotalRecording()
|
||||
{
|
||||
if (!mTotalValid)
|
||||
{
|
||||
mTotalRecording.reset();
|
||||
for (S32 i = (mCurPeriod + 1) % mNumPeriods; i < mCurPeriod; i++)
|
||||
{
|
||||
mTotalRecording.mergeRecording(mRecordingPeriods[i]);
|
||||
}
|
||||
}
|
||||
mTotalValid = true;
|
||||
return mTotalRecording;
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleStart()
|
||||
{
|
||||
getCurRecordingPeriod().handleStart();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleStop()
|
||||
{
|
||||
getCurRecordingPeriod().handleStop();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleReset()
|
||||
{
|
||||
getCurRecordingPeriod().handleReset();
|
||||
}
|
||||
|
||||
void PeriodicRecording::handleSplitTo( PeriodicRecording& other )
|
||||
{
|
||||
getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// ExtendableRecording
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExtendableRecording::extend()
|
||||
{
|
||||
mAcceptedRecording.mergeRecording(mPotentialRecording);
|
||||
mPotentialRecording.reset();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleStart()
|
||||
{
|
||||
mPotentialRecording.handleStart();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleStop()
|
||||
{
|
||||
mPotentialRecording.handleStop();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleReset()
|
||||
{
|
||||
mAcceptedRecording.handleReset();
|
||||
mPotentialRecording.handleReset();
|
||||
}
|
||||
|
||||
void ExtendableRecording::handleSplitTo( ExtendableRecording& other )
|
||||
{
|
||||
mPotentialRecording.handleSplitTo(other.mPotentialRecording);
|
||||
}
|
||||
|
||||
PeriodicRecording& get_frame_recording()
|
||||
{
|
||||
static PeriodicRecording sRecording(64);
|
||||
sRecording.start();
|
||||
return sRecording;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLVCRControlsMixinCommon::start()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
handleReset();
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void LLVCRControlsMixinCommon::stop()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStop();
|
||||
break;
|
||||
case STARTED:
|
||||
handleStop();
|
||||
break;
|
||||
}
|
||||
mPlayState = STOPPED;
|
||||
}
|
||||
|
||||
void LLVCRControlsMixinCommon::pause()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
break;
|
||||
case STARTED:
|
||||
handleStop();
|
||||
break;
|
||||
}
|
||||
mPlayState = PAUSED;
|
||||
}
|
||||
|
||||
void LLVCRControlsMixinCommon::resume()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void LLVCRControlsMixinCommon::restart()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
handleReset();
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void LLVCRControlsMixinCommon::reset()
|
||||
{
|
||||
handleReset();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,27 +34,11 @@
|
|||
#include "lltimer.h"
|
||||
#include "lltrace.h"
|
||||
|
||||
template<typename DERIVED>
|
||||
class LL_COMMON_API LLVCRControlsMixinInterface
|
||||
class LL_COMMON_API LLVCRControlsMixinCommon
|
||||
{
|
||||
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;
|
||||
};
|
||||
virtual ~LLVCRControlsMixinCommon() {}
|
||||
|
||||
template<typename DERIVED>
|
||||
class LL_COMMON_API LLVCRControlsMixin
|
||||
: private LLVCRControlsMixinInterface<DERIVED>
|
||||
{
|
||||
public:
|
||||
enum EPlayState
|
||||
{
|
||||
STOPPED,
|
||||
|
|
@ -62,94 +46,39 @@ public:
|
|||
STARTED
|
||||
};
|
||||
|
||||
void start()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
handleReset();
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
void start();
|
||||
void stop();
|
||||
void pause();
|
||||
void resume();
|
||||
void restart();
|
||||
void reset();
|
||||
|
||||
void stop()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStop();
|
||||
break;
|
||||
case STARTED:
|
||||
break;
|
||||
}
|
||||
mPlayState = STOPPED;
|
||||
}
|
||||
bool isStarted() { return mPlayState == STARTED; }
|
||||
bool isPaused() { return mPlayState == PAUSED; }
|
||||
bool isStopped() { return mPlayState == STOPPED; }
|
||||
EPlayState getPlayState() { return mPlayState; }
|
||||
|
||||
void pause()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
break;
|
||||
case PAUSED:
|
||||
break;
|
||||
case STARTED:
|
||||
handleStop();
|
||||
break;
|
||||
}
|
||||
mPlayState = PAUSED;
|
||||
}
|
||||
protected:
|
||||
LLVCRControlsMixinCommon()
|
||||
: mPlayState(STOPPED)
|
||||
{}
|
||||
|
||||
void resume()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
private:
|
||||
// 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;
|
||||
|
||||
void restart()
|
||||
{
|
||||
switch (mPlayState)
|
||||
{
|
||||
case STOPPED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case PAUSED:
|
||||
handleReset();
|
||||
handleStart();
|
||||
break;
|
||||
case STARTED:
|
||||
handleReset();
|
||||
break;
|
||||
}
|
||||
mPlayState = STARTED;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
handleReset();
|
||||
}
|
||||
EPlayState mPlayState;
|
||||
};
|
||||
|
||||
template<typename DERIVED>
|
||||
class LLVCRControlsMixin
|
||||
: public LLVCRControlsMixinCommon
|
||||
{
|
||||
public:
|
||||
void splitTo(DERIVED& other)
|
||||
{
|
||||
onSplitTo(other);
|
||||
|
|
@ -159,32 +88,15 @@ public:
|
|||
{
|
||||
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;
|
||||
// atomically stop this object while starting the other
|
||||
// no data can be missed in between stop and start
|
||||
virtual void handleSplitTo(DERIVED& other) = 0;
|
||||
|
||||
};
|
||||
|
||||
namespace LLTrace
|
||||
{
|
||||
//template<typename T, typename IS_UNIT> class Rate;
|
||||
//template<typename T, typename IS_UNIT> class Measurement;
|
||||
//template<typename T> class Count;
|
||||
//template<typename T> class AccumulatorBuffer;
|
||||
//template<typename T> class RateAccumulator;
|
||||
//template<typename T> class MeasurementAccumulator;
|
||||
//class TimerAccumulator;
|
||||
|
||||
class LL_COMMON_API Recording : public LLVCRControlsMixin<Recording>
|
||||
{
|
||||
public:
|
||||
|
|
@ -196,7 +108,6 @@ namespace LLTrace
|
|||
bool isPrimary() const;
|
||||
|
||||
void mergeRecording(const Recording& other);
|
||||
void mergeRecordingDelta(const Recording& baseline, const Recording& target);
|
||||
|
||||
void update();
|
||||
|
||||
|
|
@ -308,15 +219,13 @@ namespace LLTrace
|
|||
|
||||
F64 getSampleTime() const { return mElapsedSeconds; }
|
||||
|
||||
private:
|
||||
friend class PeriodicRecording;
|
||||
// implementation for LLVCRControlsMixin
|
||||
/*virtual*/ void handleStart();
|
||||
/*virtual*/ void handleStop();
|
||||
/*virtual*/ void handleReset();
|
||||
/*virtual*/ void handleSplitTo(Recording& other);
|
||||
|
||||
|
||||
private:
|
||||
friend class ThreadRecorder;
|
||||
// returns data for current thread
|
||||
class ThreadRecorder* getThreadRecorder();
|
||||
|
|
@ -333,38 +242,19 @@ namespace LLTrace
|
|||
: public LLVCRControlsMixin<PeriodicRecording>
|
||||
{
|
||||
public:
|
||||
PeriodicRecording(S32 num_periods)
|
||||
: mNumPeriods(num_periods),
|
||||
mCurPeriod(0),
|
||||
mTotalValid(false),
|
||||
mRecordingPeriods(new Recording[num_periods])
|
||||
{
|
||||
llassert(mNumPeriods > 0);
|
||||
PeriodicRecording(S32 num_periods);
|
||||
~PeriodicRecording();
|
||||
|
||||
void nextPeriod();
|
||||
|
||||
Recording& getLastRecordingPeriod()
|
||||
{
|
||||
return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
|
||||
}
|
||||
|
||||
~PeriodicRecording()
|
||||
const Recording& getLastRecordingPeriod() const
|
||||
{
|
||||
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;
|
||||
return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
|
||||
}
|
||||
|
||||
Recording& getCurRecordingPeriod()
|
||||
|
|
@ -377,41 +267,16 @@ namespace LLTrace
|
|||
return mRecordingPeriods[mCurPeriod];
|
||||
}
|
||||
|
||||
Recording& getTotalRecording()
|
||||
{
|
||||
if (!mTotalValid)
|
||||
{
|
||||
mTotalRecording.reset();
|
||||
for (S32 i = (mCurPeriod + 1) % mNumPeriods; i < mCurPeriod; i++)
|
||||
{
|
||||
mTotalRecording.mergeRecording(mRecordingPeriods[i]);
|
||||
}
|
||||
}
|
||||
mTotalValid = true;
|
||||
return mTotalRecording;
|
||||
}
|
||||
Recording& getTotalRecording();
|
||||
|
||||
private:
|
||||
|
||||
// implementation for LLVCRControlsMixin
|
||||
/*virtual*/ void handleStart()
|
||||
{
|
||||
getCurRecordingPeriod().handleStart();
|
||||
}
|
||||
/*virtual*/ void handleStart();
|
||||
/*virtual*/ void handleStop();
|
||||
/*virtual*/ void handleReset();
|
||||
|
||||
/*virtual*/ void handleStop()
|
||||
{
|
||||
getCurRecordingPeriod().handleStop();
|
||||
}
|
||||
|
||||
/*virtual*/ void handleReset()
|
||||
{
|
||||
getCurRecordingPeriod().handleReset();
|
||||
}
|
||||
|
||||
/*virtual*/ void handleSplitTo(PeriodicRecording& other)
|
||||
{
|
||||
getCurRecordingPeriod().handleSplitTo(other.getCurRecordingPeriod());
|
||||
}
|
||||
/*virtual*/ void handleSplitTo(PeriodicRecording& other);
|
||||
|
||||
Recording* mRecordingPeriods;
|
||||
Recording mTotalRecording;
|
||||
|
|
@ -419,6 +284,24 @@ namespace LLTrace
|
|||
S32 mNumPeriods,
|
||||
mCurPeriod;
|
||||
};
|
||||
|
||||
PeriodicRecording& get_frame_recording();
|
||||
|
||||
class ExtendableRecording
|
||||
: public LLVCRControlsMixin<ExtendableRecording>
|
||||
{
|
||||
void extend();
|
||||
|
||||
private:
|
||||
// implementation for LLVCRControlsMixin
|
||||
/*virtual*/ void handleStart();
|
||||
/*virtual*/ void handleStop();
|
||||
/*virtual*/ void handleReset();
|
||||
/*virtual*/ void handleSplitTo(ExtendableRecording& other);
|
||||
|
||||
Recording mAcceptedRecording;
|
||||
Recording mPotentialRecording;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // LL_LLTRACERECORDING_H
|
||||
|
|
|
|||
|
|
@ -36,15 +36,13 @@ namespace LLTrace
|
|||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
ThreadRecorder::ThreadRecorder()
|
||||
: mPrimaryRecording(NULL)
|
||||
{
|
||||
get_thread_recorder() = this;
|
||||
mFullRecording.start();
|
||||
}
|
||||
|
||||
ThreadRecorder::ThreadRecorder( const ThreadRecorder& other )
|
||||
: mFullRecording(other.mFullRecording),
|
||||
mPrimaryRecording(NULL)
|
||||
: mFullRecording(other.mFullRecording)
|
||||
{
|
||||
get_thread_recorder() = this;
|
||||
mFullRecording.start();
|
||||
|
|
@ -55,45 +53,40 @@ ThreadRecorder::~ThreadRecorder()
|
|||
get_thread_recorder() = NULL;
|
||||
}
|
||||
|
||||
//TODO: remove this and use llviewerstats recording
|
||||
Recording* ThreadRecorder::getPrimaryRecording()
|
||||
{
|
||||
return mPrimaryRecording;
|
||||
}
|
||||
|
||||
void ThreadRecorder::activate( Recording* recording )
|
||||
{
|
||||
mActiveRecordings.push_front(ActiveRecording(mPrimaryRecording, recording));
|
||||
mActiveRecordings.push_front(ActiveRecording(recording));
|
||||
mActiveRecordings.front().mBaseline.makePrimary();
|
||||
mPrimaryRecording = &mActiveRecordings.front().mBaseline;
|
||||
}
|
||||
|
||||
std::list<ThreadRecorder::ActiveRecording>::iterator ThreadRecorder::update( Recording* recording )
|
||||
{
|
||||
for (std::list<ActiveRecording>::iterator it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
|
||||
std::list<ActiveRecording>::iterator it, end_it;
|
||||
for (it = mActiveRecordings.begin(), end_it = mActiveRecordings.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
std::list<ActiveRecording>::iterator next_it = it;
|
||||
if (++next_it != mActiveRecordings.end())
|
||||
++next_it;
|
||||
|
||||
// if we have another recording further down in the stack...
|
||||
if (next_it != mActiveRecordings.end())
|
||||
{
|
||||
next_it->mergeMeasurements((*it));
|
||||
// ...push our gathered data down to it
|
||||
next_it->mBaseline.mergeRecording(it->mBaseline);
|
||||
}
|
||||
|
||||
it->flushAccumulators(mPrimaryRecording);
|
||||
// copy accumulated measurements into result buffer and clear accumulator (mBaseline)
|
||||
it->moveBaselineToTarget();
|
||||
|
||||
if (it->mTargetRecording == recording)
|
||||
{
|
||||
if (next_it != mActiveRecordings.end())
|
||||
{
|
||||
next_it->mBaseline.makePrimary();
|
||||
mPrimaryRecording = &next_it->mBaseline;
|
||||
}
|
||||
return it;
|
||||
// found the recording, so return it
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mActiveRecordings.end();
|
||||
return it;
|
||||
}
|
||||
|
||||
void ThreadRecorder::deactivate( Recording* recording )
|
||||
|
|
@ -101,38 +94,34 @@ void ThreadRecorder::deactivate( Recording* recording )
|
|||
std::list<ActiveRecording>::iterator it = update(recording);
|
||||
if (it != mActiveRecordings.end())
|
||||
{
|
||||
// and if we've found the recording we wanted to update
|
||||
std::list<ActiveRecording>::iterator next_it = it;
|
||||
++next_it;
|
||||
if (next_it != mActiveRecordings.end())
|
||||
{
|
||||
next_it->mTargetRecording->makePrimary();
|
||||
}
|
||||
|
||||
mActiveRecordings.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
ThreadRecorder::ActiveRecording::ActiveRecording( Recording* source, Recording* target )
|
||||
ThreadRecorder::ActiveRecording::ActiveRecording( Recording* target )
|
||||
: mTargetRecording(target)
|
||||
{
|
||||
// take snapshots of current values rates and timers
|
||||
if (source)
|
||||
{
|
||||
mBaseline.mRates.write()->copyFrom(*source->mRates);
|
||||
mBaseline.mStackTimers.write()->copyFrom(*source->mStackTimers);
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadRecorder::ActiveRecording::mergeMeasurements(ThreadRecorder::ActiveRecording& other)
|
||||
void ThreadRecorder::ActiveRecording::moveBaselineToTarget()
|
||||
{
|
||||
mBaseline.mMeasurements.write()->addSamples(*other.mBaseline.mMeasurements);
|
||||
}
|
||||
|
||||
void ThreadRecorder::ActiveRecording::flushAccumulators(Recording* current)
|
||||
{
|
||||
// accumulate statistics-like measurements
|
||||
mTargetRecording->mMeasurements.write()->addSamples(*mBaseline.mMeasurements);
|
||||
// for rate-like measurements, merge total change since baseline
|
||||
mTargetRecording->mRates.write()->addDeltas(*mBaseline.mRates, *current->mRates);
|
||||
mTargetRecording->mStackTimers.write()->addDeltas(*mBaseline.mStackTimers, *current->mStackTimers);
|
||||
// reset baselines
|
||||
mBaseline.mRates.write()->copyFrom(*current->mRates);
|
||||
mBaseline.mStackTimers.write()->copyFrom(*current->mStackTimers);
|
||||
mTargetRecording->mRates.write()->addSamples(*mBaseline.mRates);
|
||||
mTargetRecording->mStackTimers.write()->addSamples(*mBaseline.mStackTimers);
|
||||
mBaseline.mMeasurements.write()->reset();
|
||||
mBaseline.mRates.write()->reset();
|
||||
mBaseline.mStackTimers.write()->reset();
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// SlaveThreadRecorder
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -51,19 +51,16 @@ namespace LLTrace
|
|||
|
||||
virtual void pushToMaster() = 0;
|
||||
|
||||
Recording* getPrimaryRecording();
|
||||
protected:
|
||||
struct ActiveRecording
|
||||
{
|
||||
ActiveRecording(Recording* source, Recording* target);
|
||||
ActiveRecording(Recording* target);
|
||||
|
||||
Recording* mTargetRecording;
|
||||
Recording mBaseline;
|
||||
|
||||
void mergeMeasurements(ActiveRecording& other);
|
||||
void flushAccumulators(Recording* current);
|
||||
void moveBaselineToTarget();
|
||||
};
|
||||
Recording* mPrimaryRecording;
|
||||
Recording mFullRecording;
|
||||
std::list<ActiveRecording> mActiveRecordings;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#include "llstat.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "lltracerecording.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -112,17 +111,17 @@ void LLStatBar::draw()
|
|||
}
|
||||
else if (mFloatStatp)
|
||||
{
|
||||
LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording();
|
||||
LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod();
|
||||
if (mPerSec)
|
||||
{
|
||||
current = recording->getSum(*mFloatStatp) / recording->getSampleTime();
|
||||
current = recording.getPerSec(*mFloatStatp);
|
||||
//min = recording->getMin(*mFloatStatp) / recording->getSampleTime();
|
||||
//max = recording->getMax(*mFloatStatp) / recording->getSampleTime();
|
||||
//mean = recording->getMean(*mFloatStatp) / recording->getSampleTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
current = recording->getSum(*mFloatStatp);
|
||||
current = recording.getSum(*mFloatStatp);
|
||||
//min = recording->getMin(*mFloatStatp);
|
||||
//max = recording->getMax(*mFloatStatp);
|
||||
//mean = recording->getMean(*mFloatStatp);
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@
|
|||
|
||||
#include "llview.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lltrace.h"
|
||||
|
||||
#include "lltracerecording.h"
|
||||
class LLStat;
|
||||
|
||||
class LLStatBar : public LLView
|
||||
|
|
@ -39,19 +38,24 @@ public:
|
|||
|
||||
struct Params : public LLInitParam::Block<Params, LLView::Params>
|
||||
{
|
||||
Optional<std::string> label;
|
||||
Optional<std::string> unit_label;
|
||||
Optional<F32> bar_min;
|
||||
Optional<F32> bar_max;
|
||||
Optional<F32> tick_spacing;
|
||||
Optional<F32> label_spacing;
|
||||
Optional<U32> precision;
|
||||
Optional<F32> update_rate;
|
||||
Optional<bool> show_per_sec;
|
||||
Optional<bool> show_bar;
|
||||
Optional<bool> show_history;
|
||||
Optional<bool> show_mean;
|
||||
Optional<std::string> stat;
|
||||
Optional<std::string> label,
|
||||
unit_label;
|
||||
|
||||
Optional<F32> bar_min,
|
||||
bar_max,
|
||||
tick_spacing,
|
||||
label_spacing,
|
||||
update_rate;
|
||||
|
||||
Optional<U32> precision;
|
||||
|
||||
Optional<bool> show_per_sec,
|
||||
show_bar,
|
||||
show_history,
|
||||
show_mean;
|
||||
|
||||
Optional<std::string> stat;
|
||||
|
||||
Params()
|
||||
: label("label"),
|
||||
unit_label("unit_label"),
|
||||
|
|
@ -92,6 +96,7 @@ private:
|
|||
BOOL mDisplayBar; // Display the bar graph.
|
||||
BOOL mDisplayHistory;
|
||||
BOOL mDisplayMean; // If true, display mean, if false, display current value
|
||||
LLTrace::PeriodicRecording* mFrameRecording;
|
||||
|
||||
LLStat* mStatp;
|
||||
LLTrace::Rate<F32>* mFloatStatp;
|
||||
|
|
|
|||
|
|
@ -86,15 +86,15 @@ void LLStatGraph::draw()
|
|||
}
|
||||
else if (mF32Statp)
|
||||
{
|
||||
LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording();
|
||||
LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecordingPeriod();
|
||||
|
||||
if (mPerSec)
|
||||
{
|
||||
mValue = recording->getSum(*mF32Statp) / recording->getSampleTime();
|
||||
mValue = recording.getPerSec(*mF32Statp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mValue = recording->getSum(*mF32Statp);
|
||||
mValue = recording.getSum(*mF32Statp);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -497,6 +497,8 @@ void update_statistics()
|
|||
texture_stats_timer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
LLTrace::get_frame_recording().nextPeriod();
|
||||
}
|
||||
|
||||
class ViewerStatsResponder : public LLHTTPClient::Responder
|
||||
|
|
|
|||
|
|
@ -412,14 +412,12 @@ public:
|
|||
};
|
||||
|
||||
LLTrace::Recording& getRecording() { return mRecording; }
|
||||
LLTrace::Recording& getFrameRecording() { return mFrameRecording; }
|
||||
|
||||
private:
|
||||
F64 mStats[ST_COUNT];
|
||||
LLTrace::Recording mRecording;
|
||||
LLTrace::Recording mFrameRecording;
|
||||
F64 mStats[ST_COUNT];
|
||||
LLTrace::Recording mRecording;
|
||||
|
||||
F64 mLastTimeDiff; // used for time stat updates
|
||||
F64 mLastTimeDiff; // used for time stat updates
|
||||
};
|
||||
|
||||
static const F32 SEND_STATS_PERIOD = 300.0f;
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
#include "pipeline.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llxuiparser.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "lltracerecording.h"
|
||||
#include "llviewerdisplay.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -621,9 +621,9 @@ void LLViewerTextureList::updateImages(F32 max_time)
|
|||
}
|
||||
cleared = FALSE;
|
||||
|
||||
LLTrace::Recording* recording = LLTrace::get_thread_recorder()->getPrimaryRecording();
|
||||
LLTrace::Recording& recording = LLTrace::get_frame_recording().getTotalRecording();
|
||||
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(recording->getPerSec(LLStatViewer::TEXTURE_KBIT).value());
|
||||
LLAppViewer::getTextureFetch()->setTextureBandwidth(recording.getPerSec(LLStatViewer::TEXTURE_KBIT).value());
|
||||
|
||||
LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
|
||||
LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);
|
||||
|
|
|
|||
Loading…
Reference in New Issue