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