From ea2494a0839ec02d3889a405306009c2f4f9aea7 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 30 Oct 2013 00:37:11 -0700 Subject: stats now autoscale back down in range, instead of sticking at high water mark --- indra/llui/llstatbar.cpp | 132 ++++++++++++++++++++--------------------------- indra/llui/llstatbar.h | 30 ++++++----- 2 files changed, 73 insertions(+), 89 deletions(-) (limited to 'indra') diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index 2b325c27f0..bfdc6571c2 100755 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -176,8 +176,8 @@ LLStatBar::LLStatBar(const Params& p) : LLView(p), mLabel(p.label), mUnitLabel(p.unit_label), - mMinBar(llmin(p.bar_min, p.bar_max)), - mMaxBar(llmax(p.bar_max, p.bar_min)), + mTargetMinBar(llmin(p.bar_min, p.bar_max)), + mTargetMaxBar(llmax(p.bar_max, p.bar_min)), mCurMaxBar(p.bar_max), mCurMinBar(0), mDecimalDigits(p.decimal_digits), @@ -189,15 +189,18 @@ LLStatBar::LLStatBar(const Params& p) mOrientation(p.orientation), mAutoScaleMax(!p.bar_max.isProvided()), mAutoScaleMin(!p.bar_min.isProvided()), - mTickValue(p.tick_spacing), + mTickSpacing(p.tick_spacing), mLastDisplayValue(0.f), mStatType(STAT_NONE) { + mFloatingTargetMinBar = mTargetMinBar; + mFloatingTargetMaxBar = mTargetMaxBar; + mStat.valid = NULL; // tick value will be automatically calculated later if (!p.tick_spacing.isProvided() && p.bar_min.isProvided() && p.bar_max.isProvided()) { - mTickValue = calc_tick_value(mMinBar, mMaxBar); + mTickSpacing = calc_tick_value(mTargetMinBar, mTargetMaxBar); } setStat(p.stat); @@ -259,12 +262,12 @@ BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask) template S32 calc_num_rapid_changes(LLTrace::PeriodicRecording& periodic_recording, const T& stat, const F32Seconds time_period) { - F32Seconds elapsed_time, - time_since_value_changed; - S32 num_rapid_changes = 0; - const F32Seconds RAPID_CHANGE_THRESHOLD = F32Seconds(0.3f); + F32Seconds elapsed_time, + time_since_value_changed; + S32 num_rapid_changes = 0; + const F32Seconds RAPID_CHANGE_THRESHOLD = F32Seconds(0.3f); + F64 last_value = periodic_recording.getPrevRecording(1).getLastValue(stat); - F64 last_value = periodic_recording.getPrevRecording(1).getLastValue(stat); for (S32 i = 2; i < periodic_recording.getNumRecordedPeriods(); i++) { LLTrace::Recording& recording = periodic_recording.getPrevRecording(i); @@ -284,32 +287,6 @@ S32 calc_num_rapid_changes(LLTrace::PeriodicRecording& periodic_recording, const return num_rapid_changes; } -S32 calc_num_rapid_changes(LLTrace::PeriodicRecording& periodic_recording, const LLTrace::StatType& stat, const F32Seconds time_period) -{ - F32Seconds elapsed_time, - time_since_value_changed; - S32 num_rapid_changes = 0; - - F64 last_value = periodic_recording.getPrevRecording(1).getSum(stat); - for (S32 i = 1; i < periodic_recording.getNumRecordedPeriods(); i++) - { - LLTrace::Recording& recording = periodic_recording.getPrevRecording(i); - F64 cur_value = recording.getSum(stat); - - if (last_value != cur_value) - { - if (time_since_value_changed < RAPID_CHANGE_THRESHOLD) num_rapid_changes++; - time_since_value_changed = (F32Seconds)0; - } - last_value = cur_value; - - elapsed_time += recording.getDuration(); - if (elapsed_time > time_period) break; - } - - return num_rapid_changes; -} - void LLStatBar::draw() { LLLocalClipRect _(getLocalRect()); @@ -318,16 +295,16 @@ void LLStatBar::draw() LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); std::string unit_label; - F32 current = 0, - min = 0, - max = 0, - mean = 0, - display_value = 0; - S32 num_frames = mDisplayHistory - ? mNumHistoryFrames - : mNumShortHistoryFrames; - S32 num_rapid_changes = 0; - S32 decimal_digits = mDecimalDigits; + F32 current = 0, + min = 0, + max = 0, + mean = 0, + display_value = 0; + S32 num_frames = mDisplayHistory + ? mNumHistoryFrames + : mNumShortHistoryFrames; + S32 num_rapid_changes = 0; + S32 decimal_digits = mDecimalDigits; switch(mStatType) { @@ -414,8 +391,8 @@ void LLStatBar::draw() bar_rect.mBottom = llmin(bar_rect.mTop - 5, 20); } - mCurMaxBar = LLSmoothInterpolation::lerp(mCurMaxBar, mMaxBar, 0.05f); - mCurMinBar = LLSmoothInterpolation::lerp(mCurMinBar, mMinBar, 0.05f); + mCurMaxBar = LLSmoothInterpolation::lerp(mCurMaxBar, mTargetMaxBar, 0.05f); + mCurMinBar = LLSmoothInterpolation::lerp(mCurMinBar, mTargetMinBar, 0.05f); // rate limited updates if (mLastDisplayValueTimer.getElapsedTimeF32() < MEAN_VALUE_UPDATE_TIME) @@ -429,7 +406,6 @@ void LLStatBar::draw() drawLabelAndValue(display_value, unit_label, bar_rect, decimal_digits); mLastDisplayValue = display_value; - if (mDisplayBar && mStat.valid) { // Draw the tick marks. @@ -607,9 +583,11 @@ void LLStatBar::setStat(const std::string& stat_name) void LLStatBar::setRange(F32 bar_min, F32 bar_max) { - mMinBar = llmin(bar_min, bar_max); - mMaxBar = llmax(bar_min, bar_max); - mTickValue = calc_tick_value(mMinBar, mMaxBar); + mTargetMinBar = llmin(bar_min, bar_max); + mTargetMaxBar = llmax(bar_min, bar_max); + mFloatingTargetMinBar = mTargetMinBar; + mFloatingTargetMaxBar = mTargetMaxBar; + mTickSpacing = calc_tick_value(mTargetMinBar, mTargetMaxBar); } LLRect LLStatBar::getRequiredRect() @@ -660,21 +638,24 @@ void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_re void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ) { - if ((mAutoScaleMax && max >= mCurMaxBar)|| (mAutoScaleMin && min <= mCurMinBar)) + if (mAutoScaleMax || mAutoScaleMin) { - F32 range_min = mAutoScaleMin ? llmin(mMinBar, min) : mMinBar; - F32 range_max = mAutoScaleMax ? llmax(mMaxBar, max) : mMaxBar; + F32 u = LLSmoothInterpolation::getInterpolant(10.f); + mFloatingTargetMinBar = llmin(min, lerp(mFloatingTargetMinBar, min, u)); + mFloatingTargetMaxBar = llmax(max, lerp(mFloatingTargetMaxBar, max, u)); + F32 range_min = mAutoScaleMin ? mFloatingTargetMinBar : mTargetMinBar; + F32 range_max = mAutoScaleMax ? mFloatingTargetMaxBar : mTargetMaxBar; F32 tick_value = 0.f; calc_auto_scale_range(range_min, range_max, tick_value); - if (mAutoScaleMin) { mMinBar = range_min; } - if (mAutoScaleMax) { mMaxBar = range_max; } + if (mAutoScaleMin) { mTargetMinBar = range_min; } + if (mAutoScaleMax) { mTargetMaxBar = range_max; } if (mAutoScaleMin && mAutoScaleMax) { - mTickValue = tick_value; + mTickSpacing = tick_value; } else { - mTickValue = calc_tick_value(mMinBar, mMaxBar); + mTickSpacing = calc_tick_value(mTargetMinBar, mTargetMaxBar); } } @@ -682,7 +663,7 @@ void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ) // ensure ticks always hit 0 S32 last_tick = S32_MIN; S32 last_label = S32_MIN; - if (mTickValue > 0.f && value_scale > 0.f) + if (mTickSpacing > 0.f && value_scale > 0.f) { const S32 MIN_TICK_SPACING = mOrientation == HORIZONTAL ? 20 : 30; const S32 MIN_LABEL_SPACING = mOrientation == HORIZONTAL ? 30 : 60; @@ -690,17 +671,18 @@ void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ) const S32 TICK_WIDTH = 1; F32 start = mCurMinBar < 0.f - ? llceil(-mCurMinBar / mTickValue) * -mTickValue + ? llceil(-mCurMinBar / mTickSpacing) * -mTickSpacing : 0.f; - for (F32 tick_value = start; ;tick_value += mTickValue) + for (F32 tick_value = start; ;tick_value += mTickSpacing) { - const S32 begin = llfloor((tick_value - mCurMinBar)*value_scale); - const S32 end = begin + TICK_WIDTH; - if (begin < last_tick + MIN_TICK_SPACING) + // clamp to S32_MAX / 2 to avoid floating point to integer overflow resulting in S32_MIN + const S32 tick_begin = llfloor(llmin((F32)(S32_MAX / 2), (tick_value - mCurMinBar)*value_scale)); + const S32 tick_end = tick_begin + TICK_WIDTH; + if (tick_begin < last_tick + MIN_TICK_SPACING) { continue; } - last_tick = begin; + last_tick = tick_begin; S32 decimal_digits = mDecimalDigits; if (is_approx_equal((F32)(S32)tick_value, tick_value)) @@ -711,25 +693,25 @@ void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ) S32 tick_label_width = LLFontGL::getFontMonospace()->getWidth(tick_label); if (mOrientation == HORIZONTAL) { - if (begin > last_label + MIN_LABEL_SPACING) + if (tick_begin > last_label + MIN_LABEL_SPACING) { - gl_rect_2d(bar_rect.mLeft, end, bar_rect.mRight - TICK_LENGTH, begin, LLColor4(1.f, 1.f, 1.f, 0.25f)); - LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, bar_rect.mRight, begin, + gl_rect_2d(bar_rect.mLeft, tick_end, bar_rect.mRight - TICK_LENGTH, tick_begin, LLColor4(1.f, 1.f, 1.f, 0.25f)); + LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, bar_rect.mRight, tick_begin, LLColor4(1.f, 1.f, 1.f, 0.5f), LLFontGL::LEFT, LLFontGL::VCENTER); - last_label = begin; + last_label = tick_begin; } else { - gl_rect_2d(bar_rect.mLeft, end, bar_rect.mRight - TICK_LENGTH/2, begin, LLColor4(1.f, 1.f, 1.f, 0.1f)); + gl_rect_2d(bar_rect.mLeft, tick_end, bar_rect.mRight - TICK_LENGTH/2, tick_begin, LLColor4(1.f, 1.f, 1.f, 0.1f)); } } else { - if (begin > last_label + MIN_LABEL_SPACING) + if (tick_begin > last_label + MIN_LABEL_SPACING) { - gl_rect_2d(begin, bar_rect.mTop, end, bar_rect.mBottom - TICK_LENGTH, LLColor4(1.f, 1.f, 1.f, 0.25f)); - S32 label_pos = begin - llround((F32)tick_label_width * ((F32)begin / (F32)bar_rect.getWidth())); + gl_rect_2d(tick_begin, bar_rect.mTop, tick_end, bar_rect.mBottom - TICK_LENGTH, LLColor4(1.f, 1.f, 1.f, 0.25f)); + S32 label_pos = tick_begin - llround((F32)tick_label_width * ((F32)tick_begin / (F32)bar_rect.getWidth())); LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, label_pos, bar_rect.mBottom - TICK_LENGTH, LLColor4(1.f, 1.f, 1.f, 0.5f), LLFontGL::LEFT, LLFontGL::TOP); @@ -737,10 +719,10 @@ void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ) } else { - gl_rect_2d(begin, bar_rect.mTop, end, bar_rect.mBottom - TICK_LENGTH/2, LLColor4(1.f, 1.f, 1.f, 0.1f)); + gl_rect_2d(tick_begin, bar_rect.mTop, tick_end, bar_rect.mBottom - TICK_LENGTH/2, LLColor4(1.f, 1.f, 1.f, 0.1f)); } } - // always draw one tick value past end, so we can see part of the text, if possible + // always draw one tick value past tick_end, so we can see part of the text, if possible if (tick_value > mCurMaxBar) { break; diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 57e492bc80..89d7ff24ed 100755 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -44,13 +44,12 @@ public: bar_max, tick_spacing; - Optional decimal_digits; - Optional show_bar, show_history, scale_range; - Optional num_frames, + Optional decimal_digits, + num_frames, num_frames_short, max_height; Optional stat; @@ -67,7 +66,7 @@ public: void setStat(const std::string& stat_name); void setRange(F32 bar_min, F32 bar_max); - void getRange(F32& bar_min, F32& bar_max) { bar_min = mMinBar; bar_max = mMaxBar; } + void getRange(F32& bar_min, F32& bar_max) { bar_min = mTargetMinBar; bar_max = mTargetMaxBar; } /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options. @@ -75,20 +74,18 @@ private: void drawLabelAndValue( F32 mean, std::string &unit_label, LLRect &bar_rect, S32 decimal_digits ); void drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ); - F32 mMinBar, - mMaxBar, + F32 mTargetMinBar, + mTargetMaxBar, + mFloatingTargetMinBar, + mFloatingTargetMaxBar, mCurMaxBar, mCurMinBar, - mLabelSpacing; - F32 mTickValue; - U32 mDecimalDigits; - S32 mNumHistoryFrames, + mLabelSpacing, + mTickSpacing; + S32 mDecimalDigits, + mNumHistoryFrames, mNumShortHistoryFrames; S32 mMaxHeight; - bool mDisplayBar, // Display the bar graph. - mDisplayHistory, - mAutoScaleMax, - mAutoScaleMin; EOrientation mOrientation; F32 mLastDisplayValue; LLFrameTimer mLastDisplayValueTimer; @@ -113,6 +110,11 @@ private: LLUIString mLabel; std::string mUnitLabel; + + bool mDisplayBar, // Display the bar graph. + mDisplayHistory, + mAutoScaleMax, + mAutoScaleMin; }; #endif -- cgit v1.2.3