00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llframestatview.h"
00035
00036 #include "llframestats.h"
00037 #include "llrect.h"
00038 #include "llerror.h"
00039 #include "llgl.h"
00040 #include "llmath.h"
00041 #include "llfontgl.h"
00042
00043 #include "viewer.h"
00044 #include "llui.h"
00045 #include "llviewercontrol.h"
00046 #include "llstat.h"
00047
00048
00049 LLFrameStatView::LLFrameStatView(const std::string& name, const LLRect& rect)
00050 : LLView(name, rect, TRUE)
00051 {
00052 setVisible(FALSE);
00053
00054 mNumStats = 0;
00055 mTotalTime = 0.05f;
00056 mTickSpacing = 0.01f;
00057 mLabelSpacing = 0.05f;
00058 mShowPercent = TRUE;
00059 mCenterOn = 0;
00060 }
00061
00062 LLFrameStatView::~LLFrameStatView()
00063 {
00064
00065 }
00066
00067 EWidgetType LLFrameStatView::getWidgetType() const
00068 {
00069 return WIDGET_TYPE_FRAME_STAT_VIEW;
00070 }
00071
00072 LLString LLFrameStatView::getWidgetTag() const
00073 {
00074 return LL_FRAME_STAT_VIEW_TAG;
00075 }
00076
00077 void LLFrameStatView::setup(const LLFrameStats &frame_stats)
00078 {
00079 S32 i;
00080 for (i = 0; i < LLFrameStats::NUM_STATS; i++)
00081 {
00082 addStat(&gFrameStats.getStat(i),
00083 gFrameStats.getStatLabel(i),
00084 gFrameStats.getStatColor(i));
00085 }
00086 }
00087
00088 BOOL LLFrameStatView::handleMouseDown(S32 x, S32 y, MASK mask)
00089 {
00090 mShowPercent = !mShowPercent;
00091 return TRUE;
00092 }
00093
00094 BOOL LLFrameStatView::handleMouseUp(S32 x, S32 y, MASK mask)
00095 {
00096 return TRUE;
00097 }
00098
00099
00100 BOOL LLFrameStatView::handleHover(S32 x, S32 y, MASK mask)
00101 {
00102 return FALSE;
00103 }
00104
00105
00106 void LLFrameStatView::draw()
00107 {
00108 S32 i;
00109 S32 j;
00110 LLStat *statp;
00111
00112 LLGLSNoTexture gls_no_texture;
00113
00114 statp = mStats[0];
00115 if (!statp)
00116 {
00117 return;
00118 }
00119 S32 num_bins = llmin(statp->getNumValues(), (U32)32);
00120
00121 F32 total_width = mRect.getWidth() - 20.f;
00122 F32 total_height = mRect.getHeight() - 30.f;
00123 S32 left, top, right, bottom;
00124 F32 key_height = 16;
00125 S32 bar_spacing = 2;
00126 F32 time_scale = total_width / mTotalTime;
00127
00128
00129 gl_rect_2d(0, mRect.getHeight(), mRect.getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
00130
00131
00132 left = 10;
00133 top = mRect.getHeight() - 10;
00134
00135 BOOL is_active[MAX_STATS];
00136 S32 bin = mStats[0]->getCurBin() - 1;
00137 if (bin < 0)
00138 {
00139 bin += mStats[0]->getNumBins();
00140 }
00141
00142 F64 min_last_time = mStats[0]->getBinTime(bin);
00143
00144 for (i = 0; i < mNumStats; i++)
00145 {
00146 if (mStats[i]->getLastTime() >= min_last_time)
00147 {
00148 is_active[i] = TRUE;
00149 }
00150 else
00151 {
00152 is_active[i] = FALSE;
00153 }
00154 }
00155
00156 S32 cur_center = mCenterOn;
00157 if (!is_active[mCenterOn])
00158 {
00159 for (i = 0; i < mNumStats; i++)
00160 {
00161 if (is_active[i])
00162 {
00163 cur_center = i;
00164 break;
00165 }
00166 }
00167 }
00168
00169
00170 for (i = 0; i < mNumStats; i++)
00171 {
00172
00173 LLGLSNoTexture gls_no_texture;
00174 gl_rect_2d(left, top - 2, left + 10, top - 12, mColors[i]);
00175
00176 left = left + 15;
00177
00178 LLFontGL::sMonospace->renderUTF8(mLabels[i], 0, left, top,
00179 LLColor4(1.f, 1.f, 1.f, 1.f),
00180 LLFontGL::LEFT, LLFontGL::TOP);
00181
00182 left = left + LLFontGL::sMonospace->getWidth(mLabels[i]) + 10;
00183 if ((i + 1) < mNumStats)
00184 {
00185 if ((left + LLFontGL::sMonospace->getWidth(mLabels[i+1])) > (mRect.getWidth() - 10))
00186 {
00187 left = 10;
00188 top -= llfloor(LLFontGL::sMonospace->getLineHeight());
00189 key_height += LLFontGL::sMonospace->getLineHeight();
00190 }
00191 }
00192 }
00193
00194 top -= llfloor(LLFontGL::sMonospace->getLineHeight());
00195 bottom = top - llfloor(LLFontGL::sMonospace->getLineHeight());
00196 F32 total_time = 0.f;
00197 F32 bin_means[32];
00198
00199 key_height += 20;
00200
00201
00202
00203
00204 F32 tick_value;
00205 char tick_label[256];
00206 for (tick_value = 0; tick_value <= 100; tick_value += 10)
00207 {
00208 left = 10 + llfloor(tick_value*(total_width/100.f));
00209 right = left + 1;
00210 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.2f));
00211 }
00212
00213
00214 bottom = bottom - 4;
00215 for (tick_value = 0; tick_value <= 100; tick_value += 20)
00216 {
00217 LLGLSNoTexture gls_no_texture;
00218 left = 10 + llfloor(tick_value*(total_width/100.f));
00219 right = left + 1;
00220 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.2f));
00221
00222 snprintf(tick_label, sizeof(tick_label), "%.2f", tick_value);
00223
00224 LLFontGL::sMonospace->renderUTF8(tick_label, 0, left, bottom,
00225 LLColor4(1.f, 1.f, 1.f, 0.5f),
00226 LLFontGL::LEFT, LLFontGL::TOP);
00227 }
00228
00229 for (i = 0; i < mNumStats; i++)
00230 {
00231 bin_means[i] = mStats[i]->getMeanDuration();
00232 total_time += bin_means[i];
00233 }
00234
00235 F32 time_frac = total_width / total_time;
00236 F32 cur_left = .0f;
00237 for (i = 0; i < mNumStats; i++)
00238 {
00239 F32 cur_right = cur_left + bin_means[i] * time_frac;
00240 left = llfloor(cur_left) + 10;
00241 right = llfloor(cur_right) + 10;
00242 gl_rect_2d(left, top, right, bottom, mColors[i]);
00243 cur_left = cur_right;
00244 }
00245
00246 S32 bar_height = llmax(1, (S32)((total_height - bar_spacing*(num_bins-1) - key_height) / num_bins));
00247 S32 graph_height = bar_height * num_bins + bar_spacing * num_bins - 1;
00248
00249
00250 top = mRect.getHeight() - llfloor(key_height) - 20;
00251
00252 bottom = top - graph_height - 2;
00253
00254 if (mShowPercent)
00255 {
00256 for (tick_value = 0; tick_value <= 100; tick_value += 10)
00257 {
00258 left = 10 + llfloor(tick_value*(total_width/100.f));
00259 right = left + 1;
00260 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f));
00261 }
00262
00263
00264 bottom = top - graph_height - 4;
00265 for (tick_value = 0; tick_value <= 100; tick_value += 20)
00266 {
00267 LLGLSNoTexture gls_no_texture;
00268 left = 10 + llfloor(tick_value*(total_width/100.f));
00269 right = left + 1;
00270 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
00271
00272 snprintf(tick_label, sizeof(tick_label), "%.2f", tick_value);
00273
00274 LLFontGL::sMonospace->renderUTF8(tick_label, 0, left, bottom,
00275 LLColor4(1.f, 1.f, 1.f, 0.5f),
00276 LLFontGL::LEFT, LLFontGL::TOP);
00277 }
00278 }
00279 else
00280 {
00281 for (tick_value = 0; tick_value <= mTotalTime; tick_value += mTickSpacing)
00282 {
00283 left = 10 + llfloor(tick_value*time_scale);
00284 right = left + 1;
00285 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.1f));
00286 }
00287
00288
00289 bottom = top - graph_height - 4;
00290 for (tick_value = 0; tick_value <= mTotalTime; tick_value += mLabelSpacing)
00291 {
00292 LLGLSNoTexture gls_no_texture;
00293 left = 10 + llfloor(tick_value*time_scale);
00294 right = left + 1;
00295 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
00296
00297 snprintf(tick_label, sizeof(tick_label), "%.2f", tick_value);
00298
00299 LLFontGL::sMonospace->renderUTF8(tick_label, 0, left, bottom,
00300 LLColor4(1.f, 1.f, 1.f, 0.5f),
00301 LLFontGL::LEFT, LLFontGL::TOP);
00302 }
00303 }
00304
00305
00306 bottom = top - graph_height;
00307 left = 10;
00308 right = left + llfloor(total_width);
00309
00310 gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 1.f, 1.f, 0.25f));
00311
00312 F64 min_time = 0.f;
00313 F64 max_time = 0.f;
00314
00315
00316
00317 top = mRect.getHeight() - llfloor(key_height) - 20;
00318 bottom = top - bar_height;
00319 for (i = 0; i < 32; i++)
00320 {
00321
00322 min_time = mStats[0]->getPrevBeginTime(i);
00323 max_time = mStats[0]->getPrevBeginTime(i);
00324 for (j = 0; j < mNumStats; j++)
00325 {
00326 if (is_active[j])
00327 {
00328 min_time = llmin(min_time, mStats[j]->getPrevBeginTime(i));
00329 max_time = llmax(max_time, mStats[j]->getPrevTime(i));
00330 }
00331 }
00332
00333 if (mShowPercent)
00334 {
00335 for (j = 0; j < mNumStats; j++)
00336 {
00337 if (is_active[j])
00338 {
00339 statp = mStats[j];
00340 F64 begin = statp->getPrevBeginTime(i) - min_time;
00341 F64 end = statp->getPrevTime(i) - min_time;
00342
00343 F32 begin_frac = (F32)(begin/(max_time - min_time));
00344 F32 end_frac = (F32)(end/(max_time - min_time));
00345
00346 left = llfloor(begin_frac * total_width) + 10;
00347 right = llfloor(end_frac * total_width) + 10;
00348 gl_rect_2d(left, top, right, bottom, mColors[j]);
00349 }
00350 }
00351 }
00352 else
00353 {
00354 F64 center_time = mStats[cur_center]->getPrevBeginTime(i);
00355 center_time = min_time;
00356
00357
00358 for (j = 0; j < mNumStats; j++)
00359 {
00360 if (is_active[j])
00361 {
00362 statp = mStats[j];
00363 F64 begin = statp->getPrevBeginTime(i);
00364 F64 end = statp->getPrevTime(i);
00365
00366 F32 begin_frac = (F32)(begin - center_time);
00367 F32 end_frac = (F32)(end - center_time);
00368
00369 left = llfloor(begin_frac * time_scale) + 10;
00370 right = llfloor(end_frac * time_scale) + 10;
00371
00372 gl_rect_2d(left, top, right, bottom, mColors[j]);
00373 }
00374 }
00375 }
00376 top = top - bar_height - bar_spacing;
00377 bottom = top - bar_height;
00378 }
00379 LLView::draw();
00380 }
00381
00382 void LLFrameStatView::addStat(LLStat *statp, const char *label, const LLColor4 &color)
00383 {
00384 if( mNumStats >= MAX_STATS )
00385 {
00386 llwarns << "LLFrameStatView::addStat - too many stats!" << llendl;
00387 return;
00388 }
00389
00390 mStats[mNumStats] = statp;
00391 mColors[mNumStats] = color;
00392 mLabels[mNumStats] = label;
00393 mNumStats++;
00394 }