diff options
author | Richard Linden <none@none> | 2013-08-12 20:05:16 -0700 |
---|---|---|
committer | Richard Linden <none@none> | 2013-08-12 20:05:16 -0700 |
commit | cc31b4ae7934010762b8aaaa7e190c74a1cd7820 (patch) | |
tree | 61bb7e622417a5223fa108522e16f6b7dee147f3 /indra/llui | |
parent | e340009fc59d59e59b2e8d903a884acb76b178eb (diff) |
SH-4399 FIX: Interesting: Texture console MB Bound 0/384 and texture queue bounces once per second
SH-4346 FIX: Interesting: some integer Statistics are displayed as floating point after crossing region boundary
made llerrs/infos/etc properly variadic wrt tags
LL_INFOS("A", "B", "C") works, for example
fixed unit tests
remove llsimplestat
Diffstat (limited to 'indra/llui')
-rwxr-xr-x | indra/llui/llstatbar.cpp | 600 | ||||
-rwxr-xr-x | indra/llui/llstatbar.h | 11 | ||||
-rwxr-xr-x | indra/llui/llxuiparser.cpp | 10 |
3 files changed, 353 insertions, 268 deletions
diff --git a/indra/llui/llstatbar.cpp b/indra/llui/llstatbar.cpp index ee73cfa40d..900f81992c 100755 --- a/indra/llui/llstatbar.cpp +++ b/indra/llui/llstatbar.cpp @@ -160,7 +160,8 @@ LLStatBar::LLStatBar(const Params& p) mOrientation(p.orientation), mAutoScaleMax(!p.bar_max.isProvided()), mAutoScaleMin(!p.bar_min.isProvided()), - mTickValue(p.tick_spacing) + mTickValue(p.tick_spacing), + mLastDisplayValue(0.f) { // tick value will be automatically calculated later if (!p.tick_spacing.isProvided() && p.bar_min.isProvided() && p.bar_max.isProvided()) @@ -219,323 +220,281 @@ BOOL LLStatBar::handleMouseDown(S32 x, S32 y, MASK mask) return TRUE; } -void LLStatBar::draw() +template<typename T> +S32 calc_num_rapid_changes(LLTrace::PeriodicRecording& periodic_recording, const T& stat, const LLUnit<F32, LLUnits::Seconds> time_period) { - F32 current = 0, - min = 0, - max = 0, - mean = 0; + LLUnit<F32, LLUnits::Seconds> elapsed_time, + time_since_value_changed; + S32 num_rapid_changes = 0; + const LLUnit<F32, LLUnits::Seconds> RAPID_CHANGE_THRESHOLD = LLUnits::Seconds::fromValue(0.3f); - bool show_data = false; - - LLLocalClipRect _(getLocalRect()); - LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); + 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); + F64 cur_value = recording.getLastValue(stat); - S32 num_frames = mDisplayHistory ? mNumHistoryFrames : mNumShortHistoryFrames; + if (last_value != cur_value) + { + if (time_since_value_changed < RAPID_CHANGE_THRESHOLD) num_rapid_changes++; + time_since_value_changed = 0; + } + last_value = cur_value; - std::string unit_label; - if (mCountFloatp) - { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); - unit_label = mUnitLabel.empty() ? mCountFloatp->getUnitLabel() : mUnitLabel; - unit_label += "/s"; - current = last_frame_recording.getPerSec(*mCountFloatp); - min = frame_recording.getPeriodMinPerSec(*mCountFloatp, num_frames); - max = frame_recording.getPeriodMaxPerSec(*mCountFloatp, num_frames); - mean = frame_recording.getPeriodMeanPerSec(*mCountFloatp, num_frames); - - // always show count-style data - show_data = true; + elapsed_time += recording.getDuration(); + if (elapsed_time > time_period) break; } - else if (mEventFloatp) + + return num_rapid_changes; +} + +S32 calc_num_rapid_changes(LLTrace::PeriodicRecording& periodic_recording, const LLTrace::TraceType<LLTrace::CountAccumulator>& stat, const LLUnit<F32, LLUnits::Seconds> time_period) +{ + LLUnit<F32, LLUnits::Seconds> elapsed_time, + time_since_value_changed; + S32 num_rapid_changes = 0; + const LLUnit<F32, LLUnits::Seconds> RAPID_CHANGE_THRESHOLD = LLUnits::Seconds::fromValue(0.3f); + + F64 last_value = periodic_recording.getPrevRecording(1).getSum(stat); + for (S32 i = 1; i < periodic_recording.getNumRecordedPeriods(); i++) { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); - unit_label = mUnitLabel.empty() ? mEventFloatp->getUnitLabel() : mUnitLabel; + LLTrace::Recording& recording = periodic_recording.getPrevRecording(i); + F64 cur_value = recording.getSum(stat); - // only show data if there is an event in the relevant time period - current = last_frame_recording.getMean(*mEventFloatp); - min = frame_recording.getPeriodMin(*mEventFloatp, num_frames); - max = frame_recording.getPeriodMax(*mEventFloatp, num_frames); - mean = frame_recording.getPeriodMean(*mEventFloatp, num_frames); + if (last_value != cur_value) + { + if (time_since_value_changed < RAPID_CHANGE_THRESHOLD) num_rapid_changes++; + time_since_value_changed = 0; + } + last_value = cur_value; - show_data = frame_recording.getSampleCount(*mEventFloatp, num_frames) != 0; + elapsed_time += recording.getDuration(); + if (elapsed_time > time_period) break; } - else if (mSampleFloatp) - { - LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); - unit_label = mUnitLabel.empty() ? mSampleFloatp->getUnitLabel() : mUnitLabel; + return num_rapid_changes; +} - current = last_frame_recording.getMean(*mSampleFloatp); - min = frame_recording.getPeriodMin(*mSampleFloatp, num_frames); - max = frame_recording.getPeriodMax(*mSampleFloatp, num_frames); - mean = frame_recording.getPeriodMean(*mSampleFloatp, num_frames); +void LLStatBar::draw() +{ + LLLocalClipRect _(getLocalRect()); - // always show sample data if we've ever grabbed any samples - show_data = last_frame_recording.hasValue(*mSampleFloatp); - } + LLTrace::PeriodicRecording& frame_recording = LLTrace::get_frame_recording(); + LLTrace::Recording& last_frame_recording = frame_recording.getLastRecording(); - S32 bar_top, bar_left, bar_right, bar_bottom; - if (mOrientation == HORIZONTAL) + 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; + + const S32 MAX_RAPID_CHANGES = 6; + const F32 MIN_VALUE_UPDATE_TIME = 1.f / 4.f; + const LLUnit<F32, LLUnits::Seconds> CHANGE_WINDOW = LLUnits::Seconds::fromValue(2.f); + + if (mCountFloatp) { - bar_top = llmax(5, getRect().getHeight() - 15); - bar_left = 0; - bar_right = getRect().getWidth() - 40; - bar_bottom = llmin(bar_top - 5, 0); + const LLTrace::TraceType<LLTrace::CountAccumulator>& count_stat = *mCountFloatp; + + unit_label = mUnitLabel.empty() ? (std::string(count_stat.getUnitLabel()) + "/s") : mUnitLabel; + current = last_frame_recording.getPerSec(count_stat); + min = frame_recording.getPeriodMinPerSec(count_stat, num_frames); + max = frame_recording.getPeriodMaxPerSec(count_stat, num_frames); + mean = frame_recording.getPeriodMeanPerSec(count_stat, num_frames); + num_rapid_changes = calc_num_rapid_changes(frame_recording, count_stat, CHANGE_WINDOW); } - else // VERTICAL + else if (mEventFloatp) { - bar_top = llmax(5, getRect().getHeight() - 15); - bar_left = 0; - bar_right = getRect().getWidth(); - bar_bottom = llmin(bar_top - 5, 20); - } - const S32 tick_length = 4; - const S32 tick_width = 1; + const LLTrace::TraceType<LLTrace::EventAccumulator>& event_stat = *mEventFloatp; - if ((mAutoScaleMax && max >= mCurMaxBar)|| (mAutoScaleMin && min <= mCurMinBar)) - { - F32 range_min = mAutoScaleMin ? llmin(mMinBar, min) : mMinBar; - F32 range_max = mAutoScaleMax ? llmax(mMaxBar, max) : mMaxBar; - 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 && mAutoScaleMax) - { - mTickValue = tick_value; - } - else - { - mTickValue = calc_tick_value(mMinBar, mMaxBar); - } + unit_label = mUnitLabel.empty() ? event_stat.getUnitLabel() : mUnitLabel; + + current = last_frame_recording.getLastValue(event_stat); + min = frame_recording.getPeriodMin(event_stat, num_frames); + max = frame_recording.getPeriodMax(event_stat, num_frames); + mean = frame_recording.getPeriodMean(event_stat, num_frames); + num_rapid_changes = calc_num_rapid_changes(frame_recording, event_stat, CHANGE_WINDOW); } + else if (mSampleFloatp) + { + const LLTrace::TraceType<LLTrace::SampleAccumulator>& sample_stat = *mSampleFloatp; - mCurMaxBar = LLSmoothInterpolation::lerp(mCurMaxBar, mMaxBar, 0.05f); - mCurMinBar = LLSmoothInterpolation::lerp(mCurMinBar, mMinBar, 0.05f); + unit_label = mUnitLabel.empty() ? sample_stat.getUnitLabel() : mUnitLabel; - F32 value_scale; - if (mCurMaxBar == mCurMinBar) - { - value_scale = 0.f; + current = last_frame_recording.getLastValue(sample_stat); + min = frame_recording.getPeriodMin(sample_stat, num_frames); + max = frame_recording.getPeriodMax(sample_stat, num_frames); + mean = frame_recording.getPeriodMean(sample_stat, num_frames); + num_rapid_changes = calc_num_rapid_changes(frame_recording, sample_stat, CHANGE_WINDOW); } - else + + if (mLastDisplayValueTimer.getElapsedTimeF32() > MIN_VALUE_UPDATE_TIME) { - value_scale = (mOrientation == HORIZONTAL) - ? (bar_top - bar_bottom)/(mCurMaxBar - mCurMinBar) - : (bar_right - bar_left)/(mCurMaxBar - mCurMinBar); + mLastDisplayValueTimer.reset(); + display_value = (num_rapid_changes > MAX_RAPID_CHANGES) + ? mean + : current; + mLastDisplayValue = display_value; } - - LLFontGL::getFontMonospace()->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f), - LLFontGL::LEFT, LLFontGL::TOP); - - S32 decimal_digits = mDecimalDigits; - if (is_approx_equal((F32)(S32)mean, mean)) + else { - decimal_digits = 0; + display_value = mLastDisplayValue; } - std::string value_str = show_data - ? llformat("%10.*f %s", decimal_digits, mean, unit_label.c_str()) - : "n/a"; - // Draw the current value. + LLRect bar_rect; if (mOrientation == HORIZONTAL) { - LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_right, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), - LLFontGL::RIGHT, LLFontGL::TOP); + bar_rect.mTop = llmax(5, getRect().getHeight() - 15); + bar_rect.mLeft = 0; + bar_rect.mRight = getRect().getWidth() - 40; + bar_rect.mBottom = llmin(bar_rect.mTop - 5, 0); } - else + else // VERTICAL { - LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_right, getRect().getHeight(), - LLColor4(1.f, 1.f, 1.f, 0.5f), - LLFontGL::RIGHT, LLFontGL::TOP); + bar_rect.mTop = llmax(5, getRect().getHeight() - 15); + bar_rect.mLeft = 0; + bar_rect.mRight = getRect().getWidth(); + bar_rect.mBottom = llmin(bar_rect.mTop - 5, 20); } + mCurMaxBar = LLSmoothInterpolation::lerp(mCurMaxBar, mMaxBar, 0.05f); + mCurMinBar = LLSmoothInterpolation::lerp(mCurMinBar, mMinBar, 0.05f); + + drawLabelAndValue(display_value, unit_label, bar_rect); + if (mDisplayBar && (mCountFloatp || mEventFloatp || mSampleFloatp)) { // Draw the tick marks. LLGLSUIDefault gls_ui; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - S32 last_tick = 0; - S32 last_label = 0; - const S32 MIN_TICK_SPACING = mOrientation == HORIZONTAL ? 20 : 30; - const S32 MIN_LABEL_SPACING = mOrientation == HORIZONTAL ? 30 : 60; - // start counting from actual min, not current, animating min, so that ticks don't float between numbers - // ensure ticks always hit 0 - if (mTickValue > 0.f) + + F32 value_scale; + if (mCurMaxBar == mCurMinBar) + { + value_scale = 0.f; + } + else { - F32 start = mCurMinBar < 0.f - ? llceil(-mCurMinBar / mTickValue) * -mTickValue - : 0.f; - for (F32 tick_value = start; ;tick_value += mTickValue) + value_scale = (mOrientation == HORIZONTAL) + ? (bar_rect.getHeight())/(mCurMaxBar - mCurMinBar) + : (bar_rect.getWidth())/(mCurMaxBar - mCurMinBar); + } + + drawTicks(min, max, value_scale, bar_rect); + + // draw background bar. + gl_rect_2d(bar_rect.mLeft, bar_rect.mTop, bar_rect.mRight, bar_rect.mBottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); + + // draw values + if (!llisnan(display_value) && frame_recording.getNumRecordedPeriods() != 0) + { + // draw min and max + S32 begin = (S32) ((min - mCurMinBar) * value_scale); + + if (begin < 0) { - const S32 begin = llfloor((tick_value - mCurMinBar)*value_scale); - const S32 end = begin + tick_width; - if (begin - last_tick < MIN_TICK_SPACING) - { - continue; - } - last_tick = begin; + begin = 0; + } - S32 decimal_digits = mDecimalDigits; - if (is_approx_equal((F32)(S32)tick_value, tick_value)) - { - decimal_digits = 0; - } - std::string tick_string = llformat("%10.*f", decimal_digits, tick_value); + S32 end = (S32) ((max - mCurMinBar) * value_scale); + if (mOrientation == HORIZONTAL) + { + gl_rect_2d(bar_rect.mLeft, end, bar_rect.mRight, begin, LLColor4(1.f, 0.f, 0.f, 0.25f)); + } + else // VERTICAL + { + gl_rect_2d(begin, bar_rect.mTop, end, bar_rect.mBottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); + } - if (mOrientation == HORIZONTAL) + F32 span = (mOrientation == HORIZONTAL) + ? (bar_rect.getWidth()) + : (bar_rect.getHeight()); + + if (mDisplayHistory && (mCountFloatp || mEventFloatp || mSampleFloatp)) + { + const S32 num_values = frame_recording.getNumRecordedPeriods() - 1; + F32 value = 0; + S32 i; + gGL.color4f( 1.f, 0.f, 0.f, 1.f ); + gGL.begin( LLRender::QUADS ); + const S32 max_frame = llmin(num_frames, num_values); + U32 num_samples = 0; + for (i = 1; i <= max_frame; i++) { - if (begin - last_label > MIN_LABEL_SPACING) + F32 offset = ((F32)i / (F32)num_frames) * span; + LLTrace::Recording& recording = frame_recording.getPrevRecording(i); + + if (mCountFloatp) { - gl_rect_2d(bar_left, end, bar_right - tick_length, begin, LLColor4(1.f, 1.f, 1.f, 0.25f)); - LLFontGL::getFontMonospace()->renderUTF8(tick_string, 0, bar_right, begin, - LLColor4(1.f, 1.f, 1.f, 0.5f), - LLFontGL::LEFT, LLFontGL::VCENTER); - last_label = begin; + value = recording.getPerSec(*mCountFloatp); + num_samples = recording.getSampleCount(*mCountFloatp); } - else + else if (mEventFloatp) { - gl_rect_2d(bar_left, end, bar_right - tick_length/2, begin, LLColor4(1.f, 1.f, 1.f, 0.1f)); + value = recording.getMean(*mEventFloatp); + num_samples = recording.getSampleCount(*mEventFloatp); } - } - else - { - if (begin - last_label > MIN_LABEL_SPACING) + else if (mSampleFloatp) + { + value = recording.getMean(*mSampleFloatp); + num_samples = recording.getSampleCount(*mSampleFloatp); + } + + if (!num_samples) continue; + + F32 begin = (value - mCurMinBar) * value_scale; + if (mOrientation == HORIZONTAL) { - gl_rect_2d(begin, bar_top, end, bar_bottom - tick_length, LLColor4(1.f, 1.f, 1.f, 0.25f)); - LLFontGL::getFontMonospace()->renderUTF8(tick_string, 0, begin - 1, bar_bottom - tick_length, - LLColor4(1.f, 1.f, 1.f, 0.5f), - LLFontGL::RIGHT, LLFontGL::TOP); - last_label = begin; + gGL.vertex2f((F32)bar_rect.mRight - offset, begin + 1); + gGL.vertex2f((F32)bar_rect.mRight - offset, begin); + gGL.vertex2f((F32)bar_rect.mRight - offset - 1, begin); + gGL.vertex2f((F32)bar_rect.mRight - offset - 1, begin + 1); } else { - gl_rect_2d(begin, bar_top, end, bar_bottom - tick_length/2, LLColor4(1.f, 1.f, 1.f, 0.1f)); + gGL.vertex2f(begin, (F32)bar_rect.mBottom + offset + 1); + gGL.vertex2f(begin, (F32)bar_rect.mBottom + offset); + gGL.vertex2f(begin + 1, (F32)bar_rect.mBottom + offset); + gGL.vertex2f(begin + 1, (F32)bar_rect.mBottom + offset + 1 ); } } - // always draw one tick value past end, so we can see part of the text, if possible - if (tick_value > mCurMaxBar) + gGL.end(); + } + else + { + S32 begin = (S32) ((current - mCurMinBar) * value_scale) - 1; + S32 end = (S32) ((current - mCurMinBar) * value_scale) + 1; + // draw current + if (mOrientation == HORIZONTAL) + { + gl_rect_2d(bar_rect.mLeft, end, bar_rect.mRight, begin, LLColor4(1.f, 0.f, 0.f, 1.f)); + } + else { - break; + gl_rect_2d(begin, bar_rect.mTop, end, bar_rect.mBottom, LLColor4(1.f, 0.f, 0.f, 1.f)); } } - } - - // draw background bar. - gl_rect_2d(bar_left, bar_top, bar_right, bar_bottom, LLColor4(0.f, 0.f, 0.f, 0.25f)); - - if (frame_recording.getNumRecordedPeriods() == 0) - { - // No data, don't draw anything... - return; - } - // draw min and max - S32 begin = (S32) ((min - mCurMinBar) * value_scale); - - if (begin < 0) - { - begin = 0; - } - - S32 end = (S32) ((max - mCurMinBar) * value_scale); - if (mOrientation == HORIZONTAL) - { - gl_rect_2d(bar_left, end, bar_right, begin, LLColor4(1.f, 0.f, 0.f, 0.25f)); - } - else // VERTICAL - { - gl_rect_2d(begin, bar_top, end, bar_bottom, LLColor4(1.f, 0.f, 0.f, 0.25f)); + // draw mean bar + { + const S32 begin = (S32) ((mean - mCurMinBar) * value_scale) - 1; + const S32 end = (S32) ((mean - mCurMinBar) * value_scale) + 1; + if (mOrientation == HORIZONTAL) + { + gl_rect_2d(bar_rect.mLeft - 2, begin, bar_rect.mRight + 2, end, LLColor4(0.f, 1.f, 0.f, 1.f)); + } + else + { + gl_rect_2d(begin, bar_rect.mTop + 2, end, bar_rect.mBottom - 2, LLColor4(0.f, 1.f, 0.f, 1.f)); + } + } } - - if (show_data) - { - F32 span = (mOrientation == HORIZONTAL) - ? (bar_right - bar_left) - : (bar_top - bar_bottom); - - if (mDisplayHistory && (mCountFloatp || mEventFloatp || mSampleFloatp)) - { - const S32 num_values = frame_recording.getNumRecordedPeriods() - 1; - F32 value = 0; - S32 i; - gGL.color4f( 1.f, 0.f, 0.f, 1.f ); - gGL.begin( LLRender::QUADS ); - const S32 max_frame = llmin(num_frames, num_values); - U32 num_samples = 0; - for (i = 1; i <= max_frame; i++) - { - F32 offset = ((F32)i / (F32)num_frames) * span; - LLTrace::Recording& recording = frame_recording.getPrevRecording(i); - - if (mCountFloatp) - { - value = recording.getPerSec(*mCountFloatp); - num_samples = recording.getSampleCount(*mCountFloatp); - } - else if (mEventFloatp) - { - value = recording.getMean(*mEventFloatp); - num_samples = recording.getSampleCount(*mEventFloatp); - } - else if (mSampleFloatp) - { - value = recording.getMean(*mSampleFloatp); - num_samples = recording.getSampleCount(*mSampleFloatp); - } - - if (!num_samples) continue; - - F32 begin = (value - mCurMinBar) * value_scale; - if (mOrientation == HORIZONTAL) - { - gGL.vertex2f((F32)bar_right - offset, begin + 1); - gGL.vertex2f((F32)bar_right - offset, begin); - gGL.vertex2f((F32)bar_right - offset - 1, begin); - gGL.vertex2f((F32)bar_right - offset - 1, begin + 1); - } - else - { - gGL.vertex2f(begin, (F32)bar_bottom + offset + 1); - gGL.vertex2f(begin, (F32)bar_bottom + offset); - gGL.vertex2f(begin + 1, (F32)bar_bottom + offset); - gGL.vertex2f(begin + 1, (F32)bar_bottom + offset + 1 ); - } - } - gGL.end(); - } - else - { - S32 begin = (S32) ((current - mCurMinBar) * value_scale) - 1; - S32 end = (S32) ((current - mCurMinBar) * value_scale) + 1; - // draw current - if (mOrientation == HORIZONTAL) - { - gl_rect_2d(bar_left, end, bar_right, begin, LLColor4(1.f, 0.f, 0.f, 1.f)); - } - else - { - gl_rect_2d(begin, bar_top, end, bar_bottom, LLColor4(1.f, 0.f, 0.f, 1.f)); - } - } - - // draw mean bar - { - const S32 begin = (S32) ((mean - mCurMinBar) * value_scale) - 1; - const S32 end = (S32) ((mean - mCurMinBar) * value_scale) + 1; - if (mOrientation == HORIZONTAL) - { - gl_rect_2d(bar_left - 2, begin, bar_right + 2, end, LLColor4(0.f, 1.f, 0.f, 1.f)); - } - else - { - gl_rect_2d(begin, bar_top + 2, end, bar_bottom - 2, LLColor4(0.f, 1.f, 0.f, 1.f)); - } - } - } } LLView::draw(); @@ -578,3 +537,124 @@ LLRect LLStatBar::getRequiredRect() return rect; } +void LLStatBar::drawLabelAndValue( F32 value, std::string &label, LLRect &bar_rect ) +{ + LLFontGL::getFontMonospace()->renderUTF8(mLabel, 0, 0, getRect().getHeight(), LLColor4(1.f, 1.f, 1.f, 1.f), + LLFontGL::LEFT, LLFontGL::TOP); + + S32 decimal_digits = mDecimalDigits; + if (is_approx_equal((F32)(S32)value, value)) + { + decimal_digits = 0; + } + std::string value_str = !llisnan(value) + ? llformat("%10.*f %s", decimal_digits, value, label.c_str()) + : "n/a"; + + // Draw the current value. + if (mOrientation == HORIZONTAL) + { + LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), + LLColor4(1.f, 1.f, 1.f, 0.5f), + LLFontGL::RIGHT, LLFontGL::TOP); + } + else + { + LLFontGL::getFontMonospace()->renderUTF8(value_str, 0, bar_rect.mRight, getRect().getHeight(), + LLColor4(1.f, 1.f, 1.f, 0.5f), + LLFontGL::RIGHT, LLFontGL::TOP); + } +} + +void LLStatBar::drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ) +{ + if ((mAutoScaleMax && max >= mCurMaxBar)|| (mAutoScaleMin && min <= mCurMinBar)) + { + F32 range_min = mAutoScaleMin ? llmin(mMinBar, min) : mMinBar; + F32 range_max = mAutoScaleMax ? llmax(mMaxBar, max) : mMaxBar; + 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 && mAutoScaleMax) + { + mTickValue = tick_value; + } + else + { + mTickValue = calc_tick_value(mMinBar, mMaxBar); + } + } + + // start counting from actual min, not current, animating min, so that ticks don't float between numbers + // ensure ticks always hit 0 + S32 last_tick = 0; + S32 last_label = 0; + if (mTickValue > 0.f && value_scale > 0.f) + { + const S32 MIN_TICK_SPACING = mOrientation == HORIZONTAL ? 20 : 30; + const S32 MIN_LABEL_SPACING = mOrientation == HORIZONTAL ? 30 : 60; + const S32 TICK_LENGTH = 4; + const S32 TICK_WIDTH = 1; + + F32 start = mCurMinBar < 0.f + ? llceil(-mCurMinBar / mTickValue) * -mTickValue + : 0.f; + for (F32 tick_value = start; ;tick_value += mTickValue) + { + const S32 begin = llfloor((tick_value - mCurMinBar)*value_scale); + const S32 end = begin + TICK_WIDTH; + if (begin - last_tick < MIN_TICK_SPACING) + { + continue; + } + last_tick = begin; + + S32 decimal_digits = mDecimalDigits; + if (is_approx_equal((F32)(S32)tick_value, tick_value)) + { + decimal_digits = 0; + } + std::string tick_string = llformat("%10.*f", decimal_digits, tick_value); + + if (mOrientation == HORIZONTAL) + { + if (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_string, 0, bar_rect.mRight, begin, + LLColor4(1.f, 1.f, 1.f, 0.5f), + LLFontGL::LEFT, LLFontGL::VCENTER); + last_label = 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)); + } + } + else + { + if (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)); + LLFontGL::getFontMonospace()->renderUTF8(tick_string, 0, begin - 1, bar_rect.mBottom - TICK_LENGTH, + LLColor4(1.f, 1.f, 1.f, 0.5f), + LLFontGL::RIGHT, LLFontGL::TOP); + last_label = begin; + } + else + { + gl_rect_2d(begin, bar_rect.mTop, 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 + if (tick_value > mCurMaxBar) + { + break; + } + } + } +} + + + diff --git a/indra/llui/llstatbar.h b/indra/llui/llstatbar.h index 5aed98fecf..dd4d9400a5 100755 --- a/indra/llui/llstatbar.h +++ b/indra/llui/llstatbar.h @@ -89,6 +89,9 @@ public: /*virtual*/ LLRect getRequiredRect(); // Return the height of this object, given the set options. private: + void drawLabelAndValue( F32 mean, std::string &unit_label, LLRect &bar_rect ); + void drawTicks( F32 min, F32 max, F32 value_scale, LLRect &bar_rect ); + F32 mMinBar, mMaxBar, mCurMaxBar, @@ -104,10 +107,12 @@ private: mAutoScaleMax, mAutoScaleMin; EOrientation mOrientation; + F32 mLastDisplayValue; + LLFrameTimer mLastDisplayValueTimer; - LLTrace::TraceType<LLTrace::CountAccumulator>* mCountFloatp; - LLTrace::TraceType<LLTrace::EventAccumulator>* mEventFloatp; - LLTrace::TraceType<LLTrace::SampleAccumulator>* mSampleFloatp; + const LLTrace::TraceType<LLTrace::CountAccumulator>* mCountFloatp; + const LLTrace::TraceType<LLTrace::EventAccumulator>* mEventFloatp; + const LLTrace::TraceType<LLTrace::SampleAccumulator>* mSampleFloatp; LLUIString mLabel; std::string mUnitLabel; diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp index 4cbf84be73..6a1f937340 100755 --- a/indra/llui/llxuiparser.cpp +++ b/indra/llui/llxuiparser.cpp @@ -1313,7 +1313,7 @@ void LLXUIParser::parserWarning(const std::string& message) { #ifdef LL_WINDOWS // use Visual Studio friendly formatting of output message for easy access to originating xml - LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str())); + LL_INFOS() << llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()) << LL_ENDL; #else Parser::parserWarning(message); #endif @@ -1322,8 +1322,8 @@ void LLXUIParser::parserWarning(const std::string& message) void LLXUIParser::parserError(const std::string& message) { #ifdef LL_WINDOWS - // use Visual Studio friendly formatting of output message for easy access to originating xml - LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str())); + // use Visual Studio friendly formatting of output message for easy access to originating xml + LL_INFOS() << llformat("%s(%d):\t%s", mCurFileName.c_str(), mCurReadNode->getLineNumber(), message.c_str()) << LL_ENDL; #else Parser::parserError(message); #endif @@ -1641,7 +1641,7 @@ void LLSimpleXUIParser::parserWarning(const std::string& message) { #ifdef LL_WINDOWS // use Visual Studio friendly formatting of output message for easy access to originating xml - LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str())); + LL_INFOS() << llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()) << LL_ENDL; #else Parser::parserWarning(message); #endif @@ -1651,7 +1651,7 @@ void LLSimpleXUIParser::parserError(const std::string& message) { #ifdef LL_WINDOWS // use Visual Studio friendly formatting of output message for easy access to originating xml - LL_WINDOWS_OUTPUT_DEBUG(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str())); + LL_INFOS() << llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()) << LL_ENDL; #else Parser::parserError(message); #endif |