00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "indra_constants.h"
00035 #include "llfasttimerview.h"
00036 #include "llviewerwindow.h"
00037 #include "llrect.h"
00038 #include "llerror.h"
00039 #include "llgl.h"
00040 #include "llglimmediate.h"
00041 #include "llmath.h"
00042 #include "llfontgl.h"
00043
00044 #include "llappviewer.h"
00045 #include "llviewerimagelist.h"
00046 #include "llui.h"
00047 #include "llviewercontrol.h"
00048 #include "llstat.h"
00049
00050 #include "llfasttimer.h"
00051
00053
00054 static const S32 MAX_VISIBLE_HISTORY = 10;
00055 static const S32 LINE_GRAPH_HEIGHT = 240;
00056
00057 struct ft_display_info {
00058 int timer;
00059 const char *desc;
00060 const LLColor4 *color;
00061 S32 disabled;
00062 int level;
00063 int parent;
00064 };
00065
00066 static const LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f);
00067 static const LLColor4 green0(0.0f, 0.5f, 0.0f, 1.0f);
00068 static const LLColor4 blue0(0.0f, 0.0f, 0.5f, 1.0f);
00069 static const LLColor4 blue7(0.0f, 0.0f, 0.5f, 1.0f);
00070
00071 static const LLColor4 green7(0.6f, 1.0f, 0.4f, 1.0f);
00072 static const LLColor4 green8(0.4f, 1.0f, 0.6f, 1.0f);
00073 static const LLColor4 green9(0.6f, 1.0f, 0.6f, 1.0f);
00074
00075
00076
00077 static struct ft_display_info ft_display_table[] =
00078 {
00079 { LLFastTimer::FTM_FRAME, "Frame", &LLColor4::white, 0 },
00080 { LLFastTimer::FTM_MESSAGES, " System Messages", &LLColor4::grey1, 1 },
00081 { LLFastTimer::FTM_MOUSEHANDLER, " Mouse", &LLColor4::grey1, 0 },
00082 { LLFastTimer::FTM_KEYHANDLER, " Keyboard", &LLColor4::grey1, 0 },
00083 { LLFastTimer::FTM_SLEEP, " Sleep", &LLColor4::grey2, 0 },
00084 { LLFastTimer::FTM_IDLE, " Idle", &blue0, 0 },
00085 { LLFastTimer::FTM_PUMP, " Pump", &LLColor4::magenta2, 1 },
00086 { LLFastTimer::FTM_CURL, " Curl", &LLColor4::magenta3, 0 },
00087 { LLFastTimer::FTM_INVENTORY, " Inventory Update", &LLColor4::purple6, 1 },
00088 { LLFastTimer::FTM_AUTO_SELECT, " Open and Select", &LLColor4::red, 0 },
00089 { LLFastTimer::FTM_FILTER, " Filter", &LLColor4::red2, 0 },
00090 { LLFastTimer::FTM_ARRANGE, " Arrange", &LLColor4::red3, 0 },
00091 { LLFastTimer::FTM_REFRESH, " Refresh", &LLColor4::red4, 0 },
00092 { LLFastTimer::FTM_SORT, " Sort", &LLColor4::red5, 0 },
00093 { LLFastTimer::FTM_RESET_DRAWORDER, " ResetDrawOrder", &LLColor4::pink1, 0 },
00094 { LLFastTimer::FTM_WORLD_UPDATE, " World Update", &LLColor4::blue1, 1 },
00095 { LLFastTimer::FTM_UPDATE_MOVE, " Move Objects", &LLColor4::pink2, 0 },
00096 { LLFastTimer::FTM_OCTREE_BALANCE, " Octree Balance", &LLColor4::red3, 0 },
00097 { LLFastTimer::FTM_SIMULATE_PARTICLES, " Particle Sim", &LLColor4::blue4, 0 },
00098 { LLFastTimer::FTM_OBJECTLIST_UPDATE, " Object Update", &LLColor4::purple1, 1 },
00099 { LLFastTimer::FTM_AVATAR_UPDATE, " Avatars", &LLColor4::purple2, 0 },
00100 { LLFastTimer::FTM_JOINT_UPDATE, " Joints", &LLColor4::purple3, 0 },
00101 { LLFastTimer::FTM_ATTACHMENT_UPDATE, " Attachments", &LLColor4::purple4, 0 },
00102 { LLFastTimer::FTM_UPDATE_ANIMATION, " Animation", &LLColor4::purple5, 0 },
00103 { LLFastTimer::FTM_FLEXIBLE_UPDATE, " Flex Update", &LLColor4::pink2, 0 },
00104 { LLFastTimer::FTM_LOD_UPDATE, " LOD Update", &LLColor4::magenta1, 0 },
00105 { LLFastTimer::FTM_REGION_UPDATE, " Region Update", &LLColor4::cyan2, 0 },
00106 { LLFastTimer::FTM_NETWORK, " Network", &LLColor4::orange1, 1 },
00107 { LLFastTimer::FTM_IDLE_NETWORK, " Decode Msgs", &LLColor4::orange2, 0 },
00108 { LLFastTimer::FTM_PROCESS_MESSAGES, " Process Msgs", &LLColor4::orange3, 0 },
00109 { LLFastTimer::FTM_PROCESS_OBJECTS, " Object Updates",&LLColor4::orange4, 0 },
00110 { LLFastTimer::FTM_CREATE_OBJECT, " Create Obj", &LLColor4::orange5, 0 },
00111
00112 { LLFastTimer::FTM_PROCESS_IMAGES, " Image Updates",&LLColor4::orange6, 0 },
00113 { LLFastTimer::FTM_PIPELINE, " Pipeline", &LLColor4::magenta4, 0 },
00114 { LLFastTimer::FTM_CLEANUP, " Cleanup", &LLColor4::cyan3, 0 },
00115 { LLFastTimer::FTM_AUDIO_UPDATE, " Audio Update", &LLColor4::yellow3, 0 },
00116 { LLFastTimer::FTM_VFILE_WAIT, " VFile Wait", &LLColor4::cyan6, 0 },
00117
00118 { LLFastTimer::FTM_RENDER, " Render", &green0, 1 },
00119 { LLFastTimer::FTM_HUD_EFFECTS, " HUD Effects", &LLColor4::orange1, 0 },
00120 { LLFastTimer::FTM_HUD_UPDATE, " HUD Update", &LLColor4::orange2, 0 },
00121 { LLFastTimer::FTM_UPDATE_SKY, " Sky Update", &LLColor4::cyan1, 0 },
00122 { LLFastTimer::FTM_UPDATE_TEXTURES, " Textures", &LLColor4::pink2, 0 },
00123 { LLFastTimer::FTM_GEO_UPDATE, " Geo Update", &LLColor4::blue3, 1 },
00124 { LLFastTimer::FTM_UPDATE_PRIMITIVES, " Volumes", &LLColor4::blue4, 0 },
00125 { LLFastTimer::FTM_GEN_VOLUME, " Gen Volume", &LLColor4::yellow3, 0 },
00126 { LLFastTimer::FTM_GEN_FLEX, " Flexible", &LLColor4::yellow4, 0 },
00127 { LLFastTimer::FTM_GEN_TRIANGLES, " Triangles", &LLColor4::yellow5, 0 },
00128 { LLFastTimer::FTM_UPDATE_AVATAR, " Avatar", &LLColor4::yellow1, 0 },
00129 { LLFastTimer::FTM_UPDATE_TREE, " Tree", &LLColor4::yellow2, 0 },
00130 { LLFastTimer::FTM_UPDATE_TERRAIN, " Terrain", &LLColor4::yellow6, 0 },
00131 { LLFastTimer::FTM_UPDATE_CLOUDS, " Clouds", &LLColor4::yellow7, 0 },
00132 { LLFastTimer::FTM_UPDATE_GRASS, " Grass", &LLColor4::yellow8, 0 },
00133 { LLFastTimer::FTM_UPDATE_WATER, " Water", &LLColor4::yellow9, 0 },
00134 { LLFastTimer::FTM_GEO_LIGHT, " Lighting", &LLColor4::yellow1, 0 },
00135 { LLFastTimer::FTM_GEO_SHADOW, " Shadow", &LLColor4::black, 0 },
00136 { LLFastTimer::FTM_UPDATE_PARTICLES, " Particles", &LLColor4::blue5, 0 },
00137 { LLFastTimer::FTM_GEO_RESERVE, " Reserve", &LLColor4::blue6, 0 },
00138 { LLFastTimer::FTM_UPDATE_LIGHTS, " Lights", &LLColor4::yellow2, 0 },
00139 { LLFastTimer::FTM_GEO_SKY, " Sky", &LLColor4::yellow3, 0 },
00140 { LLFastTimer::FTM_UPDATE_WLPARAM, " Windlight Param",&LLColor4::magenta2, 0 },
00141 { LLFastTimer::FTM_CULL, " Object Cull", &LLColor4::blue2, 1 },
00142 { LLFastTimer::FTM_CULL_REBOUND, " Rebound", &LLColor4::blue3, 0 },
00143 { LLFastTimer::FTM_FRUSTUM_CULL, " Frustum Cull", &LLColor4::blue4, 0 },
00144 { LLFastTimer::FTM_OCCLUSION_READBACK, " Occlusion Read", &LLColor4::red2, 0 },
00145 { LLFastTimer::FTM_IMAGE_UPDATE, " Image Update", &LLColor4::yellow4, 1 },
00146 { LLFastTimer::FTM_IMAGE_CREATE, " Image CreateGL",&LLColor4::yellow5, 0 },
00147 { LLFastTimer::FTM_IMAGE_DECODE, " Image Decode", &LLColor4::yellow6, 0 },
00148 { LLFastTimer::FTM_IMAGE_MARK_DIRTY, " Dirty Textures",&LLColor4::red1, 0 },
00149 { LLFastTimer::FTM_STATESORT, " State Sort", &LLColor4::orange1, 1 },
00150 { LLFastTimer::FTM_STATESORT_DRAWABLE, " Drawable", &LLColor4::orange2, 0 },
00151 { LLFastTimer::FTM_STATESORT_POSTSORT, " Post Sort", &LLColor4::orange3, 0 },
00152 { LLFastTimer::FTM_REBUILD_OCCLUSION_VB," Occlusion", &LLColor4::cyan5, 0 },
00153 { LLFastTimer::FTM_REBUILD_VBO, " VBO Rebuild", &LLColor4::red4, 0 },
00154 { LLFastTimer::FTM_REBUILD_VOLUME_VB, " Volume", &LLColor4::blue1, 0 },
00155
00156
00157
00158 { LLFastTimer::FTM_REBUILD_TERRAIN_VB, " Terrain", &LLColor4::blue4, 0 },
00159
00160
00161 { LLFastTimer::FTM_REBUILD_PARTICLE_VB, " Particle", &LLColor4::cyan2, 0 },
00162
00163
00164 { LLFastTimer::FTM_RENDER_GEOMETRY, " Geometry", &LLColor4::green2, 1 },
00165 { LLFastTimer::FTM_POOLS, " Pools", &LLColor4::green3, 1 },
00166 { LLFastTimer::FTM_POOLRENDER, " RenderPool", &LLColor4::green4, 1 },
00167 { LLFastTimer::FTM_RENDER_TERRAIN, " Terrain", &LLColor4::green6, 0 },
00168 { LLFastTimer::FTM_RENDER_CHARACTERS, " Avatars", &LLColor4::yellow1, 0 },
00169 { LLFastTimer::FTM_RENDER_SIMPLE, " Simple", &LLColor4::yellow2, 0 },
00170 { LLFastTimer::FTM_RENDER_FULLBRIGHT, " Fullbright", &LLColor4::yellow5, 0 },
00171 { LLFastTimer::FTM_RENDER_GLOW, " Glow", &LLColor4::orange1, 0 },
00172 { LLFastTimer::FTM_RENDER_GRASS, " Grass", &LLColor4::yellow6, 0 },
00173 { LLFastTimer::FTM_RENDER_INVISIBLE, " Invisible", &LLColor4::red2, 0 },
00174 { LLFastTimer::FTM_RENDER_SHINY, " Shiny", &LLColor4::yellow3, 0 },
00175 { LLFastTimer::FTM_RENDER_BUMP, " Bump", &LLColor4::yellow4, 0 },
00176 { LLFastTimer::FTM_RENDER_TREES, " Trees", &LLColor4::yellow8, 0 },
00177 { LLFastTimer::FTM_RENDER_OCCLUSION, " Occlusion", &LLColor4::red1, 0 },
00178 { LLFastTimer::FTM_RENDER_CLOUDS, " Clouds", &LLColor4::yellow5, 0 },
00179 { LLFastTimer::FTM_RENDER_ALPHA, " Alpha", &LLColor4::yellow6, 0 },
00180 { LLFastTimer::FTM_RENDER_HUD, " HUD", &LLColor4::yellow7, 0 },
00181 { LLFastTimer::FTM_RENDER_WATER, " Water", &LLColor4::yellow9, 0 },
00182 { LLFastTimer::FTM_RENDER_WL_SKY, " WL Sky", &LLColor4::blue3, 0 },
00183 { LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE," Fake VBO update", &LLColor4::red2, 0 },
00184 { LLFastTimer::FTM_RENDER_BLOOM, " Bloom", &LLColor4::blue4, 0 },
00185 { LLFastTimer::FTM_RENDER_BLOOM_FBO, " First FBO", &LLColor4::blue, 0 },
00186 { LLFastTimer::FTM_RENDER_UI, " UI", &LLColor4::cyan4, 1 },
00187 { LLFastTimer::FTM_RENDER_TIMER, " Timers", &LLColor4::cyan5, 1, 0 },
00188 { LLFastTimer::FTM_RENDER_FONTS, " Fonts", &LLColor4::pink1, 0 },
00189 { LLFastTimer::FTM_SWAP, " Swap", &LLColor4::pink2, 0 },
00190 { LLFastTimer::FTM_CLIENT_COPY, " Client Copy", &LLColor4::red1, 1},
00191
00192 #if 0 || !LL_RELEASE_FOR_DOWNLOAD
00193 { LLFastTimer::FTM_TEMP1, " Temp1", &LLColor4::red1, 0 },
00194 { LLFastTimer::FTM_TEMP2, " Temp2", &LLColor4::magenta1, 0 },
00195 { LLFastTimer::FTM_TEMP3, " Temp3", &LLColor4::red2, 0 },
00196 { LLFastTimer::FTM_TEMP4, " Temp4", &LLColor4::magenta2, 0 },
00197 { LLFastTimer::FTM_TEMP5, " Temp5", &LLColor4::red3, 0 },
00198 { LLFastTimer::FTM_TEMP6, " Temp6", &LLColor4::magenta3, 0 },
00199 { LLFastTimer::FTM_TEMP7, " Temp7", &LLColor4::red4, 0 },
00200 { LLFastTimer::FTM_TEMP8, " Temp8", &LLColor4::magenta4, 0 },
00201 #endif
00202
00203 { LLFastTimer::FTM_OTHER, " Other", &red0 }
00204 };
00205 static int ft_display_didcalc = 0;
00206 static const int FTV_DISPLAY_NUM = (sizeof(ft_display_table)/sizeof(ft_display_table[0]));
00207
00208 S32 ft_display_idx[FTV_DISPLAY_NUM];
00209
00210 LLFastTimerView::LLFastTimerView(const std::string& name, const LLRect& rect)
00211 : LLFloater(name, rect, "Fast Timers")
00212 {
00213 setVisible(FALSE);
00214 mDisplayMode = 0;
00215 mAvgCountTotal = 0;
00216 mMaxCountTotal = 0;
00217 mDisplayCenter = 1;
00218 mDisplayCalls = 0;
00219 mDisplayHz = 0;
00220 mScrollIndex = 0;
00221 mHoverIndex = -1;
00222 mHoverBarIndex = -1;
00223 mBarStart = new S32[(MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM];
00224 memset(mBarStart, 0, (MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM * sizeof(S32));
00225 mBarEnd = new S32[(MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM];
00226 memset(mBarEnd, 0, (MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM * sizeof(S32));
00227 mSubtractHidden = 0;
00228 mPrintStats = -1;
00229
00230
00231 if (!ft_display_didcalc)
00232 {
00233 int pidx[FTV_DISPLAY_NUM];
00234 int pdisabled[FTV_DISPLAY_NUM];
00235 for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
00236 {
00237 int level = 0;
00238 const char *text = ft_display_table[i].desc;
00239 while(text[0] == ' ')
00240 {
00241 text++;
00242 level++;
00243 }
00244 llassert(level < FTV_DISPLAY_NUM);
00245 ft_display_table[i].desc = text;
00246 ft_display_table[i].level = level;
00247 if (level > 0)
00248 {
00249 ft_display_table[i].parent = pidx[level-1];
00250 if (pdisabled[level-1])
00251 {
00252 ft_display_table[i].disabled = 3;
00253 }
00254 }
00255 else
00256 {
00257 ft_display_table[i].parent = -1;
00258 }
00259 ft_display_idx[i] = i;
00260 pidx[level] = i;
00261 pdisabled[level] = ft_display_table[i].disabled;
00262 }
00263 ft_display_didcalc = 1;
00264 }
00265 }
00266
00267 LLFastTimerView::~LLFastTimerView()
00268 {
00269 delete[] mBarStart;
00270 delete[] mBarEnd;
00271 }
00272
00273 BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
00274 {
00275 if (mBarRect.pointInRect(x, y))
00276 {
00277 S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
00278 bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
00279 mPrintStats = bar_idx;
00280
00281 }
00282 return FALSE;
00283 }
00284
00285 S32 LLFastTimerView::getLegendIndex(S32 y)
00286 {
00287 S32 idx = (getRect().getHeight() - y) / ((S32) LLFontGL::sMonospace->getLineHeight()+2) - 5;
00288 if (idx >= 0 && idx < FTV_DISPLAY_NUM)
00289 {
00290 return ft_display_idx[idx];
00291 }
00292
00293 return -1;
00294 }
00295
00296 BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
00297 {
00298 if (x < mBarRect.mLeft)
00299 {
00300 S32 legend_index = getLegendIndex(y);
00301 if (legend_index >= 0 && legend_index < FTV_DISPLAY_NUM)
00302 {
00303 S32 disabled = ft_display_table[legend_index].disabled;
00304 if (++disabled > 2)
00305 disabled = 0;
00306 ft_display_table[legend_index].disabled = disabled;
00307 S32 level = ft_display_table[legend_index].level;
00308
00309
00310 legend_index++;
00311 while (legend_index < FTV_DISPLAY_NUM && ft_display_table[legend_index].level > level)
00312 {
00313 ft_display_table[legend_index].disabled = disabled ? 3 : 0;
00314 legend_index++;
00315 }
00316 }
00317 }
00318 else if (mask & MASK_ALT)
00319 {
00320 if (mask & MASK_SHIFT)
00321 {
00322 mSubtractHidden = !mSubtractHidden;
00323 }
00324 else if (mask & MASK_CONTROL)
00325 {
00326 mDisplayHz = !mDisplayHz;
00327 }
00328 else
00329 {
00330 mDisplayCalls = !mDisplayCalls;
00331 }
00332 }
00333 else if (mask & MASK_SHIFT)
00334 {
00335 if (++mDisplayMode > 3)
00336 mDisplayMode = 0;
00337 }
00338 else if (mask & MASK_CONTROL)
00339 {
00340 if (++mDisplayCenter > 2)
00341 mDisplayCenter = 0;
00342 }
00343 else
00344 {
00345
00346 LLFastTimer::sPauseHistory = !LLFastTimer::sPauseHistory;
00347
00348 if (!LLFastTimer::sPauseHistory)
00349 {
00350 mScrollIndex = 0;
00351 }
00352 }
00353
00354 return TRUE;
00355 }
00356
00357 BOOL LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask)
00358 {
00359 return FALSE;
00360 }
00361
00362
00363 BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
00364 {
00365 if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
00366 {
00367 mHoverIndex = -1;
00368 mHoverBarIndex = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
00369 if (mHoverBarIndex == 0)
00370 {
00371 return TRUE;
00372 }
00373 else if (mHoverBarIndex == -1)
00374 {
00375 mHoverBarIndex = 0;
00376 }
00377 for (S32 i = 0; i < FTV_DISPLAY_NUM; i++)
00378 {
00379 if (x > mBarStart[mHoverBarIndex * FTV_DISPLAY_NUM + i] &&
00380 x < mBarEnd[mHoverBarIndex * FTV_DISPLAY_NUM + i] &&
00381 ft_display_table[i].disabled <= 1)
00382 {
00383 mHoverIndex = i;
00384 }
00385 }
00386 }
00387 else if (x < mBarRect.mLeft)
00388 {
00389 S32 legend_index = getLegendIndex(y);
00390 if (legend_index >= 0 && legend_index < FTV_DISPLAY_NUM)
00391 {
00392 mHoverIndex = legend_index;
00393 }
00394 }
00395
00396 return FALSE;
00397 }
00398
00399 BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
00400 {
00401 LLFastTimer::sPauseHistory = TRUE;
00402 mScrollIndex = llclamp(mScrollIndex - clicks,
00403 0, llmin(LLFastTimer::sLastFrameIndex, (S32)LLFastTimer::FTM_HISTORY_NUM-MAX_VISIBLE_HISTORY));
00404 return TRUE;
00405 }
00406
00407 void LLFastTimerView::draw()
00408 {
00409 LLFastTimer t(LLFastTimer::FTM_RENDER_TIMER);
00410
00411 std::string tdesc;
00412
00413 F64 clock_freq = (F64)LLFastTimer::countsPerSecond();
00414 F64 iclock_freq = 1000.0 / clock_freq;
00415
00416 S32 margin = 10;
00417 S32 height = (S32) (gViewerWindow->getVirtualWindowRect().getHeight()*0.75f);
00418 S32 width = (S32) (gViewerWindow->getVirtualWindowRect().getWidth() * 0.75f);
00419
00420
00421 const_cast<LLRect&>(getRect()).setLeftTopAndSize(getRect().mLeft, getRect().mTop, width, height);
00422
00423 S32 left, top, right, bottom;
00424 S32 x, y, barw, barh, dx, dy;
00425 S32 texth, textw;
00426 LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("rounded_square.tga");
00427
00428
00429
00430 {
00431 S32 display_timer[LLFastTimer::FTM_NUM_TYPES];
00432 S32 hidx = LLFastTimer::sLastFrameIndex % LLFastTimer::FTM_HISTORY_NUM;
00433 for (S32 i=0; i < LLFastTimer::FTM_NUM_TYPES; i++)
00434 {
00435 display_timer[i] = 0;
00436 }
00437 for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
00438 {
00439 S32 tidx = ft_display_table[i].timer;
00440 display_timer[tidx] = 1;
00441 }
00442 LLFastTimer::sCountHistory[hidx][LLFastTimer::FTM_OTHER] = 0;
00443 LLFastTimer::sCallHistory[hidx][LLFastTimer::FTM_OTHER] = 0;
00444 for (S32 tidx = 0; tidx < LLFastTimer::FTM_NUM_TYPES; tidx++)
00445 {
00446 U64 counts = LLFastTimer::sCountHistory[hidx][tidx];
00447 if (counts > 0 && display_timer[tidx] == 0)
00448 {
00449 LLFastTimer::sCountHistory[hidx][LLFastTimer::FTM_OTHER] += counts;
00450 LLFastTimer::sCallHistory[hidx][LLFastTimer::FTM_OTHER] += 1;
00451 }
00452 }
00453 LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] = 0;
00454 LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] = 0;
00455 for (S32 h = 0; h < LLFastTimer::FTM_HISTORY_NUM; h++)
00456 {
00457 LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] += LLFastTimer::sCountHistory[h][LLFastTimer::FTM_OTHER];
00458 LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] += LLFastTimer::sCallHistory[h][LLFastTimer::FTM_OTHER];
00459 }
00460 LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] /= LLFastTimer::FTM_HISTORY_NUM;
00461 LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] /= LLFastTimer::FTM_HISTORY_NUM;
00462 }
00463
00464
00465 {
00466 LLGLSNoTexture gls_ui_no_texture;
00467 gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
00468 }
00469
00470 S32 xleft = margin;
00471 S32 ytop = margin;
00472
00473
00474 {
00475
00476 x = xleft;
00477 y = height - ytop;
00478 texth = (S32)LLFontGL::sMonospace->getLineHeight();
00479
00480 char modedesc[][32] = {
00481 "2 x Average ",
00482 "Max ",
00483 "Recent Max ",
00484 "100 ms "
00485 };
00486 char centerdesc[][32] = {
00487 "Left ",
00488 "Centered ",
00489 "Ordered "
00490 };
00491
00492 tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);
00493 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
00494
00495 textw = LLFontGL::sMonospace->getWidth(tdesc);
00496
00497 x = xleft, y -= (texth + 2);
00498 tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]);
00499 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
00500 y -= (texth + 2);
00501
00502 LLFontGL::sMonospace->renderUTF8("[Right-Click log selected] [ALT-Click toggle counts] [ALT-SHIFT-Click sub hidden]",
00503 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
00504 y -= (texth + 2);
00505 }
00506
00507
00508 S32 histmax = llmin(LLFastTimer::sLastFrameIndex+1, MAX_VISIBLE_HISTORY);
00509 U64 ticks_sum[LLFastTimer::FTM_HISTORY_NUM+1][FTV_DISPLAY_NUM];
00510 for (S32 j=-1; j<LLFastTimer::FTM_HISTORY_NUM; j++)
00511 {
00512 S32 hidx;
00513 if (j >= 0)
00514 hidx = (LLFastTimer::sLastFrameIndex+j) % LLFastTimer::FTM_HISTORY_NUM;
00515 else
00516 hidx = -1;
00517
00518
00519 for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
00520 {
00521 if (mSubtractHidden && ft_display_table[i].disabled > 1)
00522 {
00523 continue;
00524 }
00525
00526 S32 tidx = ft_display_table[i].timer;
00527 if (hidx >= 0)
00528 ticks_sum[j+1][i] = LLFastTimer::sCountHistory[hidx][tidx];
00529 else
00530 ticks_sum[j+1][i] = LLFastTimer::sCountAverage[tidx];
00531 S32 pidx = ft_display_table[i].parent;
00532
00533 while (pidx >= 0)
00534 {
00535 ticks_sum[j+1][pidx] += ticks_sum[j+1][i];
00536 pidx = ft_display_table[pidx].parent;
00537 }
00538 }
00539 }
00540
00541
00542
00543 S32 legendwidth = 0;
00544 xleft = margin;
00545 ytop = y;
00546
00547 y -= (texth + 2);
00548
00549 S32 cur_line = 0;
00550 S32 display_line[FTV_DISPLAY_NUM];
00551 for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
00552 {
00553 S32 disabled = ft_display_table[i].disabled;
00554 if (disabled == 3)
00555 {
00556 continue;
00557 }
00558 display_line[i] = cur_line;
00559 ft_display_idx[cur_line] = i;
00560 cur_line++;
00561 S32 level = ft_display_table[i].level;
00562 S32 parent = ft_display_table[i].parent;
00563
00564 x = xleft;
00565
00566 left = x; right = x + texth;
00567 top = y; bottom = y - texth;
00568 S32 scale_offset = 0;
00569 if (i == mHoverIndex)
00570 {
00571 scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
00572 }
00573 gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, *ft_display_table[i].color);
00574
00575 int tidx = ft_display_table[i].timer;
00576 F32 ms = 0;
00577 S32 calls = 0;
00578 if (mHoverBarIndex > 0 && mHoverIndex >= 0)
00579 {
00580 S32 hidx = (LLFastTimer::sLastFrameIndex + (mHoverBarIndex - 1) - mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
00581 S32 bidx = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex - mHoverBarIndex;
00582 U64 ticks = ticks_sum[bidx+1][i];
00583 ms = (F32)((F64)ticks * iclock_freq);
00584 calls = (S32)LLFastTimer::sCallHistory[hidx][tidx];
00585 }
00586 else
00587 {
00588 U64 ticks = ticks_sum[0][i];
00589 ms = (F32)((F64)ticks * iclock_freq);
00590 calls = (S32)LLFastTimer::sCallAverage[tidx];
00591 }
00592 if (mDisplayCalls)
00593 {
00594 tdesc = llformat("%s (%d)",ft_display_table[i].desc,calls);
00595 }
00596 else
00597 {
00598 tdesc = llformat("%s [%.1f]",ft_display_table[i].desc,ms);
00599 }
00600 dx = (texth+4) + level*8;
00601
00602 LLColor4 color = disabled > 1 ? LLColor4::grey : LLColor4::white;
00603 if (level > 0)
00604 {
00605 S32 line_start_y = (top + bottom) / 2;
00606 S32 line_end_y = line_start_y + ((texth + 2) * (display_line[i] - display_line[parent])) - (texth / 2);
00607 gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
00608 S32 line_x = x + (texth + 4) + ((level - 1) * 8);
00609 gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
00610 if (disabled == 1)
00611 {
00612 gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
00613 }
00614 }
00615
00616 x += dx;
00617 BOOL is_child_of_hover_item = (i == mHoverIndex);
00618 S32 next_parent = ft_display_table[i].parent;
00619 while(!is_child_of_hover_item && next_parent >= 0)
00620 {
00621 is_child_of_hover_item = (mHoverIndex == next_parent);
00622 next_parent = ft_display_table[next_parent].parent;
00623 }
00624
00625 if (is_child_of_hover_item)
00626 {
00627 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD);
00628 }
00629 else
00630 {
00631 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, color, LLFontGL::LEFT, LLFontGL::TOP);
00632 }
00633 y -= (texth + 2);
00634
00635 textw = dx + LLFontGL::sMonospace->getWidth(ft_display_table[i].desc) + 40;
00636 if (textw > legendwidth)
00637 legendwidth = textw;
00638 }
00639 for (S32 i=cur_line; i<FTV_DISPLAY_NUM; i++)
00640 {
00641 ft_display_idx[i] = -1;
00642 }
00643 xleft += legendwidth + 8;
00644
00645
00646
00647 mBarRect.mLeft = xleft;
00648 mBarRect.mRight = getRect().mRight - xleft;
00649 mBarRect.mTop = ytop - ((S32)LLFontGL::sMonospace->getLineHeight() + 4);
00650 mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT;
00651
00652 y = ytop;
00653 barh = (ytop - margin - LINE_GRAPH_HEIGHT) / (MAX_VISIBLE_HISTORY + 2);
00654 dy = barh>>2;
00655 if (dy < 1) dy = 1;
00656 barh -= dy;
00657 barw = width - xleft - margin;
00658
00659
00660 if (LLFastTimer::sLastFrameIndex >= 0)
00661 {
00662 U64 totalticks;
00663 if (!LLFastTimer::sPauseHistory)
00664 {
00665 U64 ticks = 0;
00666 int hidx = (LLFastTimer::sLastFrameIndex - mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
00667 for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
00668 {
00669 if (mSubtractHidden && ft_display_table[i].disabled > 1)
00670 {
00671 continue;
00672 }
00673 int tidx = ft_display_table[i].timer;
00674 ticks += LLFastTimer::sCountHistory[hidx][tidx];
00675 }
00676 if (LLFastTimer::sCurFrameIndex >= 10)
00677 {
00678 U64 framec = LLFastTimer::sCurFrameIndex;
00679 U64 avg = (U64)mAvgCountTotal;
00680 mAvgCountTotal = (avg*framec + ticks) / (framec + 1);
00681 if (ticks > mMaxCountTotal)
00682 {
00683 mMaxCountTotal = ticks;
00684 }
00685 }
00686 #if 1
00687 if (ticks < mAvgCountTotal/100 || ticks > mAvgCountTotal*100)
00688 LLFastTimer::sResetHistory = 1;
00689 #endif
00690 if (LLFastTimer::sCurFrameIndex < 10 || LLFastTimer::sResetHistory)
00691 {
00692 mAvgCountTotal = ticks;
00693 mMaxCountTotal = ticks;
00694 }
00695 }
00696
00697 if (mDisplayMode == 0)
00698 {
00699 totalticks = mAvgCountTotal*2;
00700 }
00701 else if (mDisplayMode == 1)
00702 {
00703 totalticks = mMaxCountTotal;
00704 }
00705 else if (mDisplayMode == 2)
00706 {
00707
00708 totalticks = 0;
00709 for (S32 j=0; j<histmax; j++)
00710 {
00711 U64 ticks = 0;
00712 for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
00713 {
00714 if (mSubtractHidden && ft_display_table[i].disabled > 1)
00715 {
00716 continue;
00717 }
00718 int tidx = ft_display_table[i].timer;
00719 ticks += LLFastTimer::sCountHistory[j][tidx];
00720 }
00721 if (ticks > totalticks)
00722 totalticks = ticks;
00723 }
00724 }
00725 else
00726 {
00727 totalticks = (U64)(clock_freq * .1);
00728 }
00729
00730
00731 {
00732 U32 ms = (U32)((F64)totalticks * iclock_freq) ;
00733
00734 tdesc = llformat("%.1f ms |", (F32)ms*.25f);
00735 x = xleft + barw/4 - LLFontGL::sMonospace->getWidth(tdesc);
00736 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white,
00737 LLFontGL::LEFT, LLFontGL::TOP);
00738
00739 tdesc = llformat("%.1f ms |", (F32)ms*.50f);
00740 x = xleft + barw/2 - LLFontGL::sMonospace->getWidth(tdesc);
00741 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white,
00742 LLFontGL::LEFT, LLFontGL::TOP);
00743
00744 tdesc = llformat("%.1f ms |", (F32)ms*.75f);
00745 x = xleft + (barw*3)/4 - LLFontGL::sMonospace->getWidth(tdesc);
00746 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white,
00747 LLFontGL::LEFT, LLFontGL::TOP);
00748
00749 tdesc = llformat( "%d ms |", ms);
00750 x = xleft + barw - LLFontGL::sMonospace->getWidth(tdesc);
00751 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white,
00752 LLFontGL::LEFT, LLFontGL::TOP);
00753 }
00754
00755 LLRect graph_rect;
00756
00757 {
00758 LLGLSNoTexture gls_ui_no_texture;
00759 gGL.color4f(0.5f,0.5f,0.5f,0.5f);
00760
00761 S32 by = y + 2;
00762
00763 y -= ((S32)LLFontGL::sMonospace->getLineHeight() + 4);
00764
00765
00766 gl_rect_2d(xleft-5, by, getRect().getWidth()-5, y+5, FALSE);
00767
00768
00769 gl_rect_2d(5, by, xleft-10, 5, FALSE);
00770
00771 by = y + 5;
00772
00773 gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-5, FALSE);
00774
00775 by -= barh*2+dy;
00776
00777
00778 gl_rect_2d(xleft-5, by, getRect().getWidth()-5, by-barh-dy-2, FALSE);
00779
00780 by -= barh+dy+1;
00781
00782
00783 gl_rect_2d(xleft-5, by, getRect().getWidth()-5, LINE_GRAPH_HEIGHT-barh-dy-2, FALSE);
00784
00785 by = LINE_GRAPH_HEIGHT-barh-dy-7;
00786
00787
00788 graph_rect = LLRect(xleft-5, by, getRect().getWidth()-5, 5);
00789
00790 gl_rect_2d(graph_rect, FALSE);
00791 }
00792
00793
00794
00795 LLViewerImage::bindTexture(box_imagep->getImage());
00796 for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++)
00797 {
00798 int sublevel_dx[FTV_DISPLAY_NUM+1];
00799 int sublevel_left[FTV_DISPLAY_NUM+1];
00800 int sublevel_right[FTV_DISPLAY_NUM+1];
00801 S32 tidx;
00802 if (j >= 0)
00803 {
00804 tidx = LLFastTimer::FTM_HISTORY_NUM - j - 1 - mScrollIndex;
00805 }
00806 else
00807 {
00808 tidx = -1;
00809 }
00810
00811 x = xleft;
00812
00813
00814 int xpos[FTV_DISPLAY_NUM+1];
00815 int deltax[FTV_DISPLAY_NUM+1];
00816 xpos[0] = xleft;
00817
00818 for (S32 i = 0; i < FTV_DISPLAY_NUM; i++)
00819 {
00820 if (ft_display_table[i].disabled > 1)
00821 {
00822 continue;
00823 }
00824
00825 F32 frac = (F32)ticks_sum[tidx+1][i] / (F32)totalticks;
00826
00827 dx = llround(frac * (F32)barw);
00828 deltax[i] = dx;
00829
00830 int level = ft_display_table[i].level;
00831 int parent = ft_display_table[i].parent;
00832 llassert(level < FTV_DISPLAY_NUM);
00833 llassert(parent < FTV_DISPLAY_NUM);
00834
00835 left = xpos[level];
00836
00837 S32 prev_idx = i - 1;
00838 while (prev_idx > 0)
00839 {
00840 if (ft_display_table[prev_idx].disabled <= 1)
00841 {
00842 break;
00843 }
00844 prev_idx--;
00845 }
00846 S32 next_idx = i + 1;
00847 while (next_idx < FTV_DISPLAY_NUM)
00848 {
00849 if (ft_display_table[next_idx].disabled <= 1)
00850 {
00851 break;
00852 }
00853 next_idx++;
00854 }
00855
00856 if (level == 0)
00857 {
00858 sublevel_left[level] = xleft;
00859 sublevel_dx[level] = dx;
00860 sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
00861 }
00862 else if (i==0 || ft_display_table[prev_idx].level < level)
00863 {
00864
00865
00866 U64 sublevelticks = ticks_sum[tidx+1][i];
00867 for (S32 k=i+1; k<FTV_DISPLAY_NUM; k++)
00868 {
00869 if (ft_display_table[k].level < level)
00870 break;
00871 if (ft_display_table[k].disabled <= 1 && ft_display_table[k].level == level)
00872 sublevelticks += ticks_sum[tidx+1][k];
00873 }
00874 F32 subfrac = (F32)sublevelticks / (F32)totalticks;
00875 sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f);
00876
00877 if (mDisplayCenter == 1)
00878 {
00879 left += (deltax[parent] - sublevel_dx[level])/2;
00880 }
00881 else if (mDisplayCenter == 2)
00882 {
00883 left += (deltax[parent] - sublevel_dx[level]);
00884 }
00885
00886 sublevel_left[level] = left;
00887 sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
00888 }
00889
00890 right = left + dx;
00891 xpos[level] = right;
00892 xpos[level+1] = left;
00893
00894 mBarStart[(j + 1) * FTV_DISPLAY_NUM + i] = left;
00895 mBarEnd[(j + 1) * FTV_DISPLAY_NUM + i] = right;
00896
00897 top = y;
00898 bottom = y - barh;
00899
00900 if (right > left)
00901 {
00902
00903 LLColor4 color = *ft_display_table[i].color;
00904 S32 scale_offset = 0;
00905
00906 BOOL is_child_of_hover_item = (i == mHoverIndex);
00907 S32 next_parent = ft_display_table[i].parent;
00908 while(!is_child_of_hover_item && next_parent >= 0)
00909 {
00910 is_child_of_hover_item = (mHoverIndex == next_parent);
00911 next_parent = ft_display_table[next_parent].parent;
00912 }
00913
00914 if (i == mHoverIndex)
00915 {
00916 scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f);
00917
00918 }
00919 else if (mHoverIndex >= 0 && !is_child_of_hover_item)
00920 {
00921 color = lerp(color, LLColor4::grey, 0.8f);
00922 }
00923
00924 gGL.color4fv(color.mV);
00925 F32 start_fragment = llclamp((F32)(left - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f);
00926 F32 end_fragment = llclamp((F32)(right - sublevel_left[level]) / (F32)sublevel_dx[level], 0.f, 1.f);
00927 gl_segmented_rect_2d_fragment_tex(sublevel_left[level], top - level + scale_offset, sublevel_right[level], bottom + level - scale_offset, box_imagep->getTextureWidth(), box_imagep->getTextureHeight(), 16, start_fragment, end_fragment);
00928
00929 }
00930
00931 }
00932 y -= (barh + dy);
00933 if (j < 0)
00934 y -= barh;
00935 }
00936
00937
00938 {
00939 LLGLSNoTexture no_texture;
00940 LLLocalClipRect clip(graph_rect);
00941
00942
00943 static U64 last_max = 0;
00944 static F32 alpha_interp = 0.f;
00945 U64 max_ticks = llmax(last_max, (U64) 1);
00946 F32 ms = (F32)((F64)max_ticks * iclock_freq);
00947
00948
00949 LLString tdesc = mDisplayCalls ?
00950 llformat("%d calls", max_ticks) :
00951 mDisplayHz ?
00952 llformat("%d Hz", max_ticks) :
00953 llformat("%4.2f ms", ms);
00954
00955 x = graph_rect.mRight - LLFontGL::sMonospace->getWidth(tdesc)-5;
00956 y = graph_rect.mTop - ((S32)LLFontGL::sMonospace->getLineHeight());
00957
00958 LLFontGL::sMonospace->renderUTF8(tdesc, 0, x, y, LLColor4::white,
00959 LLFontGL::LEFT, LLFontGL::TOP);
00960
00961
00962 {
00963 S32 first_frame = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex;
00964 S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
00965
00966 F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1);
00967
00968 F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame;
00969 F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame;
00970
00971 gGL.color4f(0.5f,0.5f,0.5f,0.3f);
00972 gl_rect_2d((S32) left, graph_rect.mTop, (S32) right, graph_rect.mBottom);
00973
00974 if (mHoverBarIndex >= 0)
00975 {
00976 S32 bar_frame = first_frame - mHoverBarIndex;
00977 F32 bar = (F32) graph_rect.mLeft + frame_delta*bar_frame;
00978
00979 gGL.color4f(0.5f,0.5f,0.5f,1);
00980
00981 gGL.begin(LLVertexBuffer::LINES);
00982 gGL.vertex2i((S32)bar, graph_rect.mBottom);
00983 gGL.vertex2i((S32)bar, graph_rect.mTop);
00984 gGL.end();
00985 }
00986 }
00987
00988 U64 cur_max = 0;
00989 for (S32 idx = 0; idx < FTV_DISPLAY_NUM; ++idx)
00990 {
00991 if (ft_display_table[idx].disabled > 1)
00992 {
00993 continue;
00994 }
00995
00996
00997 if (mHoverIndex == idx)
00998 {
00999 gGL.flush();
01000 glLineWidth(3);
01001 }
01002
01003 const F32 * col = ft_display_table[idx].color->mV;
01004
01005 F32 alpha = 1.f;
01006
01007 if (mHoverIndex >= 0 &&
01008 idx != mHoverIndex)
01009 {
01010 if (ft_display_table[idx].parent != mHoverIndex)
01011 {
01012 alpha = alpha_interp;
01013 }
01014 }
01015
01016 gGL.color4f(col[0], col[1], col[2], alpha);
01017 gGL.begin(LLVertexBuffer::LINE_STRIP);
01018 for (U32 j = 0; j < LLFastTimer::FTM_HISTORY_NUM; j++)
01019 {
01020 U64 ticks = ticks_sum[j+1][idx];
01021
01022 if (mDisplayHz)
01023 {
01024 F64 tc = (F64) (ticks+1) * iclock_freq;
01025 tc = 1000.f/tc;
01026 ticks = llmin((U64) tc, (U64) 1024);
01027 }
01028 else if (mDisplayCalls)
01029 {
01030 S32 tidx = ft_display_table[idx].timer;
01031 S32 hidx = (LLFastTimer::sLastFrameIndex + j) % LLFastTimer::FTM_HISTORY_NUM;
01032 ticks = (S32)LLFastTimer::sCallHistory[hidx][tidx];
01033 }
01034
01035 if (alpha == 1.f)
01036 {
01037 cur_max = llmax(cur_max, ticks);
01038 }
01039 F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1)*j;
01040 F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks;
01041 gGL.vertex2f(x,y);
01042 }
01043 gGL.end();
01044
01045 if (mHoverIndex == idx)
01046 {
01047 gGL.flush();
01048 glLineWidth(1);
01049 }
01050 }
01051
01052
01053 F32 dt = gFrameIntervalSeconds*3.f;
01054 last_max = (U64) ((F32) last_max + ((F32) cur_max- (F32) last_max) * dt);
01055 F32 alpha_target = last_max > cur_max ?
01056 llmin((F32) last_max/ (F32) cur_max - 1.f,1.f) :
01057 llmin((F32) cur_max/ (F32) last_max - 1.f,1.f);
01058
01059 alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt;
01060
01061 if (mHoverIndex >= 0)
01062 {
01063 x = (graph_rect.mRight + graph_rect.mLeft)/2;
01064 y = graph_rect.mBottom + 8;
01065
01066 LLFontGL::sMonospace->renderUTF8(ft_display_table[mHoverIndex].desc, 0, x, y, LLColor4::white,
01067 LLFontGL::LEFT, LLFontGL::BOTTOM);
01068 }
01069 }
01070 }
01071
01072
01073 if (mPrintStats >= 0)
01074 {
01075 LLString legend_stat;
01076 S32 stat_num;
01077 S32 first = 1;
01078 for (stat_num = 0; stat_num < FTV_DISPLAY_NUM; stat_num++)
01079 {
01080 if (ft_display_table[stat_num].disabled > 1)
01081 continue;
01082 if (!first)
01083 legend_stat += ", ";
01084 first=0;
01085 legend_stat += ft_display_table[stat_num].desc;
01086 }
01087 llinfos << legend_stat << llendl;
01088
01089 LLString timer_stat;
01090 first = 1;
01091 for (stat_num = 0; stat_num < FTV_DISPLAY_NUM; stat_num++)
01092 {
01093 S32 disabled = ft_display_table[stat_num].disabled;
01094 if (disabled > 1)
01095 continue;
01096 if (!first)
01097 timer_stat += ", ";
01098 first=0;
01099 U64 ticks;
01100 S32 tidx = ft_display_table[stat_num].timer;
01101 if (mPrintStats > 0)
01102 {
01103 S32 hidx = (LLFastTimer::sLastFrameIndex+(mPrintStats-1)-mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
01104 ticks = disabled >= 1 ? ticks_sum[mPrintStats][stat_num] : LLFastTimer::sCountHistory[hidx][tidx];
01105 }
01106 else
01107 {
01108 ticks = disabled >= 1 ? ticks_sum[0][stat_num] : LLFastTimer::sCountAverage[tidx];
01109 }
01110 F32 ms = (F32)((F64)ticks * iclock_freq);
01111
01112 timer_stat += llformat("%.1f",ms);
01113 }
01114 llinfos << timer_stat << llendl;
01115 mPrintStats = -1;
01116 }
01117
01118 mHoverIndex = -1;
01119 mHoverBarIndex = -1;
01120
01121 LLView::draw();
01122 }
01123
01124 F64 LLFastTimerView::getTime(LLFastTimer::EFastTimerType tidx)
01125 {
01126
01127 S32 i;
01128 for (i=0; i<FTV_DISPLAY_NUM; i++)
01129 {
01130 if (tidx == ft_display_table[i].timer)
01131 {
01132 break;
01133 }
01134 }
01135
01136 if (i == FTV_DISPLAY_NUM)
01137 {
01138
01139
01140 llwarns << "Timer type " << tidx << " not known." << llendl;
01141 return F64(0.0);
01142 }
01143
01144 S32 table_idx = i;
01145
01146
01147 U64 ticks = LLFastTimer::sCountAverage[tidx];
01148 S32 level = ft_display_table[table_idx].level;
01149 for (i=table_idx+1; i<FTV_DISPLAY_NUM; i++)
01150 {
01151 if (ft_display_table[i].level <= level)
01152 {
01153 break;
01154 }
01155 ticks += LLFastTimer::sCountAverage[ft_display_table[i].timer];
01156 }
01157
01158 return (F64)ticks / (F64)LLFastTimer::countsPerSecond();
01159 }