summaryrefslogtreecommitdiff
path: root/indra/newview/llfasttimerview.cpp
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2009-06-21 08:04:56 +0000
committerSteven Bennetts <steve@lindenlab.com>2009-06-21 08:04:56 +0000
commit9ec432034dc3c45d7ce763eb02dae4cc7f6b8da8 (patch)
tree4a505c1e0919af52800b3ffb3eaf135e7d6f9ce6 /indra/newview/llfasttimerview.cpp
parent351ebe9fcb76f3b99c2957004bb8493a904869ee (diff)
merge -r 122421-124917 viewer-2.0.0-2 -> viewer-2.0.0-3
ignore-dead-branch
Diffstat (limited to 'indra/newview/llfasttimerview.cpp')
-rw-r--r--indra/newview/llfasttimerview.cpp1129
1 files changed, 562 insertions, 567 deletions
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index c9037d0fbb..b373dd2241 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -41,6 +41,7 @@
#include "llrender.h"
#include "llmath.h"
#include "llfontgl.h"
+#include "llsdserialize.h"
#include "llappviewer.h"
#include "llviewerimagelist.h"
@@ -49,287 +50,108 @@
#include "llstat.h"
#include "llfasttimer.h"
-
+#include "lltreeiterators.h"
+#include "llmetricperformancetester.h"
//////////////////////////////////////////////////////////////////////////////
static const S32 MAX_VISIBLE_HISTORY = 10;
static const S32 LINE_GRAPH_HEIGHT = 240;
-struct ft_display_info {
- int timer;
- const char *desc;
- const LLColor4 *color;
- S32 disabled; // initialized to 0
- int level; // calculated based on desc
- int parent; // calculated
-};
-
-static const LLColor4 red0(0.5f, 0.0f, 0.0f, 1.0f);
-static const LLColor4 green0(0.0f, 0.5f, 0.0f, 1.0f);
-static const LLColor4 blue0(0.0f, 0.0f, 0.5f, 1.0f);
-static const LLColor4 blue7(0.0f, 0.0f, 0.5f, 1.0f);
-
-static const LLColor4 green7(0.6f, 1.0f, 0.4f, 1.0f);
-static const LLColor4 green8(0.4f, 1.0f, 0.6f, 1.0f);
-static const LLColor4 green9(0.6f, 1.0f, 0.6f, 1.0f);
-
-// green(6), blue, yellow, orange, pink(2), cyan
-// red (5) magenta (4)
-static struct ft_display_info ft_display_table[] =
-{
- { LLFastTimer::FTM_FRAME, "Frame", &LLColor4::white, 0 },
- { LLFastTimer::FTM_MESSAGES, " System Messages", &LLColor4::grey1, 1 },
- { LLFastTimer::FTM_MOUSEHANDLER, " Mouse", &LLColor4::grey1, 0 },
- { LLFastTimer::FTM_KEYHANDLER, " Keyboard", &LLColor4::grey1, 0 },
- { LLFastTimer::FTM_SLEEP, " Sleep", &LLColor4::grey2, 0 },
- { LLFastTimer::FTM_IDLE, " Idle", &blue0, 0 },
- { LLFastTimer::FTM_PUMP, " Pump", &LLColor4::magenta2, 1 },
- { LLFastTimer::FTM_CURL, " Curl", &LLColor4::magenta3, 0 },
- { LLFastTimer::FTM_INVENTORY, " Inventory Update", &LLColor4::purple6, 1 },
- { LLFastTimer::FTM_AUTO_SELECT, " Open and Select", &LLColor4::red, 0 },
- { LLFastTimer::FTM_FILTER, " Filter", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_ARRANGE, " Arrange", &LLColor4::red3, 0 },
- { LLFastTimer::FTM_REFRESH, " Refresh", &LLColor4::red4, 0 },
- { LLFastTimer::FTM_SORT, " Sort", &LLColor4::red5, 0 },
- { LLFastTimer::FTM_RESET_DRAWORDER, " ResetDrawOrder", &LLColor4::pink1, 0 },
- { LLFastTimer::FTM_WORLD_UPDATE, " World Update", &LLColor4::blue1, 1 },
- { LLFastTimer::FTM_UPDATE_MOVE, " Move Objects", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_OCTREE_BALANCE, " Octree Balance", &LLColor4::red3, 0 },
- { LLFastTimer::FTM_SIMULATE_PARTICLES, " Particle Sim", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_OBJECTLIST_UPDATE, " Object Update", &LLColor4::purple1, 1 },
- { LLFastTimer::FTM_AVATAR_UPDATE, " Avatars", &LLColor4::purple2, 0 },
- { LLFastTimer::FTM_JOINT_UPDATE, " Joints", &LLColor4::purple3, 0 },
- { LLFastTimer::FTM_ATTACHMENT_UPDATE, " Attachments", &LLColor4::purple4, 0 },
- { LLFastTimer::FTM_UPDATE_ANIMATION, " Animation", &LLColor4::purple5, 0 },
- { LLFastTimer::FTM_FLEXIBLE_UPDATE, " Flex Update", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_LOD_UPDATE, " LOD Update", &LLColor4::magenta1, 0 },
- { LLFastTimer::FTM_REGION_UPDATE, " Region Update", &LLColor4::cyan2, 0 },
- { LLFastTimer::FTM_NETWORK, " Network", &LLColor4::orange1, 1 },
- { LLFastTimer::FTM_IDLE_NETWORK, " Decode Msgs", &LLColor4::orange2, 0 },
- { LLFastTimer::FTM_PROCESS_MESSAGES, " Process Msgs", &LLColor4::orange3, 0 },
- { LLFastTimer::FTM_PROCESS_OBJECTS, " Object Updates",&LLColor4::orange4, 0 },
- { LLFastTimer::FTM_CREATE_OBJECT, " Create Obj", &LLColor4::orange5, 0 },
-// { LLFastTimer::FTM_LOAD_AVATAR, " Load Avatar", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_PROCESS_IMAGES, " Image Updates",&LLColor4::orange6, 0 },
- { LLFastTimer::FTM_PIPELINE, " Pipeline", &LLColor4::magenta4, 0 },
- { LLFastTimer::FTM_CLEANUP, " Cleanup", &LLColor4::cyan3, 0 },
- { LLFastTimer::FTM_AUDIO_UPDATE, " Audio Update", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_VFILE_WAIT, " VFile Wait", &LLColor4::cyan6, 0 },
-// { LLFastTimer::FTM_IDLE_CB, " Callbacks", &LLColor4::pink1, 0 },
- { LLFastTimer::FTM_RENDER, " Render", &green0, 1 },
- { LLFastTimer::FTM_PICK, " Pick", &LLColor4::purple, 1 },
- { LLFastTimer::FTM_HUD_EFFECTS, " HUD Effects", &LLColor4::orange1, 0 },
- { LLFastTimer::FTM_HUD_UPDATE, " HUD Update", &LLColor4::orange2, 0 },
- { LLFastTimer::FTM_UPDATE_SKY, " Sky Update", &LLColor4::cyan1, 0 },
- { LLFastTimer::FTM_UPDATE_TEXTURES, " Textures", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_GEO_UPDATE, " Geo Update", &LLColor4::blue3, 1 },
- { LLFastTimer::FTM_UPDATE_PRIMITIVES, " Volumes", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_GEN_VOLUME, " Gen Volume", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_GEN_FLEX, " Flexible", &LLColor4::yellow4, 0 },
- { LLFastTimer::FTM_GEN_TRIANGLES, " Triangles", &LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_UPDATE_AVATAR, " Avatar", &LLColor4::yellow1, 0 },
- { LLFastTimer::FTM_UPDATE_TREE, " Tree", &LLColor4::yellow2, 0 },
- { LLFastTimer::FTM_UPDATE_TERRAIN, " Terrain", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_UPDATE_CLOUDS, " Clouds", &LLColor4::yellow7, 0 },
- { LLFastTimer::FTM_UPDATE_GRASS, " Grass", &LLColor4::yellow8, 0 },
- { LLFastTimer::FTM_UPDATE_WATER, " Water", &LLColor4::yellow9, 0 },
- { LLFastTimer::FTM_GEO_LIGHT, " Lighting", &LLColor4::yellow1, 0 },
- { LLFastTimer::FTM_GEO_SHADOW, " Shadow", &LLColor4::black, 0 },
- { LLFastTimer::FTM_UPDATE_PARTICLES, " Particles", &LLColor4::blue5, 0 },
- { LLFastTimer::FTM_GEO_RESERVE, " Reserve", &LLColor4::blue6, 0 },
- { LLFastTimer::FTM_UPDATE_LIGHTS, " Lights", &LLColor4::yellow2, 0 },
- { LLFastTimer::FTM_GEO_SKY, " Sky", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_UPDATE_WLPARAM, " Windlight Param",&LLColor4::magenta2, 0 },
- { LLFastTimer::FTM_CULL, " Object Cull", &LLColor4::blue2, 1 },
- { LLFastTimer::FTM_CULL_REBOUND, " Rebound", &LLColor4::blue3, 0 },
- { LLFastTimer::FTM_FRUSTUM_CULL, " Frustum Cull", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_OCCLUSION_READBACK, " Occlusion Read", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_IMAGE_UPDATE, " Image Update", &LLColor4::yellow4, 1 },
- { LLFastTimer::FTM_IMAGE_CREATE, " Image CreateGL",&LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_IMAGE_DECODE, " Image Decode", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_IMAGE_MARK_DIRTY, " Dirty Textures",&LLColor4::red1, 0 },
- { LLFastTimer::FTM_STATESORT, " State Sort", &LLColor4::orange1, 1 },
- { LLFastTimer::FTM_STATESORT_DRAWABLE, " Drawable", &LLColor4::orange2, 0 },
- { LLFastTimer::FTM_STATESORT_POSTSORT, " Post Sort", &LLColor4::orange3, 0 },
- { LLFastTimer::FTM_REBUILD_OCCLUSION_VB," Occlusion", &LLColor4::cyan5, 0 },
- { LLFastTimer::FTM_REBUILD_VBO, " VBO Rebuild", &LLColor4::red4, 0 },
- { LLFastTimer::FTM_REBUILD_VOLUME_VB, " Volume", &LLColor4::blue1, 0 },
-// { LLFastTimer::FTM_REBUILD_NONE_VB, " Unknown", &LLColor4::cyan5, 0 },
-// { LLFastTimer::FTM_REBUILD_BRIDGE_VB, " Bridge", &LLColor4::blue2, 0 },
-// { LLFastTimer::FTM_REBUILD_HUD_VB, " HUD", &LLColor4::blue3, 0 },
- { LLFastTimer::FTM_REBUILD_TERRAIN_VB, " Terrain", &LLColor4::blue4, 0 },
-// { LLFastTimer::FTM_REBUILD_WATER_VB, " Water", &LLColor4::blue5, 0 },
-// { LLFastTimer::FTM_REBUILD_TREE_VB, " Tree", &LLColor4::cyan1, 0 },
- { LLFastTimer::FTM_REBUILD_PARTICLE_VB, " Particle", &LLColor4::cyan2, 0 },
-// { LLFastTimer::FTM_REBUILD_CLOUD_VB, " Cloud", &LLColor4::cyan3, 0 },
- { LLFastTimer::FTM_REBUILD_GRASS_VB, " Grass", &LLColor4::cyan4, 0 },
- { LLFastTimer::FTM_SHADOW_RENDER, " Shadow", &LLColor4::green5, 1 },
- { LLFastTimer::FTM_SHADOW_SIMPLE, " Simple", &LLColor4::yellow2, 1 },
- { LLFastTimer::FTM_SHADOW_ALPHA, " Alpha", &LLColor4::yellow6, 1 },
- { LLFastTimer::FTM_SHADOW_TERRAIN, " Terrain", &LLColor4::green6, 1 },
- { LLFastTimer::FTM_SHADOW_AVATAR, " Avatar", &LLColor4::yellow1, 1 },
- { LLFastTimer::FTM_SHADOW_TREE, " Tree", &LLColor4::yellow8, 1 },
- { LLFastTimer::FTM_RENDER_GEOMETRY, " Geometry", &LLColor4::green2, 1 },
- { LLFastTimer::FTM_POOLS, " Pools", &LLColor4::green3, 1 },
- { LLFastTimer::FTM_POOLRENDER, " RenderPool", &LLColor4::green4, 1 },
- { LLFastTimer::FTM_RENDER_TERRAIN, " Terrain", &LLColor4::green6, 0 },
- { LLFastTimer::FTM_RENDER_CHARACTERS, " Avatars", &LLColor4::yellow1, 0 },
- { LLFastTimer::FTM_RENDER_SIMPLE, " Simple", &LLColor4::yellow2, 0 },
- { LLFastTimer::FTM_RENDER_FULLBRIGHT, " Fullbright", &LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_RENDER_GLOW, " Glow", &LLColor4::orange1, 0 },
- { LLFastTimer::FTM_RENDER_GRASS, " Grass", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_RENDER_INVISIBLE, " Invisible", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_RENDER_SHINY, " Shiny", &LLColor4::yellow3, 0 },
- { LLFastTimer::FTM_RENDER_BUMP, " Bump", &LLColor4::yellow4, 0 },
- { LLFastTimer::FTM_RENDER_TREES, " Trees", &LLColor4::yellow8, 0 },
- { LLFastTimer::FTM_RENDER_OCCLUSION, " Occlusion", &LLColor4::red1, 0 },
- { LLFastTimer::FTM_RENDER_CLOUDS, " Clouds", &LLColor4::yellow5, 0 },
- { LLFastTimer::FTM_RENDER_ALPHA, " Alpha", &LLColor4::yellow6, 0 },
- { LLFastTimer::FTM_RENDER_HUD, " HUD", &LLColor4::yellow7, 0 },
- { LLFastTimer::FTM_RENDER_WATER, " Water", &LLColor4::yellow9, 0 },
- { LLFastTimer::FTM_RENDER_WL_SKY, " WL Sky", &LLColor4::blue3, 0 },
- { LLFastTimer::FTM_RENDER_FAKE_VBO_UPDATE," Fake VBO update", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_RENDER_BLOOM, " Bloom", &LLColor4::blue4, 0 },
- { LLFastTimer::FTM_RENDER_BLOOM_FBO, " First FBO", &LLColor4::blue, 0 },
- { LLFastTimer::FTM_RENDER_UI, " UI", &LLColor4::cyan4, 1 },
- { LLFastTimer::FTM_RENDER_TIMER, " Timers", &LLColor4::cyan5, 1, 0 },
- { LLFastTimer::FTM_RENDER_FONTS, " Fonts", &LLColor4::pink1, 0 },
- { LLFastTimer::FTM_SWAP, " Swap", &LLColor4::pink2, 0 },
- { LLFastTimer::FTM_CLIENT_COPY, " Client Copy", &LLColor4::red1, 1},
-
-#if 0 || !LL_RELEASE_FOR_DOWNLOAD
- { LLFastTimer::FTM_TEMP1, " Temp1", &LLColor4::red1, 0 },
- { LLFastTimer::FTM_TEMP2, " Temp2", &LLColor4::magenta1, 0 },
- { LLFastTimer::FTM_TEMP3, " Temp3", &LLColor4::red2, 0 },
- { LLFastTimer::FTM_TEMP4, " Temp4", &LLColor4::magenta2, 0 },
- { LLFastTimer::FTM_TEMP5, " Temp5", &LLColor4::red3, 0 },
- { LLFastTimer::FTM_TEMP6, " Temp6", &LLColor4::magenta3, 0 },
- { LLFastTimer::FTM_TEMP7, " Temp7", &LLColor4::red4, 0 },
- { LLFastTimer::FTM_TEMP8, " Temp8", &LLColor4::magenta4, 0 },
-#endif
-
- { LLFastTimer::FTM_OTHER, " Other", &red0 }
-};
-static int ft_display_didcalc = 0;
-static const int FTV_DISPLAY_NUM = LL_ARRAY_SIZE(ft_display_table);
+//static const int FTV_DISPLAY_NUM = (sizeof(ft_display_table)/sizeof(ft_display_table[0]));
+static S32 FTV_NUM_TIMERS;
+const S32 FTV_MAX_DEPTH = 8;
+
+std::vector<LLFastTimer::NamedTimer*> ft_display_idx; // line of table entry for display purposes (for collapse)
+
+typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_iterator_t;
-S32 ft_display_idx[FTV_DISPLAY_NUM]; // line of table entry for display purposes (for collapse)
+BOOL LLFastTimerView::sAnalyzePerformance = FALSE;
+
+static timer_tree_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id)
+{
+ return timer_tree_iterator_t(&id,
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1),
+ boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_iterator_t end_timer_tree()
+{
+ return timer_tree_iterator_t();
+}
-LLFastTimerView::LLFastTimerView(const std::string& name, const LLRect& rect)
- : LLFloater(name, rect, std::string("Fast Timers"))
+LLFastTimerView::LLFastTimerView(const LLRect& rect)
+: LLFloater(),
+ mHoverTimer(NULL)
{
+ setRect(rect);
setVisible(FALSE);
mDisplayMode = 0;
mAvgCountTotal = 0;
mMaxCountTotal = 0;
- mDisplayCenter = 1;
+ mDisplayCenter = ALIGN_CENTER;
mDisplayCalls = 0;
mDisplayHz = 0;
mScrollIndex = 0;
- mHoverIndex = -1;
+ mHoverID = NULL;
mHoverBarIndex = -1;
- mBarStart = new S32[(MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM];
- memset(mBarStart, 0, (MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM * sizeof(S32));
- mBarEnd = new S32[(MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM];
- memset(mBarEnd, 0, (MAX_VISIBLE_HISTORY + 1) * FTV_DISPLAY_NUM * sizeof(S32));
- mSubtractHidden = 0;
+ FTV_NUM_TIMERS = LLFastTimer::NamedTimer::instanceCount();
mPrintStats = -1;
-
- // One-time setup
- if (!ft_display_didcalc)
- {
- int pidx[FTV_DISPLAY_NUM];
- int pdisabled[FTV_DISPLAY_NUM];
- for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
- {
- int level = 0;
- const char *text = ft_display_table[i].desc;
- while(text[0] == ' ')
- {
- text++;
- level++;
- }
- llassert(level < FTV_DISPLAY_NUM);
- ft_display_table[i].desc = text;
- ft_display_table[i].level = level;
- if (level > 0)
- {
- ft_display_table[i].parent = pidx[level-1];
- if (pdisabled[level-1])
- {
- ft_display_table[i].disabled = 3;
- }
- }
- else
- {
- ft_display_table[i].parent = -1;
- }
- ft_display_idx[i] = i;
- pidx[level] = i;
- pdisabled[level] = ft_display_table[i].disabled;
- }
- ft_display_didcalc = 1;
- }
}
-LLFastTimerView::~LLFastTimerView()
-{
- delete[] mBarStart;
- delete[] mBarEnd;
-}
BOOL LLFastTimerView::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
- if (mBarRect.pointInRect(x, y))
+ if (mHoverTimer )
+ {
+ // right click collapses timers
+ if (!mHoverTimer->getCollapsed())
+ {
+ mHoverTimer->setCollapsed(true);
+ }
+ else if (mHoverTimer->getParent())
+ {
+ mHoverTimer->getParent()->setCollapsed(true);
+ }
+ }
+ else if (mBarRect.pointInRect(x, y))
{
S32 bar_idx = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
bar_idx = llclamp(bar_idx, 0, MAX_VISIBLE_HISTORY);
mPrintStats = bar_idx;
-// return TRUE; // for now, pass all mouse events through
}
return FALSE;
}
-S32 LLFastTimerView::getLegendIndex(S32 y)
+LLFastTimer::NamedTimer* LLFastTimerView::getLegendID(S32 y)
{
S32 idx = (getRect().getHeight() - y) / ((S32) LLFontGL::getFontMonospace()->getLineHeight()+2) - 5;
- if (idx >= 0 && idx < FTV_DISPLAY_NUM)
+
+ if (idx >= 0 && idx < (S32)ft_display_idx.size())
{
return ft_display_idx[idx];
}
- return -1;
+ return NULL;
}
BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (x < mBarRect.mLeft)
{
- S32 legend_index = getLegendIndex(y);
- if (legend_index >= 0 && legend_index < FTV_DISPLAY_NUM)
+ LLFastTimer::NamedTimer* idp = getLegendID(y);
+ if (idp)
{
- S32 disabled = ft_display_table[legend_index].disabled;
- if (++disabled > 2)
- disabled = 0;
- ft_display_table[legend_index].disabled = disabled;
- S32 level = ft_display_table[legend_index].level;
-
- // propagate enable/disable to all children
- legend_index++;
- while (legend_index < FTV_DISPLAY_NUM && ft_display_table[legend_index].level > level)
- {
- ft_display_table[legend_index].disabled = disabled ? 3 : 0;
- legend_index++;
- }
+ idp->setCollapsed(!idp->getCollapsed());
}
}
+ else if (mHoverTimer)
+ {
+ //left click drills down by expanding timers
+ mHoverTimer->setCollapsed(false);
+ }
else if (mask & MASK_ALT)
{
- if (mask & MASK_SHIFT)
- {
- mSubtractHidden = !mSubtractHidden;
- }
- else if (mask & MASK_CONTROL)
+ if (mask & MASK_CONTROL)
{
mDisplayHz = !mDisplayHz;
}
@@ -345,8 +167,7 @@ BOOL LLFastTimerView::handleMouseDown(S32 x, S32 y, MASK mask)
}
else if (mask & MASK_CONTROL)
{
- if (++mDisplayCenter > 2)
- mDisplayCenter = 0;
+ mDisplayCenter = (ChildAlignment)((mDisplayCenter + 1) % ALIGN_COUNT);
}
else
{
@@ -367,13 +188,14 @@ BOOL LLFastTimerView::handleMouseUp(S32 x, S32 y, MASK mask)
return FALSE;
}
-
BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
{
+ mHoverTimer = NULL;
+ mHoverID = NULL;
+
if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
{
- mHoverIndex = -1;
- mHoverBarIndex = MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight());
+ mHoverBarIndex = llmin(LLFastTimer::getCurFrameIndex() - 1, MAX_VISIBLE_HISTORY - ((y - mBarRect.mBottom) * (MAX_VISIBLE_HISTORY + 2) / mBarRect.getHeight()));
if (mHoverBarIndex == 0)
{
return TRUE;
@@ -382,39 +204,88 @@ BOOL LLFastTimerView::handleHover(S32 x, S32 y, MASK mask)
{
mHoverBarIndex = 0;
}
- for (S32 i = 0; i < FTV_DISPLAY_NUM; i++)
+
+ S32 i = 0;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it, ++i)
{
- if (x > mBarStart[mHoverBarIndex * FTV_DISPLAY_NUM + i] &&
- x < mBarEnd[mHoverBarIndex * FTV_DISPLAY_NUM + i] &&
- ft_display_table[i].disabled <= 1)
+ // is mouse over bar for this timer?
+ if (x > mBarStart[mHoverBarIndex][i] &&
+ x < mBarEnd[mHoverBarIndex][i])
+ {
+ mHoverID = (*it);
+ mHoverTimer = (*it);
+ mToolTipRect.set(mBarStart[mHoverBarIndex][i],
+ mBarRect.mBottom + llround(((F32)mHoverBarIndex + 1.f) * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))),
+ mBarEnd[mHoverBarIndex][i],
+ mBarRect.mBottom + llround((F32)mHoverBarIndex * ((F32)mBarRect.getHeight() / ((F32)MAX_VISIBLE_HISTORY + 2.f))));
+ }
+
+ if ((*it)->getCollapsed())
{
- mHoverIndex = i;
+ it.skipDescendants();
}
}
}
else if (x < mBarRect.mLeft)
{
- S32 legend_index = getLegendIndex(y);
- if (legend_index >= 0 && legend_index < FTV_DISPLAY_NUM)
+ LLFastTimer::NamedTimer* timer_id = getLegendID(y);
+ if (timer_id)
{
- mHoverIndex = legend_index;
+ mHoverID = timer_id;
}
}
return FALSE;
}
+
+BOOL LLFastTimerView::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen)
+{
+ if(LLFastTimer::sPauseHistory && mBarRect.pointInRect(x, y))
+ {
+ // tooltips for timer bars
+ if (mHoverTimer)
+ {
+ msg = mHoverTimer->getToolTip(LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex);
+ return TRUE;
+ }
+ }
+ else
+ {
+ // tooltips for timer legend
+ if (x < mBarRect.mLeft)
+ {
+ LLFastTimer::NamedTimer* idp = getLegendID(y);
+ if (idp)
+ {
+ msg = idp->getToolTip();
+ return TRUE;
+ }
+ }
+
+ }
+
+ return FALSE;
+}
+
BOOL LLFastTimerView::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
LLFastTimer::sPauseHistory = TRUE;
mScrollIndex = llclamp(mScrollIndex - clicks,
- 0, llmin(LLFastTimer::sLastFrameIndex, (S32)LLFastTimer::FTM_HISTORY_NUM-MAX_VISIBLE_HISTORY));
+ 0,
+ llmin(LLFastTimer::getLastFrameIndex(), (S32)LLFastTimer::NamedTimer::HISTORY_NUM - MAX_VISIBLE_HISTORY));
return TRUE;
}
+static LLFastTimer::DeclareTimer FTM_RENDER_TIMER("Timers", true);
+
+static std::map<LLFastTimer::NamedTimer*, LLColor4> sTimerColors;
+
void LLFastTimerView::draw()
{
- LLFastTimer t(LLFastTimer::FTM_RENDER_TIMER);
+ LLFastTimer t(FTM_RENDER_TIMER);
std::string tdesc;
@@ -433,47 +304,9 @@ void LLFastTimerView::draw()
S32 texth, textw;
LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("rounded_square.tga");
- // Make sure all timers are accounted for
- // Set 'FTM_OTHER' to unaccounted ticks last frame
- {
- S32 display_timer[LLFastTimer::FTM_NUM_TYPES];
- S32 hidx = LLFastTimer::sLastFrameIndex % LLFastTimer::FTM_HISTORY_NUM;
- for (S32 i=0; i < LLFastTimer::FTM_NUM_TYPES; i++)
- {
- display_timer[i] = 0;
- }
- for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
- {
- S32 tidx = ft_display_table[i].timer;
- display_timer[tidx] = 1;
- }
- LLFastTimer::sCountHistory[hidx][LLFastTimer::FTM_OTHER] = 0;
- LLFastTimer::sCallHistory[hidx][LLFastTimer::FTM_OTHER] = 0;
- for (S32 tidx = 0; tidx < LLFastTimer::FTM_NUM_TYPES; tidx++)
- {
- U64 counts = LLFastTimer::sCountHistory[hidx][tidx];
- if (counts > 0 && display_timer[tidx] == 0)
- {
- LLFastTimer::sCountHistory[hidx][LLFastTimer::FTM_OTHER] += counts;
- LLFastTimer::sCallHistory[hidx][LLFastTimer::FTM_OTHER] += 1;
- }
- }
- LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] = 0;
- LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] = 0;
- for (S32 h = 0; h < LLFastTimer::FTM_HISTORY_NUM; h++)
- {
- LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] += LLFastTimer::sCountHistory[h][LLFastTimer::FTM_OTHER];
- LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] += LLFastTimer::sCallHistory[h][LLFastTimer::FTM_OTHER];
- }
- LLFastTimer::sCountAverage[LLFastTimer::FTM_OTHER] /= LLFastTimer::FTM_HISTORY_NUM;
- LLFastTimer::sCallAverage[LLFastTimer::FTM_OTHER] /= LLFastTimer::FTM_HISTORY_NUM;
- }
-
// Draw the window background
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
- }
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.f, 0.f, 0.f, 0.25f));
S32 xleft = margin;
S32 ytop = margin;
@@ -512,148 +345,135 @@ void LLFastTimerView::draw()
y -= (texth + 2);
}
- // Calc the total ticks
- S32 histmax = llmin(LLFastTimer::sLastFrameIndex+1, MAX_VISIBLE_HISTORY);
- U64 ticks_sum[LLFastTimer::FTM_HISTORY_NUM+1][FTV_DISPLAY_NUM];
- for (S32 j=-1; j<LLFastTimer::FTM_HISTORY_NUM; j++)
- {
- S32 hidx;
- if (j >= 0)
- hidx = (LLFastTimer::sLastFrameIndex+j) % LLFastTimer::FTM_HISTORY_NUM;
- else
- hidx = -1;
-
- // calculate tick info by adding child ticks to parents
- for (S32 i=0; i < FTV_DISPLAY_NUM; i++)
- {
- if (mSubtractHidden && ft_display_table[i].disabled > 1)
- {
- continue;
- }
- // Get ticks
- S32 tidx = ft_display_table[i].timer;
- if (hidx >= 0)
- ticks_sum[j+1][i] = LLFastTimer::sCountHistory[hidx][tidx];
- else
- ticks_sum[j+1][i] = LLFastTimer::sCountAverage[tidx];
- S32 pidx = ft_display_table[i].parent;
- // Add ticks to parents
- while (pidx >= 0)
- {
- ticks_sum[j+1][pidx] += ticks_sum[j+1][i];
- pidx = ft_display_table[pidx].parent;
- }
- }
- }
+ S32 histmax = llmin(LLFastTimer::getLastFrameIndex()+1, MAX_VISIBLE_HISTORY);
// Draw the legend
-
- S32 legendwidth = 0;
xleft = margin;
ytop = y;
y -= (texth + 2);
- S32 cur_line = 0;
- S32 display_line[FTV_DISPLAY_NUM];
- for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
+ sTimerColors[&LLFastTimer::NamedTimer::getRootNamedTimer()] = LLColor4::grey;
+
+ F32 hue = 0.f;
+
+ for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != timer_tree_iterator_t();
+ ++it)
{
- S32 disabled = ft_display_table[i].disabled;
- if (disabled == 3)
- {
- continue; // skip row
- }
- display_line[i] = cur_line;
- ft_display_idx[cur_line] = i;
- cur_line++;
- S32 level = ft_display_table[i].level;
- S32 parent = ft_display_table[i].parent;
-
- x = xleft;
+ LLFastTimer::NamedTimer* idp = (*it);
- left = x; right = x + texth;
- top = y; bottom = y - texth;
- S32 scale_offset = 0;
- if (i == mHoverIndex)
- {
- scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
- }
- gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, *ft_display_table[i].color);
+ const F32 HUE_INCREMENT = 0.23f;
+ hue = fmodf(hue + HUE_INCREMENT, 1.f);
+ // saturation increases with depth
+ F32 saturation = clamp_rescale((F32)idp->getDepth(), 0.f, 3.f, 0.f, 1.f);
+ // lightness alternates with depth
+ F32 lightness = idp->getDepth() % 2 ? 0.5f : 0.6f;
- int tidx = ft_display_table[i].timer;
- F32 ms = 0;
- S32 calls = 0;
- if (mHoverBarIndex > 0 && mHoverIndex >= 0)
- {
- S32 hidx = (LLFastTimer::sLastFrameIndex + (mHoverBarIndex - 1) - mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
- S32 bidx = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex - mHoverBarIndex;
- U64 ticks = ticks_sum[bidx+1][i]; // : LLFastTimer::sCountHistory[hidx][tidx];
- ms = (F32)((F64)ticks * iclock_freq);
- calls = (S32)LLFastTimer::sCallHistory[hidx][tidx];
- }
- else
- {
- U64 ticks = ticks_sum[0][i];
- ms = (F32)((F64)ticks * iclock_freq);
- calls = (S32)LLFastTimer::sCallAverage[tidx];
- }
- if (mDisplayCalls)
- {
- tdesc = llformat("%s (%d)",ft_display_table[i].desc,calls);
- }
- else
- {
- tdesc = llformat("%s [%.1f]",ft_display_table[i].desc,ms);
- }
- dx = (texth+4) + level*8;
+ LLColor4 child_color;
+ child_color.setHSL(hue, saturation, lightness);
+
+ sTimerColors[idp] = child_color;
+ }
- LLColor4 color = disabled > 1 ? LLColor4::grey : LLColor4::white;
- if (level > 0)
+ const S32 LEGEND_WIDTH = 220;
+ {
+ LLLocalClipRect clip(LLRect(margin, y, LEGEND_WIDTH, margin));
+ S32 cur_line = 0;
+ ft_display_idx.clear();
+ std::map<LLFastTimer::NamedTimer*, S32> display_line;
+ for (timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != timer_tree_iterator_t();
+ ++it)
{
- S32 line_start_y = (top + bottom) / 2;
- S32 line_end_y = line_start_y + ((texth + 2) * (display_line[i] - display_line[parent])) - (texth / 2);
- gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
- S32 line_x = x + (texth + 4) + ((level - 1) * 8);
- gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
- if (disabled == 1)
+ LLFastTimer::NamedTimer* idp = (*it);
+ display_line[idp] = cur_line;
+ ft_display_idx.push_back(idp);
+ cur_line++;
+
+ x = xleft;
+
+ left = x; right = x + texth;
+ top = y; bottom = y - texth;
+ S32 scale_offset = 0;
+ if (idp == mHoverID)
{
- gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
+ scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 2.f);
}
- }
+ gl_rect_2d(left - scale_offset, top + scale_offset, right + scale_offset, bottom - scale_offset, sTimerColors[idp]);
- x += dx;
- BOOL is_child_of_hover_item = (i == mHoverIndex);
- S32 next_parent = ft_display_table[i].parent;
- while(!is_child_of_hover_item && next_parent >= 0)
- {
- is_child_of_hover_item = (mHoverIndex == next_parent);
- next_parent = ft_display_table[next_parent].parent;
- }
+ F32 ms = 0;
+ S32 calls = 0;
+ if (mHoverBarIndex > 0 && mHoverID)
+ {
+ S32 hidx = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex - mHoverBarIndex;
+ U64 ticks = idp->getHistoricalCount(hidx);
+ ms = (F32)((F64)ticks * iclock_freq);
+ calls = (S32)idp->getHistoricalCalls(hidx);
+ }
+ else
+ {
+ U64 ticks = idp->getCountAverage();
+ ms = (F32)((F64)ticks * iclock_freq);
+ calls = (S32)idp->getCallAverage();
+ }
- if (is_child_of_hover_item)
- {
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD);
- }
- else
- {
- LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, color, LLFontGL::LEFT, LLFontGL::TOP);
- }
- y -= (texth + 2);
+ if (mDisplayCalls)
+ {
+ tdesc = llformat("%s (%d)",idp->getName().c_str(),calls);
+ }
+ else
+ {
+ tdesc = llformat("%s [%.1f]",idp->getName().c_str(),ms);
+ }
+ dx = (texth+4) + idp->getDepth()*8;
- textw = dx + LLFontGL::getFontMonospace()->getWidth(std::string(ft_display_table[i].desc)) + 40;
- if (textw > legendwidth)
- legendwidth = textw;
- }
- for (S32 i=cur_line; i<FTV_DISPLAY_NUM; i++)
- {
- ft_display_idx[i] = -1;
+ LLColor4 color = LLColor4::white;
+ if (idp->getDepth() > 0)
+ {
+ S32 line_start_y = (top + bottom) / 2;
+ S32 line_end_y = line_start_y + ((texth + 2) * (cur_line - display_line[idp->getParent()])) - texth;
+ gl_line_2d(x + dx - 8, line_start_y, x + dx, line_start_y, color);
+ S32 line_x = x + (texth + 4) + ((idp->getDepth() - 1) * 8);
+ gl_line_2d(line_x, line_start_y, line_x, line_end_y, color);
+ if (idp->getCollapsed() && !idp->getChildren().empty())
+ {
+ gl_line_2d(line_x+4, line_start_y-3, line_x+4, line_start_y+4, color);
+ }
+ }
+
+ x += dx;
+ BOOL is_child_of_hover_item = (idp == mHoverID);
+ LLFastTimer::NamedTimer* next_parent = idp->getParent();
+ while(!is_child_of_hover_item && next_parent)
+ {
+ is_child_of_hover_item = (mHoverID == next_parent);
+ next_parent = next_parent->getParent();
+ }
+
+ LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0,
+ x, y,
+ color,
+ LLFontGL::LEFT, LLFontGL::TOP,
+ is_child_of_hover_item ? LLFontGL::BOLD : LLFontGL::NORMAL);
+
+ y -= (texth + 2);
+
+ textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40;
+
+ if (idp->getCollapsed())
+ {
+ it.skipDescendants();
+ }
+ }
}
- xleft += legendwidth + 8;
+
+ xleft += LEGEND_WIDTH + 8;
// ytop = ytop;
// update rectangle that includes timer bars
mBarRect.mLeft = xleft;
- mBarRect.mRight = getRect().mRight - xleft;
+ mBarRect.mRight = getRect().getWidth();
mBarRect.mTop = ytop - ((S32)LLFontGL::getFontMonospace()->getLineHeight() + 4);
mBarRect.mBottom = margin + LINE_GRAPH_HEIGHT;
@@ -665,25 +485,18 @@ void LLFastTimerView::draw()
barw = width - xleft - margin;
// Draw the history bars
- if (LLFastTimer::sLastFrameIndex >= 0)
+ if (LLFastTimer::getLastFrameIndex() >= 0)
{
+ LLLocalClipRect clip(LLRect(xleft, ytop - margin, getRect().getWidth() - margin, margin));
+
U64 totalticks;
if (!LLFastTimer::sPauseHistory)
{
- U64 ticks = 0;
- int hidx = (LLFastTimer::sLastFrameIndex - mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
- for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
- {
- if (mSubtractHidden && ft_display_table[i].disabled > 1)
- {
- continue;
- }
- int tidx = ft_display_table[i].timer;
- ticks += LLFastTimer::sCountHistory[hidx][tidx];
- }
- if (LLFastTimer::sCurFrameIndex >= 10)
+ U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(mScrollIndex);
+
+ if (LLFastTimer::getCurFrameIndex() >= 10)
{
- U64 framec = LLFastTimer::sCurFrameIndex;
+ U64 framec = LLFastTimer::getCurFrameIndex();
U64 avg = (U64)mAvgCountTotal;
mAvgCountTotal = (avg*framec + ticks) / (framec + 1);
if (ticks > mMaxCountTotal)
@@ -691,11 +504,13 @@ void LLFastTimerView::draw()
mMaxCountTotal = ticks;
}
}
-#if 1
+
if (ticks < mAvgCountTotal/100 || ticks > mAvgCountTotal*100)
- LLFastTimer::sResetHistory = 1;
-#endif
- if (LLFastTimer::sCurFrameIndex < 10 || LLFastTimer::sResetHistory)
+ {
+ LLFastTimer::sResetHistory = true;
+ }
+
+ if (LLFastTimer::getCurFrameIndex() < 10 || LLFastTimer::sResetHistory)
{
mAvgCountTotal = ticks;
mMaxCountTotal = ticks;
@@ -716,16 +531,8 @@ void LLFastTimerView::draw()
totalticks = 0;
for (S32 j=0; j<histmax; j++)
{
- U64 ticks = 0;
- for (S32 i=0; i<FTV_DISPLAY_NUM; i++)
- {
- if (mSubtractHidden && ft_display_table[i].disabled > 1)
- {
- continue;
- }
- int tidx = ft_display_table[i].timer;
- ticks += LLFastTimer::sCountHistory[j][tidx];
- }
+ U64 ticks = LLFastTimer::NamedTimer::getRootNamedTimer().getHistoricalCount(j);
+
if (ticks > totalticks)
totalticks = ticks;
}
@@ -798,18 +605,23 @@ void LLFastTimerView::draw()
gl_rect_2d(graph_rect, FALSE);
}
+ mBarStart.clear();
+ mBarEnd.clear();
+
// Draw bars for each history entry
// Special: -1 = show running average
gGL.getTexUnit(0)->bind(box_imagep->getImage());
for (S32 j=-1; j<histmax && y > LINE_GRAPH_HEIGHT; j++)
{
- int sublevel_dx[FTV_DISPLAY_NUM+1];
- int sublevel_left[FTV_DISPLAY_NUM+1];
- int sublevel_right[FTV_DISPLAY_NUM+1];
+ mBarStart.push_back(std::vector<S32>());
+ mBarEnd.push_back(std::vector<S32>());
+ int sublevel_dx[FTV_MAX_DEPTH];
+ int sublevel_left[FTV_MAX_DEPTH];
+ int sublevel_right[FTV_MAX_DEPTH];
S32 tidx;
if (j >= 0)
{
- tidx = LLFastTimer::FTM_HISTORY_NUM - j - 1 - mScrollIndex;
+ tidx = LLFastTimer::NamedTimer::HISTORY_NUM - j - 1 - mScrollIndex;
}
else
{
@@ -819,88 +631,75 @@ void LLFastTimerView::draw()
x = xleft;
// draw the bars for each stat
- int xpos[FTV_DISPLAY_NUM+1];
- int deltax[FTV_DISPLAY_NUM+1];
- xpos[0] = xleft;
+ std::vector<S32> xpos;
+ std::vector<S32> deltax;
+ xpos.push_back(xleft);
+
+ LLFastTimer::NamedTimer* prev_id = NULL;
- for (S32 i = 0; i < FTV_DISPLAY_NUM; i++)
+ S32 i = 0;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it, ++i)
{
- if (ft_display_table[i].disabled > 1)
- {
- continue;
- }
-
- F32 frac = (F32)ticks_sum[tidx+1][i] / (F32)totalticks;
+ LLFastTimer::NamedTimer* idp = (*it);
+ F32 frac = tidx == -1
+ ? (F32)idp->getCountAverage() / (F32)totalticks
+ : (F32)idp->getHistoricalCount(tidx) / (F32)totalticks;
dx = llround(frac * (F32)barw);
- deltax[i] = dx;
+ S32 prev_delta_x = deltax.empty() ? 0 : deltax.back();
+ deltax.push_back(dx);
- int level = ft_display_table[i].level;
- int parent = ft_display_table[i].parent;
- llassert(level < FTV_DISPLAY_NUM);
- llassert(parent < FTV_DISPLAY_NUM);
+ int level = idp->getDepth() - 1;
- left = xpos[level];
-
- S32 prev_idx = i - 1;
- while (prev_idx > 0)
- {
- if (ft_display_table[prev_idx].disabled <= 1)
- {
- break;
- }
- prev_idx--;
- }
- S32 next_idx = i + 1;
- while (next_idx < FTV_DISPLAY_NUM)
+ while ((S32)xpos.size() > level + 1)
{
- if (ft_display_table[next_idx].disabled <= 1)
- {
- break;
- }
- next_idx++;
+ xpos.pop_back();
}
-
+ left = xpos.back();
+
if (level == 0)
- {
+ {
sublevel_left[level] = xleft;
sublevel_dx[level] = dx;
sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
- }
- else if (i==0 || ft_display_table[prev_idx].level < level)
+ }
+ else if (prev_id && prev_id->getDepth() < idp->getDepth())
{
- // If we are the first entry at a new sublevel block, calc the
- // total width of this sublevel and modify left to align block.
- U64 sublevelticks = ticks_sum[tidx+1][i];
- for (S32 k=i+1; k<FTV_DISPLAY_NUM; k++)
- {
- if (ft_display_table[k].level < level)
- break;
- if (ft_display_table[k].disabled <= 1 && ft_display_table[k].level == level)
- sublevelticks += ticks_sum[tidx+1][k];
- }
- F32 subfrac = (F32)sublevelticks / (F32)totalticks;
+ U64 sublevelticks = 0;
+
+ for (LLFastTimer::NamedTimer::child_const_iter it = prev_id->beginChildren();
+ it != prev_id->endChildren();
+ ++it)
+ {
+ sublevelticks += (tidx == -1)
+ ? (*it)->getCountAverage()
+ : (*it)->getHistoricalCount(tidx);
+ }
+
+ F32 subfrac = (F32)sublevelticks / (F32)totalticks;
sublevel_dx[level] = (int)(subfrac * (F32)barw + .5f);
- if (mDisplayCenter == 1) // center aligned
+ if (mDisplayCenter == ALIGN_CENTER)
{
- left += (deltax[parent] - sublevel_dx[level])/2;
+ left += (prev_delta_x - sublevel_dx[level])/2;
}
- else if (mDisplayCenter == 2) // right aligned
+ else if (mDisplayCenter == ALIGN_RIGHT)
{
- left += (deltax[parent] - sublevel_dx[level]);
- }
+ left += (prev_delta_x - sublevel_dx[level]);
+ }
sublevel_left[level] = left;
sublevel_right[level] = sublevel_left[level] + sublevel_dx[level];
}
right = left + dx;
- xpos[level] = right;
- xpos[level+1] = left;
+ xpos.back() = right;
+ xpos.push_back(left);
- mBarStart[(j + 1) * FTV_DISPLAY_NUM + i] = left;
- mBarEnd[(j + 1) * FTV_DISPLAY_NUM + i] = right;
+ mBarStart.back().push_back(left);
+ mBarEnd.back().push_back(right);
top = y;
bottom = y - barh;
@@ -908,23 +707,23 @@ void LLFastTimerView::draw()
if (right > left)
{
//U32 rounded_edges = 0;
- LLColor4 color = *ft_display_table[i].color;
+ LLColor4 color = sTimerColors[idp];//*ft_display_table[i].color;
S32 scale_offset = 0;
- BOOL is_child_of_hover_item = (i == mHoverIndex);
- S32 next_parent = ft_display_table[i].parent;
- while(!is_child_of_hover_item && next_parent >= 0)
+ BOOL is_child_of_hover_item = (idp == mHoverID);
+ LLFastTimer::NamedTimer* next_parent = idp->getParent();
+ while(!is_child_of_hover_item && next_parent)
{
- is_child_of_hover_item = (mHoverIndex == next_parent);
- next_parent = ft_display_table[next_parent].parent;
+ is_child_of_hover_item = (mHoverID == next_parent);
+ next_parent = next_parent->getParent();
}
- if (i == mHoverIndex)
+ if (idp == mHoverID)
{
scale_offset = llfloor(sinf(mHighlightTimer.getElapsedTimeF32() * 6.f) * 3.f);
//color = lerp(color, LLColor4::black, -0.4f);
}
- else if (mHoverIndex >= 0 && !is_child_of_hover_item)
+ else if (mHoverID != NULL && !is_child_of_hover_item)
{
color = lerp(color, LLColor4::grey, 0.8f);
}
@@ -935,7 +734,13 @@ void LLFastTimerView::draw()
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);
}
-
+
+ if ((*it)->getCollapsed())
+ {
+ it.skipDescendants();
+ }
+
+ prev_id = idp;
}
y -= (barh + dy);
if (j < 0)
@@ -970,10 +775,10 @@ void LLFastTimerView::draw()
//highlight visible range
{
- S32 first_frame = LLFastTimer::FTM_HISTORY_NUM - mScrollIndex;
+ S32 first_frame = LLFastTimer::NamedTimer::HISTORY_NUM - mScrollIndex;
S32 last_frame = first_frame - MAX_VISIBLE_HISTORY;
- F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1);
+ F32 frame_delta = ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1);
F32 right = (F32) graph_rect.mLeft + frame_delta*first_frame;
F32 left = (F32) graph_rect.mLeft + frame_delta*last_frame;
@@ -996,28 +801,27 @@ void LLFastTimerView::draw()
}
U64 cur_max = 0;
- for (S32 idx = 0; idx < FTV_DISPLAY_NUM; ++idx)
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it)
{
- if (ft_display_table[idx].disabled > 1)
- { //skip disabled timers
- continue;
- }
+ LLFastTimer::NamedTimer* idp = (*it);
//fatten highlighted timer
- if (mHoverIndex == idx)
+ if (mHoverID == idp)
{
gGL.flush();
glLineWidth(3);
}
- const F32 * col = ft_display_table[idx].color->mV;
+ const F32 * col = sTimerColors[idp].mV;// ft_display_table[idx].color->mV;
F32 alpha = 1.f;
- if (mHoverIndex >= 0 &&
- idx != mHoverIndex)
+ if (mHoverID != NULL &&
+ idp != mHoverID)
{ //fade out non-hihglighted timers
- if (ft_display_table[idx].parent != mHoverIndex)
+ if (idp->getParent() != mHoverID)
{
alpha = alpha_interp;
}
@@ -1025,9 +829,9 @@ void LLFastTimerView::draw()
gGL.color4f(col[0], col[1], col[2], alpha);
gGL.begin(LLRender::LINE_STRIP);
- for (U32 j = 0; j < LLFastTimer::FTM_HISTORY_NUM; j++)
+ for (U32 j = 0; j < LLFastTimer::NamedTimer::HISTORY_NUM; j++)
{
- U64 ticks = ticks_sum[j+1][idx];
+ U64 ticks = idp->getHistoricalCount(j);
if (mDisplayHz)
{
@@ -1037,26 +841,31 @@ void LLFastTimerView::draw()
}
else if (mDisplayCalls)
{
- S32 tidx = ft_display_table[idx].timer;
- S32 hidx = (LLFastTimer::sLastFrameIndex + j) % LLFastTimer::FTM_HISTORY_NUM;
- ticks = (S32)LLFastTimer::sCallHistory[hidx][tidx];
+ ticks = (S32)idp->getHistoricalCalls(j);
}
if (alpha == 1.f)
- { //normalize to highlighted timer
+ {
+ //normalize to highlighted timer
cur_max = llmax(cur_max, ticks);
}
- F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::FTM_HISTORY_NUM-1)*j;
+ F32 x = graph_rect.mLeft + ((F32) (graph_rect.getWidth()))/(LLFastTimer::NamedTimer::HISTORY_NUM-1)*j;
F32 y = graph_rect.mBottom + (F32) graph_rect.getHeight()/max_ticks*ticks;
gGL.vertex2f(x,y);
}
gGL.end();
- if (mHoverIndex == idx)
+ if (mHoverID == idp)
{
gGL.flush();
glLineWidth(1);
}
+
+ if (idp->getCollapsed())
+ {
+ //skip hidden timers
+ it.skipDescendants();
+ }
}
//interpolate towards new maximum
@@ -1068,12 +877,16 @@ void LLFastTimerView::draw()
alpha_interp = alpha_interp + (alpha_target-alpha_interp) * dt;
- if (mHoverIndex >= 0)
+ if (mHoverID != NULL)
{
x = (graph_rect.mRight + graph_rect.mLeft)/2;
y = graph_rect.mBottom + 8;
- LLFontGL::getFontMonospace()->renderUTF8(std::string(ft_display_table[mHoverIndex].desc), 0, x, y, LLColor4::white,
+ LLFontGL::getFontMonospace()->renderUTF8(
+ mHoverID->getName(),
+ 0,
+ x, y,
+ LLColor4::white,
LLFontGL::LEFT, LLFontGL::BOTTOM);
}
}
@@ -1083,87 +896,269 @@ void LLFastTimerView::draw()
if (mPrintStats >= 0)
{
std::string legend_stat;
- S32 stat_num;
- S32 first = 1;
- for (stat_num = 0; stat_num < FTV_DISPLAY_NUM; stat_num++)
+ bool first = true;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it)
{
- if (ft_display_table[stat_num].disabled > 1)
- continue;
+ LLFastTimer::NamedTimer* idp = (*it);
+
if (!first)
+ {
legend_stat += ", ";
- first=0;
- legend_stat += ft_display_table[stat_num].desc;
+ }
+ first = true;
+ legend_stat += idp->getName();
+
+ if (idp->getCollapsed())
+ {
+ it.skipDescendants();
+ }
}
llinfos << legend_stat << llendl;
std::string timer_stat;
- first = 1;
- for (stat_num = 0; stat_num < FTV_DISPLAY_NUM; stat_num++)
+ first = true;
+ for(timer_tree_iterator_t it = begin_timer_tree(LLFastTimer::NamedTimer::getRootNamedTimer());
+ it != end_timer_tree();
+ ++it)
{
- S32 disabled = ft_display_table[stat_num].disabled;
- if (disabled > 1)
- continue;
+ LLFastTimer::NamedTimer* idp = (*it);
+
if (!first)
+ {
timer_stat += ", ";
- first=0;
+ }
+ first = false;
+
U64 ticks;
- S32 tidx = ft_display_table[stat_num].timer;
if (mPrintStats > 0)
{
- S32 hidx = (LLFastTimer::sLastFrameIndex+(mPrintStats-1)-mScrollIndex) % LLFastTimer::FTM_HISTORY_NUM;
- ticks = disabled >= 1 ? ticks_sum[mPrintStats][stat_num] : LLFastTimer::sCountHistory[hidx][tidx];
+ S32 hidx = (mPrintStats - 1) - mScrollIndex;
+ ticks = idp->getHistoricalCount(hidx);
}
else
{
- ticks = disabled >= 1 ? ticks_sum[0][stat_num] : LLFastTimer::sCountAverage[tidx];
+ ticks = idp->getCountAverage();
}
F32 ms = (F32)((F64)ticks * iclock_freq);
timer_stat += llformat("%.1f",ms);
+
+ if (idp->getCollapsed())
+ {
+ it.skipDescendants();
+ }
}
llinfos << timer_stat << llendl;
mPrintStats = -1;
}
- mHoverIndex = -1;
+ mHoverID = NULL;
mHoverBarIndex = -1;
LLView::draw();
}
-F64 LLFastTimerView::getTime(LLFastTimer::EFastTimerType tidx)
+F64 LLFastTimerView::getTime(LLFastTimer::NamedTimer::FrameState& id)
{
- // Find table index
- S32 i;
- for (i=0; i<FTV_DISPLAY_NUM; i++)
+ return (F64)id.mTimer->getCountAverage() / (F64)LLFastTimer::countsPerSecond();
+}
+
+//static
+LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)
+{
+ LLSD ret;
+
+ LLSD cur;
+
+ LLSD::Real total_time = 0.0;
+ LLSD::Integer total_frames = 0;
+
+ while (!is.eof() && LLSDSerialize::fromXML(cur, is))
{
- if (tidx == ft_display_table[i].timer)
+ for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
{
- break;
+ std::string label = iter->first;
+
+ F64 time = iter->second["Time"].asReal();
+
+ total_time += time;
+
+ if (time > 0.0)
+ {
+ ret[label]["TotalTime"] = ret[label]["TotalTime"].asReal() + time;
+ ret[label]["MaxTime"] = llmax(time, ret[label]["MaxTime"].asReal());
+
+ if (ret[label]["MinTime"].asReal() == 0)
+ {
+ ret[label]["MinTime"] = time;
+ }
+ else
+ {
+ ret[label]["MinTime"] = llmin(ret[label]["MinTime"].asReal(), time);
+ }
+
+ LLSD::Integer samples = iter->second["Calls"].asInteger();
+
+ ret[label]["Samples"] = ret[label]["Samples"].asInteger() + samples;
+ ret[label]["MaxSamples"] = llmax(ret[label]["MaxSamples"].asInteger(), samples);
+
+ if (ret[label]["MinSamples"].asInteger() == 0)
+ {
+ ret[label]["MinSamples"] = samples;
+ }
+ else
+ {
+ ret[label]["MinSamples"] = llmin(ret[label]["MinSamples"].asInteger(), samples);
+ }
+ }
}
+ total_frames++;
}
+
+ ret["SessionTime"] = total_time;
+ ret["FrameCount"] = total_frames;
- if (i == FTV_DISPLAY_NUM)
+ return ret;
+
+}
+
+//static
+void LLFastTimerView::doAnalysisDefault(std::string baseline, std::string target, std::string output)
+{
+
+ //analyze baseline
+ std::ifstream base_is(baseline.c_str());
+ LLSD base = analyzePerformanceLogDefault(base_is);
+ base_is.close();
+
+ //analyze current
+ std::ifstream target_is(target.c_str());
+ LLSD current = analyzePerformanceLogDefault(target_is);
+ target_is.close();
+
+ //output comparision
+ std::ofstream os(output.c_str());
+
+ LLSD::Real session_time = current["SessionTime"].asReal();
+
+ os << "Label, % Change, % of Session, Cur Min, Cur Max, Cur Mean, Cur Total, Cur Samples, Base Min, Base Max, Base Mean, Base Total, Base Samples\n";
+ for (LLSD::map_iterator iter = base.beginMap(); iter != base.endMap(); ++iter)
{
- // walked off the end of ft_display_table without finding
- // the desired timer type
- llwarns << "Timer type " << tidx << " not known." << llendl;
- return F64(0.0);
+ LLSD::String label = iter->first;
+
+ if (current[label]["Samples"].asInteger() == 0 ||
+ base[label]["Samples"].asInteger() == 0)
+ {
+ //cannot compare
+ continue;
+ }
+ LLSD::Real a = base[label]["TotalTime"].asReal() / base[label]["Samples"].asReal();
+ LLSD::Real b = current[label]["TotalTime"].asReal() / base[label]["Samples"].asReal();
+
+ LLSD::Real diff = b-a;
+
+ LLSD::Real perc = diff/a * 100;
+
+ os << llformat("%s, %.2f, %.4f, %.4f, %.4f, %.4f, %.4f, %d, %.4f, %.4f, %.4f, %.4f, %d\n",
+ label.c_str(),
+ (F32) perc,
+ (F32) (current[label]["TotalTime"].asReal()/session_time * 100.0),
+ (F32) current[label]["MinTime"].asReal(),
+ (F32) current[label]["MaxTime"].asReal(),
+ (F32) b,
+ (F32) current[label]["TotalTime"].asReal(),
+ current[label]["Samples"].asInteger(),
+ (F32) base[label]["MinTime"].asReal(),
+ (F32) base[label]["MaxTime"].asReal(),
+ (F32) a,
+ (F32) base[label]["TotalTime"].asReal(),
+ base[label]["Samples"].asInteger());
}
- S32 table_idx = i;
- // Add child ticks to parent
- U64 ticks = LLFastTimer::sCountAverage[tidx];
- S32 level = ft_display_table[table_idx].level;
- for (i=table_idx+1; i<FTV_DISPLAY_NUM; i++)
+ os.flush();
+ os.close();
+}
+
+//-------------------------
+//static
+LLSD LLFastTimerView::analyzeMetricPerformanceLog(std::istream& is)
+{
+ LLSD ret;
+ LLSD cur;
+
+ while (!is.eof() && LLSDSerialize::fromXML(cur, is))
{
- if (ft_display_table[i].level <= level)
+ for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
{
- break;
+ std::string label = iter->first;
+
+ LLMetricPerformanceTester* tester = LLMetricPerformanceTester::getTester(iter->second["Name"].asString()) ;
+ if(tester)
+ {
+ ret[label]["Name"] = iter->second["Name"] ;
+
+ S32 num_of_strings = tester->getNumOfMetricStrings() ;
+ for(S32 index = 0 ; index < num_of_strings ; index++)
+ {
+ ret[label][ tester->getMetricString(index) ] = iter->second[ tester->getMetricString(index) ] ;
+ }
+ }
}
- ticks += LLFastTimer::sCountAverage[ft_display_table[i].timer];
}
+
+ return ret;
+}
+
+//static
+void LLFastTimerView::doAnalysisMetrics(std::string baseline, std::string target, std::string output)
+{
+ if(!LLMetricPerformanceTester::hasMetricPerformanceTesters())
+ {
+ return ;
+ }
+
+ //analyze baseline
+ std::ifstream base_is(baseline.c_str());
+ LLSD base = analyzeMetricPerformanceLog(base_is);
+ base_is.close();
+
+ //analyze current
+ std::ifstream target_is(target.c_str());
+ LLSD current = analyzeMetricPerformanceLog(target_is);
+ target_is.close();
- return (F64)ticks / (F64)LLFastTimer::countsPerSecond();
+ //output comparision
+ std::ofstream os(output.c_str());
+
+ os << "Label, Metric, Base(B), Target(T), Diff(T-B), Percentage(100*T/B)\n";
+ for(LLMetricPerformanceTester::name_tester_map_t::iterator iter = LLMetricPerformanceTester::sTesterMap.begin() ;
+ iter != LLMetricPerformanceTester::sTesterMap.end() ; ++iter)
+ {
+ LLMetricPerformanceTester* tester = ((LLMetricPerformanceTester*)iter->second) ;
+ tester->analyzePerformance(&os, &base, &current) ;
+ }
+
+ os.flush();
+ os.close();
}
+
+//static
+void LLFastTimerView::doAnalysis(std::string baseline, std::string target, std::string output)
+{
+ if(LLFastTimer::sLog)
+ {
+ doAnalysisDefault(baseline, target, output) ;
+ return ;
+ }
+
+ if(LLFastTimer::sMetricLog)
+ {
+ doAnalysisMetrics(baseline, target, output) ;
+ return ;
+ }
+}
+
+