385 lines
9.8 KiB
C++
385 lines
9.8 KiB
C++
/**
|
|
* @file llframestatview.cpp
|
|
* @brief LLFrameStatView class implementation
|
|
*
|
|
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
|
*
|
|
* Copyright (c) 2001-2009, Linden Research, Inc.
|
|
*
|
|
* Second Life Viewer Source Code
|
|
* The source code in this file ("Source Code") is provided by Linden Lab
|
|
* to you under the terms of the GNU General Public License, version 2.0
|
|
* ("GPL"), unless you have obtained a separate licensing agreement
|
|
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
|
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
|
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
|
*
|
|
* There are special exceptions to the terms and conditions of the GPL as
|
|
* it is applied to this Source Code. View the full text of the exception
|
|
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
|
* online at
|
|
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
|
*
|
|
* By copying, modifying or distributing this software, you acknowledge
|
|
* that you have read and understood your obligations described above,
|
|
* and agree to abide by those obligations.
|
|
*
|
|
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
|
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
|
* COMPLETENESS OR PERFORMANCE.
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#include "llframestatview.h"
|
|
|
|
#include "llframestats.h"
|
|
#include "llrect.h"
|
|
#include "llerror.h"
|
|
#include "llgl.h"
|
|
#include "llmath.h"
|
|
#include "llfontgl.h"
|
|
|
|
#include "llui.h"
|
|
#include "llviewercontrol.h"
|
|
#include "llstat.h"
|
|
|
|
|
|
LLFrameStatView::LLFrameStatView(const std::string& name, const LLRect& rect)
|
|
: LLView(name, rect, TRUE)
|
|
{
|
|
setVisible(FALSE);
|
|
|
|
mNumStats = 0;
|
|
mTotalTime = 0.05f;
|
|
mTickSpacing = 0.01f;
|
|
mLabelSpacing = 0.05f;
|
|
mShowPercent = TRUE;
|
|
mCenterOn = 0;
|
|
}
|
|
|
|
LLFrameStatView::~LLFrameStatView()
|
|
{
|
|
// Children all cleaned up by default view destructor.
|
|
}
|
|
|
|
void LLFrameStatView::setup(const LLFrameStats &frame_stats)
|
|
{
|
|
S32 i;
|
|
for (i = 0; i < LLFrameStats::NUM_STATS; i++)
|
|
{
|
|
addStat(&gFrameStats.getStat(i),
|
|
gFrameStats.getStatLabel(i),
|
|
gFrameStats.getStatColor(i));
|
|
}
|
|
}
|
|
|
|
BOOL LLFrameStatView::handleMouseDown(S32 x, S32 y, MASK mask)
|
|
{
|
|
mShowPercent = !mShowPercent;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL LLFrameStatView::handleMouseUp(S32 x, S32 y, MASK mask)
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL LLFrameStatView::handleHover(S32 x, S32 y, MASK mask)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void LLFrameStatView::draw()
|
|
{
|
|
S32 i;
|
|
S32 j;
|
|
LLStat *statp;
|
|
|
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
|
|
|
statp = mStats[0];
|
|
if (!statp)
|
|
{
|
|
return;
|
|
}
|
|
S32 num_bins = llmin(statp->getNumValues(), (U32)32);
|
|
|
|
F32 total_width = getRect().getWidth() - 20.f;
|
|
F32 total_height = getRect().getHeight() - 30.f;
|
|
S32 left, top, right, bottom;
|
|
F32 key_height = 16;
|
|
S32 bar_spacing = 2;
|
|
F32 time_scale = total_width / mTotalTime;
|
|
|
|
// Draw the window background
|
|
gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
|
|
|
|
// Render the key
|
|
left = 10;
|
|
top = getRect().getHeight() - 10;
|
|
|
|
BOOL is_active[MAX_STATS];
|
|
S32 bin = mStats[0]->getCurBin() - 1;
|
|
if (bin < 0)
|
|
{
|
|
bin += mStats[0]->getNumBins();
|
|
}
|
|
|
|
F64 min_last_time = mStats[0]->getBinTime(bin);
|
|
|
|
for (i = 0; i < mNumStats; i++)
|
|
{
|
|
if (mStats[i]->getLastTime() >= min_last_time)
|
|
{
|
|
is_active[i] = TRUE;
|
|
}
|
|
else
|
|
{
|
|
is_active[i] = FALSE;
|
|
}
|
|
}
|
|
|
|
S32 cur_center = mCenterOn;
|
|
if (!is_active[mCenterOn])
|
|
{
|
|
for (i = 0; i < mNumStats; i++)
|
|
{
|
|
if (is_active[i])
|
|
{
|
|
cur_center = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for (i = 0; i < mNumStats; i++)
|
|
{
|
|
// Draw the color key.
|
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
|
gl_rect_2d(left, top - 2, left + 10, top - 12, mColors[i]);
|
|
|
|
left = left + 15;
|
|
// Draw the label.
|
|
LLFontGL::getFontMonospace()->renderUTF8(mLabels[i], 0, left, top,
|
|
LLColor4(1.f, 1.f, 1.f, 1.f),
|
|
LLFontGL::LEFT, LLFontGL::TOP);
|
|
|
|
left = left + LLFontGL::getFontMonospace()->getWidth(mLabels[i]) + 10;
|
|
if ((i + 1) < mNumStats)
|
|
{
|
|
if ((left + LLFontGL::getFontMonospace()->getWidth(mLabels[i+1])) > (getRect().getWidth() - 10))
|
|
{
|
|
left = 10;
|
|
top -= llfloor(LLFontGL::getFontMonospace()->getLineHeight());
|
|
key_height += LLFontGL::getFontMonospace()->getLineHeight();
|
|
}
|
|
}
|
|
}
|
|
|
|
top -= llfloor(LLFontGL::getFontMonospace()->getLineHeight());
|
|
bottom = top - llfloor(LLFontGL::getFontMonospace()->getLineHeight());
|
|
F32 total_time = 0.f;
|
|
F32 bin_means[32];
|
|
|
|
key_height += 20;
|
|
|
|
// Draw the "Average" bar
|
|
|
|
// Draw ticks for the "Average bar"
|
|
F32 tick_value;
|
|
std::string tick_label;
|
|
for (tick_value = 0; tick_value <= 100; tick_value += 10)
|
|
{
|
|
left = 10 + llfloor(tick_value*(total_width/100.f));
|
|
right = left + 1;
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.2f));
|
|
}
|
|
|
|
// Draw the tick labels (and big ticks).
|
|
bottom = bottom - 4;
|
|
for (tick_value = 0; tick_value <= 100; tick_value += 20)
|
|
{
|
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
|
left = 10 + llfloor(tick_value*(total_width/100.f));
|
|
right = left + 1;
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.2f));
|
|
|
|
tick_label = llformat("%.2f", tick_value);
|
|
// draw labels for the tick marks
|
|
LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left, bottom,
|
|
LLColor4(1.f, 1.f, 1.f, 0.5f),
|
|
LLFontGL::LEFT, LLFontGL::TOP);
|
|
}
|
|
|
|
for (i = 0; i < mNumStats; i++)
|
|
{
|
|
bin_means[i] = mStats[i]->getMeanDuration();
|
|
total_time += bin_means[i];
|
|
}
|
|
|
|
F32 time_frac = total_width / total_time;
|
|
F32 cur_left = .0f;
|
|
for (i = 0; i < mNumStats; i++)
|
|
{
|
|
F32 cur_right = cur_left + bin_means[i] * time_frac;
|
|
left = llfloor(cur_left) + 10;
|
|
right = llfloor(cur_right) + 10;
|
|
gl_rect_2d(left, top, right, bottom, mColors[i]);
|
|
cur_left = cur_right;
|
|
}
|
|
|
|
S32 bar_height = llmax(1, (S32)((total_height - bar_spacing*(num_bins-1) - key_height) / num_bins));
|
|
S32 graph_height = bar_height * num_bins + bar_spacing * num_bins - 1;
|
|
|
|
// Draw the tick marks.
|
|
top = getRect().getHeight() - llfloor(key_height) - 20;
|
|
|
|
bottom = top - graph_height - 2;
|
|
// Render the ticks and labels
|
|
if (mShowPercent)
|
|
{
|
|
for (tick_value = 0; tick_value <= 100; tick_value += 10)
|
|
{
|
|
left = 10 + llfloor(tick_value*(total_width/100.f));
|
|
right = left + 1;
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f));
|
|
}
|
|
|
|
// Draw the tick labels (and big ticks).
|
|
bottom = top - graph_height - 4;
|
|
for (tick_value = 0; tick_value <= 100; tick_value += 20)
|
|
{
|
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
|
left = 10 + llfloor(tick_value*(total_width/100.f));
|
|
right = left + 1;
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
|
|
|
|
tick_label = llformat("%.2f", tick_value);
|
|
// draw labels for the tick marks
|
|
LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left, bottom,
|
|
LLColor4(1.f, 1.f, 1.f, 0.5f),
|
|
LLFontGL::LEFT, LLFontGL::TOP);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (tick_value = 0; tick_value <= mTotalTime; tick_value += mTickSpacing)
|
|
{
|
|
left = 10 + llfloor(tick_value*time_scale);
|
|
right = left + 1;
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f));
|
|
}
|
|
|
|
// Draw the tick labels (and big ticks).
|
|
bottom = top - graph_height - 4;
|
|
for (tick_value = 0; tick_value <= mTotalTime; tick_value += mLabelSpacing)
|
|
{
|
|
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
|
left = 10 + llfloor(tick_value*time_scale);
|
|
right = left + 1;
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
|
|
|
|
tick_label = llformat("%.2f", tick_value);
|
|
// draw labels for the tick marks
|
|
LLFontGL::getFontMonospace()->renderUTF8(tick_label, 0, left, bottom,
|
|
LLColor4(1.f, 1.f, 1.f, 0.5f),
|
|
LLFontGL::LEFT, LLFontGL::TOP);
|
|
}
|
|
}
|
|
|
|
// Draw the graph background
|
|
bottom = top - graph_height;
|
|
left = 10;
|
|
right = left + llfloor(total_width);
|
|
|
|
gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
|
|
|
|
F64 min_time = 0.f;
|
|
F64 max_time = 0.f;
|
|
|
|
// Determine which stats are active.
|
|
|
|
top = getRect().getHeight() - llfloor(key_height) - 20;
|
|
bottom = top - bar_height;
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
// Find the min time for this set of bins.
|
|
min_time = mStats[0]->getPrevBeginTime(i);
|
|
max_time = mStats[0]->getPrevBeginTime(i);
|
|
for (j = 0; j < mNumStats; j++)
|
|
{
|
|
if (is_active[j])
|
|
{
|
|
min_time = llmin(min_time, mStats[j]->getPrevBeginTime(i));
|
|
max_time = llmax(max_time, mStats[j]->getPrevTime(i));
|
|
}
|
|
}
|
|
|
|
if (mShowPercent)
|
|
{
|
|
for (j = 0; j < mNumStats; j++)
|
|
{
|
|
if (is_active[j])
|
|
{
|
|
statp = mStats[j];
|
|
F64 begin = statp->getPrevBeginTime(i) - min_time;
|
|
F64 end = statp->getPrevTime(i) - min_time;
|
|
|
|
F32 begin_frac = (F32)(begin/(max_time - min_time));
|
|
F32 end_frac = (F32)(end/(max_time - min_time));
|
|
|
|
left = llfloor(begin_frac * total_width) + 10;
|
|
right = llfloor(end_frac * total_width) + 10;
|
|
gl_rect_2d(left, top, right, bottom, mColors[j]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
F64 center_time = mStats[cur_center]->getPrevBeginTime(i);
|
|
center_time = min_time;
|
|
|
|
// Now, draw the bars for each stat
|
|
for (j = 0; j < mNumStats; j++)
|
|
{
|
|
if (is_active[j])
|
|
{
|
|
statp = mStats[j];
|
|
F64 begin = statp->getPrevBeginTime(i);
|
|
F64 end = statp->getPrevTime(i);
|
|
|
|
F32 begin_frac = (F32)(begin - center_time);
|
|
F32 end_frac = (F32)(end - center_time);
|
|
|
|
left = llfloor(begin_frac * time_scale) + 10;
|
|
right = llfloor(end_frac * time_scale) + 10;
|
|
|
|
gl_rect_2d(left, top, right, bottom, mColors[j]);
|
|
}
|
|
}
|
|
}
|
|
top = top - bar_height - bar_spacing;
|
|
bottom = top - bar_height;
|
|
}
|
|
LLView::draw();
|
|
}
|
|
|
|
void LLFrameStatView::addStat(LLStat *statp, const std::string& label, const LLColor4 &color)
|
|
{
|
|
if( mNumStats >= MAX_STATS )
|
|
{
|
|
llwarns << "LLFrameStatView::addStat - too many stats!" << llendl;
|
|
return;
|
|
}
|
|
|
|
mStats[mNumStats] = statp;
|
|
mColors[mNumStats] = color;
|
|
mLabels[mNumStats] = label;
|
|
mNumStats++;
|
|
}
|